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

View File

@ -2,7 +2,7 @@ package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.mail.EmailService;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -18,7 +18,7 @@ class TestEmailSender implements DebugSection {
private DataSource dataSource; private DataSource dataSource;
@Inject @Inject
private SendMailSSL sendMailSSL; private EmailService emailService;
@Override @Override
@ -33,7 +33,7 @@ class TestEmailSender implements DebugSection {
@Override @Override
public void execute(CommandSender sender, List<String> arguments) { public void execute(CommandSender sender, List<String> arguments) {
if (!sendMailSSL.hasAllInformation()) { if (!emailService.hasAllInformation()) {
sender.sendMessage(ChatColor.RED + "You haven't set all required configurations in config.yml " + sender.sendMessage(ChatColor.RED + "You haven't set all required configurations in config.yml " +
"for sending emails. Please check your config.yml"); "for sending emails. Please check your config.yml");
return; return;
@ -43,7 +43,7 @@ class TestEmailSender implements DebugSection {
// getEmail() takes care of informing the sender of the error if email == null // getEmail() takes care of informing the sender of the error if email == null
if (email != null) { if (email != null) {
boolean sendMail = sendMailSSL.sendTestEmail(email); boolean sendMail = emailService.sendTestEmail(email);
if (sendMail) { if (sendMail) {
sender.sendMessage("Test email sent to " + email + " with success"); sender.sendMessage("Test email sent to " + email + " with success");
} else { } else {

View File

@ -5,7 +5,7 @@ import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
@ -37,7 +37,7 @@ public class RecoverEmailCommand extends PlayerCommand {
private PlayerCache playerCache; private PlayerCache playerCache;
@Inject @Inject
private SendMailSSL sendMailSsl; private EmailService emailService;
@Inject @Inject
private RecoveryCodeService recoveryCodeService; private RecoveryCodeService recoveryCodeService;
@ -47,7 +47,7 @@ public class RecoverEmailCommand extends PlayerCommand {
final String playerMail = arguments.get(0); final String playerMail = arguments.get(0);
final String playerName = player.getName(); final String playerName = player.getName();
if (!sendMailSsl.hasAllInformation()) { if (!emailService.hasAllInformation()) {
ConsoleLogger.warning("Mail API is not set"); ConsoleLogger.warning("Mail API is not set");
commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
return; return;
@ -84,7 +84,7 @@ public class RecoverEmailCommand extends PlayerCommand {
private void createAndSendRecoveryCode(Player player, String email) { private void createAndSendRecoveryCode(Player player, String email) {
String recoveryCode = recoveryCodeService.generateCode(player.getName()); String recoveryCode = recoveryCodeService.generateCode(player.getName());
boolean couldSendMail = sendMailSsl.sendRecoveryCode(player.getName(), email, recoveryCode); boolean couldSendMail = emailService.sendRecoveryCode(player.getName(), email, recoveryCode);
if (couldSendMail) { if (couldSendMail) {
commonService.send(player, MessageKey.RECOVERY_CODE_SENT); commonService.send(player, MessageKey.RECOVERY_CODE_SENT);
} else { } else {
@ -108,7 +108,7 @@ public class RecoverEmailCommand extends PlayerCommand {
HashedPassword hashNew = passwordSecurity.computeHash(thePass, name); HashedPassword hashNew = passwordSecurity.computeHash(thePass, name);
dataSource.updatePassword(name, hashNew); dataSource.updatePassword(name, hashNew);
boolean couldSendMail = sendMailSsl.sendPasswordMail(name, email, thePass); boolean couldSendMail = emailService.sendPasswordMail(name, email, thePass);
if (couldSendMail) { if (couldSendMail) {
commonService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); commonService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
} else { } else {

View File

@ -2,7 +2,7 @@ package fr.xephi.authme.command.executable.register;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.process.register.RegisterSecondaryArgument; import fr.xephi.authme.process.register.RegisterSecondaryArgument;
@ -37,7 +37,7 @@ public class RegisterCommand extends PlayerCommand {
private CommonService commonService; private CommonService commonService;
@Inject @Inject
private SendMailSSL sendMailSsl; private EmailService emailService;
@Inject @Inject
private ValidationService validationService; private ValidationService validationService;
@ -127,7 +127,7 @@ public class RegisterCommand extends PlayerCommand {
} }
private void handleEmailRegistration(Player player, List<String> arguments) { private void handleEmailRegistration(Player player, List<String> arguments) {
if (!sendMailSsl.hasAllInformation()) { if (!emailService.hasAllInformation()) {
commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
ConsoleLogger.warning("Cannot register player '" + player.getName() + "': no email or password is set " ConsoleLogger.warning("Cannot register player '" + player.getName() + "': no email or password is set "
+ "to send emails from. Please adjust your config at " + EmailSettings.MAIL_ACCOUNT.getPath()); + "to send emails from. Please adjust your config at " + EmailSettings.MAIL_ACCOUNT.getPath());

View File

@ -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));
}
}

View File

@ -1,27 +1,17 @@
package fr.xephi.authme.mail; package fr.xephi.authme.mail;
import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import org.apache.commons.mail.EmailConstants; import org.apache.commons.mail.EmailConstants;
import org.apache.commons.mail.EmailException; import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail; import org.apache.commons.mail.HtmlEmail;
import org.bukkit.Server;
import javax.activation.CommandMap; import javax.activation.CommandMap;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.MailcapCommandMap; import javax.activation.MailcapCommandMap;
import javax.imageio.ImageIO;
import javax.inject.Inject; import javax.inject.Inject;
import javax.mail.Session; import javax.mail.Session;
import java.io.File;
import java.io.IOException;
import java.security.Security; import java.security.Security;
import java.util.Properties; import java.util.Properties;
@ -34,14 +24,10 @@ import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
*/ */
public class SendMailSSL { public class SendMailSSL {
private final File dataFolder;
private final String serverName;
private final Settings settings; private final Settings settings;
@Inject @Inject
SendMailSSL(@DataFolder File dataFolder, Server server, Settings settings) { SendMailSSL(Settings settings) {
this.dataFolder = dataFolder;
this.serverName = server.getServerName();
this.settings = settings; this.settings = settings;
} }
@ -55,91 +41,7 @@ public class SendMailSSL {
&& !settings.getProperty(MAIL_PASSWORD).isEmpty(); && !settings.getProperty(MAIL_PASSWORD).isEmpty();
} }
/** public HtmlEmail initializeMail(String emailAddress) throws EmailException {
* 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 = 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 = sendEmail(mailText, email);
FileUtils.delete(file);
return couldSendEmail;
}
public boolean sendRecoveryCode(String name, String email, String code) {
HtmlEmail htmlEmail;
try {
htmlEmail = 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 sendEmail(message, htmlEmail);
}
public boolean sendTestEmail(String email) {
HtmlEmail htmlEmail;
try {
htmlEmail = 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 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 + "\">");
}
@VisibleForTesting
HtmlEmail initializeMail(String emailAddress) throws EmailException {
String senderMail = StringUtils.isEmpty(settings.getProperty(EmailSettings.MAIL_ADDRESS)) String senderMail = StringUtils.isEmpty(settings.getProperty(EmailSettings.MAIL_ADDRESS))
? settings.getProperty(EmailSettings.MAIL_ACCOUNT) ? settings.getProperty(EmailSettings.MAIL_ACCOUNT)
: settings.getProperty(EmailSettings.MAIL_ADDRESS); : settings.getProperty(EmailSettings.MAIL_ADDRESS);
@ -163,8 +65,7 @@ public class SendMailSSL {
return email; return email;
} }
@VisibleForTesting public boolean sendEmail(String content, HtmlEmail email) {
boolean sendEmail(String content, HtmlEmail email) {
Thread.currentThread().setContextClassLoader(SendMailSSL.class.getClassLoader()); Thread.currentThread().setContextClassLoader(SendMailSSL.class.getClassLoader());
// Issue #999: Prevent UnsupportedDataTypeException: no object DCH for MIME type multipart/alternative // Issue #999: Prevent UnsupportedDataTypeException: no object DCH for MIME type multipart/alternative
// cf. http://stackoverflow.com/questions/21856211/unsupporteddatatypeexception-no-object-dch-for-mime-type // cf. http://stackoverflow.com/questions/21856211/unsupporteddatatypeexception-no-object-dch-for-mime-type
@ -191,21 +92,6 @@ public class SendMailSSL {
} }
} }
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));
}
private void setPropertiesForPort(HtmlEmail email, int port) throws EmailException { private void setPropertiesForPort(HtmlEmail email, int port) throws EmailException {
switch (port) { switch (port) {
case 587: case 587:

View File

@ -2,7 +2,7 @@ package fr.xephi.authme.process.register.executors;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.process.SyncProcessManager; import fr.xephi.authme.process.SyncProcessManager;
@ -15,8 +15,8 @@ import org.bukkit.entity.Player;
import javax.inject.Inject; import javax.inject.Inject;
import static fr.xephi.authme.process.register.executors.PlayerAuthBuilderHelper.createPlayerAuth;
import static fr.xephi.authme.permission.PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS; import static fr.xephi.authme.permission.PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS;
import static fr.xephi.authme.process.register.executors.PlayerAuthBuilderHelper.createPlayerAuth;
import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWORD_LENGTH; import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWORD_LENGTH;
/** /**
@ -34,7 +34,7 @@ class EmailRegisterExecutorProvider {
private CommonService commonService; private CommonService commonService;
@Inject @Inject
private SendMailSSL sendMailSsl; private EmailService emailService;
@Inject @Inject
private SyncProcessManager syncProcessManager; private SyncProcessManager syncProcessManager;
@ -80,7 +80,7 @@ class EmailRegisterExecutorProvider {
@Override @Override
public void executePostPersistAction() { public void executePostPersistAction() {
boolean couldSendMail = sendMailSsl.sendPasswordMail(player.getName(), email, password); boolean couldSendMail = emailService.sendPasswordMail(player.getName(), email, password);
if (couldSendMail) { if (couldSendMail) {
syncProcessManager.processSyncEmailRegister(player); syncProcessManager.processSyncEmailRegister(player);
} else { } else {

View File

@ -4,7 +4,7 @@ import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
@ -59,7 +59,7 @@ public class RecoverEmailCommandTest {
private PlayerCache playerCache; private PlayerCache playerCache;
@Mock @Mock
private SendMailSSL sendMailSsl; private EmailService emailService;
@Mock @Mock
private RecoveryCodeService recoveryCodeService; private RecoveryCodeService recoveryCodeService;
@ -72,7 +72,7 @@ public class RecoverEmailCommandTest {
@Test @Test
public void shouldHandleMissingMailProperties() { public void shouldHandleMissingMailProperties() {
// given // given
given(sendMailSsl.hasAllInformation()).willReturn(false); given(emailService.hasAllInformation()).willReturn(false);
Player sender = mock(Player.class); Player sender = mock(Player.class);
// when // when
@ -89,14 +89,14 @@ public class RecoverEmailCommandTest {
String name = "Bobby"; String name = "Bobby";
Player sender = mock(Player.class); Player sender = mock(Player.class);
given(sender.getName()).willReturn(name); given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(true); given(playerCache.isAuthenticated(name)).willReturn(true);
// when // when
command.executeCommand(sender, Collections.singletonList("bobby@example.org")); command.executeCommand(sender, Collections.singletonList("bobby@example.org"));
// then // then
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verifyZeroInteractions(dataSource); verifyZeroInteractions(dataSource);
verify(commandService).send(sender, MessageKey.ALREADY_LOGGED_IN_ERROR); verify(commandService).send(sender, MessageKey.ALREADY_LOGGED_IN_ERROR);
} }
@ -107,7 +107,7 @@ public class RecoverEmailCommandTest {
String name = "Player123"; String name = "Player123";
Player sender = mock(Player.class); Player sender = mock(Player.class);
given(sender.getName()).willReturn(name); given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false); given(playerCache.isAuthenticated(name)).willReturn(false);
given(dataSource.getAuth(name)).willReturn(null); given(dataSource.getAuth(name)).willReturn(null);
@ -115,7 +115,7 @@ public class RecoverEmailCommandTest {
command.executeCommand(sender, Collections.singletonList("someone@example.com")); command.executeCommand(sender, Collections.singletonList("someone@example.com"));
// then // then
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verify(dataSource).getAuth(name); verify(dataSource).getAuth(name);
verifyNoMoreInteractions(dataSource); verifyNoMoreInteractions(dataSource);
verify(commandService).send(sender, MessageKey.USAGE_REGISTER); verify(commandService).send(sender, MessageKey.USAGE_REGISTER);
@ -127,7 +127,7 @@ public class RecoverEmailCommandTest {
String name = "Tract0r"; String name = "Tract0r";
Player sender = mock(Player.class); Player sender = mock(Player.class);
given(sender.getName()).willReturn(name); given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false); given(playerCache.isAuthenticated(name)).willReturn(false);
given(dataSource.getAuth(name)).willReturn(newAuthWithEmail(DEFAULT_EMAIL)); given(dataSource.getAuth(name)).willReturn(newAuthWithEmail(DEFAULT_EMAIL));
@ -135,7 +135,7 @@ public class RecoverEmailCommandTest {
command.executeCommand(sender, Collections.singletonList(DEFAULT_EMAIL)); command.executeCommand(sender, Collections.singletonList(DEFAULT_EMAIL));
// then // then
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verify(dataSource).getAuth(name); verify(dataSource).getAuth(name);
verifyNoMoreInteractions(dataSource); verifyNoMoreInteractions(dataSource);
verify(commandService).send(sender, MessageKey.INVALID_EMAIL); verify(commandService).send(sender, MessageKey.INVALID_EMAIL);
@ -147,7 +147,7 @@ public class RecoverEmailCommandTest {
String name = "Rapt0r"; String name = "Rapt0r";
Player sender = mock(Player.class); Player sender = mock(Player.class);
given(sender.getName()).willReturn(name); given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false); given(playerCache.isAuthenticated(name)).willReturn(false);
given(dataSource.getAuth(name)).willReturn(newAuthWithEmail("raptor@example.org")); given(dataSource.getAuth(name)).willReturn(newAuthWithEmail("raptor@example.org"));
@ -155,7 +155,7 @@ public class RecoverEmailCommandTest {
command.executeCommand(sender, Collections.singletonList("wrong-email@example.com")); command.executeCommand(sender, Collections.singletonList("wrong-email@example.com"));
// then // then
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verify(dataSource).getAuth(name); verify(dataSource).getAuth(name);
verifyNoMoreInteractions(dataSource); verifyNoMoreInteractions(dataSource);
verify(commandService).send(sender, MessageKey.INVALID_EMAIL); verify(commandService).send(sender, MessageKey.INVALID_EMAIL);
@ -167,8 +167,8 @@ public class RecoverEmailCommandTest {
String name = "Vultur3"; String name = "Vultur3";
Player sender = mock(Player.class); Player sender = mock(Player.class);
given(sender.getName()).willReturn(name); given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
given(sendMailSsl.sendRecoveryCode(anyString(), anyString(), anyString())).willReturn(true); given(emailService.sendRecoveryCode(anyString(), anyString(), anyString())).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false); given(playerCache.isAuthenticated(name)).willReturn(false);
String email = "v@example.com"; String email = "v@example.com";
given(dataSource.getAuth(name)).willReturn(newAuthWithEmail(email)); given(dataSource.getAuth(name)).willReturn(newAuthWithEmail(email));
@ -180,11 +180,11 @@ public class RecoverEmailCommandTest {
command.executeCommand(sender, Collections.singletonList(email.toUpperCase())); command.executeCommand(sender, Collections.singletonList(email.toUpperCase()));
// then // then
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verify(dataSource).getAuth(name); verify(dataSource).getAuth(name);
verify(recoveryCodeService).generateCode(name); verify(recoveryCodeService).generateCode(name);
verify(commandService).send(sender, MessageKey.RECOVERY_CODE_SENT); verify(commandService).send(sender, MessageKey.RECOVERY_CODE_SENT);
verify(sendMailSsl).sendRecoveryCode(name, email, code); verify(emailService).sendRecoveryCode(name, email, code);
} }
@Test @Test
@ -193,7 +193,7 @@ public class RecoverEmailCommandTest {
String name = "Vultur3"; String name = "Vultur3";
Player sender = mock(Player.class); Player sender = mock(Player.class);
given(sender.getName()).willReturn(name); given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false); given(playerCache.isAuthenticated(name)).willReturn(false);
String email = "vulture@example.com"; String email = "vulture@example.com";
PlayerAuth auth = newAuthWithEmail(email); PlayerAuth auth = newAuthWithEmail(email);
@ -205,10 +205,10 @@ public class RecoverEmailCommandTest {
command.executeCommand(sender, Arrays.asList(email, "bogus")); command.executeCommand(sender, Arrays.asList(email, "bogus"));
// then // then
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verify(dataSource, only()).getAuth(name); verify(dataSource, only()).getAuth(name);
verify(commandService).send(sender, MessageKey.INCORRECT_RECOVERY_CODE); verify(commandService).send(sender, MessageKey.INCORRECT_RECOVERY_CODE);
verifyNoMoreInteractions(sendMailSsl); verifyNoMoreInteractions(emailService);
} }
@Test @Test
@ -217,8 +217,8 @@ public class RecoverEmailCommandTest {
String name = "Vultur3"; String name = "Vultur3";
Player sender = mock(Player.class); Player sender = mock(Player.class);
given(sender.getName()).willReturn(name); given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
given(sendMailSsl.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true); given(emailService.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false); given(playerCache.isAuthenticated(name)).willReturn(false);
String email = "vulture@example.com"; String email = "vulture@example.com";
String code = "A6EF3AC8"; String code = "A6EF3AC8";
@ -234,7 +234,7 @@ public class RecoverEmailCommandTest {
command.executeCommand(sender, Arrays.asList(email, code)); command.executeCommand(sender, Arrays.asList(email, code));
// then // then
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verify(dataSource).getAuth(name); verify(dataSource).getAuth(name);
ArgumentCaptor<String> passwordCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> passwordCaptor = ArgumentCaptor.forClass(String.class);
verify(passwordSecurity).computeHash(passwordCaptor.capture(), eq(name)); verify(passwordSecurity).computeHash(passwordCaptor.capture(), eq(name));
@ -242,7 +242,7 @@ public class RecoverEmailCommandTest {
assertThat(generatedPassword, stringWithLength(20)); assertThat(generatedPassword, stringWithLength(20));
verify(dataSource).updatePassword(eq(name), any(HashedPassword.class)); verify(dataSource).updatePassword(eq(name), any(HashedPassword.class));
verify(recoveryCodeService).removeCode(name); verify(recoveryCodeService).removeCode(name);
verify(sendMailSsl).sendPasswordMail(name, email, generatedPassword); verify(emailService).sendPasswordMail(name, email, generatedPassword);
verify(commandService).send(sender, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); verify(commandService).send(sender, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
} }
@ -252,8 +252,8 @@ public class RecoverEmailCommandTest {
String name = "sh4rK"; String name = "sh4rK";
Player sender = mock(Player.class); Player sender = mock(Player.class);
given(sender.getName()).willReturn(name); given(sender.getName()).willReturn(name);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
given(sendMailSsl.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true); given(emailService.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true);
given(playerCache.isAuthenticated(name)).willReturn(false); given(playerCache.isAuthenticated(name)).willReturn(false);
String email = "shark@example.org"; String email = "shark@example.org";
PlayerAuth auth = newAuthWithEmail(email); PlayerAuth auth = newAuthWithEmail(email);
@ -267,14 +267,14 @@ public class RecoverEmailCommandTest {
command.executeCommand(sender, Collections.singletonList(email)); command.executeCommand(sender, Collections.singletonList(email));
// then // then
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verify(dataSource).getAuth(name); verify(dataSource).getAuth(name);
ArgumentCaptor<String> passwordCaptor = ArgumentCaptor.forClass(String.class); ArgumentCaptor<String> passwordCaptor = ArgumentCaptor.forClass(String.class);
verify(passwordSecurity).computeHash(passwordCaptor.capture(), eq(name)); verify(passwordSecurity).computeHash(passwordCaptor.capture(), eq(name));
String generatedPassword = passwordCaptor.getValue(); String generatedPassword = passwordCaptor.getValue();
assertThat(generatedPassword, stringWithLength(20)); assertThat(generatedPassword, stringWithLength(20));
verify(dataSource).updatePassword(eq(name), any(HashedPassword.class)); verify(dataSource).updatePassword(eq(name), any(HashedPassword.class));
verify(sendMailSsl).sendPasswordMail(name, email, generatedPassword); verify(emailService).sendPasswordMail(name, email, generatedPassword);
verify(commandService).send(sender, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); verify(commandService).send(sender, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
} }

View File

@ -1,7 +1,7 @@
package fr.xephi.authme.command.executable.register; package fr.xephi.authme.command.executable.register;
import fr.xephi.authme.TestHelper; import fr.xephi.authme.TestHelper;
import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.process.register.RegisterSecondaryArgument; import fr.xephi.authme.process.register.RegisterSecondaryArgument;
@ -52,7 +52,7 @@ public class RegisterCommandTest {
private Management management; private Management management;
@Mock @Mock
private SendMailSSL sendMailSsl; private EmailService emailService;
@Mock @Mock
private ValidationService validationService; private ValidationService validationService;
@ -82,7 +82,7 @@ public class RegisterCommandTest {
// then // then
verify(sender).sendMessage(argThat(containsString("Player only!"))); verify(sender).sendMessage(argThat(containsString("Player only!")));
verifyZeroInteractions(management, sendMailSsl); verifyZeroInteractions(management, emailService);
} }
@Test @Test
@ -98,7 +98,7 @@ public class RegisterCommandTest {
// then // then
verify(management).performRegister(player, executor); verify(management).performRegister(player, executor);
verifyZeroInteractions(sendMailSsl); verifyZeroInteractions(emailService);
} }
@Test @Test
@ -111,7 +111,7 @@ public class RegisterCommandTest {
// then // then
verify(commonService).send(player, MessageKey.USAGE_REGISTER); verify(commonService).send(player, MessageKey.USAGE_REGISTER);
verifyZeroInteractions(management, sendMailSsl); verifyZeroInteractions(management, emailService);
} }
@Test @Test
@ -126,13 +126,13 @@ public class RegisterCommandTest {
// then // then
verify(commonService).send(player, MessageKey.USAGE_REGISTER); verify(commonService).send(player, MessageKey.USAGE_REGISTER);
verifyZeroInteractions(management, sendMailSsl); verifyZeroInteractions(management, emailService);
} }
@Test @Test
public void shouldReturnErrorForMissingEmailConfirmation() { public void shouldReturnErrorForMissingEmailConfirmation() {
// given // given
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL); given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL);
given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.EMAIL_MANDATORY); given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.EMAIL_MANDATORY);
given(validationService.validateEmail(anyString())).willReturn(true); given(validationService.validateEmail(anyString())).willReturn(true);
@ -150,7 +150,7 @@ public class RegisterCommandTest {
public void shouldThrowErrorForMissingEmailConfiguration() { public void shouldThrowErrorForMissingEmailConfiguration() {
// given // given
given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL); given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL);
given(sendMailSsl.hasAllInformation()).willReturn(false); given(emailService.hasAllInformation()).willReturn(false);
Player player = mock(Player.class); Player player = mock(Player.class);
// when // when
@ -158,7 +158,7 @@ public class RegisterCommandTest {
// then // then
verify(commonService).send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); verify(commonService).send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verifyZeroInteractions(management); verifyZeroInteractions(management);
} }
@ -168,7 +168,7 @@ public class RegisterCommandTest {
String playerMail = "player@example.org"; String playerMail = "player@example.org";
given(validationService.validateEmail(playerMail)).willReturn(false); given(validationService.validateEmail(playerMail)).willReturn(false);
given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL); given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
Player player = mock(Player.class); Player player = mock(Player.class);
// when // when
@ -187,7 +187,7 @@ public class RegisterCommandTest {
given(validationService.validateEmail(playerMail)).willReturn(true); given(validationService.validateEmail(playerMail)).willReturn(true);
given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL); given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL);
given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.CONFIRMATION); given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.CONFIRMATION);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
Player player = mock(Player.class); Player player = mock(Player.class);
// when // when
@ -195,7 +195,7 @@ public class RegisterCommandTest {
// then // then
verify(commonService).send(player, MessageKey.USAGE_REGISTER); verify(commonService).send(player, MessageKey.USAGE_REGISTER);
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verifyZeroInteractions(management); verifyZeroInteractions(management);
} }
@ -206,7 +206,7 @@ public class RegisterCommandTest {
given(validationService.validateEmail(playerMail)).willReturn(true); given(validationService.validateEmail(playerMail)).willReturn(true);
given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL); given(commonService.getProperty(RegistrationSettings.REGISTRATION_TYPE)).willReturn(RegistrationType.EMAIL);
given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.CONFIRMATION); given(commonService.getProperty(RegistrationSettings.REGISTER_SECOND_ARGUMENT)).willReturn(RegisterSecondaryArgument.CONFIRMATION);
given(sendMailSsl.hasAllInformation()).willReturn(true); given(emailService.hasAllInformation()).willReturn(true);
Player player = mock(Player.class); Player player = mock(Player.class);
RegistrationExecutor executor = mock(RegistrationExecutor.class); RegistrationExecutor executor = mock(RegistrationExecutor.class);
given(registrationExecutorProvider.getEmailRegisterExecutor(player, playerMail)).willReturn(executor); given(registrationExecutorProvider.getEmailRegisterExecutor(player, playerMail)).willReturn(executor);
@ -216,7 +216,7 @@ public class RegisterCommandTest {
// then // then
verify(validationService).validateEmail(playerMail); verify(validationService).validateEmail(playerMail);
verify(sendMailSsl).hasAllInformation(); verify(emailService).hasAllInformation();
verify(management).performRegister(player, executor); verify(management).performRegister(player, executor);
} }
@ -232,7 +232,7 @@ public class RegisterCommandTest {
// then // then
verify(commonService).send(player, MessageKey.PASSWORD_MATCH_ERROR); verify(commonService).send(player, MessageKey.PASSWORD_MATCH_ERROR);
verifyZeroInteractions(management, sendMailSsl); verifyZeroInteractions(management, emailService);
} }
@Test @Test

View File

@ -0,0 +1,190 @@
package fr.xephi.authme.mail;
import ch.jalu.injector.testing.BeforeInjecting;
import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.TestHelper;
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 org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.bukkit.Server;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import java.io.File;
import java.io.IOException;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
/**
* Test for {@link EmailService}.
*/
@RunWith(DelayedInjectionRunner.class)
public class EmailServiceTest {
@InjectDelayed
private EmailService emailService;
@Mock
private Settings settings;
@Mock
private Server server;
@Mock
private SendMailSSL sendMailSSL;
@DataFolder
private File dataFolder;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@BeforeClass
public static void initLogger() {
TestHelper.setupLogger();
}
@BeforeInjecting
public void initFields() throws IOException {
dataFolder = temporaryFolder.newFolder();
given(server.getServerName()).willReturn("serverName");
given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("mail@example.org");
given(settings.getProperty(EmailSettings.MAIL_PASSWORD)).willReturn("pass1234");
given(sendMailSSL.hasAllInformation()).willReturn(true);
}
@Test
public void shouldHaveAllInformation() {
// given / when / then
assertThat(emailService.hasAllInformation(), equalTo(true));
}
@Test
public void shouldSendPasswordMail() throws EmailException {
// given
given(settings.getPasswordEmailMessage())
.willReturn("Hi <playername />, your new password for <servername /> is <generatedpass />");
given(settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)).willReturn(false);
HtmlEmail email = mock(HtmlEmail.class);
given(sendMailSSL.initializeMail(anyString())).willReturn(email);
given(sendMailSSL.sendEmail(anyString(), eq(email))).willReturn(true);
// when
boolean result = emailService.sendPasswordMail("Player", "user@example.com", "new_password");
// then
assertThat(result, equalTo(true));
verify(sendMailSSL).initializeMail("user@example.com");
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sendMailSSL).sendEmail(messageCaptor.capture(), eq(email));
assertThat(messageCaptor.getValue(),
equalTo("Hi Player, your new password for serverName is new_password"));
}
@Test
public void shouldHandleMailCreationError() throws EmailException {
// given
doThrow(EmailException.class).when(sendMailSSL).initializeMail(anyString());
// when
boolean result = emailService.sendPasswordMail("Player", "user@example.com", "new_password");
// then
assertThat(result, equalTo(false));
verify(sendMailSSL).initializeMail("user@example.com");
verify(sendMailSSL, never()).sendEmail(anyString(), any(HtmlEmail.class));
}
@Test
public void shouldHandleMailSendingFailure() throws EmailException {
// given
given(settings.getPasswordEmailMessage()).willReturn("Hi <playername />, your new pass is <generatedpass />");
given(settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)).willReturn(false);
HtmlEmail email = mock(HtmlEmail.class);
given(sendMailSSL.initializeMail(anyString())).willReturn(email);
given(sendMailSSL.sendEmail(anyString(), any(HtmlEmail.class))).willReturn(false);
// when
boolean result = emailService.sendPasswordMail("bobby", "user@example.com", "myPassw0rd");
// then
assertThat(result, equalTo(false));
verify(sendMailSSL).initializeMail("user@example.com");
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sendMailSSL).sendEmail(messageCaptor.capture(), eq(email));
assertThat(messageCaptor.getValue(), equalTo("Hi bobby, your new pass is myPassw0rd"));
}
@Test
public void shouldSendRecoveryCode() throws EmailException {
// given
given(settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)).willReturn(7);
given(settings.getRecoveryCodeEmailMessage())
.willReturn("Hi <playername />, your code on <servername /> is <recoverycode /> (valid <hoursvalid /> hours)");
HtmlEmail email = mock(HtmlEmail.class);
given(sendMailSSL.initializeMail(anyString())).willReturn(email);
given(sendMailSSL.sendEmail(anyString(), any(HtmlEmail.class))).willReturn(true);
// when
boolean result = emailService.sendRecoveryCode("Timmy", "tim@example.com", "12C56A");
// then
assertThat(result, equalTo(true));
verify(sendMailSSL).initializeMail("tim@example.com");
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sendMailSSL).sendEmail(messageCaptor.capture(), eq(email));
assertThat(messageCaptor.getValue(), equalTo("Hi Timmy, your code on serverName is 12C56A (valid 7 hours)"));
}
@Test
public void shouldHandleMailCreationErrorForRecoveryCode() throws EmailException {
// given
given(sendMailSSL.initializeMail(anyString())).willThrow(EmailException.class);
// when
boolean result = emailService.sendRecoveryCode("Player", "player@example.org", "ABC1234");
// then
assertThat(result, equalTo(false));
verify(sendMailSSL).initializeMail("player@example.org");
verify(sendMailSSL, never()).sendEmail(anyString(), any(HtmlEmail.class));
}
@Test
public void shouldHandleFailureToSendRecoveryCode() throws EmailException {
// given
given(settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)).willReturn(7);
given(settings.getRecoveryCodeEmailMessage()).willReturn("Hi <playername />, your code is <recoverycode />");
EmailService sendMailSpy = spy(emailService);
HtmlEmail email = mock(HtmlEmail.class);
given(sendMailSSL.initializeMail(anyString())).willReturn(email);
given(sendMailSSL.sendEmail(anyString(), any(HtmlEmail.class))).willReturn(false);
// when
boolean result = sendMailSpy.sendRecoveryCode("John", "user@example.com", "1DEF77");
// then
assertThat(result, equalTo(false));
verify(sendMailSSL).initializeMail("user@example.com");
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sendMailSSL).sendEmail(messageCaptor.capture(), eq(email));
assertThat(messageCaptor.getValue(), equalTo("Hi John, your code is 1DEF77"));
}
}

View File

@ -4,22 +4,17 @@ import ch.jalu.injector.testing.BeforeInjecting;
import ch.jalu.injector.testing.DelayedInjectionRunner; import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed; import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.TestHelper; import fr.xephi.authme.TestHelper;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.apache.commons.mail.EmailException; import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail; import org.apache.commons.mail.HtmlEmail;
import org.bukkit.Server;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock; import org.mockito.Mock;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Properties; import java.util.Properties;
@ -28,16 +23,7 @@ import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
/** /**
* Test for {@link SendMailSSL}. * Test for {@link SendMailSSL}.
@ -50,10 +36,6 @@ public class SendMailSSLTest {
@Mock @Mock
private Settings settings; private Settings settings;
@Mock
private Server server;
@DataFolder
private File dataFolder;
@Rule @Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder(); public TemporaryFolder temporaryFolder = new TemporaryFolder();
@ -65,8 +47,6 @@ public class SendMailSSLTest {
@BeforeInjecting @BeforeInjecting
public void initFields() throws IOException { public void initFields() throws IOException {
dataFolder = temporaryFolder.newFolder();
given(server.getServerName()).willReturn("serverName");
given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("mail@example.org"); given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("mail@example.org");
given(settings.getProperty(EmailSettings.MAIL_PASSWORD)).willReturn("pass1234"); given(settings.getProperty(EmailSettings.MAIL_PASSWORD)).willReturn("pass1234");
} }
@ -77,123 +57,6 @@ public class SendMailSSLTest {
assertThat(sendMailSSL.hasAllInformation(), equalTo(true)); assertThat(sendMailSSL.hasAllInformation(), equalTo(true));
} }
@Test
public void shouldSendPasswordMail() throws EmailException {
// given
given(settings.getPasswordEmailMessage())
.willReturn("Hi <playername />, your new password for <servername /> is <generatedpass />");
given(settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)).willReturn(false);
SendMailSSL sendMailSpy = spy(sendMailSSL);
HtmlEmail email = mock(HtmlEmail.class);
doReturn(email).when(sendMailSpy).initializeMail(anyString());
doReturn(true).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class));
// when
boolean result = sendMailSpy.sendPasswordMail("Player", "user@example.com", "new_password");
// then
assertThat(result, equalTo(true));
verify(sendMailSpy).initializeMail("user@example.com");
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email));
assertThat(messageCaptor.getValue(),
equalTo("Hi Player, your new password for serverName is new_password"));
}
@Test
public void shouldHandleMailCreationError() throws EmailException {
// given
SendMailSSL sendMailSpy = spy(sendMailSSL);
doThrow(EmailException.class).when(sendMailSpy).initializeMail(anyString());
// when
boolean result = sendMailSpy.sendPasswordMail("Player", "user@example.com", "new_password");
// then
assertThat(result, equalTo(false));
verify(sendMailSpy).initializeMail("user@example.com");
verify(sendMailSpy, never()).sendEmail(anyString(), any(HtmlEmail.class));
}
@Test
public void shouldHandleMailSendingFailure() throws EmailException {
// given
given(settings.getPasswordEmailMessage()).willReturn("Hi <playername />, your new pass is <generatedpass />");
given(settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)).willReturn(false);
SendMailSSL sendMailSpy = spy(sendMailSSL);
HtmlEmail email = mock(HtmlEmail.class);
doReturn(email).when(sendMailSpy).initializeMail(anyString());
doReturn(false).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class));
// when
boolean result = sendMailSpy.sendPasswordMail("bobby", "user@example.com", "myPassw0rd");
// then
assertThat(result, equalTo(false));
verify(sendMailSpy).initializeMail("user@example.com");
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email));
assertThat(messageCaptor.getValue(), equalTo("Hi bobby, your new pass is myPassw0rd"));
}
@Test
public void shouldSendRecoveryCode() throws EmailException {
// given
given(settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)).willReturn(7);
given(settings.getRecoveryCodeEmailMessage())
.willReturn("Hi <playername />, your code on <servername /> is <recoverycode /> (valid <hoursvalid /> hours)");
SendMailSSL sendMailSpy = spy(sendMailSSL);
HtmlEmail email = mock(HtmlEmail.class);
doReturn(email).when(sendMailSpy).initializeMail(anyString());
doReturn(true).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class));
// when
boolean result = sendMailSpy.sendRecoveryCode("Timmy", "tim@example.com", "12C56A");
// then
assertThat(result, equalTo(true));
verify(sendMailSpy).initializeMail("tim@example.com");
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email));
assertThat(messageCaptor.getValue(), equalTo("Hi Timmy, your code on serverName is 12C56A (valid 7 hours)"));
}
@Test
public void shouldHandleMailCreationErrorForRecoveryCode() throws EmailException {
// given
SendMailSSL sendMailSpy = spy(sendMailSSL);
doThrow(EmailException.class).when(sendMailSpy).initializeMail(anyString());
// when
boolean result = sendMailSpy.sendRecoveryCode("Player", "player@example.org", "ABC1234");
// then
assertThat(result, equalTo(false));
verify(sendMailSpy).initializeMail("player@example.org");
verify(sendMailSpy, never()).sendEmail(anyString(), any(HtmlEmail.class));
}
@Test
public void shouldHandleFailureToSendRecoveryCode() throws EmailException {
// given
given(settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)).willReturn(7);
given(settings.getRecoveryCodeEmailMessage()).willReturn("Hi <playername />, your code is <recoverycode />");
SendMailSSL sendMailSpy = spy(sendMailSSL);
HtmlEmail email = mock(HtmlEmail.class);
doReturn(email).when(sendMailSpy).initializeMail(anyString());
doReturn(false).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class));
// when
boolean result = sendMailSpy.sendRecoveryCode("John", "user@example.com", "1DEF77");
// then
assertThat(result, equalTo(false));
verify(sendMailSpy).initializeMail("user@example.com");
ArgumentCaptor<String> messageCaptor = ArgumentCaptor.forClass(String.class);
verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email));
assertThat(messageCaptor.getValue(), equalTo("Hi John, your code is 1DEF77"));
}
@Test @Test
public void shouldCreateEmailObject() throws EmailException { public void shouldCreateEmailObject() throws EmailException {
// given // given
@ -270,5 +133,4 @@ public class SendMailSSLTest {
assertThat(mailProperties.getProperty("mail.smtp.auth.plain.disable"), equalTo("true")); assertThat(mailProperties.getProperty("mail.smtp.auth.plain.disable"), equalTo("true"));
assertThat(mailProperties.getProperty(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP), equalTo("oAuth2 token")); assertThat(mailProperties.getProperty(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP), equalTo("oAuth2 token"));
} }
} }

View File

@ -4,7 +4,7 @@ import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.TestHelper; import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.mail.EmailService;
import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.permission.PlayerStatePermission;
@ -49,7 +49,7 @@ public class EmailRegisterExecutorProviderTest {
@Mock @Mock
private CommonService commonService; private CommonService commonService;
@Mock @Mock
private SendMailSSL sendMailSsl; private EmailService emailService;
@Mock @Mock
private SyncProcessManager syncProcessManager; private SyncProcessManager syncProcessManager;
@Mock @Mock
@ -135,7 +135,7 @@ public class EmailRegisterExecutorProviderTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void shouldPerformActionAfterDataSourceSave() { public void shouldPerformActionAfterDataSourceSave() {
// given // given
given(sendMailSsl.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true); given(emailService.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true);
Player player = mock(Player.class); Player player = mock(Player.class);
given(player.getName()).willReturn("Laleh"); given(player.getName()).willReturn("Laleh");
RegistrationExecutor executor = emailRegisterExecutorProvider.new EmailRegisterExecutor(player, "test@example.com"); RegistrationExecutor executor = emailRegisterExecutorProvider.new EmailRegisterExecutor(player, "test@example.com");
@ -146,7 +146,7 @@ public class EmailRegisterExecutorProviderTest {
executor.executePostPersistAction(); executor.executePostPersistAction();
// then // then
verify(sendMailSsl).sendPasswordMail("Laleh", "test@example.com", password); verify(emailService).sendPasswordMail("Laleh", "test@example.com", password);
verify(syncProcessManager).processSyncEmailRegister(player); verify(syncProcessManager).processSyncEmailRegister(player);
} }
@ -154,7 +154,7 @@ public class EmailRegisterExecutorProviderTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void shouldHandleEmailSendingFailure() { public void shouldHandleEmailSendingFailure() {
// given // given
given(sendMailSsl.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(false); given(emailService.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(false);
Player player = mock(Player.class); Player player = mock(Player.class);
given(player.getName()).willReturn("Laleh"); given(player.getName()).willReturn("Laleh");
RegistrationExecutor executor = emailRegisterExecutorProvider.new EmailRegisterExecutor(player, "test@example.com"); RegistrationExecutor executor = emailRegisterExecutorProvider.new EmailRegisterExecutor(player, "test@example.com");
@ -165,7 +165,7 @@ public class EmailRegisterExecutorProviderTest {
executor.executePostPersistAction(); executor.executePostPersistAction();
// then // then
verify(sendMailSsl).sendPasswordMail("Laleh", "test@example.com", password); verify(emailService).sendPasswordMail("Laleh", "test@example.com", password);
verify(commonService).send(player, MessageKey.EMAIL_SEND_FAILURE); verify(commonService).send(player, MessageKey.EMAIL_SEND_FAILURE);
verifyZeroInteractions(syncProcessManager); verifyZeroInteractions(syncProcessManager);
} }