diff --git a/li.strolch.utils/src/main/java/li/strolch/utils/SmtpMailer.java b/li.strolch.utils/src/main/java/li/strolch/utils/SmtpMailer.java
index 3298dbb70..74b1ccac6 100644
--- a/li.strolch.utils/src/main/java/li/strolch/utils/SmtpMailer.java
+++ b/li.strolch.utils/src/main/java/li/strolch/utils/SmtpMailer.java
@@ -2,13 +2,19 @@ package li.strolch.utils;
import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
import java.util.Properties;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
+import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
@@ -22,8 +28,8 @@ import org.slf4j.LoggerFactory;
* The {@link Properties} required are as follows:
*
* fromAddr
and fromName
- defines the address from which the e-mail comes from
- * overrideRecipientAddr
and overrideRecipientName
- if defined, overrides any recipient -
- * useful for testng purposes
+ * overrideRecipients
- if defined, overrides any recipients - useful for testng purposes
+ * recipientWhitelist
- if defined allows those e-mail addresses to not be overridden
* - username - the username to authenticate at the SMTP Server
* - password - the password to authenticate at the SMTP Server
* - auth - boolean to define if auth is to be done
@@ -51,7 +57,7 @@ public class SmtpMailer {
public static void init(Properties properties) {
try {
instance = new SmtpMailer(properties);
- } catch (UnsupportedEncodingException e) {
+ } catch (UnsupportedEncodingException | AddressException e) {
throw new RuntimeException("Failed to initialize Mailer due to " + e.getMessage(), e);
}
}
@@ -68,7 +74,8 @@ public class SmtpMailer {
}
private final InternetAddress from;
- private final InternetAddress overrideRecipient;
+ private final InternetAddress[] overrideRecipients;
+ private final Set recipientWhitelist;
private final String username;
private final String password;
private final Properties props;
@@ -81,30 +88,49 @@ public class SmtpMailer {
*
* @throws UnsupportedEncodingException
* if something goes wrong parsing the from or override addresses
+ * @throws AddressException
+ * if something goes wrong parsing the from or override addresses
*/
- private SmtpMailer(Properties properties) throws UnsupportedEncodingException {
+ private SmtpMailer(Properties properties) throws UnsupportedEncodingException, AddressException {
String fromAddr = properties.getProperty("fromAddr", null);
String fromName = properties.getProperty("fromName", null);
this.from = new InternetAddress(fromAddr, fromName);
- if (properties.containsKey("overrideRecipientAddr")) {
- String addr = properties.getProperty("overrideRecipientAddr", null);
- String name = properties.getProperty("overrideRecipientName", null);
- this.overrideRecipient = new InternetAddress(addr, name);
+ if (properties.containsKey("overrideRecipients")) {
+ String addr = properties.getProperty("overrideRecipients", null);
+ this.overrideRecipients = InternetAddress.parse(addr);
} else {
- this.overrideRecipient = null;
+ this.overrideRecipients = null;
+ }
+
+ if (!properties.containsKey("recipientWhitelist")) {
+ this.recipientWhitelist = null;
+ } else {
+ String whiteListProp = properties.getProperty("recipientWhitelist");
+ this.recipientWhitelist = Arrays.stream(whiteListProp.split(",")) //
+ .map(s -> s.trim()) //
+ .map(s -> Arrays.asList(parseAddress(s))) //
+ .flatMap(List::stream) //
+ .collect(Collectors.toSet());
}
this.username = properties.getProperty("username", null);
this.password = properties.getProperty("password", null);
this.props = new Properties();
- props.put("mail.smtp.auth", properties.getProperty("auth", null));
- props.put("mail.smtp.starttls.enable", properties.getProperty("startTls", null));
- props.put("mail.smtp.host", properties.getProperty("host", null));
- props.put("mail.smtp.port", properties.getProperty("port", null));
+ this.props.put("mail.smtp.auth", properties.getProperty("auth", null));
+ this.props.put("mail.smtp.starttls.enable", properties.getProperty("startTls", null));
+ this.props.put("mail.smtp.host", properties.getProperty("host", null));
+ this.props.put("mail.smtp.port", properties.getProperty("port", null));
+ }
+ private InternetAddress[] parseAddress(String s) {
+ try {
+ return InternetAddress.parse(s);
+ } catch (AddressException e) {
+ throw new IllegalArgumentException("Failed to parse address: " + s, e);
+ }
}
/**
@@ -114,46 +140,81 @@ public class SmtpMailer {
* the subject of the e-mail
* @param text
* the test of the e-mail
- * @param recipient
- * the address to whom to send the e-mail
+ * @param recipients
+ * the addresses to whom to send the e-mail. See {@link InternetAddress#parse(String)}
*/
- public void sendMail(String subject, String text, String recipient) {
+ public void sendMail(String subject, String text, String recipients) {
try {
- Session session = Session.getInstance(this.props, new javax.mail.Authenticator() {
- protected PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication(SmtpMailer.this.username, SmtpMailer.this.password);
+ if (this.overrideRecipients == null) {
+
+ // no override, just send
+ send(subject, text, parseAddress(recipients));
+ logger.info(MessageFormat.format("Sent E-mail to {0}: {1}", recipients, subject));
+
+ } else if (this.recipientWhitelist == null) {
+
+ // override, with no white list, so send to override
+ text = "Override recipient. Original recipients: " + recipients + ".\n\n" + text;
+ send(subject, text, this.overrideRecipients);
+ logger.info(MessageFormat.format("Sent E-mail to override recipient {0}: {1}",
+ Arrays.asList(this.overrideRecipients).stream() //
+ .map(Object::toString) //
+ .collect(Collectors.joining(",")),
+ subject));
+
+ } else {
+
+ // override with whitelist, so we have to perhaps send to override and white list
+
+ Set allowList = new HashSet<>();
+ boolean needsOverrides = false;
+
+ for (InternetAddress recipient : parseAddress(recipients)) {
+ if (this.recipientWhitelist.contains(recipient))
+ allowList.add(recipient);
+ else
+ needsOverrides = true;
}
- });
- Message message = new MimeMessage(session);
- message.setFrom(this.from);
- if (this.overrideRecipient != null)
- message.setRecipient(Message.RecipientType.TO, this.overrideRecipient);
- else
- message.addRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
+ if (!allowList.isEmpty()) {
+ send(subject, text, parseAddress(recipients));
+ logger.info(MessageFormat.format("Sent E-mail to {0}: {1}", recipients, subject));
+ }
- message.setSubject(subject);
+ if (needsOverrides) {
- if (this.overrideRecipient != null)
- text = "Override recipient. Original recipient " + recipient + ".\n\n" + text;
- message.setText(text);
-
- Transport.send(message);
-
- String msg;
- if (this.overrideRecipient != null)
- msg = MessageFormat.format("Sent E-mail to override recipient {0}: {1}",
- message.getRecipients(Message.RecipientType.TO)[0], message.getSubject());
- else {
- msg = MessageFormat.format("Sent E-mail to {0}: {1}",
- message.getRecipients(Message.RecipientType.TO)[0], message.getSubject());
+ // override, with no white list, so send to override
+ text = "Override recipient. Original recipients: " + recipients + ".\n\n" + text;
+ send(subject, text, this.overrideRecipients);
+ logger.info(MessageFormat.format("Sent E-mail to override recipient {0}: {1}",
+ Arrays.asList(this.overrideRecipients).stream() //
+ .map(Object::toString) //
+ .collect(Collectors.joining(",")),
+ subject));
+ }
}
- logger.info(msg);
} catch (MessagingException e) {
throw new RuntimeException("Failed to send e-mail due to " + e.getMessage(), e);
}
}
+
+ private void send(String subject, String text, InternetAddress[] recipients) throws MessagingException {
+
+ Session session = Session.getInstance(this.props, new javax.mail.Authenticator() {
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(SmtpMailer.this.username, SmtpMailer.this.password);
+ }
+ });
+
+ Message message = new MimeMessage(session);
+ message.setFrom(this.from);
+ message.addRecipients(Message.RecipientType.TO, recipients);
+ message.setSubject(subject);
+ message.setText(text);
+
+ Transport.send(message);
+ }
}