Separate email preparation and email sending into separate classes

- SendMailSSL keeps on handling the technical details for sending mails, while EmailService offers methods to other classes and worries about generating the correct email content
This commit is contained in:
ljacqu
2017-02-25 20:14:58 +01:00
parent 72c5cfac68
commit a4b440bcca
11 changed files with 396 additions and 318 deletions
@@ -0,0 +1,140 @@
package fr.xephi.authme.mail;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.FileUtils;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.bukkit.Server;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.imageio.ImageIO;
import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
/**
* Creates emails and sends them.
*/
public class EmailService {
private final File dataFolder;
private final String serverName;
private final Settings settings;
private final SendMailSSL sendMailSSL;
@Inject
EmailService(@DataFolder File dataFolder, Server server, Settings settings, SendMailSSL sendMailSSL) {
this.dataFolder = dataFolder;
this.serverName = server.getServerName();
this.settings = settings;
this.sendMailSSL = sendMailSSL;
}
public boolean hasAllInformation() {
return sendMailSSL.hasAllInformation();
}
/**
* Sends an email to the user with his new password.
*
* @param name the name of the player
* @param mailAddress the player's email
* @param newPass the new password
* @return true if email could be sent, false otherwise
*/
public boolean sendPasswordMail(String name, String mailAddress, String newPass) {
if (!hasAllInformation()) {
ConsoleLogger.warning("Cannot perform email registration: not all email settings are complete");
return false;
}
HtmlEmail email;
try {
email = sendMailSSL.initializeMail(mailAddress);
} catch (EmailException e) {
ConsoleLogger.logException("Failed to create email with the given settings:", e);
return false;
}
String mailText = replaceTagsForPasswordMail(settings.getPasswordEmailMessage(), name, newPass);
// Generate an image?
File file = null;
if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) {
try {
file = generateImage(name, newPass);
mailText = embedImageIntoEmailContent(file, email, mailText);
} catch (IOException | EmailException e) {
ConsoleLogger.logException(
"Unable to send new password as image for email " + mailAddress + ":", e);
}
}
boolean couldSendEmail = sendMailSSL.sendEmail(mailText, email);
FileUtils.delete(file);
return couldSendEmail;
}
public boolean sendRecoveryCode(String name, String email, String code) {
HtmlEmail htmlEmail;
try {
htmlEmail = sendMailSSL.initializeMail(email);
} catch (EmailException e) {
ConsoleLogger.logException("Failed to create email for recovery code:", e);
return false;
}
String message = replaceTagsForRecoveryCodeMail(settings.getRecoveryCodeEmailMessage(),
name, code, settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID));
return sendMailSSL.sendEmail(message, htmlEmail);
}
public boolean sendTestEmail(String email) {
HtmlEmail htmlEmail;
try {
htmlEmail = sendMailSSL.initializeMail(email);
} catch (EmailException e) {
ConsoleLogger.logException("Failed to create email for sample email:", e);
return false;
}
htmlEmail.setSubject("AuthMe test email");
String message = "Hello there!<br />This is a sample email sent to you from a Minecraft server ("
+ serverName + ") via /authme debug mail. If you're seeing this, sending emails should be fine.";
return sendMailSSL.sendEmail(message, htmlEmail);
}
private File generateImage(String name, String newPass) throws IOException {
ImageGenerator gen = new ImageGenerator(newPass);
File file = new File(dataFolder, name + "_new_pass.jpg");
ImageIO.write(gen.generateImage(), "jpg", file);
return file;
}
private static String embedImageIntoEmailContent(File image, HtmlEmail email, String content)
throws EmailException {
DataSource source = new FileDataSource(image);
String tag = email.embed(source, image.getName());
return content.replace("<image />", "<img src=\"cid:" + tag + "\">");
}
private String replaceTagsForPasswordMail(String mailText, String name, String newPass) {
return mailText
.replace("<playername />", name)
.replace("<servername />", serverName)
.replace("<generatedpass />", newPass);
}
private String replaceTagsForRecoveryCodeMail(String mailText, String name, String code, int hoursValid) {
return mailText
.replace("<playername />", name)
.replace("<servername />", serverName)
.replace("<recoverycode />", code)
.replace("<hoursvalid />", String.valueOf(hoursValid));
}
}