Skip to content
Permalink
Browse files
Merge pull request #88 from tfitch/JENKINS-21730-bcc-support-in-email…
…-ext

JENKINS-21730 - Add bcc support to email-ext plugin
  • Loading branch information
slide committed Feb 24, 2014
2 parents 624bb6e + 4aacabf commit d97977c44e12c7e0e2ff9e92f6d63e2bf1a1d6ab
@@ -31,6 +31,7 @@ public class EmailRecipientUtils {

public static final int TO = 0;
public static final int CC = 1;
public static final int BCC = 2;

public static Set<InternetAddress> convertRecipientString(String recipientList, EnvVars envVars)
throws AddressException, UnsupportedEncodingException {
@@ -42,28 +43,35 @@ public static Set<InternetAddress> convertRecipientString(String recipientList,
final Set<InternetAddress> internetAddresses = new LinkedHashSet<InternetAddress>();
if (!StringUtils.isBlank(recipientList)) {
final String expandedRecipientList = fixupSpaces(envVars.expand(recipientList));
InternetAddress[] all = InternetAddress.parse(expandedRecipientList.replace("cc:", ""));
InternetAddress[] all = InternetAddress.parse(expandedRecipientList.replace("bcc:", "").replace("cc:", ""));
final Set<InternetAddress> to = new LinkedHashSet<InternetAddress>();
final Set<InternetAddress> cc = new LinkedHashSet<InternetAddress>();
final Set<InternetAddress> bcc = new LinkedHashSet<InternetAddress>();
final String defaultSuffix = Mailer.descriptor().getDefaultSuffix();

for(InternetAddress address : all) {
if(address.getPersonal() != null) {
if(expandedRecipientList.contains("cc:" + address.getPersonal()) || expandedRecipientList.contains("cc:\"" + address.toString() + "\"")) {
if(expandedRecipientList.contains("bcc:" + address.getPersonal()) || expandedRecipientList.contains("bcc:\"" + address.toString() + "\"")) {
bcc.add(address);
} else if(expandedRecipientList.contains("cc:" + address.getPersonal()) || expandedRecipientList.contains("cc:\"" + address.toString() + "\"")) {
cc.add(address);
} else {
to.add(address);
}
} else {
if(expandedRecipientList.contains("cc:" + address.toString())) {
if(expandedRecipientList.contains("bcc:" + address.toString())) {
bcc.add(address);
} else if(expandedRecipientList.contains("cc:" + address.toString())) {
cc.add(address);
} else {
to.add(address);
}
}
}

if(type == CC) {
if(type == BCC) {
internetAddresses.addAll(bcc);
} else if(type == CC) {
internetAddresses.addAll(cc);
} else {
internetAddresses.addAll(to);
@@ -111,6 +119,7 @@ public FormValidation validateFormRecipientList(String recipientList) {
// Try and convert the recipient string to a list of InternetAddress. If this fails then the validation fails.
try {
convertRecipientString(recipientList, new EnvVars(), TO);
convertRecipientString(recipientList, new EnvVars(), BCC);
convertRecipientString(recipientList, new EnvVars(), CC);
return FormValidation.ok();
} catch (AddressException e) {
@@ -151,11 +160,15 @@ public static boolean isExcludedRecipient(User user, TaskListener listener) {
return false;
}

public static void addAddressesFromRecipientList(Set<InternetAddress> to, Set<InternetAddress> cc, String recipientList,
public static void addAddressesFromRecipientList(Set<InternetAddress> to, Set<InternetAddress> cc, Set<InternetAddress> bcc, String recipientList,
EnvVars envVars, TaskListener listener) {
try {
Set<InternetAddress> internetAddresses = convertRecipientString(recipientList, envVars, EmailRecipientUtils.TO);
to.addAll(internetAddresses);
if(bcc != null) {
Set<InternetAddress> bccInternetAddresses = convertRecipientString(recipientList, envVars, EmailRecipientUtils.BCC);
bcc.addAll(bccInternetAddresses);
}
if(cc != null) {
Set<InternetAddress> ccInternetAddresses = convertRecipientString(recipientList, envVars, EmailRecipientUtils.CC);
cc.addAll(ccInternetAddresses);
@@ -503,20 +503,21 @@ private MimeMessage createMail(ExtendedEmailPublisherContext context) throws Mes
// Get the recipients from the global list of addresses
Set<InternetAddress> to = new LinkedHashSet<InternetAddress>();
Set<InternetAddress> cc = new LinkedHashSet<InternetAddress>();
Set<InternetAddress> bcc = new LinkedHashSet<InternetAddress>();

String emergencyReroute = descriptor.getEmergencyReroute();

if (StringUtils.isNotBlank(emergencyReroute)) {
debug(context.getListener().getLogger(), "Emergency reroute turned on");
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, emergencyReroute, env, context.getListener());
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, bcc, emergencyReroute, env, context.getListener());
debug(context.getListener().getLogger(), "Emergency reroute is set to: " + emergencyReroute);
} else {
for (RecipientProvider provider : context.getTrigger().getEmail().getRecipientProviders()) {
provider.addRecipients(context, env, to, cc);
provider.addRecipients(context, env, to, cc, bcc);
}

descriptor.debug(context.getListener().getLogger(), "Adding recipients from trigger recipient list");
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, EmailRecipientUtils.getRecipientList(context, context.getTrigger().getEmail().getRecipientList()), env, context.getListener());
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, bcc, EmailRecipientUtils.getRecipientList(context, context.getTrigger().getEmail().getRecipientList()), env, context.getListener());
}

// remove the excluded recipients
@@ -528,20 +529,24 @@ private MimeMessage createMail(ExtendedEmailPublisherContext context) throws Mes
}
to.removeAll(excludedRecipients);
cc.removeAll(excludedRecipients);
bcc.removeAll(excludedRecipients);

msg.setRecipients(Message.RecipientType.TO, to.toArray(new InternetAddress[to.size()]));
if (cc.size() > 0) {
msg.setRecipients(Message.RecipientType.CC, cc.toArray(new InternetAddress[cc.size()]));
}
if (bcc.size() > 0) {
msg.setRecipients(Message.RecipientType.BCC, bcc.toArray(new InternetAddress[bcc.size()]));
}

Set<InternetAddress> replyToAddresses = new LinkedHashSet<InternetAddress>();

if (StringUtils.isNotBlank(replyTo)) {
EmailRecipientUtils.addAddressesFromRecipientList(replyToAddresses, null, EmailRecipientUtils.getRecipientList(context, replyTo), env, context.getListener());
EmailRecipientUtils.addAddressesFromRecipientList(replyToAddresses, null, null, EmailRecipientUtils.getRecipientList(context, replyTo), env, context.getListener());
}

if (StringUtils.isNotBlank(context.getTrigger().getEmail().getReplyTo())) {
EmailRecipientUtils.addAddressesFromRecipientList(replyToAddresses, null, EmailRecipientUtils.getRecipientList(context, context.getTrigger().getEmail().getReplyTo()), env, context.getListener());
EmailRecipientUtils.addAddressesFromRecipientList(replyToAddresses, null, null, EmailRecipientUtils.getRecipientList(context, context.getTrigger().getEmail().getReplyTo()), env, context.getListener());
}

if (replyToAddresses.size() > 0) {
@@ -24,5 +24,5 @@ public RecipientProviderDescriptor getDescriptor() {
return (RecipientProviderDescriptor) Jenkins.getInstance().getDescriptor(getClass());
}

public abstract void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc);
public abstract void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc, Set<InternetAddress> bcc);
}
@@ -32,7 +32,7 @@ public CulpritsRecipientProvider() {
}

@Override
public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc) {
public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc, Set<InternetAddress> bcc) {
ExtendedEmailPublisherDescriptor descriptor = Jenkins.getInstance().getDescriptorByType(ExtendedEmailPublisherDescriptor.class);
Set<User> users = context.getBuild().getCulprits();

@@ -41,7 +41,7 @@ public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Se
String userAddress = EmailRecipientUtils.getUserConfiguredEmail(user);
if (userAddress != null) {
descriptor.debug(context.getListener().getLogger(), "Adding user address %s, they were not considered an excluded committer", userAddress);
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, userAddress, env, context.getListener());
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, bcc, userAddress, env, context.getListener());
} else {
context.getListener().getLogger().println("Failed to send e-mail to " + user.getFullName() + " because no e-mail address is known, and no default e-mail domain is configured");
}
@@ -26,7 +26,7 @@ public DevelopersRecipientProvider() {
}

@Override
public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc) {
public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc, Set<InternetAddress> bcc) {
ExtendedEmailPublisherDescriptor descriptor = Jenkins.getInstance().getDescriptorByType(ExtendedEmailPublisherDescriptor.class);
Set<User> users = new HashSet<User>();
for (ChangeLogSet.Entry change : context.getBuild().getChangeSet()) {
@@ -38,7 +38,7 @@ public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Se
String userAddress = EmailRecipientUtils.getUserConfiguredEmail(user);
if (userAddress != null) {
descriptor.debug(context.getListener().getLogger(), "Adding user address %s, they were not considered an excluded committer", userAddress);
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, userAddress, env, context.getListener());
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, bcc, userAddress, env, context.getListener());
} else {
context.getListener().getLogger().println("Failed to send e-mail to " + user.getFullName() + " because no e-mail address is known, and no default e-mail domain is configured");
}
@@ -33,11 +33,11 @@ public ListRecipientProvider() {
}

@Override
public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc) {
public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc, Set<InternetAddress> bcc) {
try {
ExtendedEmailPublisherDescriptor descriptor = Jenkins.getInstance().getDescriptorByType(ExtendedEmailPublisherDescriptor.class);
descriptor.debug(context.getListener().getLogger(), "Adding recipients from project recipient list");
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, EmailRecipientUtils.getRecipientList(context, context.getPublisher().recipientList), env, context.getListener());
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, bcc, EmailRecipientUtils.getRecipientList(context, context.getPublisher().recipientList), env, context.getListener());
} catch (MessagingException ex) {
Logger.getLogger(ListRecipientProvider.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -32,7 +32,7 @@ public RequesterRecipientProvider() {
}

@Override
public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc) {
public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Set<InternetAddress> to, Set<InternetAddress> cc, Set<InternetAddress> bcc) {
// looking for Upstream build.
AbstractBuild<?, ?> cur = context.getBuild();
Cause.UpstreamCause upc = context.getBuild().getCause(Cause.UpstreamCause.class);
@@ -45,10 +45,10 @@ public void addRecipients(ExtendedEmailPublisherContext context, EnvVars env, Se
cur = p.getBuildByNumber(upc.getUpstreamBuild());
upc = cur.getCause(Cause.UpstreamCause.class);
}
addUserTriggeringTheBuild(cur, to, cc, env, context.getListener());
addUserTriggeringTheBuild(cur, to, cc, bcc, env, context.getListener());
}

private void addUserTriggeringTheBuild(AbstractBuild<?, ?> build, Set<InternetAddress> to, Set<InternetAddress> cc,
private void addUserTriggeringTheBuild(AbstractBuild<?, ?> build, Set<InternetAddress> to, Set<InternetAddress> cc, Set<InternetAddress> bcc,
EnvVars env, TaskListener listener) {
User user = getByUserIdCause(build);
if (user == null) {
@@ -58,10 +58,10 @@ private void addUserTriggeringTheBuild(AbstractBuild<?, ?> build, Set<InternetAd
if (user != null) {
String adrs = user.getProperty(Mailer.UserProperty.class).getAddress();
if (adrs != null) {
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, adrs, env, listener);
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, bcc, adrs, env, listener);
} else {
listener.getLogger().println("The user does not have a configured email address, trying the user's id");
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, user.getId(), env, listener);
EmailRecipientUtils.addAddressesFromRecipientList(to, cc, bcc, user.getId(), env, listener);
}
}
}
@@ -4,6 +4,7 @@
project configuration. You may use the $DEFAULT_RECIPIENTS
token in projects to include this default list, as well as
add new addresses at the project level.
To CC someone instead of putting them in the To list, add
cc: before the email address (e.g., cc:someone@somewhere.com).
To CC or BCC someone instead of putting them in the To list, add
cc: or bcc: before the email address
(e.g., cc:someone@example.com, bcc:bob@example.com).
</div>
@@ -2,6 +2,6 @@
自訂電子郵件通知的預設收件人清單。
如果沒有被專案設定覆蓋掉,就會使用這一組清單。
您可以在專案中使用 <code>$DEFAULT_RECIPIENTS</code> Token,在專案層級設定其他收件人的同時也加入這份預設清單。
要是想把某些人放在副本清單,而不是放在收件人清單裡,請在信箱前面加上 <code>cc:</code>
(例如: <code>cc:someone@somewhere.com</code>)。
要是想把某些人放在副本清單,而不是放在收件人清單裡,請在信箱前面加上 <code>cc:/bcc:</code>
(例如: <code>cc:someone@example.com, bcc:bob@example.com</code>)。
</div>
@@ -1,6 +1,7 @@
<div>
This is a comma separated list (optional whitespace after commas) of email addresses
that should receive emails. May contain references to build parameters.
To CC someone instead of putting them in the To list, add cc: before the email address
(e.g., cc:someone@somewhere.com).
To CC or BCC someone instead of putting them in the To list, add
cc: or bcc: before the email address
(e.g., cc:someone@example.com, bcc:bob@example.com).
</div>
@@ -2,5 +2,5 @@
要接收本觸發程序送出郵件的收件者信箱清單,多筆信箱之間以半形逗號隔開 (逗號後可以接空格)。
可以參照到建置參數。
要是想把某些人放在副本清單,而不是放在收件人清單裡,請在信箱前面加上 <code>cc:</code>
(例如: <code>cc:someone@somewhere.com</code>)。
(例如: <code>cc:someone@example.com, bcc:bob@example.com</code>)。
</div>
@@ -1,6 +1,7 @@
<div>
This is a comma separated list (optional whitespace after commas) of email addresses
that should receive emails for this trigger. May contain references to build parameters.
To CC someone instead of putting them in the To list, add cc: before the email address
(e.g., cc:someone@somewhere.com).
To CC or BCC someone instead of putting them in the To list, add
cc: or bcc: before the email address
(e.g., cc:someone@example.com, bcc:bob@example.com).
</div>
@@ -1,6 +1,6 @@
<div>
要接收本觸發程序送出郵件的收件者信箱清單,多筆信箱之間以半形逗號隔開 (逗號後可以接空格)。
可以參照到建置參數。
要是想把某些人放在副本清單,而不是放在收件人清單裡,請在信箱前面加上 <code>cc:</code>
(例如: <code>cc:someone@somewhere.com</code>)。
要是想把某些人放在副本清單,而不是放在收件人清單裡,請在信箱前面加上 <code>cc:/bcc:</code>
(例如: <code>cc:someone@example.com, bcc:bob@example.com</code>)。
</div>
@@ -173,6 +173,45 @@ public void testCC()
assertTrue(internetAddresses.contains(new InternetAddress("slide.o.mix@gmail.com")));
}

@Test
public void testBCC()
throws Exception {
envVars.put("EMAIL_LIST", "ashlux@gmail.com, bcc:slide.o.mix@gmail.com, another@gmail.com");

Set<InternetAddress> internetAddresses = emailRecipientUtils.convertRecipientString("$EMAIL_LIST", envVars);

assertEquals(2, internetAddresses.size());
assertTrue(internetAddresses.contains(new InternetAddress("ashlux@gmail.com")));
assertTrue(internetAddresses.contains(new InternetAddress("another@gmail.com")));

internetAddresses = emailRecipientUtils.convertRecipientString("$EMAIL_LIST", envVars, EmailRecipientUtils.BCC);

assertEquals(1, internetAddresses.size());
assertTrue(internetAddresses.contains(new InternetAddress("slide.o.mix@gmail.com")));
}

@Test
public void testBCCandCC()
throws Exception {
envVars.put("EMAIL_LIST", "ashlux@gmail.com, bcc:slide.o.mix@gmail.com, another@gmail.com, cc:example@gmail.com");

Set<InternetAddress> internetAddresses = emailRecipientUtils.convertRecipientString("$EMAIL_LIST", envVars);

assertEquals(2, internetAddresses.size());
assertTrue(internetAddresses.contains(new InternetAddress("ashlux@gmail.com")));
assertTrue(internetAddresses.contains(new InternetAddress("another@gmail.com")));

internetAddresses = emailRecipientUtils.convertRecipientString("$EMAIL_LIST", envVars, EmailRecipientUtils.BCC);

assertEquals(1, internetAddresses.size());
assertTrue(internetAddresses.contains(new InternetAddress("slide.o.mix@gmail.com")));

internetAddresses = emailRecipientUtils.convertRecipientString("$EMAIL_LIST", envVars, EmailRecipientUtils.CC);

assertEquals(1, internetAddresses.size());
assertTrue(internetAddresses.contains(new InternetAddress("example@gmail.com")));
}

@Test
public void testUTF8()
throws Exception {

0 comments on commit d97977c

Please sign in to comment.