Skip to content
Snippets Groups Projects
Commit 71cba435 authored by Benoit Lavenier's avatar Benoit Lavenier
Browse files

[fix] Mail: add attachments, and embedded urls

parent c77f26f2
No related branches found
No related tags found
No related merge requests found
......@@ -22,6 +22,12 @@ package org.duniter.core.model;
* #L%
*/
import lombok.*;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SmtpConfig {
......@@ -31,70 +37,11 @@ public class SmtpConfig {
private String smtpPassword;
private String senderAddress;
private String senderName;
private boolean useSsl;
private boolean startTLS;
public String getSmtpHost() {
return smtpHost;
}
public void setSmtpHost(String smtpHost) {
this.smtpHost = smtpHost;
}
public int getSmtpPort() {
return smtpPort;
}
public void setSmtpPort(int smtpPort) {
this.smtpPort = smtpPort;
}
public String getSmtpUsername() {
return smtpUsername;
}
public void setSmtpUsername(String smtpUsername) {
this.smtpUsername = smtpUsername;
}
public String getSmtpPassword() {
return smtpPassword;
}
public void setSmtpPassword(String smtpPassword) {
this.smtpPassword = smtpPassword;
}
public String getSenderAddress() {
return senderAddress;
}
public void setSenderAddress(String senderAddress) {
this.senderAddress = senderAddress;
}
public String getSenderName() {
return senderName;
}
@Builder.Default
private boolean useSsl = false;
public void setSenderName(String senderName) {
this.senderName = senderName;
}
@Builder.Default
private boolean startTLS = false;
public boolean isUseSsl() {
return useSsl;
}
public void setUseSsl(boolean useSsl) {
this.useSsl = useSsl;
}
public boolean isStartTLS() {
return startTLS;
}
public void setStartTLS(boolean startTLS) {
this.startTLS = startTLS;
}
}
......@@ -28,6 +28,8 @@ import org.duniter.core.model.SmtpConfig;
import javax.mail.internet.ContentType;
import javax.mail.internet.ParseException;
import java.net.URL;
import java.util.List;
/**
* Created by blavenie on 28/11/16.
......@@ -47,8 +49,14 @@ public interface MailService extends Bean {
void sendHtmlEmailWithText(
String subject,
String utf8textContent,
String utf8HtmlContent,
String messageText,
String messageHtml,
String... recipients);
void sendHtmlEmailWithText(
String subject,
String messageText,
String messageHtml,
List<URL> attachments,
String... recipients);
}
......@@ -28,6 +28,7 @@ import org.duniter.core.model.SmtpConfig;
import org.duniter.core.util.CollectionUtils;
import org.duniter.core.util.Preconditions;
import org.duniter.core.util.StringUtils;
import org.duniter.core.util.mail.MailContentBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -37,7 +38,9 @@ import javax.mail.*;
import javax.mail.internet.*;
import java.io.Closeable;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
......@@ -96,32 +99,25 @@ public class MailServiceImpl implements MailService, Closeable {
@Override
public void sendHtmlEmailWithText(String subject,
String textContent,
String htmlContent,
String messageText,
String messageHtml,
String... recipients) {
try{
Multipart content = new MimeMultipart("alternative");
// Add text part
{
MimeBodyPart mbp = new MimeBodyPart();
ContentType contentType = new ContentType("text/plain");
contentType.setParameter("charset", "UTF-8");
mbp.setContent(textContent, contentType.toString());
content.addBodyPart(mbp);
sendHtmlEmailWithText(subject, messageText, messageHtml, null, recipients);
}
// Add html part
{
MimeBodyPart mbp = new MimeBodyPart();
ContentType contentType = new ContentType("text/html");
contentType.setParameter("charset", "UTF-8");
mbp.setContent(htmlContent, contentType.toString());
content.addBodyPart(mbp);
}
@Override
public void sendHtmlEmailWithText(String subject, String messageText, String messageHtml,
List<URL> attachments,
String... recipients) {
try {
sendEmail(subject, content.getContentType(), content, recipients);
MailContentBuilder mailContentBuilder = new MailContentBuilder();
final Multipart mixed = mailContentBuilder.build(messageText,
messageHtml,
mailContentBuilder.findUrls(messageHtml),
attachments);
sendEmail(subject, mixed.getContentType(), mixed, recipients);
}
catch(MessagingException e) {
// Should never occur
......@@ -166,21 +162,26 @@ public class MailServiceImpl implements MailService, Closeable {
message.setFrom(getSenderAddress(smtpConfig));
Address[] recipientsAddresses = Arrays.asList(recipients).stream().map(recipient -> {
try {
return new InternetAddress(recipient);
}
catch (AddressException e) {
throw new TechnicalException(String.format("Error while sending email. Bad recipient address [%s]", recipient), e);
}
}).collect(Collectors.toList()).toArray(new InternetAddress[recipients.length]);
Address[] recipientsAddresses = Arrays.stream(recipients)
.map(this::toInternetAddress)
.toArray(InternetAddress[]::new);
if (recipientsAddresses.length == 1) {
message.setRecipients(Message.RecipientType.TO, recipientsAddresses);
}
else {
message.setRecipients(Message.RecipientType.BCC, recipientsAddresses);
}
message.setSubject(subject);
if (content instanceof Multipart) {
message.setContent((Multipart)content);
}
else {
message.setContent(content, contentType);
}
message.setSentDate(new java.util.Date());
message.saveChanges();
//message.saveChanges();
transport.sendMessage(message, message.getAllRecipients());
} catch (MessagingException e) {
......@@ -303,8 +304,6 @@ public class MailServiceImpl implements MailService, Closeable {
} else {
transport.connect();
}
} catch (NoSuchProviderException e) {
throw new TechnicalException(e);
} catch (MessagingException e) {
throw new TechnicalException(e);
}
......@@ -325,11 +324,34 @@ public class MailServiceImpl implements MailService, Closeable {
protected void configureJavaMailMimeTypes() {
MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
/*mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
//mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("multipart/alternative;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
mc.addMailcap("message/rfc822;; x-java-content- handler=com.sun.mail.handlers.message_rfc822");*/
mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed; x-java-fallback-entry=true");
mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
}
protected Multipart newChild(Multipart parent, String alternative) throws MessagingException {
MimeMultipart child = new MimeMultipart(alternative);
final MimeBodyPart mbp = new MimeBodyPart();
parent.addBodyPart(mbp);
mbp.setContent(child);
return child;
}
protected InternetAddress toInternetAddress(String address) {
try {
return new InternetAddress(address);
}
catch (AddressException e) {
throw new TechnicalException(String.format("Invalid email address: %s", address), e);
}
}
}
\ No newline at end of file
......@@ -22,13 +22,25 @@ package org.duniter.core.service;
* #L%
*/
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import org.apache.commons.io.FileUtils;
import org.duniter.core.model.SmtpConfig;
import org.duniter.core.test.TestFixtures;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
/**
* Created by blavenie on 20/04/17.
......@@ -40,12 +52,13 @@ public class MailServiceTest {
@Before
public void setUp() throws UnsupportedEncodingException {
service = new MailServiceImpl();
SmtpConfig config = new SmtpConfig();
config.setSenderName("test");
config.setSenderAddress("no-reply@duniter.fr");
config.setSmtpHost("localhost");
config.setSmtpPort(25);
service.setSmtpConfig(config);
service.setSmtpConfig(SmtpConfig.builder()
.senderName("test")
.senderAddress("no-reply@duniter.fr")
.smtpHost("localhost")
.smtpPort(25)
.build());
}
@Test
......@@ -55,4 +68,36 @@ public class MailServiceTest {
"a test content",
"root@localhost");
}
@Test
//@Ignore
public void sendHtmlEmailWithText() throws MalformedURLException {
service.sendHtmlEmailWithText("Test " + System.currentTimeMillis() + " with HTML",
"a test text content",
"<b>a test HTML</b> content.",
"benoit.lavenier@e-is.pro");
service.sendHtmlEmailWithText("Test " + System.currentTimeMillis() + " with HTML and Image",
"a test text content",
"<b>a test HTML</b> content.<br/><img src=\"https://demo.cesium.app/img/logo_128px.png\">",
"benoit.lavenier@e-is.pro");
// Send file attachments
try {
File temp = new File("/tmp/mail-attachment.csv");
FileUtils.write(temp, "col1;col2\nval1;val2", StandardCharsets.UTF_8);
service.sendHtmlEmailWithText("Test " + System.currentTimeMillis() + " with HTML and Image + attachment",
"a test text content",
"<b>a test HTML</b> content.<br/><img src=\"https://demo.cesium.app/img/logo_128px.png\">",
Lists.newArrayList(
new URL("https://demo.cesium.app/img/logo_128px.png"),
new URL("file://" + temp.getAbsolutePath())
),
"benoit.lavenier@e-is.pro");
} catch (IOException e) {
Assert.fail("error");
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment