[New] SmtpMailer now understands whitelists for override
This commit is contained in:
parent
a88a098bf3
commit
58248058e5
|
@ -2,13 +2,19 @@ package li.strolch.utils;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.mail.Message;
|
import javax.mail.Message;
|
||||||
import javax.mail.MessagingException;
|
import javax.mail.MessagingException;
|
||||||
import javax.mail.PasswordAuthentication;
|
import javax.mail.PasswordAuthentication;
|
||||||
import javax.mail.Session;
|
import javax.mail.Session;
|
||||||
import javax.mail.Transport;
|
import javax.mail.Transport;
|
||||||
|
import javax.mail.internet.AddressException;
|
||||||
import javax.mail.internet.InternetAddress;
|
import javax.mail.internet.InternetAddress;
|
||||||
import javax.mail.internet.MimeMessage;
|
import javax.mail.internet.MimeMessage;
|
||||||
|
|
||||||
|
@ -22,8 +28,8 @@ import org.slf4j.LoggerFactory;
|
||||||
* The {@link Properties} required are as follows:
|
* The {@link Properties} required are as follows:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li><code>fromAddr</code> and <code>fromName</code> - defines the address from which the e-mail comes from</li>
|
* <li><code>fromAddr</code> and <code>fromName</code> - defines the address from which the e-mail comes from</li>
|
||||||
* <li><code>overrideRecipientAddr</code> and <code>overrideRecipientName</code> - if defined, overrides any recipient -
|
* <li><code>overrideRecipients</code> - if defined, overrides any recipients - useful for testng purposes</li>
|
||||||
* useful for testng purposes</li>
|
* <li><code>recipientWhitelist</code> - if defined allows those e-mail addresses to not be overridden</li>
|
||||||
* <li>username - the username to authenticate at the SMTP Server</li>
|
* <li>username - the username to authenticate at the SMTP Server</li>
|
||||||
* <li>password - the password to authenticate at the SMTP Server</li>
|
* <li>password - the password to authenticate at the SMTP Server</li>
|
||||||
* <li>auth - boolean to define if auth is to be done</li>
|
* <li>auth - boolean to define if auth is to be done</li>
|
||||||
|
@ -51,7 +57,7 @@ public class SmtpMailer {
|
||||||
public static void init(Properties properties) {
|
public static void init(Properties properties) {
|
||||||
try {
|
try {
|
||||||
instance = new SmtpMailer(properties);
|
instance = new SmtpMailer(properties);
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException | AddressException e) {
|
||||||
throw new RuntimeException("Failed to initialize Mailer due to " + e.getMessage(), 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 from;
|
||||||
private final InternetAddress overrideRecipient;
|
private final InternetAddress[] overrideRecipients;
|
||||||
|
private final Set<InternetAddress> recipientWhitelist;
|
||||||
private final String username;
|
private final String username;
|
||||||
private final String password;
|
private final String password;
|
||||||
private final Properties props;
|
private final Properties props;
|
||||||
|
@ -81,30 +88,49 @@ public class SmtpMailer {
|
||||||
*
|
*
|
||||||
* @throws UnsupportedEncodingException
|
* @throws UnsupportedEncodingException
|
||||||
* if something goes wrong parsing the from or override addresses
|
* 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 fromAddr = properties.getProperty("fromAddr", null);
|
||||||
String fromName = properties.getProperty("fromName", null);
|
String fromName = properties.getProperty("fromName", null);
|
||||||
this.from = new InternetAddress(fromAddr, fromName);
|
this.from = new InternetAddress(fromAddr, fromName);
|
||||||
|
|
||||||
if (properties.containsKey("overrideRecipientAddr")) {
|
if (properties.containsKey("overrideRecipients")) {
|
||||||
String addr = properties.getProperty("overrideRecipientAddr", null);
|
String addr = properties.getProperty("overrideRecipients", null);
|
||||||
String name = properties.getProperty("overrideRecipientName", null);
|
this.overrideRecipients = InternetAddress.parse(addr);
|
||||||
this.overrideRecipient = new InternetAddress(addr, name);
|
|
||||||
} else {
|
} 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.username = properties.getProperty("username", null);
|
||||||
this.password = properties.getProperty("password", null);
|
this.password = properties.getProperty("password", null);
|
||||||
|
|
||||||
this.props = new Properties();
|
this.props = new Properties();
|
||||||
props.put("mail.smtp.auth", properties.getProperty("auth", null));
|
this.props.put("mail.smtp.auth", properties.getProperty("auth", null));
|
||||||
props.put("mail.smtp.starttls.enable", properties.getProperty("startTls", null));
|
this.props.put("mail.smtp.starttls.enable", properties.getProperty("startTls", null));
|
||||||
props.put("mail.smtp.host", properties.getProperty("host", null));
|
this.props.put("mail.smtp.host", properties.getProperty("host", null));
|
||||||
props.put("mail.smtp.port", properties.getProperty("port", 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
|
* the subject of the e-mail
|
||||||
* @param text
|
* @param text
|
||||||
* the test of the e-mail
|
* the test of the e-mail
|
||||||
* @param recipient
|
* @param recipients
|
||||||
* the address to whom to send the e-mail
|
* 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 {
|
try {
|
||||||
|
|
||||||
Session session = Session.getInstance(this.props, new javax.mail.Authenticator() {
|
if (this.overrideRecipients == null) {
|
||||||
protected PasswordAuthentication getPasswordAuthentication() {
|
|
||||||
return new PasswordAuthentication(SmtpMailer.this.username, SmtpMailer.this.password);
|
// 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<InternetAddress> 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);
|
if (!allowList.isEmpty()) {
|
||||||
message.setFrom(this.from);
|
send(subject, text, parseAddress(recipients));
|
||||||
if (this.overrideRecipient != null)
|
logger.info(MessageFormat.format("Sent E-mail to {0}: {1}", recipients, subject));
|
||||||
message.setRecipient(Message.RecipientType.TO, this.overrideRecipient);
|
}
|
||||||
else
|
|
||||||
message.addRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
|
|
||||||
|
|
||||||
message.setSubject(subject);
|
if (needsOverrides) {
|
||||||
|
|
||||||
if (this.overrideRecipient != null)
|
// override, with no white list, so send to override
|
||||||
text = "Override recipient. Original recipient " + recipient + ".\n\n" + text;
|
text = "Override recipient. Original recipients: " + recipients + ".\n\n" + text;
|
||||||
message.setText(text);
|
send(subject, text, this.overrideRecipients);
|
||||||
|
logger.info(MessageFormat.format("Sent E-mail to override recipient {0}: {1}",
|
||||||
Transport.send(message);
|
Arrays.asList(this.overrideRecipients).stream() //
|
||||||
|
.map(Object::toString) //
|
||||||
String msg;
|
.collect(Collectors.joining(",")),
|
||||||
if (this.overrideRecipient != null)
|
subject));
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
logger.info(msg);
|
|
||||||
|
|
||||||
} catch (MessagingException e) {
|
} catch (MessagingException e) {
|
||||||
throw new RuntimeException("Failed to send e-mail due to " + e.getMessage(), 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue