#567 Move email validation logic to validation service

This commit is contained in:
ljacqu 2016-04-03 20:44:13 +02:00
parent b6ccb3e632
commit 9ea75c502c
19 changed files with 402 additions and 253 deletions

View File

@ -261,7 +261,7 @@ public class AuthMe extends JavaPlugin {
// Set up the permissions manager and command handler // Set up the permissions manager and command handler
permsMan = initializePermissionsManager(); permsMan = initializePermissionsManager();
ValidationService validationService = new ValidationService(newSettings); ValidationService validationService = new ValidationService(newSettings, database, permsMan);
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings, ipAddressManager, commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings, ipAddressManager,
pluginHooks, spawnLoader, antiBot, validationService); pluginHooks, spawnLoader, antiBot, validationService);

View File

@ -222,4 +222,12 @@ public class CommandService {
return validationService.validatePassword(password, username); return validationService.validatePassword(password, username);
} }
public boolean validateEmail(String email) {
return validationService.validateEmail(email);
}
public boolean isEmailFreeForRegistration(String email, CommandSender sender) {
return validationService.isEmailFreeForRegistration(email, sender);
}
} }

View File

@ -6,12 +6,13 @@ import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.util.Utils;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.List; import java.util.List;
/**
* Admin command for setting an email to an account.
*/
public class SetEmailCommand implements ExecutableCommand { public class SetEmailCommand implements ExecutableCommand {
@Override @Override
@ -22,7 +23,7 @@ public class SetEmailCommand implements ExecutableCommand {
final String playerEmail = arguments.get(1); final String playerEmail = arguments.get(1);
// Validate the email address // Validate the email address
if (!Utils.isEmailCorrect(playerEmail, commandService.getSettings())) { if (!commandService.validateEmail(playerEmail)) {
commandService.send(sender, MessageKey.INVALID_EMAIL); commandService.send(sender, MessageKey.INVALID_EMAIL);
return; return;
} }
@ -36,8 +37,7 @@ public class SetEmailCommand implements ExecutableCommand {
if (auth == null) { if (auth == null) {
commandService.send(sender, MessageKey.UNKNOWN_USER); commandService.send(sender, MessageKey.UNKNOWN_USER);
return; return;
} else if (dataSource.countAuthsByEmail(playerEmail) } else if (!commandService.isEmailFreeForRegistration(playerEmail, sender)) {
>= commandService.getProperty(EmailSettings.MAX_REG_PER_EMAIL)) {
commandService.send(sender, MessageKey.EMAIL_ALREADY_USED_ERROR); commandService.send(sender, MessageKey.EMAIL_ALREADY_USED_ERROR);
return; return;
} }

View File

@ -3,11 +3,13 @@ package fr.xephi.authme.command.executable.email;
import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.util.Utils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
/**
* Command for setting an email to an account.
*/
public class AddEmailCommand extends PlayerCommand { public class AddEmailCommand extends PlayerCommand {
@Override @Override
@ -15,9 +17,8 @@ public class AddEmailCommand extends PlayerCommand {
String email = arguments.get(0); String email = arguments.get(0);
String emailConfirmation = arguments.get(1); String emailConfirmation = arguments.get(1);
if (!Utils.isEmailCorrect(email, commandService.getSettings())) { if (email.equals(emailConfirmation)) {
commandService.send(player, MessageKey.INVALID_EMAIL); // Closer inspection of the mail address handled by the async task
} else if (email.equals(emailConfirmation)) {
commandService.getManagement().performAddEmail(player, email); commandService.getManagement().performAddEmail(player, email);
} else { } else {
commandService.send(player, MessageKey.CONFIRM_EMAIL_MESSAGE); commandService.send(player, MessageKey.CONFIRM_EMAIL_MESSAGE);

View File

@ -7,13 +7,16 @@ import fr.xephi.authme.process.Management;
import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.RandomString; import fr.xephi.authme.security.RandomString;
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.RegistrationSettings;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.Utils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.List; import java.util.List;
import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWORD_LENGTH;
import static fr.xephi.authme.settings.properties.RestrictionSettings.ENABLE_PASSWORD_CONFIRMATION;
public class RegisterCommand extends PlayerCommand { public class RegisterCommand extends PlayerCommand {
@Override @Override
@ -24,25 +27,27 @@ public class RegisterCommand extends PlayerCommand {
return; return;
} }
if (arguments.isEmpty() || Settings.enablePasswordConfirmation && arguments.size() < 2) { if (arguments.isEmpty() || commandService.getProperty(ENABLE_PASSWORD_CONFIRMATION) && arguments.size() < 2) {
commandService.send(player, MessageKey.USAGE_REGISTER); commandService.send(player, MessageKey.USAGE_REGISTER);
return; return;
} }
final Management management = commandService.getManagement(); final Management management = commandService.getManagement();
if (Settings.emailRegistration && !Settings.getmailAccount.isEmpty()) { if (commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)
if (Settings.doubleEmailCheck && arguments.size() < 2 || !arguments.get(0).equals(arguments.get(1))) { && !commandService.getProperty(EmailSettings.MAIL_ACCOUNT).isEmpty()) {
boolean emailDoubleCheck = commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL);
if (emailDoubleCheck && arguments.size() < 2 || !arguments.get(0).equals(arguments.get(1))) {
commandService.send(player, MessageKey.USAGE_REGISTER); commandService.send(player, MessageKey.USAGE_REGISTER);
return; return;
} }
final String email = arguments.get(0); final String email = arguments.get(0);
if (!Utils.isEmailCorrect(email, commandService.getSettings())) { if (!commandService.validateEmail(email)) {
commandService.send(player, MessageKey.INVALID_EMAIL); commandService.send(player, MessageKey.INVALID_EMAIL);
return; return;
} }
final String thePass = RandomString.generate(Settings.getRecoveryPassLength); final String thePass = RandomString.generate(commandService.getProperty(RECOVERY_PASSWORD_LENGTH));
management.performRegister(player, thePass, email); management.performRegister(player, thePass, email);
return; return;
} }

View File

@ -213,4 +213,12 @@ public class ProcessService {
return validationService.validatePassword(password, username); return validationService.validatePassword(password, username);
} }
public boolean validateEmail(String email) {
return validationService.validateEmail(email);
}
public boolean isEmailFreeForRegistration(String email, CommandSender sender) {
return validationService.isEmailFreeForRegistration(email, sender);
}
} }

View File

@ -7,9 +7,7 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.process.Process; import fr.xephi.authme.process.Process;
import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.util.Utils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**
@ -42,9 +40,9 @@ public class AsyncAddEmail implements Process {
if (currentEmail != null && !"your@email.com".equals(currentEmail)) { if (currentEmail != null && !"your@email.com".equals(currentEmail)) {
service.send(player, MessageKey.USAGE_CHANGE_EMAIL); service.send(player, MessageKey.USAGE_CHANGE_EMAIL);
} else if (!Utils.isEmailCorrect(email, service.getSettings())) { } else if (!service.validateEmail(email)) {
service.send(player, MessageKey.INVALID_EMAIL); service.send(player, MessageKey.INVALID_EMAIL);
} else if (dataSource.countAuthsByEmail(email) >= service.getProperty(EmailSettings.MAX_REG_PER_EMAIL)) { } else if (!service.isEmailFreeForRegistration(email, player)) {
service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR); service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
} else { } else {
auth.setEmail(email); auth.setEmail(email);

View File

@ -6,9 +6,7 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.process.Process; import fr.xephi.authme.process.Process;
import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.util.Utils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**
@ -42,11 +40,11 @@ public class AsyncChangeEmail implements Process {
if (currentEmail == null) { if (currentEmail == null) {
service.send(player, MessageKey.USAGE_ADD_EMAIL); service.send(player, MessageKey.USAGE_ADD_EMAIL);
} else if (newEmail == null || !Utils.isEmailCorrect(newEmail, service.getSettings())) { } else if (newEmail == null || !service.validateEmail(newEmail)) {
service.send(player, MessageKey.INVALID_NEW_EMAIL); service.send(player, MessageKey.INVALID_NEW_EMAIL);
} else if (!oldEmail.equals(currentEmail)) { } else if (!oldEmail.equals(currentEmail)) {
service.send(player, MessageKey.INVALID_OLD_EMAIL); service.send(player, MessageKey.INVALID_OLD_EMAIL);
} else if (dataSource.countAuthsByEmail(newEmail) >= service.getProperty(EmailSettings.MAX_REG_PER_EMAIL)) { } else if (!service.isEmailFreeForRegistration(newEmail, player)) {
service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR); service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
} else { } else {
saveNewEmail(auth); saveNewEmail(auth);

View File

@ -39,7 +39,6 @@ public final class Settings {
public static List<String> forceRegisterCommandsAsConsole; public static List<String> forceRegisterCommandsAsConsole;
public static HashAlgorithm getPasswordHash; public static HashAlgorithm getPasswordHash;
public static Pattern nickPattern; public static Pattern nickPattern;
public static boolean useLogging = false;
public static boolean isChatAllowed, isPermissionCheckEnabled, public static boolean isChatAllowed, isPermissionCheckEnabled,
isForcedRegistrationEnabled, isTeleportToSpawnEnabled, isForcedRegistrationEnabled, isTeleportToSpawnEnabled,
isSessionsEnabled, isAllowRestrictedIp, isSessionsEnabled, isAllowRestrictedIp,
@ -50,8 +49,7 @@ public final class Settings {
protectInventoryBeforeLogInEnabled, isStopEnabled, reloadSupport, protectInventoryBeforeLogInEnabled, isStopEnabled, reloadSupport,
rakamakUseIp, noConsoleSpam, removePassword, displayOtherAccounts, rakamakUseIp, noConsoleSpam, removePassword, displayOtherAccounts,
emailRegistration, multiverse, bungee, emailRegistration, multiverse, bungee,
banUnsafeIp, doubleEmailCheck, sessionExpireOnIpChange, banUnsafeIp, sessionExpireOnIpChange, useEssentialsMotd,
disableSocialSpy, useEssentialsMotd,
enableProtection, recallEmail, useWelcomeMessage, enableProtection, recallEmail, useWelcomeMessage,
broadcastWelcomeMessage, forceRegKick, forceRegLogin, broadcastWelcomeMessage, forceRegKick, forceRegLogin,
checkVeryGames, removeJoinMessage, removeLeaveMessage, delayJoinMessage, checkVeryGames, removeJoinMessage, removeLeaveMessage, delayJoinMessage,
@ -59,15 +57,13 @@ public final class Settings {
kickPlayersBeforeStopping, allowAllCommandsIfRegIsOptional, kickPlayersBeforeStopping, allowAllCommandsIfRegIsOptional,
customAttributes, isRemoveSpeedEnabled, preventOtherCase, keepCollisionsDisabled; customAttributes, isRemoveSpeedEnabled, preventOtherCase, keepCollisionsDisabled;
public static String getNickRegex, getUnloggedinGroup, public static String getNickRegex, getUnloggedinGroup,
unRegisteredGroup, unRegisteredGroup, backupWindowsPath, getRegisteredGroup,
backupWindowsPath, getRegisteredGroup,
rakamakUsers, rakamakUsersIp, getmailAccount, defaultWorld, rakamakUsers, rakamakUsersIp, getmailAccount, defaultWorld,
spawnPriority, crazyloginFileName, sendPlayerTo; spawnPriority, crazyloginFileName, sendPlayerTo;
public static int getWarnMessageInterval, getSessionTimeout, public static int getWarnMessageInterval, getSessionTimeout,
getRegistrationTimeout, getMaxNickLength, getMinNickLength, getRegistrationTimeout, getMaxNickLength, getMinNickLength,
getPasswordMinLen, getMovementRadius, getPasswordMinLen, getMovementRadius, getNonActivatedGroup, passwordMaxLength,
getNonActivatedGroup, passwordMaxLength, getRecoveryPassLength, maxLoginTry, captchaLength, saltLength,
getMailPort, maxLoginTry, captchaLength, saltLength,
bCryptLog2Rounds, getMaxLoginPerIp, getMaxJoinPerIp; bCryptLog2Rounds, getMaxLoginPerIp, getMaxJoinPerIp;
protected static FileConfiguration configFile; protected static FileConfiguration configFile;
@ -145,8 +141,6 @@ public final class Settings {
noConsoleSpam = load(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE); noConsoleSpam = load(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE);
removePassword = configFile.getBoolean("Security.console.removePassword", true); removePassword = configFile.getBoolean("Security.console.removePassword", true);
getmailAccount = load(EmailSettings.MAIL_ACCOUNT); getmailAccount = load(EmailSettings.MAIL_ACCOUNT);
getMailPort = configFile.getInt("Email.mailPort", 465);
getRecoveryPassLength = configFile.getInt("Email.RecoveryPasswordLength", 8);
displayOtherAccounts = configFile.getBoolean("settings.restrictions.displayOtherAccounts", true); displayOtherAccounts = configFile.getBoolean("settings.restrictions.displayOtherAccounts", true);
maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5); maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5);
captchaLength = configFile.getInt("Security.captcha.captchaLength", 5); captchaLength = configFile.getInt("Security.captcha.captchaLength", 5);
@ -156,10 +150,7 @@ public final class Settings {
bungee = configFile.getBoolean("Hooks.bungeecord", false); bungee = configFile.getBoolean("Hooks.bungeecord", false);
getForcedWorlds = configFile.getStringList("settings.restrictions.ForceSpawnOnTheseWorlds"); getForcedWorlds = configFile.getStringList("settings.restrictions.ForceSpawnOnTheseWorlds");
banUnsafeIp = configFile.getBoolean("settings.restrictions.banUnsafedIP", false); banUnsafeIp = configFile.getBoolean("settings.restrictions.banUnsafedIP", false);
doubleEmailCheck = configFile.getBoolean("settings.registration.doubleEmailCheck", false);
sessionExpireOnIpChange = configFile.getBoolean("settings.sessions.sessionExpireOnIpChange", true); sessionExpireOnIpChange = configFile.getBoolean("settings.sessions.sessionExpireOnIpChange", true);
useLogging = configFile.getBoolean("Security.console.logConsole", false);
disableSocialSpy = configFile.getBoolean("Hooks.disableSocialSpy", true);
bCryptLog2Rounds = configFile.getInt("ExternalBoardOptions.bCryptLog2Round", 10); bCryptLog2Rounds = configFile.getInt("ExternalBoardOptions.bCryptLog2Round", 10);
useEssentialsMotd = configFile.getBoolean("Hooks.useEssentialsMotd", false); useEssentialsMotd = configFile.getBoolean("Hooks.useEssentialsMotd", false);
defaultWorld = configFile.getString("Purge.defaultWorld", "world"); defaultWorld = configFile.getString("Purge.defaultWorld", "world");

View File

@ -7,9 +7,7 @@ import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.events.AuthMeTeleportEvent; import fr.xephi.authme.events.AuthMeTeleportEvent;
import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -21,7 +19,6 @@ import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List;
/** /**
* Utility class for various operations used in the codebase. * Utility class for various operations used in the codebase.
@ -254,38 +251,12 @@ public final class Utils {
} }
} }
public static boolean isEmailCorrect(String email, NewSetting settings) {
if (!email.contains("@") || "your@email.com".equalsIgnoreCase(email)) {
return false;
}
final String emailDomain = email.split("@")[1];
List<String> whitelist = settings.getProperty(EmailSettings.DOMAIN_WHITELIST);
if (!CollectionUtils.isEmpty(whitelist)) {
return containsIgnoreCase(whitelist, emailDomain);
}
List<String> blacklist = settings.getProperty(EmailSettings.DOMAIN_BLACKLIST);
return CollectionUtils.isEmpty(blacklist) || !containsIgnoreCase(blacklist, emailDomain);
}
private static boolean containsIgnoreCase(Collection<String> coll, String needle) {
for (String entry : coll) {
if (entry.equalsIgnoreCase(needle)) {
return true;
}
}
return false;
}
public static String getUUIDorName(OfflinePlayer player) { public static String getUUIDorName(OfflinePlayer player) {
String uuidOrName;
try { try {
uuidOrName = player.getUniqueId().toString(); return player.getUniqueId().toString();
} catch (Exception ignore) { } catch (Exception ignore) {
uuidOrName = player.getName(); return player.getName();
} }
return uuidOrName;
} }
public enum GroupType { public enum GroupType {

View File

@ -1,9 +1,17 @@
package fr.xephi.authme.util; package fr.xephi.authme.util;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.command.CommandSender;
import java.util.Collection;
import java.util.List;
/** /**
* Validation service. * Validation service.
@ -11,9 +19,13 @@ import fr.xephi.authme.settings.properties.SecuritySettings;
public class ValidationService { public class ValidationService {
private final NewSetting settings; private final NewSetting settings;
private final DataSource dataSource;
private final PermissionsManager permissionsManager;
public ValidationService(NewSetting settings) { public ValidationService(NewSetting settings, DataSource dataSource, PermissionsManager permissionsManager) {
this.settings = settings; this.settings = settings;
this.dataSource = dataSource;
this.permissionsManager = permissionsManager;
} }
/** /**
@ -39,4 +51,33 @@ public class ValidationService {
} }
return null; return null;
} }
public boolean validateEmail(String email) {
if (!email.contains("@") || "your@email.com".equalsIgnoreCase(email)) {
return false;
}
final String emailDomain = email.split("@")[1];
List<String> whitelist = settings.getProperty(EmailSettings.DOMAIN_WHITELIST);
if (!CollectionUtils.isEmpty(whitelist)) {
return containsIgnoreCase(whitelist, emailDomain);
}
List<String> blacklist = settings.getProperty(EmailSettings.DOMAIN_BLACKLIST);
return CollectionUtils.isEmpty(blacklist) || !containsIgnoreCase(blacklist, emailDomain);
}
public boolean isEmailFreeForRegistration(String email, CommandSender sender) {
return permissionsManager.hasPermission(sender, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|| dataSource.countAuthsByEmail(email) < settings.getProperty(EmailSettings.MAX_REG_PER_EMAIL);
}
private static boolean containsIgnoreCase(Collection<String> coll, String needle) {
for (String entry : coll) {
if (entry.equalsIgnoreCase(needle)) {
return true;
}
}
return false;
}
} }

View File

@ -246,4 +246,35 @@ public class CommandServiceTest {
assertThat(result, equalTo(MessageKey.INVALID_PASSWORD_LENGTH)); assertThat(result, equalTo(MessageKey.INVALID_PASSWORD_LENGTH));
verify(validationService).validatePassword(password, user); verify(validationService).validatePassword(password, user);
} }
@Test
public void shouldValidateEmail() {
// given
String email = "test@example.tld";
given(validationService.validateEmail(email)).willReturn(true);
// when
boolean result = commandService.validateEmail(email);
// then
assertThat(result, equalTo(true));
verify(validationService).validateEmail(email);
}
@Test
public void shouldCheckIfEmailCanBeUsed() {
// given
String email = "mail@example.com";
CommandSender sender = mock(CommandSender.class);
given(validationService.isEmailFreeForRegistration(email, sender))
.willReturn(true);
// when
boolean result = commandService.isEmailFreeForRegistration(email, sender);
// then
assertThat(result, equalTo(true));
verify(validationService).isEmailFreeForRegistration(email, sender);
}
} }

View File

@ -1,14 +1,15 @@
package fr.xephi.authme.command.executable.email; package fr.xephi.authme.command.executable.email;
import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.NewSetting;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -21,19 +22,16 @@ import static org.mockito.Mockito.verify;
/** /**
* Test for {@link AddEmailCommand}. * Test for {@link AddEmailCommand}.
*/ */
@RunWith(MockitoJUnitRunner.class)
public class AddEmailCommandTest { public class AddEmailCommandTest {
@Mock
private CommandService commandService; private CommandService commandService;
@Before
public void setUpMocks() {
commandService = mock(CommandService.class);
}
@Test @Test
public void shouldRejectNonPlayerSender() { public void shouldRejectNonPlayerSender() {
// given // given
CommandSender sender = Mockito.mock(BlockCommandSender.class); CommandSender sender = mock(BlockCommandSender.class);
AddEmailCommand command = new AddEmailCommand(); AddEmailCommand command = new AddEmailCommand();
// when // when
@ -46,18 +44,34 @@ public class AddEmailCommandTest {
@Test @Test
public void shouldForwardData() { public void shouldForwardData() {
// given // given
Player sender = Mockito.mock(Player.class); Player sender = mock(Player.class);
AddEmailCommand command = new AddEmailCommand(); String email = "mail@example";
given(commandService.validateEmail(email)).willReturn(true);
Management management = mock(Management.class); Management management = mock(Management.class);
given(commandService.getManagement()).willReturn(management); given(commandService.getManagement()).willReturn(management);
NewSetting settings = mock(NewSetting.class); AddEmailCommand command = new AddEmailCommand();
given(commandService.getSettings()).willReturn(settings);
// when // when
command.executeCommand(sender, Arrays.asList("mail@example", "mail@example"), commandService); command.executeCommand(sender, Arrays.asList(email, email), commandService);
// then // then
verify(management).performAddEmail(sender, "mail@example"); verify(management).performAddEmail(sender, email);
}
@Test
public void shouldFailForConfirmationMismatch() {
// given
Player sender = mock(Player.class);
String email = "asdfasdf@example.com";
given(commandService.validateEmail(email)).willReturn(true);
AddEmailCommand command = new AddEmailCommand();
// when
command.executeCommand(sender, Arrays.asList(email, "wrongConf"), commandService);
// then
verify(commandService, never()).getManagement();
verify(commandService).send(sender, MessageKey.CONFIRM_EMAIL_MESSAGE);
} }
} }

View File

@ -3,7 +3,7 @@ package fr.xephi.authme.command.executable.register;
import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.process.Management; import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.util.WrapperMock; import fr.xephi.authme.util.WrapperMock;
import org.bukkit.command.BlockCommandSender; import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -14,6 +14,7 @@ import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import static fr.xephi.authme.settings.properties.RestrictionSettings.ENABLE_PASSWORD_CONFIRMATION;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.argThat;
@ -31,7 +32,6 @@ public class RegisterCommandTest {
@Before @Before
public void initializeAuthMeMock() { public void initializeAuthMeMock() {
WrapperMock.createInstance(); WrapperMock.createInstance();
Settings.captchaLength = 10;
commandService = mock(CommandService.class); commandService = mock(CommandService.class);
} }
@ -70,6 +70,8 @@ public class RegisterCommandTest {
RegisterCommand command = new RegisterCommand(); RegisterCommand command = new RegisterCommand();
Management management = mock(Management.class); Management management = mock(Management.class);
given(commandService.getManagement()).willReturn(management); given(commandService.getManagement()).willReturn(management);
given(commandService.getProperty(ENABLE_PASSWORD_CONFIRMATION)).willReturn(false);
given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(false);
// when // when
command.executeCommand(sender, Collections.singletonList("password"), commandService); command.executeCommand(sender, Collections.singletonList("password"), commandService);

View File

@ -15,9 +15,9 @@ import fr.xephi.authme.util.ValidationService;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.HashMap; import org.mockito.Mock;
import java.util.Map; import org.mockito.runners.MockitoJUnitRunner;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -28,23 +28,38 @@ import static org.mockito.Mockito.verify;
/** /**
* Test for {@link ProcessService}. * Test for {@link ProcessService}.
*/ */
@RunWith(MockitoJUnitRunner.class)
public class ProcessServiceTest { public class ProcessServiceTest {
private ProcessService processService; private ProcessService processService;
private Map<Class<?>, Object> mocks; @Mock
private ValidationService validationService;
@Mock
private NewSetting settings;
@Mock
private Messages messages;
@Mock
private IpAddressManager ipAddressManager;
@Mock
private PasswordSecurity passwordSecurity;
@Mock
private AuthMe authMe;
@Mock
private DataSource dataSource;
@Mock
private SpawnLoader spawnLoader;
@Mock
private PluginHooks pluginHooks;
@Before @Before
public void setUpService() { public void setUpService() {
mocks = new HashMap<>(); processService = new ProcessService(settings, messages, authMe, dataSource, ipAddressManager, passwordSecurity,
processService = new ProcessService(newMock(NewSetting.class), newMock(Messages.class), newMock(AuthMe.class), pluginHooks, spawnLoader, validationService);
newMock(DataSource.class), newMock(IpAddressManager.class), newMock(PasswordSecurity.class),
newMock(PluginHooks.class), newMock(SpawnLoader.class), newMock(ValidationService.class));
} }
@Test @Test
public void shouldGetProperty() { public void shouldGetProperty() {
// given // given
NewSetting settings = getMock(NewSetting.class);
given(settings.getProperty(SecuritySettings.CAPTCHA_LENGTH)).willReturn(8); given(settings.getProperty(SecuritySettings.CAPTCHA_LENGTH)).willReturn(8);
// when // when
@ -58,16 +73,15 @@ public class ProcessServiceTest {
@Test @Test
public void shouldReturnSettings() { public void shouldReturnSettings() {
// given/when // given/when
NewSetting settings = processService.getSettings(); NewSetting result = processService.getSettings();
// then // then
assertThat(settings, equalTo(getMock(NewSetting.class))); assertThat(result, equalTo(settings));
} }
@Test @Test
public void shouldSendMessageToPlayer() { public void shouldSendMessageToPlayer() {
// given // given
Messages messages = getMock(Messages.class);
CommandSender sender = mock(CommandSender.class); CommandSender sender = mock(CommandSender.class);
MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED; MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED;
@ -81,7 +95,6 @@ public class ProcessServiceTest {
@Test @Test
public void shouldSendMessageWithReplacements() { public void shouldSendMessageWithReplacements() {
// given // given
Messages messages = getMock(Messages.class);
CommandSender sender = mock(CommandSender.class); CommandSender sender = mock(CommandSender.class);
MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED; MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED;
String[] replacements = new String[]{"test", "toast"}; String[] replacements = new String[]{"test", "toast"};
@ -96,7 +109,6 @@ public class ProcessServiceTest {
@Test @Test
public void shouldRetrieveMessage() { public void shouldRetrieveMessage() {
// given // given
Messages messages = getMock(Messages.class);
MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED; MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED;
String[] lines = new String[]{"First message line", "second line"}; String[] lines = new String[]{"First message line", "second line"};
given(messages.retrieve(key)).willReturn(lines); given(messages.retrieve(key)).willReturn(lines);
@ -112,7 +124,6 @@ public class ProcessServiceTest {
@Test @Test
public void shouldRetrieveSingleMessage() { public void shouldRetrieveSingleMessage() {
// given // given
Messages messages = getMock(Messages.class);
MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED; MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED;
String text = "Test text"; String text = "Test text";
given(messages.retrieveSingle(key)).willReturn(text); given(messages.retrieveSingle(key)).willReturn(text);
@ -128,52 +139,51 @@ public class ProcessServiceTest {
@Test @Test
public void shouldReturnAuthMeInstance() { public void shouldReturnAuthMeInstance() {
// given / when // given / when
AuthMe authMe = processService.getAuthMe(); AuthMe result = processService.getAuthMe();
// then // then
assertThat(authMe, equalTo(getMock(AuthMe.class))); assertThat(result, equalTo(authMe));
} }
@Test @Test
public void shouldReturnPluginHooks() { public void shouldReturnPluginHooks() {
// given / when // given / when
PluginHooks pluginHooks = processService.getPluginHooks(); PluginHooks result = processService.getPluginHooks();
// then // then
assertThat(pluginHooks, equalTo(getMock(PluginHooks.class))); assertThat(result, equalTo(pluginHooks));
} }
@Test @Test
public void shouldReturnIpAddressManager() { public void shouldReturnIpAddressManager() {
// given / when // given / when
IpAddressManager ipAddressManager = processService.getIpAddressManager(); IpAddressManager result = processService.getIpAddressManager();
// then // then
assertThat(ipAddressManager, equalTo(getMock(IpAddressManager.class))); assertThat(result, equalTo(ipAddressManager));
} }
@Test @Test
public void shouldReturnSpawnLoader() { public void shouldReturnSpawnLoader() {
// given / when // given / when
SpawnLoader spawnLoader = processService.getSpawnLoader(); SpawnLoader result = processService.getSpawnLoader();
// then // then
assertThat(spawnLoader, equalTo(getMock(SpawnLoader.class))); assertThat(result, equalTo(spawnLoader));
} }
@Test @Test
public void shouldReturnDatasource() { public void shouldReturnDatasource() {
// given / when // given / when
DataSource dataSource = processService.getDataSource(); DataSource result = processService.getDataSource();
// then // then
assertThat(dataSource, equalTo(getMock(DataSource.class))); assertThat(result, equalTo(dataSource));
} }
@Test @Test
public void shouldComputeHash() { public void shouldComputeHash() {
// given // given
PasswordSecurity passwordSecurity = getMock(PasswordSecurity.class);
String password = "test123"; String password = "test123";
String username = "Username"; String username = "Username";
HashedPassword hashedPassword = new HashedPassword("hashedResult", "salt12342"); HashedPassword hashedPassword = new HashedPassword("hashedResult", "salt12342");
@ -192,7 +202,6 @@ public class ProcessServiceTest {
// given // given
String user = "test-user"; String user = "test-user";
String password = "passw0rd"; String password = "passw0rd";
ValidationService validationService = getMock(ValidationService.class);
given(validationService.validatePassword(password, user)).willReturn(MessageKey.PASSWORD_MATCH_ERROR); given(validationService.validatePassword(password, user)).willReturn(MessageKey.PASSWORD_MATCH_ERROR);
// when // when
@ -203,17 +212,33 @@ public class ProcessServiceTest {
verify(validationService).validatePassword(password, user); verify(validationService).validatePassword(password, user);
} }
private <T> T newMock(Class<T> clazz) { @Test
T mock = mock(clazz); public void shouldValidateEmail() {
mocks.put(clazz, mock); // given
return mock; String email = "test@example.tld";
given(validationService.validateEmail(email)).willReturn(true);
// when
boolean result = processService.validateEmail(email);
// then
assertThat(result, equalTo(true));
verify(validationService).validateEmail(email);
} }
private <T> T getMock(Class<T> clazz) { @Test
Object mock = mocks.get(clazz); public void shouldCheckIfEmailCanBeUsed() {
if (mock == null) { // given
throw new IllegalArgumentException("No mock of type " + clazz); String email = "mail@example.com";
} CommandSender sender = mock(CommandSender.class);
return clazz.cast(mock); given(validationService.isEmailFreeForRegistration(email, sender))
.willReturn(true);
// when
boolean result = processService.isEmailFreeForRegistration(email, sender);
// then
assertThat(result, equalTo(true));
verify(validationService).isEmailFreeForRegistration(email, sender);
} }
} }

View File

@ -6,8 +6,6 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.junit.BeforeClass; import org.junit.BeforeClass;
@ -21,7 +19,6 @@ import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/** /**
* Test for {@link AsyncAddEmail}. * Test for {@link AsyncAddEmail}.
@ -46,14 +43,16 @@ public class AsyncAddEmailTest {
@Test @Test
public void shouldAddEmail() { public void shouldAddEmail() {
// given // given
AsyncAddEmail process = createProcess("my.mail@example.org"); String email = "my.mail@example.org";
AsyncAddEmail process = createProcess(email);
given(player.getName()).willReturn("testEr"); given(player.getName()).willReturn("testEr");
given(playerCache.isAuthenticated("tester")).willReturn(true); given(playerCache.isAuthenticated("tester")).willReturn(true);
PlayerAuth auth = mock(PlayerAuth.class); PlayerAuth auth = mock(PlayerAuth.class);
given(auth.getEmail()).willReturn(null); given(auth.getEmail()).willReturn(null);
given(playerCache.getAuth("tester")).willReturn(auth); given(playerCache.getAuth("tester")).willReturn(auth);
given(dataSource.countAuthsByEmail("my.mail@example.org")).willReturn(1);
given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(true); given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(true);
given(service.validateEmail(email)).willReturn(true);
given(service.isEmailFreeForRegistration(email, player)).willReturn(true);
// when // when
process.run(); process.run();
@ -61,21 +60,24 @@ public class AsyncAddEmailTest {
// then // then
verify(dataSource).updateEmail(auth); verify(dataSource).updateEmail(auth);
verify(service).send(player, MessageKey.EMAIL_ADDED_SUCCESS); verify(service).send(player, MessageKey.EMAIL_ADDED_SUCCESS);
verify(auth).setEmail("my.mail@example.org"); verify(auth).setEmail(email);
verify(playerCache).updatePlayer(auth); verify(playerCache).updatePlayer(auth);
} }
@Test @Test
public void shouldReturnErrorWhenMailCannotBeSaved() { public void shouldReturnErrorWhenMailCannotBeSaved() {
// given // given
AsyncAddEmail process = createProcess("my.mail@example.org"); String email = "my.mail@example.org";
AsyncAddEmail process = createProcess(email);
given(player.getName()).willReturn("testEr"); given(player.getName()).willReturn("testEr");
given(playerCache.isAuthenticated("tester")).willReturn(true); given(playerCache.isAuthenticated("tester")).willReturn(true);
PlayerAuth auth = mock(PlayerAuth.class); PlayerAuth auth = mock(PlayerAuth.class);
given(auth.getEmail()).willReturn(null); given(auth.getEmail()).willReturn(null);
given(playerCache.getAuth("tester")).willReturn(auth); given(playerCache.getAuth("tester")).willReturn(auth);
given(dataSource.countAuthsByEmail("my.mail@example.org")).willReturn(0); given(dataSource.countAuthsByEmail(email)).willReturn(0);
given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(false); given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(false);
given(service.validateEmail(email)).willReturn(true);
given(service.isEmailFreeForRegistration(email, player)).willReturn(true);
// when // when
process.run(); process.run();
@ -94,7 +96,6 @@ public class AsyncAddEmailTest {
PlayerAuth auth = mock(PlayerAuth.class); PlayerAuth auth = mock(PlayerAuth.class);
given(auth.getEmail()).willReturn("another@mail.tld"); given(auth.getEmail()).willReturn("another@mail.tld");
given(playerCache.getAuth("my_player")).willReturn(auth); given(playerCache.getAuth("my_player")).willReturn(auth);
given(dataSource.countAuthsByEmail("some.mail@example.org")).willReturn(0);
// when // when
process.run(); process.run();
@ -107,13 +108,14 @@ public class AsyncAddEmailTest {
@Test @Test
public void shouldNotAddMailIfItIsInvalid() { public void shouldNotAddMailIfItIsInvalid() {
// given // given
AsyncAddEmail process = createProcess("invalid_mail"); String email = "invalid_mail";
AsyncAddEmail process = createProcess(email);
given(player.getName()).willReturn("my_Player"); given(player.getName()).willReturn("my_Player");
given(playerCache.isAuthenticated("my_player")).willReturn(true); given(playerCache.isAuthenticated("my_player")).willReturn(true);
PlayerAuth auth = mock(PlayerAuth.class); PlayerAuth auth = mock(PlayerAuth.class);
given(auth.getEmail()).willReturn(null); given(auth.getEmail()).willReturn(null);
given(playerCache.getAuth("my_player")).willReturn(auth); given(playerCache.getAuth("my_player")).willReturn(auth);
given(dataSource.countAuthsByEmail("invalid_mail")).willReturn(0); given(service.validateEmail(email)).willReturn(false);
// when // when
process.run(); process.run();
@ -126,13 +128,15 @@ public class AsyncAddEmailTest {
@Test @Test
public void shouldNotAddMailIfAlreadyUsed() { public void shouldNotAddMailIfAlreadyUsed() {
// given // given
AsyncAddEmail process = createProcess("player@mail.tld"); String email = "player@mail.tld";
AsyncAddEmail process = createProcess(email);
given(player.getName()).willReturn("TestName"); given(player.getName()).willReturn("TestName");
given(playerCache.isAuthenticated("testname")).willReturn(true); given(playerCache.isAuthenticated("testname")).willReturn(true);
PlayerAuth auth = mock(PlayerAuth.class); PlayerAuth auth = mock(PlayerAuth.class);
given(auth.getEmail()).willReturn(null); given(auth.getEmail()).willReturn(null);
given(playerCache.getAuth("testname")).willReturn(auth); given(playerCache.getAuth("testname")).willReturn(auth);
given(dataSource.countAuthsByEmail("player@mail.tld")).willReturn(2); given(service.validateEmail(email)).willReturn(true);
given(service.isEmailFreeForRegistration(email, player)).willReturn(false);
// when // when
process.run(); process.run();
@ -193,15 +197,12 @@ public class AsyncAddEmailTest {
} }
/** /**
* Create an instance of {@link AsyncAddEmail} and save the mocks to this class' fields. * Create an instance of {@link AsyncAddEmail} with the class' mocks.
* *
* @param email The email to use * @param email The email to use
* @return The created process * @return The created process
*/ */
private AsyncAddEmail createProcess(String email) { private AsyncAddEmail createProcess(String email) {
NewSetting settings = mock(NewSetting.class);
when(service.getProperty(EmailSettings.MAX_REG_PER_EMAIL)).thenReturn(2);
when(service.getSettings()).thenReturn(settings);
return new AsyncAddEmail(player, email, dataSource, playerCache, service); return new AsyncAddEmail(player, email, dataSource, playerCache, service);
} }

View File

@ -5,7 +5,6 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RegistrationSettings;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -35,18 +34,19 @@ public class AsyncChangeEmailTest {
private DataSource dataSource; private DataSource dataSource;
@Mock @Mock
private ProcessService service; private ProcessService service;
@Mock
private NewSetting settings;
@Test @Test
public void shouldAddEmail() { public void shouldAddEmail() {
// given // given
AsyncChangeEmail process = createProcess("old@mail.tld", "new@mail.tld"); String newEmail = "new@mail.tld";
AsyncChangeEmail process = createProcess("old@mail.tld", newEmail);
given(player.getName()).willReturn("Bobby"); given(player.getName()).willReturn("Bobby");
given(playerCache.isAuthenticated("bobby")).willReturn(true); given(playerCache.isAuthenticated("bobby")).willReturn(true);
PlayerAuth auth = authWithMail("old@mail.tld"); PlayerAuth auth = authWithMail("old@mail.tld");
given(playerCache.getAuth("bobby")).willReturn(auth); given(playerCache.getAuth("bobby")).willReturn(auth);
given(dataSource.updateEmail(auth)).willReturn(true); given(dataSource.updateEmail(auth)).willReturn(true);
given(service.validateEmail(newEmail)).willReturn(true);
given(service.isEmailFreeForRegistration(newEmail, player)).willReturn(true);
// when // when
process.run(); process.run();
@ -60,12 +60,15 @@ public class AsyncChangeEmailTest {
@Test @Test
public void shouldShowErrorIfSaveFails() { public void shouldShowErrorIfSaveFails() {
// given // given
AsyncChangeEmail process = createProcess("old@mail.tld", "new@mail.tld"); String newEmail = "new@mail.tld";
AsyncChangeEmail process = createProcess("old@mail.tld", newEmail);
given(player.getName()).willReturn("Bobby"); given(player.getName()).willReturn("Bobby");
given(playerCache.isAuthenticated("bobby")).willReturn(true); given(playerCache.isAuthenticated("bobby")).willReturn(true);
PlayerAuth auth = authWithMail("old@mail.tld"); PlayerAuth auth = authWithMail("old@mail.tld");
given(playerCache.getAuth("bobby")).willReturn(auth); given(playerCache.getAuth("bobby")).willReturn(auth);
given(dataSource.updateEmail(auth)).willReturn(false); given(dataSource.updateEmail(auth)).willReturn(false);
given(service.validateEmail(newEmail)).willReturn(true);
given(service.isEmailFreeForRegistration(newEmail, player)).willReturn(true);
// when // when
process.run(); process.run();
@ -97,11 +100,13 @@ public class AsyncChangeEmailTest {
@Test @Test
public void shouldRejectInvalidNewMail() { public void shouldRejectInvalidNewMail() {
// given // given
AsyncChangeEmail process = createProcess("old@mail.tld", "bogus"); String newEmail = "bogus";
AsyncChangeEmail process = createProcess("old@mail.tld", newEmail);
given(player.getName()).willReturn("Bobby"); given(player.getName()).willReturn("Bobby");
given(playerCache.isAuthenticated("bobby")).willReturn(true); given(playerCache.isAuthenticated("bobby")).willReturn(true);
PlayerAuth auth = authWithMail("old@mail.tld"); PlayerAuth auth = authWithMail("old@mail.tld");
given(playerCache.getAuth("bobby")).willReturn(auth); given(playerCache.getAuth("bobby")).willReturn(auth);
given(service.validateEmail(newEmail)).willReturn(false);
// when // when
process.run(); process.run();
@ -115,11 +120,15 @@ public class AsyncChangeEmailTest {
@Test @Test
public void shouldRejectInvalidOldEmail() { public void shouldRejectInvalidOldEmail() {
// given // given
AsyncChangeEmail process = createProcess("old@mail.tld", "new@mail.tld"); String newEmail = "new@mail.tld";
AsyncChangeEmail process = createProcess("old@mail.tld", newEmail);
given(player.getName()).willReturn("Bobby"); given(player.getName()).willReturn("Bobby");
given(playerCache.isAuthenticated("bobby")).willReturn(true); given(playerCache.isAuthenticated("bobby")).willReturn(true);
PlayerAuth auth = authWithMail("other@address.email"); PlayerAuth auth = authWithMail("other@address.email");
given(playerCache.getAuth("bobby")).willReturn(auth); given(playerCache.getAuth("bobby")).willReturn(auth);
given(service.validateEmail(newEmail)).willReturn(true);
given(service.isEmailFreeForRegistration(newEmail, player)).willReturn(true);
// when // when
process.run(); process.run();
@ -133,12 +142,14 @@ public class AsyncChangeEmailTest {
@Test @Test
public void shouldRejectAlreadyUsedEmail() { public void shouldRejectAlreadyUsedEmail() {
// given // given
AsyncChangeEmail process = createProcess("old@example.com", "new@example.com"); String newEmail = "new@example.com";
AsyncChangeEmail process = createProcess("old@example.com", newEmail);
given(player.getName()).willReturn("Username"); given(player.getName()).willReturn("Username");
given(playerCache.isAuthenticated("username")).willReturn(true); given(playerCache.isAuthenticated("username")).willReturn(true);
PlayerAuth auth = authWithMail("old@example.com"); PlayerAuth auth = authWithMail("old@example.com");
given(playerCache.getAuth("username")).willReturn(auth); given(playerCache.getAuth("username")).willReturn(auth);
given(dataSource.countAuthsByEmail("new@example.com")).willReturn(5); given(service.validateEmail(newEmail)).willReturn(true);
given(service.isEmailFreeForRegistration(newEmail, player)).willReturn(false);
// when // when
process.run(); process.run();
@ -210,7 +221,6 @@ public class AsyncChangeEmailTest {
private AsyncChangeEmail createProcess(String oldEmail, String newEmail) { private AsyncChangeEmail createProcess(String oldEmail, String newEmail) {
given(service.getProperty(EmailSettings.MAX_REG_PER_EMAIL)).willReturn(5); given(service.getProperty(EmailSettings.MAX_REG_PER_EMAIL)).willReturn(5);
given(service.getSettings()).willReturn(settings);
return new AsyncChangeEmail(player, oldEmail, newEmail, dataSource, playerCache, service); return new AsyncChangeEmail(player, oldEmail, newEmail, dataSource, playerCache, service);
} }
} }

View File

@ -3,26 +3,23 @@ package fr.xephi.authme.util;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLoggerTestInitializer; import fr.xephi.authme.ConsoleLoggerTestInitializer;
import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.ReflectionTestUtils;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
/** /**
* Test for the {@link Utils} class. * Test for the {@link Utils} class.
@ -30,7 +27,6 @@ import static org.mockito.Mockito.*;
public class UtilsTest { public class UtilsTest {
private static AuthMe authMeMock; private static AuthMe authMeMock;
private PermissionsManager permissionsManagerMock;
/** /**
* The Utils class initializes its fields in a {@code static} block which is only executed once during the JUnit * The Utils class initializes its fields in a {@code static} block which is only executed once during the JUnit
@ -51,9 +47,6 @@ public class UtilsTest {
// before every test -- this is OK because it is retrieved via authMeMock. It is just crucial that authMeMock // before every test -- this is OK because it is retrieved via authMeMock. It is just crucial that authMeMock
// remain the same object. // remain the same object.
reset(authMeMock); reset(authMeMock);
permissionsManagerMock = mock(PermissionsManager.class);
when(authMeMock.getPermissionsManager()).thenReturn(permissionsManagerMock);
} }
@Test @Test
@ -103,95 +96,6 @@ public class UtilsTest {
assertThat(players, hasSize(2)); assertThat(players, hasSize(2));
} }
// ----------------
// Tests for Utils#isEmailCorrect()
// ----------------
@Test
public void shouldAcceptEmailWithEmptyLists() {
// given
NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.<String> emptyList());
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.<String> emptyList());
// when
boolean result = Utils.isEmailCorrect("test@example.org", settings);
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldAcceptEmailWithWhitelist() {
// given
NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST))
.willReturn(Arrays.asList("domain.tld", "example.com"));
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.<String> emptyList());
// when
boolean result = Utils.isEmailCorrect("TesT@Example.com", settings);
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldRejectEmailNotInWhitelist() {
// given
NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST))
.willReturn(Arrays.asList("domain.tld", "example.com"));
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.<String> emptyList());
// when
boolean result = Utils.isEmailCorrect("email@other-domain.abc", settings);
// then
assertThat(result, equalTo(false));
}
@Test
public void shouldAcceptEmailNotInBlacklist() {
// given
NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.<String> emptyList());
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST))
.willReturn(Arrays.asList("Example.org", "a-test-name.tld"));
// when
boolean result = Utils.isEmailCorrect("sample@valid-name.tld", settings);
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldRejectEmailInBlacklist() {
// given
NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.<String> emptyList());
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST))
.willReturn(Arrays.asList("Example.org", "a-test-name.tld"));
// when
boolean result = Utils.isEmailCorrect("sample@a-Test-name.tld", settings);
// then
assertThat(result, equalTo(false));
}
@Test
public void shouldRejectInvalidEmail() {
// given/when/then
assertThat(Utils.isEmailCorrect("invalidinput", mock(NewSetting.class)), equalTo(false));
}
@Test
public void shouldRejectDefaultEmail() {
// given/when/then
assertThat(Utils.isEmailCorrect("your@email.com", mock(NewSetting.class)), equalTo(false));
}
// Note: This method is used through reflections // Note: This method is used through reflections
public static Player[] onlinePlayersImpl() { public static Player[] onlinePlayersImpl() {
return new Player[]{ return new Player[]{

View File

@ -1,14 +1,23 @@
package fr.xephi.authme.util; package fr.xephi.authme.util;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.command.CommandSender;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
@ -19,19 +28,26 @@ import static org.mockito.Mockito.mock;
/** /**
* Test for {@link ValidationService}. * Test for {@link ValidationService}.
*/ */
@RunWith(MockitoJUnitRunner.class)
public class ValidationServiceTest { public class ValidationServiceTest {
private ValidationService validationService; private ValidationService validationService;
@Mock
private NewSetting settings;
@Mock
private DataSource dataSource;
@Mock
private PermissionsManager permissionsManager;
@Before @Before
public void createService() { public void createService() {
NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).willReturn("[a-zA-Z]+"); given(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).willReturn("[a-zA-Z]+");
given(settings.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(3); given(settings.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(3);
given(settings.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)).willReturn(20); given(settings.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)).willReturn(20);
given(settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS)) given(settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS))
.willReturn(Arrays.asList("unsafe", "other-unsafe")); .willReturn(Arrays.asList("unsafe", "other-unsafe"));
validationService = new ValidationService(settings); given(settings.getProperty(EmailSettings.MAX_REG_PER_EMAIL)).willReturn(3);
validationService = new ValidationService(settings, dataSource, permissionsManager);
} }
@Test @Test
@ -89,4 +105,129 @@ public class ValidationServiceTest {
assertThat(error, nullValue()); assertThat(error, nullValue());
} }
@Test
public void shouldAcceptEmailWithEmptyLists() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.<String>emptyList());
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.<String>emptyList());
// when
boolean result = validationService.validateEmail("test@example.org");
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldAcceptEmailWithWhitelist() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST))
.willReturn(Arrays.asList("domain.tld", "example.com"));
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.<String>emptyList());
// when
boolean result = validationService.validateEmail("TesT@Example.com");
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldRejectEmailNotInWhitelist() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST))
.willReturn(Arrays.asList("domain.tld", "example.com"));
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.<String>emptyList());
// when
boolean result = validationService.validateEmail("email@other-domain.abc");
// then
assertThat(result, equalTo(false));
}
@Test
public void shouldAcceptEmailNotInBlacklist() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.<String>emptyList());
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST))
.willReturn(Arrays.asList("Example.org", "a-test-name.tld"));
// when
boolean result = validationService.validateEmail("sample@valid-name.tld");
// then
assertThat(result, equalTo(true));
}
@Test
public void shouldRejectEmailInBlacklist() {
// given
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.<String>emptyList());
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST))
.willReturn(Arrays.asList("Example.org", "a-test-name.tld"));
// when
boolean result = validationService.validateEmail("sample@a-Test-name.tld");
// then
assertThat(result, equalTo(false));
}
@Test
public void shouldRejectInvalidEmail() {
// given/when/then
assertThat(validationService.validateEmail("invalidinput"), equalTo(false));
}
@Test
public void shouldRejectDefaultEmail() {
// given/when/then
assertThat(validationService.validateEmail("your@email.com"), equalTo(false));
}
public void shouldAllowRegistration() {
// given
CommandSender sender = mock(CommandSender.class);
String email = "my.address@example.org";
given(permissionsManager.hasPermission(sender, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS))
.willReturn(false);
given(dataSource.countAuthsByEmail(email)).willReturn(2);
// when
boolean result = validationService.isEmailFreeForRegistration(email, sender);
// then
assertThat(result, equalTo(true));
}
public void shouldRejectEmailWithTooManyAccounts() {
// given
CommandSender sender = mock(CommandSender.class);
String email = "mail@example.org";
given(permissionsManager.hasPermission(sender, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS))
.willReturn(false);
given(dataSource.countAuthsByEmail(email)).willReturn(5);
// when
boolean result = validationService.isEmailFreeForRegistration(email, sender);
// then
assertThat(result, equalTo(false));
}
public void shouldAllowBypassForPresentPermission() {
// given
CommandSender sender = mock(CommandSender.class);
String email = "mail-address@example.com";
given(permissionsManager.hasPermission(sender, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS))
.willReturn(true);
given(dataSource.countAuthsByEmail(email)).willReturn(7);
// when
boolean result = validationService.isEmailFreeForRegistration(email, sender);
// then
assertThat(result, equalTo(true));
}
} }