Check valid password via service

- Create validation service; fixes same code being duplicated in four places
   - Goal is to remove Utils class, by moving methods to validation service or other services
 - Remove unused properties in legacy settings
This commit is contained in:
ljacqu 2016-04-02 22:44:20 +02:00
parent 73161de808
commit 4f86604699
15 changed files with 263 additions and 246 deletions

View File

@ -62,6 +62,7 @@ import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.MigrationService; import fr.xephi.authme.util.MigrationService;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils; import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.ValidationService;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -260,8 +261,9 @@ 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);
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings, ipAddressManager, commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings, ipAddressManager,
pluginHooks, spawnLoader, antiBot); pluginHooks, spawnLoader, antiBot, validationService);
// AntiBot delay // AntiBot delay
BukkitService bukkitService = new BukkitService(this); BukkitService bukkitService = new BukkitService(this);
@ -299,7 +301,7 @@ public class AuthMe extends JavaPlugin {
// Set up the management // Set up the management
ProcessService processService = new ProcessService(newSettings, messages, this, database, ipAddressManager, ProcessService processService = new ProcessService(newSettings, messages, this, database, ipAddressManager,
passwordSecurity, pluginHooks, spawnLoader); passwordSecurity, pluginHooks, spawnLoader, validationService);
management = new Management(this, processService, database, PlayerCache.getInstance()); management = new Management(this, processService, database, PlayerCache.getInstance());
// Set up the BungeeCord hook // Set up the BungeeCord hook
@ -432,12 +434,13 @@ public class AuthMe extends JavaPlugin {
private CommandHandler initializeCommandHandler(PermissionsManager permissionsManager, Messages messages, private CommandHandler initializeCommandHandler(PermissionsManager permissionsManager, Messages messages,
PasswordSecurity passwordSecurity, NewSetting settings, PasswordSecurity passwordSecurity, NewSetting settings,
IpAddressManager ipAddressManager, PluginHooks pluginHooks, IpAddressManager ipAddressManager, PluginHooks pluginHooks,
SpawnLoader spawnLoader, AntiBot antiBot) { SpawnLoader spawnLoader, AntiBot antiBot,
ValidationService validationService) {
HelpProvider helpProvider = new HelpProvider(permissionsManager, settings.getProperty(HELP_HEADER)); HelpProvider helpProvider = new HelpProvider(permissionsManager, settings.getProperty(HELP_HEADER));
Set<CommandDescription> baseCommands = CommandInitializer.buildCommands(); Set<CommandDescription> baseCommands = CommandInitializer.buildCommands();
CommandMapper mapper = new CommandMapper(baseCommands, permissionsManager); CommandMapper mapper = new CommandMapper(baseCommands, permissionsManager);
CommandService commandService = new CommandService(this, mapper, helpProvider, messages, passwordSecurity, CommandService commandService = new CommandService(this, mapper, helpProvider, messages, passwordSecurity,
permissionsManager, settings, ipAddressManager, pluginHooks, spawnLoader, antiBot); permissionsManager, settings, ipAddressManager, pluginHooks, spawnLoader, antiBot, validationService);
return new CommandHandler(commandService); return new CommandHandler(commandService);
} }

View File

@ -15,6 +15,7 @@ import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.SpawnLoader; import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.domain.Property; import fr.xephi.authme.settings.domain.Property;
import fr.xephi.authme.util.ValidationService;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.List; import java.util.List;
@ -36,6 +37,7 @@ public class CommandService {
private final PluginHooks pluginHooks; private final PluginHooks pluginHooks;
private final SpawnLoader spawnLoader; private final SpawnLoader spawnLoader;
private final AntiBot antiBot; private final AntiBot antiBot;
private final ValidationService validationService;
/** /**
* Constructor. * Constructor.
@ -54,7 +56,7 @@ public class CommandService {
public CommandService(AuthMe authMe, CommandMapper commandMapper, HelpProvider helpProvider, Messages messages, public CommandService(AuthMe authMe, CommandMapper commandMapper, HelpProvider helpProvider, Messages messages,
PasswordSecurity passwordSecurity, PermissionsManager permissionsManager, NewSetting settings, PasswordSecurity passwordSecurity, PermissionsManager permissionsManager, NewSetting settings,
IpAddressManager ipAddressManager, PluginHooks pluginHooks, SpawnLoader spawnLoader, IpAddressManager ipAddressManager, PluginHooks pluginHooks, SpawnLoader spawnLoader,
AntiBot antiBot) { AntiBot antiBot, ValidationService validationService) {
this.authMe = authMe; this.authMe = authMe;
this.messages = messages; this.messages = messages;
this.helpProvider = helpProvider; this.helpProvider = helpProvider;
@ -66,6 +68,7 @@ public class CommandService {
this.pluginHooks = pluginHooks; this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader; this.spawnLoader = spawnLoader;
this.antiBot = antiBot; this.antiBot = antiBot;
this.validationService = validationService;
} }
/** /**
@ -219,4 +222,15 @@ public class CommandService {
return antiBot; return antiBot;
} }
/**
* Verifies whether a password is valid according to the plugin settings.
*
* @param password the password to verify
* @param username the username the password is associated with
* @return message key with the password error, or {@code null} if password is valid
*/
public MessageKey validatePassword(String password, String username) {
return validationService.validatePassword(password, username);
}
} }

View File

@ -7,8 +7,6 @@ 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.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.List; import java.util.List;
@ -22,30 +20,16 @@ public class ChangePasswordAdminCommand implements ExecutableCommand {
public void executeCommand(final CommandSender sender, List<String> arguments, public void executeCommand(final CommandSender sender, List<String> arguments,
final CommandService commandService) { final CommandService commandService) {
// Get the player and password // Get the player and password
String playerName = arguments.get(0); final String playerName = arguments.get(0);
final String playerPass = arguments.get(1); final String playerPass = arguments.get(1);
// Validate the password // Validate the password
String playerPassLowerCase = playerPass.toLowerCase(); MessageKey passwordError = commandService.validatePassword(playerPass, playerName);
if (!playerPassLowerCase.matches(commandService.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX))) { if (passwordError != null) {
commandService.send(sender, MessageKey.PASSWORD_MATCH_ERROR); commandService.send(sender, passwordError);
return;
}
if (playerPassLowerCase.equalsIgnoreCase(playerName)) {
commandService.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
return;
}
if (playerPassLowerCase.length() < commandService.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)
|| playerPassLowerCase.length() > commandService.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)) {
commandService.send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
return;
}
// TODO #602 20160312: The UNSAFE_PASSWORDS should be all lowercase
// -> introduce a lowercase String list property type
if (commandService.getProperty(SecuritySettings.UNSAFE_PASSWORDS).contains(playerPassLowerCase)) {
commandService.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
return; return;
} }
// Set the password // Set the password
final String playerNameLowerCase = playerName.toLowerCase(); final String playerNameLowerCase = playerName.toLowerCase();
commandService.runTaskAsynchronously(new Runnable() { commandService.runTaskAsynchronously(new Runnable() {

View File

@ -6,8 +6,6 @@ import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -25,26 +23,14 @@ public class RegisterAdminCommand implements ExecutableCommand {
final String playerName = arguments.get(0); final String playerName = arguments.get(0);
final String playerPass = arguments.get(1); final String playerPass = arguments.get(1);
final String playerNameLowerCase = playerName.toLowerCase(); final String playerNameLowerCase = playerName.toLowerCase();
final String playerPassLowerCase = playerPass.toLowerCase();
// Command logic // Command logic
if (!playerPassLowerCase.matches(Settings.getPassRegex)) { MessageKey passwordError = commandService.validatePassword(playerPass, playerName);
commandService.send(sender, MessageKey.PASSWORD_MATCH_ERROR); if (passwordError != null) {
return; commandService.send(sender, passwordError);
}
if (playerPassLowerCase.equalsIgnoreCase(playerName)) {
commandService.send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
return;
}
if (playerPassLowerCase.length() < commandService.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)
|| playerPassLowerCase.length() > commandService.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)) {
commandService.send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
return;
}
if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(playerPassLowerCase)) {
commandService.send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
return; return;
} }
commandService.runTaskAsynchronously(new Runnable() { commandService.runTaskAsynchronously(new Runnable() {
@Override @Override

View File

@ -5,8 +5,6 @@ import fr.xephi.authme.cache.auth.PlayerCache;
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.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.task.ChangePasswordTask; import fr.xephi.authme.task.ChangePasswordTask;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -30,22 +28,9 @@ public class ChangePasswordCommand extends PlayerCommand {
} }
// Make sure the password is allowed // Make sure the password is allowed
String playerPassLowerCase = newPassword.toLowerCase(); MessageKey passwordError = commandService.validatePassword(newPassword, name);
if (!playerPassLowerCase.matches(commandService.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX))) { if (passwordError != null) {
commandService.send(player, MessageKey.PASSWORD_MATCH_ERROR); commandService.send(player, passwordError);
return;
}
if (playerPassLowerCase.equalsIgnoreCase(name)) {
commandService.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR);
return;
}
if (playerPassLowerCase.length() < commandService.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)
|| playerPassLowerCase.length() > commandService.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)) {
commandService.send(player, MessageKey.INVALID_PASSWORD_LENGTH);
return;
}
if (commandService.getProperty(SecuritySettings.UNSAFE_PASSWORDS).contains(playerPassLowerCase)) {
commandService.send(player, MessageKey.PASSWORD_UNSAFE_ERROR);
return; return;
} }

View File

@ -41,7 +41,7 @@ public class Management {
} }
public void performRegister(final Player player, final String password, final String email) { public void performRegister(final Player player, final String password, final String email) {
runTask(new AsyncRegister(player, password, email, plugin, dataSource, processService)); runTask(new AsyncRegister(player, password, email, plugin, dataSource, playerCache, processService));
} }
public void performUnregister(final Player player, final String password, final boolean force) { public void performUnregister(final Player player, final String password, final boolean force) {

View File

@ -11,6 +11,7 @@ import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.SpawnLoader; import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.domain.Property; import fr.xephi.authme.settings.domain.Property;
import fr.xephi.authme.util.ValidationService;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
@ -28,10 +29,11 @@ public class ProcessService {
private final PasswordSecurity passwordSecurity; private final PasswordSecurity passwordSecurity;
private final PluginHooks pluginHooks; private final PluginHooks pluginHooks;
private final SpawnLoader spawnLoader; private final SpawnLoader spawnLoader;
private final ValidationService validationService;
public ProcessService(NewSetting settings, Messages messages, AuthMe authMe, DataSource dataSource, public ProcessService(NewSetting settings, Messages messages, AuthMe authMe, DataSource dataSource,
IpAddressManager ipAddressManager, PasswordSecurity passwordSecurity, PluginHooks pluginHooks, IpAddressManager ipAddressManager, PasswordSecurity passwordSecurity, PluginHooks pluginHooks,
SpawnLoader spawnLoader) { SpawnLoader spawnLoader, ValidationService validationService) {
this.settings = settings; this.settings = settings;
this.messages = messages; this.messages = messages;
this.authMe = authMe; this.authMe = authMe;
@ -40,6 +42,7 @@ public class ProcessService {
this.passwordSecurity = passwordSecurity; this.passwordSecurity = passwordSecurity;
this.pluginHooks = pluginHooks; this.pluginHooks = pluginHooks;
this.spawnLoader = spawnLoader; this.spawnLoader = spawnLoader;
this.validationService = validationService;
} }
/** /**
@ -199,4 +202,15 @@ public class ProcessService {
return dataSource; return dataSource;
} }
/**
* Verifies whether a password is valid according to the plugin settings.
*
* @param password the password to verify
* @param username the username the password is associated with
* @return message key with the password error, or {@code null} if password is valid
*/
public MessageKey validatePassword(String password, String username) {
return validationService.validatePassword(password, username);
}
} }

View File

@ -12,6 +12,8 @@ import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.security.crypts.TwoFactor; import fr.xephi.authme.security.crypts.TwoFactor;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.StringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -30,10 +32,11 @@ public class AsyncRegister implements Process {
private final String email; private final String email;
private final AuthMe plugin; private final AuthMe plugin;
private final DataSource database; private final DataSource database;
private final PlayerCache playerCache;
private final ProcessService service; private final ProcessService service;
public AsyncRegister(Player player, String password, String email, AuthMe plugin, DataSource data, public AsyncRegister(Player player, String password, String email, AuthMe plugin, DataSource data,
ProcessService service) { PlayerCache playerCache, ProcessService service) {
this.player = player; this.player = player;
this.password = password; this.password = password;
this.name = player.getName().toLowerCase(); this.name = player.getName().toLowerCase();
@ -41,32 +44,24 @@ public class AsyncRegister implements Process {
this.plugin = plugin; this.plugin = plugin;
this.database = data; this.database = data;
this.ip = service.getIpAddressManager().getPlayerIp(player); this.ip = service.getIpAddressManager().getPlayerIp(player);
this.playerCache = playerCache;
this.service = service; this.service = service;
} }
private boolean preRegisterCheck() { private boolean preRegisterCheck() {
String passLow = password.toLowerCase(); if (playerCache.isAuthenticated(name)) {
if (PlayerCache.getInstance().isAuthenticated(name)) {
service.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); service.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
return false; return false;
} else if (!Settings.isRegistrationEnabled) { } else if (!service.getProperty(RegistrationSettings.IS_ENABLED)) {
service.send(player, MessageKey.REGISTRATION_DISABLED); service.send(player, MessageKey.REGISTRATION_DISABLED);
return false; return false;
} }
//check the password safety only if it's not a automatically generated password //check the password safety only if it's not a automatically generated password
if (service.getProperty(SecuritySettings.PASSWORD_HASH) != HashAlgorithm.TWO_FACTOR) { if (service.getProperty(SecuritySettings.PASSWORD_HASH) != HashAlgorithm.TWO_FACTOR) {
if (!passLow.matches(Settings.getPassRegex)) { MessageKey passwordError = service.validatePassword(password, player.getName());
service.send(player, MessageKey.PASSWORD_MATCH_ERROR); if (passwordError != null) {
return false; service.send(player, passwordError);
} else if (passLow.equalsIgnoreCase(player.getName())) {
service.send(player, MessageKey.PASSWORD_IS_USERNAME_ERROR);
return false;
} else if (password.length() < Settings.getPasswordMinLen || password.length() > Settings.passwordMaxLength) {
service.send(player, MessageKey.INVALID_PASSWORD_LENGTH);
return false;
} else if (!Settings.unsafePasswords.isEmpty() && Settings.unsafePasswords.contains(password.toLowerCase())) {
service.send(player, MessageKey.PASSWORD_UNSAFE_ERROR);
return false; return false;
} }
} }
@ -75,15 +70,17 @@ public class AsyncRegister implements Process {
if (database.isAuthAvailable(name)) { if (database.isAuthAvailable(name)) {
service.send(player, MessageKey.NAME_ALREADY_REGISTERED); service.send(player, MessageKey.NAME_ALREADY_REGISTERED);
return false; return false;
} else if(Settings.getmaxRegPerIp > 0 }
&& !ip.equalsIgnoreCase("127.0.0.1")
&& !ip.equalsIgnoreCase("localhost") final int maxRegPerIp = service.getProperty(RestrictionSettings.MAX_REGISTRATION_PER_IP);
if (maxRegPerIp > 0
&& !"127.0.0.1".equalsIgnoreCase(ip)
&& !"localhost".equalsIgnoreCase(ip)
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) { && !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)) {
int maxReg = Settings.getmaxRegPerIp;
List<String> otherAccounts = database.getAllAuthsByIp(ip); List<String> otherAccounts = database.getAllAuthsByIp(ip);
if (otherAccounts.size() >= maxReg) { if (otherAccounts.size() >= maxRegPerIp) {
service.send(player, MessageKey.MAX_REGISTER_EXCEEDED, Integer.toString(maxReg), service.send(player, MessageKey.MAX_REGISTER_EXCEEDED, Integer.toString(maxRegPerIp),
Integer.toString(otherAccounts.size()), StringUtils.join(", ", otherAccounts.toString())); Integer.toString(otherAccounts.size()), StringUtils.join(", ", otherAccounts));
return false; return false;
} }
} }

View File

@ -38,11 +38,10 @@ public final class Settings {
public static List<String> forceCommandsAsConsole; public static List<String> forceCommandsAsConsole;
public static List<String> forceRegisterCommands; public static List<String> forceRegisterCommands;
public static List<String> forceRegisterCommandsAsConsole; public static List<String> forceRegisterCommandsAsConsole;
public static List<String> unsafePasswords;
public static HashAlgorithm getPasswordHash; public static HashAlgorithm getPasswordHash;
public static Pattern nickPattern; public static Pattern nickPattern;
public static boolean useLogging = false; public static boolean useLogging = false;
public static boolean isChatAllowed, isPermissionCheckEnabled, isRegistrationEnabled, public static boolean isChatAllowed, isPermissionCheckEnabled,
isForcedRegistrationEnabled, isTeleportToSpawnEnabled, isForcedRegistrationEnabled, isTeleportToSpawnEnabled,
isSessionsEnabled, isAllowRestrictedIp, isSessionsEnabled, isAllowRestrictedIp,
isMovementAllowed, isKickNonRegisteredEnabled, isMovementAllowed, isKickNonRegisteredEnabled,
@ -64,10 +63,10 @@ public final class Settings {
unRegisteredGroup, unRegisteredGroup,
backupWindowsPath, getRegisteredGroup, backupWindowsPath, getRegisteredGroup,
rakamakUsers, rakamakUsersIp, getmailAccount, defaultWorld, rakamakUsers, rakamakUsersIp, getmailAccount, defaultWorld,
spawnPriority, crazyloginFileName, getPassRegex, sendPlayerTo; spawnPriority, crazyloginFileName, sendPlayerTo;
public static int getWarnMessageInterval, getSessionTimeout, public static int getWarnMessageInterval, getSessionTimeout,
getRegistrationTimeout, getMaxNickLength, getMinNickLength, getRegistrationTimeout, getMaxNickLength, getMinNickLength,
getPasswordMinLen, getMovementRadius, getmaxRegPerIp, getPasswordMinLen, getMovementRadius,
getNonActivatedGroup, passwordMaxLength, getRecoveryPassLength, getNonActivatedGroup, passwordMaxLength, getRecoveryPassLength,
getMailPort, maxLoginTry, captchaLength, saltLength, getMailPort, maxLoginTry, captchaLength, saltLength,
getmaxRegPerEmail, bCryptLog2Rounds, getMaxLoginPerIp, getMaxJoinPerIp; getmaxRegPerEmail, bCryptLog2Rounds, getMaxLoginPerIp, getMaxJoinPerIp;
@ -86,7 +85,6 @@ public final class Settings {
private static void loadVariables() { private static void loadVariables() {
isPermissionCheckEnabled = load(PluginSettings.ENABLE_PERMISSION_CHECK); isPermissionCheckEnabled = load(PluginSettings.ENABLE_PERMISSION_CHECK);
isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true); isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true);
isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true);
isTeleportToSpawnEnabled = load(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN); isTeleportToSpawnEnabled = load(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN);
getWarnMessageInterval = load(RegistrationSettings.MESSAGE_INTERVAL); getWarnMessageInterval = load(RegistrationSettings.MESSAGE_INTERVAL);
isSessionsEnabled = load(PluginSettings.SESSIONS_ENABLED); isSessionsEnabled = load(PluginSettings.SESSIONS_ENABLED);
@ -110,7 +108,6 @@ public final class Settings {
isForceSpawnLocOnJoinEnabled = configFile.getBoolean("settings.restrictions.ForceSpawnLocOnJoinEnabled", false); isForceSpawnLocOnJoinEnabled = configFile.getBoolean("settings.restrictions.ForceSpawnLocOnJoinEnabled", false);
isSaveQuitLocationEnabled = configFile.getBoolean("settings.restrictions.SaveQuitLocation", false); isSaveQuitLocationEnabled = configFile.getBoolean("settings.restrictions.SaveQuitLocation", false);
isForceSurvivalModeEnabled = configFile.getBoolean("settings.GameMode.ForceSurvivalMode", false); isForceSurvivalModeEnabled = configFile.getBoolean("settings.GameMode.ForceSurvivalMode", false);
getmaxRegPerIp = configFile.getInt("settings.restrictions.maxRegPerIp", 1);
getPasswordHash = load(SecuritySettings.PASSWORD_HASH); getPasswordHash = load(SecuritySettings.PASSWORD_HASH);
getUnloggedinGroup = load(SecuritySettings.UNLOGGEDIN_GROUP); getUnloggedinGroup = load(SecuritySettings.UNLOGGEDIN_GROUP);
getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1); getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
@ -174,7 +171,6 @@ public final class Settings {
forceCommandsAsConsole = configFile.getStringList("settings.forceCommandsAsConsole"); forceCommandsAsConsole = configFile.getStringList("settings.forceCommandsAsConsole");
recallEmail = configFile.getBoolean("Email.recallPlayers", false); recallEmail = configFile.getBoolean("Email.recallPlayers", false);
useWelcomeMessage = load(RegistrationSettings.USE_WELCOME_MESSAGE); useWelcomeMessage = load(RegistrationSettings.USE_WELCOME_MESSAGE);
unsafePasswords = configFile.getStringList("settings.security.unsafePasswords");
countriesBlacklist = configFile.getStringList("Protection.countriesBlacklist"); countriesBlacklist = configFile.getStringList("Protection.countriesBlacklist");
broadcastWelcomeMessage = load(RegistrationSettings.BROADCAST_WELCOME_MESSAGE); broadcastWelcomeMessage = load(RegistrationSettings.BROADCAST_WELCOME_MESSAGE);
forceRegKick = configFile.getBoolean("settings.registration.forceKickAfterRegister", false); forceRegKick = configFile.getBoolean("settings.registration.forceKickAfterRegister", false);
@ -188,7 +184,6 @@ public final class Settings {
delayJoinMessage = load(RegistrationSettings.DELAY_JOIN_MESSAGE); delayJoinMessage = load(RegistrationSettings.DELAY_JOIN_MESSAGE);
noTeleport = load(RestrictionSettings.NO_TELEPORT); noTeleport = load(RestrictionSettings.NO_TELEPORT);
crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db"); crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db");
getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*");
forceRegisterCommands = configFile.getStringList("settings.forceRegisterCommands"); forceRegisterCommands = configFile.getStringList("settings.forceRegisterCommands");
forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole"); forceRegisterCommandsAsConsole = configFile.getStringList("settings.forceRegisterCommandsAsConsole");
customAttributes = configFile.getBoolean("Hooks.customAttributes"); customAttributes = configFile.getBoolean("Hooks.customAttributes");
@ -198,21 +193,6 @@ public final class Settings {
keepCollisionsDisabled = configFile.getBoolean("settings.keepCollisionsDisabled"); keepCollisionsDisabled = configFile.getBoolean("settings.keepCollisionsDisabled");
} }
/**
* Method switchAntiBotMod.
*
* @param mode boolean
*/
public static void switchAntiBotMod(boolean mode) {
if (mode) {
isKickNonRegisteredEnabled = true;
antiBotInAction = true;
} else {
isKickNonRegisteredEnabled = configFile.getBoolean("settings.restrictions.kickNonRegistered", false);
antiBotInAction = false;
}
}
/** /**
* Load the value via the new Property setup for temporary support within this old settings manager. * Load the value via the new Property setup for temporary support within this old settings manager.
* *

View File

@ -0,0 +1,42 @@
package fr.xephi.authme.util;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
/**
* Validation service.
*/
public class ValidationService {
private final NewSetting settings;
public ValidationService(NewSetting settings) {
this.settings = settings;
}
/**
* Verifies whether a password is valid according to the plugin settings.
*
* @param password the password to verify
* @param username the username the password is associated with
* @return message key with the password error, or {@code null} if password is valid
*/
public MessageKey validatePassword(String password, String username) {
String passLow = password.toLowerCase();
if (!passLow.matches(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX))) {
return MessageKey.PASSWORD_MATCH_ERROR;
} else if (passLow.equalsIgnoreCase(username)) {
return MessageKey.PASSWORD_IS_USERNAME_ERROR;
} else if (password.length() < settings.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)
|| password.length() > settings.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)) {
return MessageKey.INVALID_PASSWORD_LENGTH;
} else if (settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS).contains(passLow)) {
// TODO #602 20160312: The UNSAFE_PASSWORDS should be all lowercase
// -> introduce a lowercase String list property type
return MessageKey.PASSWORD_UNSAFE_ERROR;
}
return null;
}
}

View File

@ -15,6 +15,7 @@ import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.SpawnLoader; import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.domain.Property; import fr.xephi.authme.settings.domain.Property;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.ValidationService;
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.Before;
@ -63,11 +64,13 @@ public class CommandServiceTest {
private SpawnLoader spawnLoader; private SpawnLoader spawnLoader;
@Mock @Mock
private AntiBot antiBot; private AntiBot antiBot;
@Mock
private ValidationService validationService;
@Before @Before
public void setUpService() { public void setUpService() {
commandService = new CommandService(authMe, commandMapper, helpProvider, messages, passwordSecurity, commandService = new CommandService(authMe, commandMapper, helpProvider, messages, passwordSecurity,
permissionsManager, settings, ipAddressManager, pluginHooks, spawnLoader, antiBot); permissionsManager, settings, ipAddressManager, pluginHooks, spawnLoader, antiBot, validationService);
} }
@Test @Test
@ -228,4 +231,19 @@ public class CommandServiceTest {
// then // then
assertThat(ipManager, equalTo(ipAddressManager)); assertThat(ipManager, equalTo(ipAddressManager));
} }
@Test
public void shouldValidatePassword() {
// given
String user = "asdf";
String password = "mySecret55";
given(validationService.validatePassword(password, user)).willReturn(MessageKey.INVALID_PASSWORD_LENGTH);
// when
MessageKey result = commandService.validatePassword(password, user);
// then
assertThat(result, equalTo(MessageKey.INVALID_PASSWORD_LENGTH));
verify(validationService).validatePassword(password, user);
}
} }

View File

@ -1,6 +1,5 @@
package fr.xephi.authme.command.executable.authme; package fr.xephi.authme.command.executable.authme;
import com.google.common.base.Strings;
import fr.xephi.authme.ConsoleLoggerTestInitializer; import fr.xephi.authme.ConsoleLoggerTestInitializer;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
@ -10,12 +9,12 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey; import fr.xephi.authme.output.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;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
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;
@ -29,8 +28,10 @@ import static org.mockito.Mockito.verify;
/** /**
* Test for {@link ChangePasswordAdminCommand}. * Test for {@link ChangePasswordAdminCommand}.
*/ */
@RunWith(MockitoJUnitRunner.class)
public class ChangePasswordAdminCommandTest { public class ChangePasswordAdminCommandTest {
@Mock
private CommandService service; private CommandService service;
@BeforeClass @BeforeClass
@ -38,88 +39,22 @@ public class ChangePasswordAdminCommandTest {
ConsoleLoggerTestInitializer.setupLogger(); ConsoleLoggerTestInitializer.setupLogger();
} }
@Before
public void setUpServiceMock() {
service = mock(CommandService.class);
given(service.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).willReturn("[a-zA-Z]+");
given(service.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(3);
given(service.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)).willReturn(20);
given(service.getProperty(SecuritySettings.UNSAFE_PASSWORDS))
.willReturn(Arrays.asList("unsafe", "otherUnsafe"));
}
@Test @Test
public void shouldRejectPasswordSameAsUsername() { public void shouldRejectInvalidPassword() {
// given // given
ExecutableCommand command = new ChangePasswordAdminCommand(); ExecutableCommand command = new ChangePasswordAdminCommand();
CommandSender sender = mock(CommandSender.class); CommandSender sender = mock(CommandSender.class);
given(service.validatePassword("Bobby", "bobby")).willReturn(MessageKey.PASSWORD_IS_USERNAME_ERROR);
// when // when
command.executeCommand(sender, Arrays.asList("bobby", "Bobby"), service); command.executeCommand(sender, Arrays.asList("bobby", "Bobby"), service);
// then // then
verify(service).validatePassword("Bobby", "bobby");
verify(service).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR); verify(service).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
verify(service, never()).getDataSource(); verify(service, never()).getDataSource();
} }
@Test
public void shouldRejectPasswordNotMatchingPattern() {
// given
ExecutableCommand command = new ChangePasswordAdminCommand();
CommandSender sender = mock(CommandSender.class);
// service mock returns pattern a-zA-Z -> numbers should not be accepted
String invalidPassword = "invalid1234";
// when
command.executeCommand(sender, Arrays.asList("myPlayer123", invalidPassword), service);
// then
verify(service).send(sender, MessageKey.PASSWORD_MATCH_ERROR);
verify(service, never()).getDataSource();
}
@Test
public void shouldRejectTooShortPassword() {
// given
ExecutableCommand command = new ChangePasswordAdminCommand();
CommandSender sender = mock(CommandSender.class);
// when
command.executeCommand(sender, Arrays.asList("player", "ab"), service);
// then
verify(service).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
verify(service, never()).getDataSource();
}
@Test
public void shouldRejectTooLongPassword() {
// given
ExecutableCommand command = new ChangePasswordAdminCommand();
CommandSender sender = mock(CommandSender.class);
// when
command.executeCommand(sender, Arrays.asList("player", Strings.repeat("a", 30)), service);
// then
verify(service).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
verify(service, never()).getDataSource();
}
@Test
public void shouldRejectUnsafePassword() {
// given
ExecutableCommand command = new ChangePasswordAdminCommand();
CommandSender sender = mock(CommandSender.class);
// when
command.executeCommand(sender, Arrays.asList("player", "unsafe"), service);
// then
verify(service).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
verify(service, never()).getDataSource();
}
@Test @Test
public void shouldRejectCommandForUnknownUser() { public void shouldRejectCommandForUnknownUser() {
// given // given
@ -173,6 +108,7 @@ public class ChangePasswordAdminCommandTest {
runInnerRunnable(service); runInnerRunnable(service);
// then // then
verify(service).validatePassword(password, player);
verify(service).send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS); verify(service).send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS);
verify(passwordSecurity).computeHash(password, player); verify(passwordSecurity).computeHash(password, player);
verify(auth).setPassword(hashedPassword); verify(auth).setPassword(hashedPassword);
@ -209,6 +145,7 @@ public class ChangePasswordAdminCommandTest {
runInnerRunnable(service); runInnerRunnable(service);
// then // then
verify(service).validatePassword(password, player);
verify(service).send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS); verify(service).send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS);
verify(passwordSecurity).computeHash(password, player); verify(passwordSecurity).computeHash(password, player);
verify(auth).setPassword(hashedPassword); verify(auth).setPassword(hashedPassword);
@ -244,6 +181,7 @@ public class ChangePasswordAdminCommandTest {
runInnerRunnable(service); runInnerRunnable(service);
// then // then
verify(service).validatePassword(password, player);
verify(service).send(sender, MessageKey.ERROR); verify(service).send(sender, MessageKey.ERROR);
verify(passwordSecurity).computeHash(password, player); verify(passwordSecurity).computeHash(password, player);
verify(auth).setPassword(hashedPassword); verify(auth).setPassword(hashedPassword);

View File

@ -22,6 +22,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq; import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ -57,9 +58,7 @@ public class ChangePasswordCommandTest {
command.executeCommand(sender, new ArrayList<String>(), commandService); command.executeCommand(sender, new ArrayList<String>(), commandService);
// then // then
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); verify(sender).sendMessage(argThat(containsString("only for players")));
verify(sender).sendMessage(captor.capture());
assertThat(captor.getValue(), containsString("only for players"));
} }
@Test @Test
@ -76,75 +75,21 @@ public class ChangePasswordCommandTest {
} }
@Test @Test
public void shouldDenyInvalidPassword() { public void shouldRejectInvalidPassword() {
// given
CommandSender sender = initPlayerWithName("name", true);
ChangePasswordCommand command = new ChangePasswordCommand();
// when
command.executeCommand(sender, Arrays.asList("old123", "!pass"), commandService);
// then
verify(commandService).send(sender, MessageKey.PASSWORD_MATCH_ERROR);
}
@Test
public void shouldRejectPasswordEqualToNick() {
// given
CommandSender sender = initPlayerWithName("tester", true);
ChangePasswordCommand command = new ChangePasswordCommand();
// when
command.executeCommand(sender, Arrays.asList("old_", "Tester"), commandService);
// then
verify(commandService).send(sender, MessageKey.PASSWORD_IS_USERNAME_ERROR);
}
@Test
public void shouldRejectTooLongPassword() {
// given // given
CommandSender sender = initPlayerWithName("abc12", true); CommandSender sender = initPlayerWithName("abc12", true);
ChangePasswordCommand command = new ChangePasswordCommand(); ChangePasswordCommand command = new ChangePasswordCommand();
given(commandService.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)).willReturn(3); String password = "newPW";
given(commandService.validatePassword(password, "abc12")).willReturn(MessageKey.INVALID_PASSWORD_LENGTH);
// when // when
command.executeCommand(sender, Arrays.asList("12", "test"), commandService); command.executeCommand(sender, Arrays.asList("tester", password), commandService);
// then // then
verify(commandService).validatePassword(password, "abc12");
verify(commandService).send(sender, MessageKey.INVALID_PASSWORD_LENGTH); verify(commandService).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
} }
@Test
public void shouldRejectTooShortPassword() {
// given
CommandSender sender = initPlayerWithName("abc12", true);
ChangePasswordCommand command = new ChangePasswordCommand();
given(commandService.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(7);
// when
command.executeCommand(sender, Arrays.asList("oldverylongpassword", "tester"), commandService);
// then
verify(commandService).send(sender, MessageKey.INVALID_PASSWORD_LENGTH);
}
@Test
public void shouldRejectUnsafeCustomPassword() {
// given
CommandSender sender = initPlayerWithName("player", true);
ChangePasswordCommand command = new ChangePasswordCommand();
given(commandService.getProperty(SecuritySettings.UNSAFE_PASSWORDS))
.willReturn(Arrays.asList("test", "abc123"));
// when
command.executeCommand(sender, Arrays.asList("oldpw", "abc123"), commandService);
// then
verify(commandService).send(sender, MessageKey.PASSWORD_UNSAFE_ERROR);
}
@Test @Test
public void shouldForwardTheDataForValidPassword() { public void shouldForwardTheDataForValidPassword() {
// given // given
@ -155,6 +100,7 @@ public class ChangePasswordCommandTest {
command.executeCommand(sender, Arrays.asList("abc123", "abc123"), commandService); command.executeCommand(sender, Arrays.asList("abc123", "abc123"), commandService);
// then // then
verify(commandService).validatePassword("abc123", "parker");
verify(commandService, never()).send(eq(sender), any(MessageKey.class)); verify(commandService, never()).send(eq(sender), any(MessageKey.class));
ArgumentCaptor<ChangePasswordTask> taskCaptor = ArgumentCaptor.forClass(ChangePasswordTask.class); ArgumentCaptor<ChangePasswordTask> taskCaptor = ArgumentCaptor.forClass(ChangePasswordTask.class);
verify(commandService).runTaskAsynchronously(taskCaptor.capture()); verify(commandService).runTaskAsynchronously(taskCaptor.capture());

View File

@ -11,7 +11,9 @@ import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.NewSetting; import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.SpawnLoader; import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.ValidationService;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.hamcrest.MatcherAssert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -37,7 +39,7 @@ public class ProcessServiceTest {
mocks = new HashMap<>(); mocks = new HashMap<>();
processService = new ProcessService(newMock(NewSetting.class), newMock(Messages.class), newMock(AuthMe.class), processService = new ProcessService(newMock(NewSetting.class), newMock(Messages.class), newMock(AuthMe.class),
newMock(DataSource.class), newMock(IpAddressManager.class), newMock(PasswordSecurity.class), newMock(DataSource.class), newMock(IpAddressManager.class), newMock(PasswordSecurity.class),
newMock(PluginHooks.class), newMock(SpawnLoader.class)); newMock(PluginHooks.class), newMock(SpawnLoader.class), newMock(ValidationService.class));
} }
@Test @Test
@ -186,6 +188,22 @@ public class ProcessServiceTest {
verify(passwordSecurity).computeHash(password, username); verify(passwordSecurity).computeHash(password, username);
} }
@Test
public void shouldValidatePassword() {
// given
String user = "test-user";
String password = "passw0rd";
ValidationService validationService = getMock(ValidationService.class);
given(validationService.validatePassword(password, user)).willReturn(MessageKey.PASSWORD_MATCH_ERROR);
// when
MessageKey result = processService.validatePassword(password, user);
// then
MatcherAssert.assertThat(result, equalTo(MessageKey.PASSWORD_MATCH_ERROR));
verify(validationService).validatePassword(password, user);
}
private <T> T newMock(Class<T> clazz) { private <T> T newMock(Class<T> clazz) {
T mock = mock(clazz); T mock = mock(clazz);
mocks.put(clazz, mock); mocks.put(clazz, mock);

View File

@ -0,0 +1,92 @@
package fr.xephi.authme.util;
import com.google.common.base.Strings;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Test for {@link ValidationService}.
*/
public class ValidationServiceTest {
private ValidationService validationService;
@Before
public void createService() {
NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).willReturn("[a-zA-Z]+");
given(settings.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).willReturn(3);
given(settings.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)).willReturn(20);
given(settings.getProperty(SecuritySettings.UNSAFE_PASSWORDS))
.willReturn(Arrays.asList("unsafe", "other-unsafe"));
validationService = new ValidationService(settings);
}
@Test
public void shouldRejectPasswordSameAsUsername() {
// given/when
MessageKey error = validationService.validatePassword("bobby", "Bobby");
// then
assertThat(error, equalTo(MessageKey.PASSWORD_IS_USERNAME_ERROR));
}
@Test
public void shouldRejectPasswordNotMatchingPattern() {
// given/when
// service mock returns pattern a-zA-Z -> numbers should not be accepted
MessageKey error = validationService.validatePassword("invalid1234", "myPlayer");
// then
assertThat(error, equalTo(MessageKey.PASSWORD_MATCH_ERROR));
}
@Test
public void shouldRejectTooShortPassword() {
// given/when
MessageKey error = validationService.validatePassword("ab", "tester");
// then
assertThat(error, equalTo(MessageKey.INVALID_PASSWORD_LENGTH));
}
@Test
public void shouldRejectTooLongPassword() {
// given/when
MessageKey error = validationService.validatePassword(Strings.repeat("a", 30), "player");
// then
assertThat(error, equalTo(MessageKey.INVALID_PASSWORD_LENGTH));
}
@Test
public void shouldRejectUnsafePassword() {
// given/when
MessageKey error = validationService.validatePassword("unsafe", "playertest");
// then
assertThat(error, equalTo(MessageKey.PASSWORD_UNSAFE_ERROR));
}
@Test
public void shouldAcceptValidPassword() {
// given/when
MessageKey error = validationService.validatePassword("safePass", "some_user");
// then
assertThat(error, nullValue());
}
}