diff --git a/src/main/java/fr/xephi/authme/command/CommandManager.java b/src/main/java/fr/xephi/authme/command/CommandManager.java index 02e77267..aaae7e6a 100644 --- a/src/main/java/fr/xephi/authme/command/CommandManager.java +++ b/src/main/java/fr/xephi/authme/command/CommandManager.java @@ -138,6 +138,21 @@ public class CommandManager { registerCommand.addArgument(new CommandArgumentDescription("player", "Player name", false)); registerCommand.addArgument(new CommandArgumentDescription("password", "Password", false)); + // Register the changepassword command + CommandDescription changePasswordCommand = new CommandDescription( + new RegisterCommand(), + new ArrayList() {{ + add("changepassword"); + add("changepass"); + add("cp"); + }}, + "Change player's password", + "Change the password of a player.", + authMeCommand); + changePasswordCommand.setCommandPermissions("authme.admin.changepassword", CommandPermissions.DefaultPermission.OP_ONLY); + changePasswordCommand.addArgument(new CommandArgumentDescription("player", "Player name", false)); + changePasswordCommand.addArgument(new CommandArgumentDescription("password", "New password", false)); + // Register the purge command CommandDescription lastLoginCommand = new CommandDescription( new LastLoginCommand(), diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java new file mode 100644 index 00000000..4e2a0c2a --- /dev/null +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordCommand.java @@ -0,0 +1,100 @@ +package fr.xephi.authme.command.executable.authme; + +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.cache.auth.PlayerAuth; +import fr.xephi.authme.cache.auth.PlayerCache; +import fr.xephi.authme.command.CommandParts; +import fr.xephi.authme.command.ExecutableCommand; +import fr.xephi.authme.security.PasswordSecurity; +import fr.xephi.authme.settings.Messages; +import fr.xephi.authme.settings.Settings; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; + +import java.security.NoSuchAlgorithmException; + +public class ChangePasswordCommand extends ExecutableCommand { + + /** + * Execute the command. + * + * @param sender The command sender. + * @param commandReference The command reference. + * @param commandArguments The command arguments. + * + * @return True if the command was executed successfully, false otherwise. + */ + @Override + public boolean executeCommand(final CommandSender sender, CommandParts commandReference, CommandParts commandArguments) { + // AuthMe plugin instance + final AuthMe plugin = AuthMe.getInstance(); + + // Messages instance + final Messages m = Messages.getInstance(); + + // Get the player and password + String playerName = commandArguments.get(0); + final String playerPass = commandArguments.get(1); + + // Validate the password + String playerPassLowerCase = playerPass.toLowerCase(); + if (playerPassLowerCase.contains("delete") || playerPassLowerCase.contains("where") || playerPassLowerCase.contains("insert") || playerPassLowerCase.contains("modify") || playerPassLowerCase.contains("from") || playerPassLowerCase.contains("select") || playerPassLowerCase.contains(";") || playerPassLowerCase.contains("null") || !playerPassLowerCase.matches(Settings.getPassRegex)) { + m.send(sender, "password_error"); + return true; + } + if (playerPassLowerCase.equalsIgnoreCase(playerName)) { + m.send(sender, "password_error_nick"); + return true; + } + if (playerPassLowerCase.length() < Settings.getPasswordMinLen || playerPassLowerCase.length() > Settings.passwordMaxLength) { + m.send(sender, "pass_len"); + return true; + } + if (!Settings.unsafePasswords.isEmpty()) { + if (Settings.unsafePasswords.contains(playerPassLowerCase)) { + m.send(sender, "password_error_unsafe"); + return true; + } + } + + // Set the password + final String playerNameLowerCase = playerName.toLowerCase(); + Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { + + @Override + public void run() { + String hash; + try { + hash = PasswordSecurity.getHash(Settings.getPasswordHash, playerPass, playerNameLowerCase); + } catch (NoSuchAlgorithmException e) { + m.send(sender, "error"); + return; + } + PlayerAuth auth = null; + if (PlayerCache.getInstance().isAuthenticated(playerNameLowerCase)) { + auth = PlayerCache.getInstance().getAuth(playerNameLowerCase); + } else if (plugin.database.isAuthAvailable(playerNameLowerCase)) { + auth = plugin.database.getAuth(playerNameLowerCase); + } + if (auth == null) { + m.send(sender, "unknown_user"); + return; + } + auth.setHash(hash); + if (PasswordSecurity.userSalt.containsKey(playerNameLowerCase)) { + auth.setSalt(PasswordSecurity.userSalt.get(playerNameLowerCase)); + plugin.database.updateSalt(auth); + } + if (!plugin.database.updatePassword(auth)) { + m.send(sender, "error"); + return; + } + sender.sendMessage("pwd_changed"); + ConsoleLogger.info(playerNameLowerCase + "'s password changed"); + } + + }); + return true; + } +}