diff --git a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java index a23883c6b..0e1e099e6 100644 --- a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java +++ b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java @@ -285,6 +285,16 @@ public class AuthMeApi { management.performUnregisterByAdmin(null, name, Bukkit.getPlayer(name)); } + /** + * Change a user's password + * + * @param name the user name + * @param newPassword the new password + */ + public void changePassword(String name, String newPassword) { + management.performPasswordChangeAsAdmin(null, name, newPassword); + } + /** * Get all the registered names (lowercase) * diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommand.java index e12f4d386..26054241a 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommand.java @@ -1,12 +1,10 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.process.Management; import fr.xephi.authme.security.PasswordSecurity; -import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.ValidationService; @@ -39,6 +37,9 @@ public class ChangePasswordAdminCommand implements ExecutableCommand { @Inject private CommonService commonService; + @Inject + private Management management; + @Override public void executeCommand(final CommandSender sender, List arguments) { // Get the player and password @@ -53,32 +54,6 @@ public class ChangePasswordAdminCommand implements ExecutableCommand { } // Set the password - bukkitService.runTaskOptionallyAsync(() -> changePassword(playerName.toLowerCase(), playerPass, sender)); - } - - /** - * Changes the password of the given player to the given password. - * - * @param nameLowercase the name of the player - * @param password the password to set - * @param sender the sender initiating the password change - */ - private void changePassword(String nameLowercase, String password, CommandSender sender) { - if (!isNameRegistered(nameLowercase)) { - commonService.send(sender, MessageKey.UNKNOWN_USER); - return; - } - - HashedPassword hashedPassword = passwordSecurity.computeHash(password, nameLowercase); - if (dataSource.updatePassword(nameLowercase, hashedPassword)) { - commonService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS); - ConsoleLogger.info(sender.getName() + " changed password of " + nameLowercase); - } else { - commonService.send(sender, MessageKey.ERROR); - } - } - - private boolean isNameRegistered(String nameLowercase) { - return playerCache.isAuthenticated(nameLowercase) || dataSource.isAuthAvailable(nameLowercase); + management.performPasswordChangeAsAdmin(sender, playerName, playerPass); } } diff --git a/src/main/java/fr/xephi/authme/process/Management.java b/src/main/java/fr/xephi/authme/process/Management.java index d2707c52e..4f0743ed7 100644 --- a/src/main/java/fr/xephi/authme/process/Management.java +++ b/src/main/java/fr/xephi/authme/process/Management.java @@ -94,6 +94,10 @@ public class Management { runTask(() -> asyncChangePassword.changePassword(player, oldPassword, newPassword)); } + public void performPasswordChangeAsAdmin(CommandSender sender, String playerName, String newPassword) { + runTask(() -> asyncChangePassword.changePasswordAsAdmin(sender, playerName, newPassword)); + } + private void runTask(Runnable runnable) { bukkitService.runTaskOptionallyAsync(runnable); } diff --git a/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java b/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java index 2a3fa1755..0a7d11fe9 100644 --- a/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java +++ b/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java @@ -9,6 +9,7 @@ import fr.xephi.authme.process.AsynchronousProcess; import fr.xephi.authme.service.CommonService; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.HashedPassword; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -30,7 +31,13 @@ public class AsyncChangePassword implements AsynchronousProcess { AsyncChangePassword() { } - + /** + * Change password for an online player + * + * @param player the player + * @param oldPassword the old password used by the player + * @param newPassword the new password chosen by the player + */ public void changePassword(final Player player, String oldPassword, String newPassword) { final String name = player.getName().toLowerCase(); PlayerAuth auth = playerCache.getAuth(name); @@ -50,5 +57,38 @@ public class AsyncChangePassword implements AsynchronousProcess { commonService.send(player, MessageKey.WRONG_PASSWORD); } } -} + /** + * Change a user's password as an administrator, without asking for the previous one + * + * @param sender who is performing the operation, null if called by other plugins + * @param playerName the player name + * @param newPassword the new password chosen for the player + */ + public void changePasswordAsAdmin(CommandSender sender, final String playerName, String newPassword) { + final String lowerCaseName = playerName.toLowerCase(); + if (!(playerCache.isAuthenticated(lowerCaseName) || dataSource.isAuthAvailable(lowerCaseName))) { + if(sender == null) { + ConsoleLogger.warning("Tried to change password for user " + lowerCaseName + " but it doesn't exist!"); + } else { + commonService.send(sender, MessageKey.UNKNOWN_USER); + } + return; + } + + HashedPassword hashedPassword = passwordSecurity.computeHash(newPassword, lowerCaseName); + if (dataSource.updatePassword(lowerCaseName, hashedPassword)) { + if(sender != null) { + commonService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS); + ConsoleLogger.info(sender.getName() + " changed password of " + lowerCaseName); + } else { + ConsoleLogger.info("Changed password of " + lowerCaseName); + } + } else { + if(sender != null) { + commonService.send(sender, MessageKey.ERROR); + } + ConsoleLogger.warning("An error occurred while changing password for user " + lowerCaseName + "!"); + } + } +} diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java index 9e957a627..4bcfec99f 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ChangePasswordAdminCommandTest.java @@ -5,6 +5,7 @@ import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.process.Management; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.service.BukkitService; @@ -56,6 +57,9 @@ public class ChangePasswordAdminCommandTest { @Mock private ValidationService validationService; + @Mock + private Management management; + @BeforeClass public static void setUpLogger() { TestHelper.setupLogger(); @@ -88,7 +92,6 @@ public class ChangePasswordAdminCommandTest { // when command.executeCommand(sender, Arrays.asList(player, password)); - runOptionallyAsyncTask(bukkitService); // then verify(service).send(sender, MessageKey.UNKNOWN_USER); @@ -110,7 +113,6 @@ public class ChangePasswordAdminCommandTest { // when command.executeCommand(sender, Arrays.asList(player, password)); - runOptionallyAsyncTask(bukkitService); // then verify(validationService).validatePassword(password, player); @@ -135,7 +137,6 @@ public class ChangePasswordAdminCommandTest { // when command.executeCommand(sender, Arrays.asList(player, password)); - runOptionallyAsyncTask(bukkitService); // then verify(validationService).validatePassword(password, player); @@ -159,7 +160,6 @@ public class ChangePasswordAdminCommandTest { // when command.executeCommand(sender, Arrays.asList(player, password)); - runOptionallyAsyncTask(bukkitService); // then verify(validationService).validatePassword(password, player);