mirror of
https://github.com/sismics/docs.git
synced 2024-06-14 14:01:23 +02:00
293 lines
11 KiB
Java
293 lines
11 KiB
Java
package com.sismics.util;
|
|
|
|
import com.google.common.base.Strings;
|
|
import com.google.common.collect.Lists;
|
|
import com.sismics.docs.core.constant.ConfigType;
|
|
import com.sismics.docs.core.constant.Constants;
|
|
import com.sismics.docs.core.dao.ConfigDao;
|
|
import com.sismics.docs.core.dao.dto.UserDto;
|
|
import com.sismics.docs.core.model.context.AppContext;
|
|
import com.sismics.docs.core.model.jpa.Config;
|
|
import com.sismics.docs.core.util.ConfigUtil;
|
|
import freemarker.template.Configuration;
|
|
import freemarker.template.DefaultObjectWrapperBuilder;
|
|
import freemarker.template.Template;
|
|
import org.apache.commons.mail.HtmlEmail;
|
|
import org.jsoup.Jsoup;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import jakarta.json.Json;
|
|
import jakarta.json.JsonObject;
|
|
import jakarta.json.JsonReader;
|
|
import javax.mail.Message;
|
|
import javax.mail.MessagingException;
|
|
import javax.mail.Multipart;
|
|
import javax.mail.Part;
|
|
import javax.mail.internet.MimeBodyPart;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.StringReader;
|
|
import java.io.StringWriter;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.StandardCopyOption;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* Emails utilities.
|
|
*
|
|
* @author jtremeaux
|
|
*/
|
|
public class EmailUtil {
|
|
/**
|
|
* Logger.
|
|
*/
|
|
private static final Logger log = LoggerFactory.getLogger(EmailUtil.class);
|
|
|
|
/**
|
|
* Returns an email content as string.
|
|
* The content is formatted from the given Freemarker template and parameters.
|
|
*
|
|
* @param templateName Template name
|
|
* @param paramRootMap Map of Freemarker parameters
|
|
* @param locale Locale
|
|
* @return Template as string
|
|
* @throws Exception e
|
|
*/
|
|
private static String getFormattedHtml(String templateName, Map<String, Object> paramRootMap, Locale locale) throws Exception {
|
|
Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
|
|
cfg.setClassForTemplateLoading(EmailUtil.class, "/email_template");
|
|
cfg.setObjectWrapper(new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_23).build());
|
|
Template template = cfg.getTemplate(templateName + "/template.ftl");
|
|
paramRootMap.put("messages", new ResourceBundleModel(MessageUtil.getMessage(locale),
|
|
new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_23).build()));
|
|
StringWriter sw = new StringWriter();
|
|
template.process(paramRootMap, sw);
|
|
|
|
return sw.toString();
|
|
}
|
|
|
|
/**
|
|
* Sending an email to a user.
|
|
*
|
|
* @param templateName Template name
|
|
* @param recipientUser Recipient user
|
|
* @param subject Email subject
|
|
* @param paramMap Email parameters
|
|
*/
|
|
private static void sendEmail(String templateName, UserDto recipientUser, String subject, Map<String, Object> paramMap) {
|
|
if (log.isInfoEnabled()) {
|
|
log.info("Sending email from template=" + templateName + " to user " + recipientUser);
|
|
}
|
|
|
|
try {
|
|
// Build email headers
|
|
HtmlEmail email = new HtmlEmail();
|
|
email.setCharset(StandardCharsets.UTF_8.name());
|
|
ConfigDao configDao = new ConfigDao();
|
|
|
|
// Hostname
|
|
String envHostname = System.getenv(Constants.SMTP_HOSTNAME_ENV);
|
|
if (Strings.isNullOrEmpty(envHostname)) {
|
|
email.setHostName(ConfigUtil.getConfigStringValue(ConfigType.SMTP_HOSTNAME));
|
|
} else {
|
|
email.setHostName(envHostname);
|
|
}
|
|
|
|
// Port
|
|
int port = ConfigUtil.getConfigIntegerValue(ConfigType.SMTP_PORT);
|
|
String envPort = System.getenv(Constants.SMTP_PORT_ENV);
|
|
if (!Strings.isNullOrEmpty(envPort)) {
|
|
port = Integer.valueOf(envPort);
|
|
}
|
|
email.setSmtpPort(port);
|
|
if (port == 465) {
|
|
email.setSSLOnConnect(true);
|
|
} else if (port == 587) {
|
|
email.setStartTLSRequired(true);
|
|
}
|
|
|
|
// Username and password
|
|
String envUsername = System.getenv(Constants.SMTP_USERNAME_ENV);
|
|
String envPassword = System.getenv(Constants.SMTP_PASSWORD_ENV);
|
|
if (Strings.isNullOrEmpty(envUsername) || Strings.isNullOrEmpty(envPassword)) {
|
|
Config usernameConfig = configDao.getById(ConfigType.SMTP_USERNAME);
|
|
Config passwordConfig = configDao.getById(ConfigType.SMTP_PASSWORD);
|
|
if (usernameConfig != null && passwordConfig != null) {
|
|
email.setAuthentication(usernameConfig.getValue(), passwordConfig.getValue());
|
|
}
|
|
} else {
|
|
email.setAuthentication(envUsername, envPassword);
|
|
}
|
|
|
|
// Recipient
|
|
email.addTo(recipientUser.getEmail(), recipientUser.getUsername());
|
|
|
|
// Application name
|
|
Config themeConfig = configDao.getById(ConfigType.THEME);
|
|
String appName = "Teedy";
|
|
if (themeConfig != null) {
|
|
try (JsonReader reader = Json.createReader(new StringReader(themeConfig.getValue()))) {
|
|
JsonObject themeJson = reader.readObject();
|
|
appName = themeJson.getString("name", "Teedy");
|
|
}
|
|
}
|
|
|
|
// From email address (defined only by configuration value in the database)
|
|
email.setFrom(ConfigUtil.getConfigStringValue(ConfigType.SMTP_FROM), appName);
|
|
|
|
// Locale (defined only by environment variable)
|
|
java.util.Locale userLocale = LocaleUtil.getLocale(System.getenv(Constants.DEFAULT_LANGUAGE_ENV));
|
|
|
|
// Subject and content
|
|
email.setSubject(appName + " - " + subject);
|
|
email.setTextMsg(MessageUtil.getMessage(userLocale, "email.no_html.error"));
|
|
|
|
// Add automatic parameters
|
|
String baseUrl = System.getenv(Constants.BASE_URL_ENV);
|
|
if (Strings.isNullOrEmpty(baseUrl)) {
|
|
log.error("DOCS_BASE_URL environnement variable needs to be set for proper email links");
|
|
baseUrl = ""; // At least the mail will be sent...
|
|
}
|
|
paramMap.put("base_url", baseUrl);
|
|
paramMap.put("app_name", appName);
|
|
|
|
// Build HTML content from Freemarker template
|
|
String htmlEmailTemplate = getFormattedHtml(templateName, paramMap, userLocale);
|
|
email.setHtmlMsg(htmlEmailTemplate);
|
|
|
|
// Send the email
|
|
email.send();
|
|
} catch (Exception e) {
|
|
log.error("Error sending email with template=" + templateName + " to user " + recipientUser, e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sending an email to a user.
|
|
*
|
|
* @param templateName Template name
|
|
* @param recipientUser Recipient user
|
|
* @param paramMap Email parameters
|
|
*/
|
|
public static void sendEmail(String templateName, UserDto recipientUser, Map<String, Object> paramMap) {
|
|
java.util.Locale userLocale = LocaleUtil.getLocale(System.getenv(Constants.DEFAULT_LANGUAGE_ENV));
|
|
String subject = MessageUtil.getMessage(userLocale, "email.template." + templateName + ".subject");
|
|
sendEmail(templateName, recipientUser, subject, paramMap);
|
|
}
|
|
|
|
/**
|
|
* Parse an email content to be imported.
|
|
*
|
|
* @param part Email part
|
|
* @param mailContent Mail content modified by side-effect
|
|
*
|
|
* @throws MessagingException e
|
|
* @throws IOException e
|
|
*/
|
|
public static void parseMailContent(Part part, MailContent mailContent) throws MessagingException, IOException {
|
|
Object content = part.getContent();
|
|
if (content instanceof Multipart) {
|
|
Multipart multiPart = (Multipart) content;
|
|
int partCount = multiPart.getCount();
|
|
|
|
for (int partIndex = 0; partIndex < partCount; partIndex++) {
|
|
MimeBodyPart subPart = (MimeBodyPart) multiPart.getBodyPart(partIndex);
|
|
String disposition = subPart.getDisposition();
|
|
if (Part.ATTACHMENT.equalsIgnoreCase(disposition)) {
|
|
FileContent fileContent = new FileContent();
|
|
fileContent.name = subPart.getFileName();
|
|
fileContent.file = AppContext.getInstance().getFileService().createTemporaryFile();
|
|
Files.copy(subPart.getInputStream(), fileContent.file, StandardCopyOption.REPLACE_EXISTING);
|
|
fileContent.size = Files.size(fileContent.file);
|
|
mailContent.fileContentList.add(fileContent);
|
|
} else {
|
|
parseMailContent(subPart, mailContent);
|
|
}
|
|
}
|
|
} else if (content instanceof Message) {
|
|
// An email attached to an email, traverse its content
|
|
parseMailContent((Message) content, mailContent);
|
|
} else if (content instanceof String) {
|
|
if (mailContent.message == null) {
|
|
// Do not overwrite the content
|
|
if (part.isMimeType("text/plain")) {
|
|
mailContent.message = (String) content;
|
|
} else if (part.isMimeType("text/html")) {
|
|
// Convert HTML to plain text
|
|
mailContent.message = new HtmlToPlainText().getPlainText(Jsoup.parse((String) content));
|
|
}
|
|
}
|
|
} else if (content instanceof InputStream) {
|
|
FileContent fileContent = new FileContent();
|
|
fileContent.file = AppContext.getInstance().getFileService().createTemporaryFile();
|
|
Files.copy((InputStream) content, fileContent.file, StandardCopyOption.REPLACE_EXISTING);
|
|
fileContent.size = Files.size(fileContent.file);
|
|
mailContent.fileContentList.add(fileContent);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Structure defining a parsed email to be imported.
|
|
*/
|
|
public static class MailContent {
|
|
private String subject;
|
|
private String message;
|
|
private Date date;
|
|
|
|
List<FileContent> fileContentList = Lists.newArrayList();
|
|
|
|
public String getSubject() {
|
|
return subject;
|
|
}
|
|
|
|
public String getMessage() {
|
|
return message;
|
|
}
|
|
|
|
public List<FileContent> getFileContentList() {
|
|
return fileContentList;
|
|
}
|
|
|
|
public MailContent setSubject(String subject) {
|
|
this.subject = subject;
|
|
return this;
|
|
}
|
|
|
|
public Date getDate() {
|
|
return date;
|
|
}
|
|
|
|
public MailContent setDate(Date date) {
|
|
this.date = date;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Structure defining a file from an email to be imported.
|
|
*/
|
|
public static class FileContent {
|
|
private String name;
|
|
private Path file;
|
|
private long size;
|
|
|
|
public String getName() {
|
|
return name;
|
|
}
|
|
|
|
public Path getFile() {
|
|
return file;
|
|
}
|
|
|
|
public long getSize() {
|
|
return size;
|
|
}
|
|
}
|
|
}
|