/src/main/java/com/redradishtech/jira/ccmailer/UnsubscribeCCField.java
Java | 176 lines | 141 code | 18 blank | 17 comment | 8 complexity | 0893d38c3788637143591b7f469f3f0b MD5 | raw file
- package com.redradishtech.jira.ccmailer;
- import com.atlassian.jira.ManagerFactory;
- import com.atlassian.jira.issue.CustomFieldManager;
- import com.atlassian.jira.issue.IssueFactory;
- import com.atlassian.jira.issue.MutableIssue;
- import com.atlassian.jira.issue.fields.CustomField;
- import com.atlassian.jira.web.action.JiraWebActionSupport;
- import com.opensymphony.util.TextUtils;
- import com.redradishtech.jira.ccmailer.util.CustomFieldHelperBean;
- import org.ofbiz.core.entity.GenericValue;
- import javax.mail.Address;
- import javax.mail.Message;
- import javax.mail.MessagingException;
- import javax.mail.internet.InternetAddress;
- import javax.mail.internet.MimeMessage;
- import java.util.HashSet;
- import java.util.Properties;
- import java.util.Set;
- /**
- * JIRA action that removes an email address from an issue's CC custom field list. The email address, CC field ID and an
- * authorizing token are passed in as parameters of a GET request, usually in the form of an 'unsubscribe' URL in an email
- * notification.
- * <p/>
- * To prevent anyone from being allowed to remove any address from a CC list, we verify that the invoker was the recipient
- * of a JIRA notification email involving the issue they are trying to remove a CC email from. This is done by requiring
- * a token parameter, which we look up in the database. In this implementation we piggy-back off JIRA's mail threading
- * facility, which allows lookup of an issue by token (message ID stored in the notificationinstance table).
- */
- public class UnsubscribeCCField extends JiraWebActionSupport
- {
- String unsubToken;
- String email;
- String cfId;
- private CustomFieldManager customFieldManager;
- private IssueFactory issueFactory;
- private String resultMessage = null;
- public UnsubscribeCCField(CustomFieldManager customFieldManager, IssueFactory issueFactory)
- {
- this.customFieldManager = customFieldManager;
- this.issueFactory = issueFactory;
- }
- protected void doValidation()
- {
- if (!TextUtils.stringSet(email))
- addError("email", "'email' param: Email address not specified");
- if (!TextUtils.stringSet(unsubToken))
- addError("unsubToken", "'unsubToken' param: Unsubscribe token not specified");
- if (!TextUtils.stringSet(cfId))
- addError("cfId", "'cfId' param: Custom field ID not specified");
- try
- {
- Long.parseLong(cfId);
- } catch (Exception e)
- {
- addError("cfId", "cfId must be an integer");
- }
- super.doValidation();
- }
- protected String doExecute() throws Exception
- {
- MutableIssue issue = getIssue();
- if (issue != null)
- {
- CustomFieldHelperBean cfHelper = new CustomFieldHelperBean(customFieldManager, log);
- HashSet<Address> addressHashSet = new HashSet<Address>();
- try
- {
- Set<InternetAddress> oldCCAddresses = cfHelper.getCustomFieldValueSet(issue, getCCCustomField());
- InternetAddress emailAddr = new InternetAddress(email);
- addressHashSet.add(emailAddr);
- cfHelper.removeCustomFieldValueSet(issue, getCCCustomField(), addressHashSet);
- if (oldCCAddresses.contains(emailAddr))
- {
- resultMessage = "removed";
- // resultMessage = "Removed " + TextUtils.htmlEncode(emailAddr.toString() + " from CC list of " + issue);
- }
- else
- {
- resultMessage = "notcced";
- // resultMessage = TextUtils.htmlEncode(emailAddr.toString() + " was not in the CC list of " + issue);
- }
- log.debug(resultMessage);
- } catch (MessagingException e)
- {
- addError("email", "Invalid email address: " + TextUtils.htmlEncode(email));
- }
- }
- else
- {
- addErrorMessage("Could not find unsubscribe token '" + TextUtils.htmlEncode(unsubToken) + "'. Check that you pasted it correctly from the email.");
- return ERROR;
- }
- return super.doExecute();
- }
- /**
- * Find the issue associated with the given unsubToken param.
- *
- * @return Issue to unsub an email from, or null if not found or token was invalid.
- */
- private MutableIssue getIssue()
- {
- MutableIssue issue = null;
- Message message = new MimeMessage(javax.mail.Session.getDefaultInstance(new Properties()));
- try
- {
- message.setHeader("In-Reply-To", unsubToken);
- GenericValue issueGV = ManagerFactory.getMailThreadManager().getAssociatedIssue(message);
- if (issueGV != null)
- {
- issue = issueFactory.getIssue(issueGV);
- }
- else
- {
- log.info("In attempt to unsubscribe " + email + ", could not find given CC unsubscribe token: " + unsubToken);
- }
- } catch (MessagingException e)
- {
- log.error("Invalid token could not be set as In-Reply-To: header value: " + unsubToken);
- }
- return issue;
- }
- public String getIssueKey()
- {
- return getIssue().getKey();
- }
- public String getUnsubToken()
- {
- return unsubToken;
- }
- public void setUnsubToken(String unsubToken)
- {
- this.unsubToken = unsubToken;
- }
- public String getEmail()
- {
- return email;
- }
- public void setEmail(String email)
- {
- this.email = email;
- }
- public String getCfId()
- {
- return cfId;
- }
- public void setCfId(String cfId)
- {
- this.cfId = cfId;
- }
- public String getResultMessage()
- {
- return resultMessage;
- }
- public CustomField getCCCustomField()
- {
- return customFieldManager.getCustomFieldObject(new Long(cfId));
- }
- }