mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-11-23 02:35:11 +01:00
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:
parent
73161de808
commit
4f86604699
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
42
src/main/java/fr/xephi/authme/util/ValidationService.java
Normal file
42
src/main/java/fr/xephi/authme/util/ValidationService.java
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user