From b3fd6170fe5c4fb19fe183741bf4959848c32916 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 18 Oct 2016 02:53:20 +0700 Subject: [PATCH 01/67] Use timestamp to determine if antibot should be activated - removed handleJoin method. --- .../xephi/authme/listener/OnJoinVerifier.java | 4 +- .../xephi/authme/listener/PlayerListener.java | 14 +-- .../xephi/authme/service/AntiBotService.java | 94 ++++++++----------- 3 files changed, 47 insertions(+), 65 deletions(-) diff --git a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java index 93783346..755d2a6e 100644 --- a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java +++ b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java @@ -9,14 +9,14 @@ import fr.xephi.authme.message.Messages; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.service.AntiBotService; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.ProtectionSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; -import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.util.StringUtils; import fr.xephi.authme.util.Utils; -import fr.xephi.authme.service.ValidationService; import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerLoginEvent; diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index b6484fb3..73a552f0 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -6,14 +6,14 @@ import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.Messages; import fr.xephi.authme.process.Management; import fr.xephi.authme.service.AntiBotService; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.TeleportationService; +import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.SpawnLoader; import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; -import fr.xephi.authme.service.BukkitService; -import fr.xephi.authme.service.TeleportationService; -import fr.xephi.authme.service.ValidationService; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -233,7 +233,6 @@ public class PlayerListener implements Listener { return; } - antiBotService.handlePlayerJoin(); teleportationService.teleportOnJoin(player); } @@ -306,12 +305,7 @@ public class PlayerListener implements Listener { * @note little hack cause InventoryOpenEvent cannot be cancelled for * real, cause no packet is send to server by client for the main inv */ - bukkitService.scheduleSyncDelayedTask(new Runnable() { - @Override - public void run() { - player.closeInventory(); - } - }, 1); + bukkitService.scheduleSyncDelayedTask(player::closeInventory, 1); } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) diff --git a/src/main/java/fr/xephi/authme/service/AntiBotService.java b/src/main/java/fr/xephi/authme/service/AntiBotService.java index 24118d40..9a0db2e8 100644 --- a/src/main/java/fr/xephi/authme/service/AntiBotService.java +++ b/src/main/java/fr/xephi/authme/service/AntiBotService.java @@ -7,10 +7,11 @@ import fr.xephi.authme.permission.AdminPermission; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.ProtectionSettings; -import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitTask; import javax.inject.Inject; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.concurrent.CopyOnWriteArrayList; import static fr.xephi.authme.service.BukkitService.TICKS_PER_MINUTE; @@ -25,18 +26,17 @@ public class AntiBotService implements SettingsDependent { private final Messages messages; private final PermissionsManager permissionsManager; private final BukkitService bukkitService; - + private final CopyOnWriteArrayList antibotKicked = new CopyOnWriteArrayList<>(); // Settings private int duration; private int sensibility; private int delay; - // Service status private AntiBotStatus antiBotStatus; private boolean startup; private BukkitTask disableTask; - private int antibotPlayers; - private final CopyOnWriteArrayList antibotKicked = new CopyOnWriteArrayList<>(); + private Instant lastFlaggedJoin; + private int flagged = 0; @Inject AntiBotService(Settings settings, Messages messages, PermissionsManager permissionsManager, @@ -47,7 +47,7 @@ public class AntiBotService implements SettingsDependent { this.bukkitService = bukkitService; // Initial status disableTask = null; - antibotPlayers = 0; + flagged = 0; antiBotStatus = AntiBotStatus.DISABLED; startup = true; // Load settings and start if required @@ -71,15 +71,10 @@ public class AntiBotService implements SettingsDependent { } // Bot activation task - Runnable enableTask = new Runnable() { - @Override - public void run() { - antiBotStatus = AntiBotStatus.LISTENING; - } - }; + Runnable enableTask = () -> antiBotStatus = AntiBotStatus.LISTENING; // Delay the schedule on first start - if(startup) { + if (startup) { bukkitService.scheduleSyncDelayedTask(enableTask, delay * TICKS_PER_SECOND); startup = false; } else { @@ -94,19 +89,12 @@ public class AntiBotService implements SettingsDependent { antiBotStatus = AntiBotStatus.ACTIVE; // Inform admins - for (Player player : bukkitService.getOnlinePlayers()) { - if (permissionsManager.hasPermission(player, AdminPermission.ANTIBOT_MESSAGES)) { - messages.send(player, MessageKey.ANTIBOT_AUTO_ENABLED_MESSAGE); - } - } + bukkitService.getOnlinePlayers().stream() + .filter(player -> permissionsManager.hasPermission(player, AdminPermission.ANTIBOT_MESSAGES)) + .forEach(player -> messages.send(player, MessageKey.ANTIBOT_AUTO_ENABLED_MESSAGE)); // Schedule auto-disable - disableTask = bukkitService.runTaskLater(new Runnable() { - @Override - public void run() { - stopProtection(); - } - }, duration * TICKS_PER_MINUTE); + disableTask = bukkitService.runTaskLater(this::stopProtection, duration * TICKS_PER_MINUTE); } private void stopProtection() { @@ -116,7 +104,7 @@ public class AntiBotService implements SettingsDependent { // Change status antiBotStatus = AntiBotStatus.LISTENING; - antibotPlayers = 0; + flagged = 0; antibotKicked.clear(); // Cancel auto-disable task @@ -124,11 +112,10 @@ public class AntiBotService implements SettingsDependent { disableTask = null; // Inform admins - for (Player player : bukkitService.getOnlinePlayers()) { - if (permissionsManager.hasPermission(player, AdminPermission.ANTIBOT_MESSAGES)) { - messages.send(player, MessageKey.ANTIBOT_AUTO_DISABLED_MESSAGE, Integer.toString(duration)); - } - } + String durationString = Integer.toString(duration); + bukkitService.getOnlinePlayers().stream() + .filter(player -> permissionsManager.hasPermission(player, AdminPermission.ANTIBOT_MESSAGES)) + .forEach(player -> messages.send(player, MessageKey.ANTIBOT_AUTO_DISABLED_MESSAGE, durationString)); } /** @@ -155,36 +142,37 @@ public class AntiBotService implements SettingsDependent { } } - /** - * Handles a player joining the server and checks if AntiBot needs to be activated. - */ - public void handlePlayerJoin() { - if (antiBotStatus != AntiBotStatus.LISTENING) { - return; - } - - antibotPlayers++; - if (antibotPlayers > sensibility) { - startProtection(); - return; - } - - bukkitService.scheduleSyncDelayedTask(new Runnable() { - @Override - public void run() { - antibotPlayers--; - } - }, 5 * TICKS_PER_SECOND); - } - /** * Returns if a player should be kicked due to antibot service. * * @param isAuthAvailable if the player is registered + * * @return if the player should be kicked */ public boolean shouldKick(boolean isAuthAvailable) { - return !isAuthAvailable && (antiBotStatus == AntiBotStatus.ACTIVE); + if (antiBotStatus == AntiBotStatus.DISABLED || isAuthAvailable) { + return false; + } + + if (antiBotStatus == AntiBotStatus.ACTIVE) { + return true; + } + + if (lastFlaggedJoin == null) { + lastFlaggedJoin = Instant.now(); + } + if (ChronoUnit.SECONDS.between(Instant.now(), lastFlaggedJoin) <= 5) { + flagged++; + } else { + // reset to 1 because this player is also count as not registered + flagged = 1; + lastFlaggedJoin = null; + } + if (flagged > sensibility) { + startProtection(); + return true; + } + return false; } /** From cbd9add1b79dbcec4ccf3ede4c2d883051bf082e Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 18 Oct 2016 03:46:15 +0700 Subject: [PATCH 02/67] Removed a test for antibot service. --- .../xephi/authme/service/AntiBotService.java | 2 +- .../authme/listener/PlayerListenerTest.java | 1 - .../authme/service/AntiBotServiceTest.java | 26 +++---------------- 3 files changed, 4 insertions(+), 25 deletions(-) diff --git a/src/main/java/fr/xephi/authme/service/AntiBotService.java b/src/main/java/fr/xephi/authme/service/AntiBotService.java index 9a0db2e8..a329e5de 100644 --- a/src/main/java/fr/xephi/authme/service/AntiBotService.java +++ b/src/main/java/fr/xephi/authme/service/AntiBotService.java @@ -161,7 +161,7 @@ public class AntiBotService implements SettingsDependent { if (lastFlaggedJoin == null) { lastFlaggedJoin = Instant.now(); } - if (ChronoUnit.SECONDS.between(Instant.now(), lastFlaggedJoin) <= 5) { + if (ChronoUnit.SECONDS.between(lastFlaggedJoin, Instant.now()) <= 5) { flagged++; } else { // reset to 1 because this player is also count as not registered diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java index 15bf4c6e..992752f9 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java @@ -565,7 +565,6 @@ public class PlayerListenerTest { verify(onJoinVerifier).checkKickNonRegistered(true); verify(onJoinVerifier).checkNameCasing(player, auth); verify(onJoinVerifier).checkPlayerCountry(true, ip); - verify(antiBotService).handlePlayerJoin(); verify(teleportationService).teleportOnJoin(player); verifyNoModifyingCalls(event); } diff --git a/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java b/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java index e40d5ca7..a39c7a6e 100644 --- a/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java @@ -3,7 +3,6 @@ package fr.xephi.authme.service; import ch.jalu.injector.testing.BeforeInjecting; import ch.jalu.injector.testing.DelayedInjectionRunner; import ch.jalu.injector.testing.InjectDelayed; -import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.Messages; import fr.xephi.authme.permission.AdminPermission; @@ -152,22 +151,6 @@ public class AntiBotServiceTest { assertThat(kickWithAuth, equalTo(false)); } - @Test - public void shouldIncreaseCountAndDecreaseAfterDelay() { - // given - listening antibot - runSyncDelayedTaskWithDelay(bukkitService); - reset(bukkitService); - assertThat(getAntiBotCount(antiBotService), equalTo(0)); - - // when - antiBotService.handlePlayerJoin(); - - // then - assertThat(getAntiBotCount(antiBotService), equalTo(1)); - runSyncDelayedTaskWithDelay(bukkitService); - assertThat(getAntiBotCount(antiBotService), equalTo(0)); - } - @Test public void shouldActivateAntibotAfterThreshold() { // given @@ -178,19 +161,19 @@ public class AntiBotServiceTest { runSyncDelayedTaskWithDelay(bukkitService); for (int i = 0; i < sensitivity; ++i) { - antiBotService.handlePlayerJoin(); + antiBotService.shouldKick(false); } assertThat(antiBotService.getAntiBotStatus(), equalTo(AntiBotService.AntiBotStatus.LISTENING)); // when - antiBotService.handlePlayerJoin(); + antiBotService.shouldKick(false); // then assertThat(antiBotService.getAntiBotStatus(), equalTo(AntiBotService.AntiBotStatus.ACTIVE)); } @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({"unchecked", "rawtypes"}) public void shouldInformPlayersOnActivation() { // given - listening antibot runSyncDelayedTaskWithDelay(bukkitService); @@ -222,7 +205,4 @@ public class AntiBotServiceTest { assertThat(antiBotService.getAntiBotStatus(), equalTo(AntiBotService.AntiBotStatus.LISTENING)); } - private static int getAntiBotCount(AntiBotService antiBotService) { - return ReflectionTestUtils.getFieldValue(AntiBotService.class, antiBotService, "antibotPlayers"); - } } From cc151e6e8db1fa916d3a69fe1138760aecec0b62 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 23 Oct 2016 15:31:58 +0200 Subject: [PATCH 03/67] Update HU messages #836 --- src/main/resources/messages/messages_hu.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/messages/messages_hu.yml b/src/main/resources/messages/messages_hu.yml index 88142bbc..daabe573 100644 --- a/src/main/resources/messages/messages_hu.yml +++ b/src/main/resources/messages/messages_hu.yml @@ -72,5 +72,5 @@ kicked_admin_registered: 'Adminisztrátor által regisztrálva lettél; kérlek accounts_owned_self: '%count db regisztrációd van:' recovery_code_incorrect: 'A visszaállító kód helytelen volt! Használd a következő parancsot: /email recovery [email címed] egy új generálásához' recovery_code_sent: 'A jelszavad visszaállításához szükséges kódot sikeresen kiküldtük az email címedre!' -# TODO email_show: '&2Your current email address is: &f%email' -# TODO show_no_email: '&2You currently don''t have email address associated with this account.' \ No newline at end of file +email_show: '&2A jelenlegi email-ed a következő: &f%email' +show_no_email: '&2Ehhez a felhasználóhoz jelenleg még nincs email hozzárendelve.' From dd9ac75f3a804d1ef3cfc7194edaa155a1675205 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 23 Oct 2016 15:39:53 +0200 Subject: [PATCH 04/67] #916 Fix authme.vip node description --- docs/permission_nodes.md | 8 ++++---- .../fr/xephi/authme/permission/PlayerStatePermission.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/permission_nodes.md b/docs/permission_nodes.md index 60d39a15..fb640820 100644 --- a/docs/permission_nodes.md +++ b/docs/permission_nodes.md @@ -1,5 +1,5 @@ - + ## AuthMe Permission Nodes The following are the permission nodes that are currently supported by the latest dev builds. @@ -38,15 +38,15 @@ The following are the permission nodes that are currently supported by the lates - **authme.player.email** – Grants all email permissions. - **authme.player.email.add** – Command permission to add an email address. - **authme.player.email.change** – Command permission to change the email address. -- **authme.player.email.recover** – Command permission to recover an account using it's email address. +- **authme.player.email.recover** – Command permission to recover an account using its email address. - **authme.player.login** – Command permission to login. - **authme.player.logout** – Command permission to logout. - **authme.player.register** – Command permission to register. - **authme.player.seeownaccounts** – Permission to use to see own other accounts. - **authme.player.unregister** – Command permission to unregister. -- **authme.vip** – Permission node to identify VIP users. +- **authme.vip** – When the server is full and someone with this permission joins the server, someone will be kicked. --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 16 21:39:10 CEST 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 23 15:38:58 CEST 2016 diff --git a/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java b/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java index 0820be01..aaeb0eea 100644 --- a/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java @@ -17,7 +17,7 @@ public enum PlayerStatePermission implements PermissionNode { BYPASS_FORCE_SURVIVAL("authme.bypassforcesurvival", DefaultPermission.OP_ONLY), /** - * Permission node to identify VIP users. + * When the server is full and someone with this permission joins the server, someone will be kicked. */ IS_VIP("authme.vip", DefaultPermission.OP_ONLY), From 8f6643207e7fc6ad5fb867c0803f5cc94aa7dd87 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 23 Oct 2016 16:25:34 +0200 Subject: [PATCH 05/67] #979 Create tool task to verify help translations --- .../HelpTranslationVerifier.java | 162 ++++++++++++++++++ .../VerifyHelpTranslations.java | 72 ++++++++ 2 files changed, 234 insertions(+) create mode 100644 src/test/java/tools/helptranslation/HelpTranslationVerifier.java create mode 100644 src/test/java/tools/helptranslation/VerifyHelpTranslations.java diff --git a/src/test/java/tools/helptranslation/HelpTranslationVerifier.java b/src/test/java/tools/helptranslation/HelpTranslationVerifier.java new file mode 100644 index 00000000..2ed130fa --- /dev/null +++ b/src/test/java/tools/helptranslation/HelpTranslationVerifier.java @@ -0,0 +1,162 @@ +package tools.helptranslation; + +import com.google.common.collect.Sets; +import de.bananaco.bpermissions.imp.YamlConfiguration; +import fr.xephi.authme.command.CommandDescription; +import fr.xephi.authme.command.CommandInitializer; +import fr.xephi.authme.command.CommandUtils; +import fr.xephi.authme.command.help.HelpMessage; +import fr.xephi.authme.command.help.HelpSection; +import org.bukkit.configuration.MemorySection; +import org.bukkit.configuration.file.FileConfiguration; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.google.common.collect.Lists.newArrayList; + +/** + * Verifies a help messages translation. + */ +public class HelpTranslationVerifier { + + private final FileConfiguration configuration; + + // missing and unknown HelpSection and HelpMessage entries + private final List missingSections = new ArrayList<>(); + private final List unknownSections = new ArrayList<>(); + // missing and unknown command entries + private final List missingCommands = new ArrayList<>(); + private final List unknownCommands = new ArrayList<>(); + + public HelpTranslationVerifier(File translation) { + this.configuration = YamlConfiguration.loadConfiguration(translation); + checkFile(); + } + + private void checkFile() { + checkHelpSections(); + checkCommands(); + } + + public List getMissingSections() { + return missingSections; + } + + public List getUnknownSections() { + return unknownSections; + } + + public List getMissingCommands() { + return missingCommands; + } + + public List getUnknownCommands() { + return unknownCommands; + } + + /** + * Verifies that the file has the expected entries for {@link HelpSection} and {@link HelpMessage}. + */ + private void checkHelpSections() { + Set knownSections = Arrays.stream(HelpSection.values()) + .map(HelpSection::getKey).collect(Collectors.toSet()); + knownSections.addAll(Arrays.stream(HelpMessage.values()).map(HelpMessage::getKey).collect(Collectors.toSet())); + knownSections.addAll(Arrays.asList("common.defaultPermissions.notAllowed", + "common.defaultPermissions.opOnly", "common.defaultPermissions.allowed")); + Set sectionKeys = getLeafKeys("section"); + sectionKeys.addAll(getLeafKeys("common")); + + if (sectionKeys.isEmpty()) { + missingSections.addAll(knownSections); + } else { + missingSections.addAll(Sets.difference(knownSections, sectionKeys)); + unknownSections.addAll(Sets.difference(sectionKeys, knownSections)); + } + } + + /** + * Verifies that the file has the expected entries for AuthMe commands. + */ + private void checkCommands() { + Set commandPaths = buildCommandPaths(); + Set existingKeys = getLeafKeys("commands"); + if (existingKeys.isEmpty()) { + missingCommands.addAll(commandPaths); + } else { + missingCommands.addAll(Sets.difference(commandPaths, existingKeys)); + unknownCommands.addAll(Sets.difference(existingKeys, commandPaths)); + } + } + + private static Set buildCommandPaths() { + Set commandPaths = new LinkedHashSet<>(); + for (CommandDescription command : new CommandInitializer().getCommands()) { + commandPaths.addAll(getYamlPaths(command)); + command.getChildren().forEach(child -> commandPaths.addAll(getYamlPaths(child))); + } + return commandPaths; + } + + private static List getYamlPaths(CommandDescription command) { + // e.g. commands.authme.register + String commandPath = "commands." + CommandUtils.constructParentList(command).stream() + .map(cmd -> cmd.getLabels().get(0)) + .collect(Collectors.joining(".")); + + // Entries each command can have + List paths = newArrayList(commandPath + ".description", commandPath + ".detailedDescription"); + + // Add argument entries that may exist + for (int argIndex = 1; argIndex <= command.getArguments().size(); ++argIndex) { + String argPath = String.format("%s.arg%d", commandPath, argIndex); + paths.add(argPath + ".label"); + paths.add(argPath + ".description"); + } + return paths; + } + + /** + * Returns the leaf keys of the section at the given path of the file configuration. + * + * @param path the path whose leaf keys should be retrieved + * @return leaf keys of the memory section, + * empty set if the configuration does not have a memory section at the given path + */ + private Set getLeafKeys(String path) { + if (!(configuration.get(path) instanceof MemorySection)) { + return Collections.emptySet(); + } + MemorySection memorySection = (MemorySection) configuration.get(path); + + // MemorySection#getKeys(true) returns all keys on all levels, e.g. if the configuration has + // 'commands.authme.register' then it also has 'commands.authme' and 'commands'. We can traverse each node and + // build its parents (e.g. for commands.authme.register.description: commands.authme.register, commands.authme, + // and commands, which we can remove from the collection since we know they are not a leaf. + Set leafKeys = memorySection.getKeys(true); + Set allKeys = new HashSet<>(leafKeys); + + for (String key : allKeys) { + List pathParts = Arrays.asList(key.split("\\.")); + + // We perform construction of parents & their removal in reverse order so we can build the lowest-level + // parent of a node first. As soon as the parent doesn't exist in the set already, we know we can continue + // with the next node since another node has already removed the concerned parents. + for (int i = pathParts.size() - 1; i > 0; --i) { + // e.g. for commands.authme.register -> i = {2, 1} => {commands.authme, commands} + String parentPath = String.join(".", pathParts.subList(0, i)); + if (!leafKeys.remove(parentPath)) { + break; + } + } + } + return leafKeys.stream().map(leaf -> path + "." + leaf).collect(Collectors.toSet()); + } +} diff --git a/src/test/java/tools/helptranslation/VerifyHelpTranslations.java b/src/test/java/tools/helptranslation/VerifyHelpTranslations.java new file mode 100644 index 00000000..f97447bf --- /dev/null +++ b/src/test/java/tools/helptranslation/VerifyHelpTranslations.java @@ -0,0 +1,72 @@ +package tools.helptranslation; + +import tools.utils.ToolTask; +import tools.utils.ToolsConstants; + +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * Verifies the help translations for validity and completeness. + */ +public class VerifyHelpTranslations implements ToolTask { + + private static final Pattern HELP_MESSAGE_PATTERN = Pattern.compile("help_[a-z]{2,7}\\.yml"); + private static final String FOLDER = ToolsConstants.MAIN_RESOURCES_ROOT + "messages/"; + + @Override + public String getTaskName() { + return "verifyHelpTranslations"; + } + + @Override + public void execute(Scanner scanner) { + System.out.println("Check specific language file?"); + System.out.println("Enter the language code for a specific file (e.g. 'it' for help_it.yml)"); + System.out.println("Empty line will check all files in the resources messages folder (default)"); + + String language = scanner.nextLine(); + if (language.isEmpty()) { + getHelpTranslations().forEach(this::processFile); + } else { + processFile(new File(FOLDER, "help_" + language + ".yml")); + } + } + + private void processFile(File file) { + System.out.println("Checking '" + file.getName() + "'"); + HelpTranslationVerifier verifier = new HelpTranslationVerifier(file); + + // Check and output errors + if (!verifier.getMissingSections().isEmpty()) { + System.out.println("Missing sections: " + String.join(", ", verifier.getMissingSections())); + } + if (!verifier.getUnknownSections().isEmpty()) { + System.out.println("Unknown sections: " + String.join(", ", verifier.getUnknownSections())); + } + if (!verifier.getMissingCommands().isEmpty()) { + System.out.println("Missing command entries: " + String.join(", ", verifier.getMissingCommands())); + } + if (!verifier.getUnknownCommands().isEmpty()) { + System.out.println("Unknown command entries: " + String.join(", ", verifier.getUnknownCommands())); + } + } + + private static List getHelpTranslations() { + File[] files = new File(FOLDER).listFiles(); + if (files == null) { + throw new IllegalStateException("Could not get files from '" + FOLDER + "'"); + } + List helpFiles = Arrays.stream(files) + .filter(file -> HELP_MESSAGE_PATTERN.matcher(file.getName()).matches()) + .collect(Collectors.toList()); + if (helpFiles.isEmpty()) { + throw new IllegalStateException("Could not get any matching files!"); + } + return helpFiles; + } +} From 9d21a4cda288acd658121b694bb5783d0030a5d7 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 23 Oct 2016 18:17:09 +0200 Subject: [PATCH 06/67] Minor maintenance on ToolTask classes - Use default method on AutoToolTask interface in favor of abstract SimpleAutoTask class - Adjust the path in various .tpl.md files - Remove unused constant in ToolsConstants --- .../tools/checktestmocks/CheckTestMocks.java | 4 +-- src/test/java/tools/docs/UpdateDocsTask.java | 35 ++++++++----------- .../docs/commands/CommandPageCreater.java | 4 +-- .../java/tools/docs/commands/commands.tpl.md | 2 +- .../HashAlgorithmsDescriptionTask.java | 4 +-- .../docs/hashmethods/hash_algorithms.tpl.md | 2 +- .../permissions/PermissionsListWriter.java | 4 +-- .../docs/permissions/permission_nodes.tpl.md | 2 +- .../TranslationPageGenerator.java | 4 +-- .../docs/translations/translations.tpl.md | 2 +- .../filegeneration/GeneratePluginYml.java | 4 +-- src/test/java/tools/utils/AutoToolTask.java | 7 ++++ src/test/java/tools/utils/SimpleAutoTask.java | 15 -------- src/test/java/tools/utils/ToolsConstants.java | 3 -- 14 files changed, 37 insertions(+), 55 deletions(-) delete mode 100644 src/test/java/tools/utils/SimpleAutoTask.java diff --git a/src/test/java/tools/checktestmocks/CheckTestMocks.java b/src/test/java/tools/checktestmocks/CheckTestMocks.java index 1e8817aa..9af3ae04 100644 --- a/src/test/java/tools/checktestmocks/CheckTestMocks.java +++ b/src/test/java/tools/checktestmocks/CheckTestMocks.java @@ -4,8 +4,8 @@ import com.google.common.collect.Sets; import fr.xephi.authme.ClassCollector; import fr.xephi.authme.TestHelper; import org.mockito.Mock; +import tools.utils.AutoToolTask; import tools.utils.InjectorUtils; -import tools.utils.SimpleAutoTask; import java.lang.reflect.Field; import java.util.ArrayList; @@ -19,7 +19,7 @@ import java.util.stream.Collectors; * Task checking if all tests' {@code @Mock} fields have a corresponding * {@code @Inject} field in the class they are testing. */ -public class CheckTestMocks extends SimpleAutoTask { +public class CheckTestMocks implements AutoToolTask { private List errors = new ArrayList<>(); diff --git a/src/test/java/tools/docs/UpdateDocsTask.java b/src/test/java/tools/docs/UpdateDocsTask.java index cfdb69ef..84f723c6 100644 --- a/src/test/java/tools/docs/UpdateDocsTask.java +++ b/src/test/java/tools/docs/UpdateDocsTask.java @@ -1,26 +1,20 @@ package tools.docs; -import com.google.common.collect.ImmutableSet; -import tools.docs.commands.CommandPageCreater; -import tools.docs.hashmethods.HashAlgorithmsDescriptionTask; -import tools.docs.permissions.PermissionsListWriter; -import tools.docs.translations.TranslationPageGenerator; +import fr.xephi.authme.ClassCollector; +import fr.xephi.authme.TestHelper; import tools.utils.AutoToolTask; import tools.utils.ToolTask; +import java.util.List; import java.util.Scanner; -import java.util.Set; import java.util.function.Consumer; +import java.util.stream.Collectors; /** * Task that runs all tasks which update files in the docs folder. */ public class UpdateDocsTask implements AutoToolTask { - private static final Set> TASKS = ImmutableSet - .of(CommandPageCreater.class, HashAlgorithmsDescriptionTask.class, - PermissionsListWriter.class, TranslationPageGenerator.class); - @Override public String getTaskName() { return "updateDocs"; @@ -40,19 +34,18 @@ public class UpdateDocsTask implements AutoToolTask { }); } - private static ToolTask instantiateTask(Class clazz) { - try { - return clazz.newInstance(); - } catch (IllegalAccessException | InstantiationException e) { - throw new UnsupportedOperationException("Could not instantiate task class '" + clazz + "'", e); - } - } - - private static void executeTasks(Consumer taskRunner) { - for (Class taskClass : TASKS) { - ToolTask task = instantiateTask(taskClass); + private void executeTasks(Consumer taskRunner) { + for (ToolTask task : getDocTasks()) { System.out.println("\nRunning " + task.getTaskName() + "\n-------------------"); taskRunner.accept(task); } } + + private List getDocTasks() { + ClassCollector classCollector = + new ClassCollector(TestHelper.TEST_SOURCES_FOLDER, "tools/docs"); + return classCollector.getInstancesOfType(ToolTask.class).stream() + .filter(task -> task.getClass() != getClass()) + .collect(Collectors.toList()); + } } diff --git a/src/test/java/tools/docs/commands/CommandPageCreater.java b/src/test/java/tools/docs/commands/CommandPageCreater.java index eab18256..ecf98466 100644 --- a/src/test/java/tools/docs/commands/CommandPageCreater.java +++ b/src/test/java/tools/docs/commands/CommandPageCreater.java @@ -5,15 +5,15 @@ import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandInitializer; import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.permission.PermissionNode; +import tools.utils.AutoToolTask; import tools.utils.FileUtils; -import tools.utils.SimpleAutoTask; import tools.utils.TagValue.NestedTagValue; import tools.utils.TagValueHolder; import tools.utils.ToolsConstants; import java.util.Collection; -public class CommandPageCreater extends SimpleAutoTask { +public class CommandPageCreater implements AutoToolTask { private static final String OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "commands.md"; diff --git a/src/test/java/tools/docs/commands/commands.tpl.md b/src/test/java/tools/docs/commands/commands.tpl.md index c0f4da12..61018634 100644 --- a/src/test/java/tools/docs/commands/commands.tpl.md +++ b/src/test/java/tools/docs/commands/commands.tpl.md @@ -1,5 +1,5 @@ - + ## AuthMe Commands You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >` diff --git a/src/test/java/tools/docs/hashmethods/HashAlgorithmsDescriptionTask.java b/src/test/java/tools/docs/hashmethods/HashAlgorithmsDescriptionTask.java index d6ba721c..998214cf 100644 --- a/src/test/java/tools/docs/hashmethods/HashAlgorithmsDescriptionTask.java +++ b/src/test/java/tools/docs/hashmethods/HashAlgorithmsDescriptionTask.java @@ -1,8 +1,8 @@ package tools.docs.hashmethods; import fr.xephi.authme.security.HashAlgorithm; +import tools.utils.AutoToolTask; import tools.utils.FileUtils; -import tools.utils.SimpleAutoTask; import tools.utils.TagValue.NestedTagValue; import tools.utils.TagValueHolder; import tools.utils.ToolsConstants; @@ -14,7 +14,7 @@ import java.util.Map; * * @see fr.xephi.authme.security.HashAlgorithm */ -public class HashAlgorithmsDescriptionTask extends SimpleAutoTask { +public class HashAlgorithmsDescriptionTask implements AutoToolTask { private static final String CUR_FOLDER = ToolsConstants.TOOLS_SOURCE_ROOT + "docs/hashmethods/"; private static final String OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "hash_algorithms.md"; diff --git a/src/test/java/tools/docs/hashmethods/hash_algorithms.tpl.md b/src/test/java/tools/docs/hashmethods/hash_algorithms.tpl.md index 17431eb5..2f542b50 100644 --- a/src/test/java/tools/docs/hashmethods/hash_algorithms.tpl.md +++ b/src/test/java/tools/docs/hashmethods/hash_algorithms.tpl.md @@ -1,5 +1,5 @@ - + ## Hash Algorithms AuthMe supports the following hash algorithms for storing your passwords safely. diff --git a/src/test/java/tools/docs/permissions/PermissionsListWriter.java b/src/test/java/tools/docs/permissions/PermissionsListWriter.java index ffd418e2..4e2197ee 100644 --- a/src/test/java/tools/docs/permissions/PermissionsListWriter.java +++ b/src/test/java/tools/docs/permissions/PermissionsListWriter.java @@ -1,7 +1,7 @@ package tools.docs.permissions; +import tools.utils.AutoToolTask; import tools.utils.FileUtils; -import tools.utils.SimpleAutoTask; import tools.utils.TagValue.NestedTagValue; import tools.utils.TagValueHolder; import tools.utils.ToolsConstants; @@ -12,7 +12,7 @@ import java.util.Map; * Task responsible for formatting a permissions node list and * for writing it to a file if desired. */ -public class PermissionsListWriter extends SimpleAutoTask { +public class PermissionsListWriter implements AutoToolTask { private static final String TEMPLATE_FILE = ToolsConstants.TOOLS_SOURCE_ROOT + "docs/permissions/permission_nodes.tpl.md"; private static final String PERMISSIONS_OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "permission_nodes.md"; diff --git a/src/test/java/tools/docs/permissions/permission_nodes.tpl.md b/src/test/java/tools/docs/permissions/permission_nodes.tpl.md index 8d2a2b4f..8987f08b 100644 --- a/src/test/java/tools/docs/permissions/permission_nodes.tpl.md +++ b/src/test/java/tools/docs/permissions/permission_nodes.tpl.md @@ -1,5 +1,5 @@ - + ## AuthMe Permission Nodes The following are the permission nodes that are currently supported by the latest dev builds. diff --git a/src/test/java/tools/docs/translations/TranslationPageGenerator.java b/src/test/java/tools/docs/translations/TranslationPageGenerator.java index 80619ba5..75232d28 100644 --- a/src/test/java/tools/docs/translations/TranslationPageGenerator.java +++ b/src/test/java/tools/docs/translations/TranslationPageGenerator.java @@ -2,8 +2,8 @@ package tools.docs.translations; import com.google.common.collect.ImmutableMap; import tools.docs.translations.TranslationsGatherer.TranslationInfo; +import tools.utils.AutoToolTask; import tools.utils.FileUtils; -import tools.utils.SimpleAutoTask; import tools.utils.TagValue.NestedTagValue; import tools.utils.TagValueHolder; import tools.utils.ToolsConstants; @@ -17,7 +17,7 @@ import static com.google.common.base.Objects.firstNonNull; /** * Generates the translations page in docs. */ -public class TranslationPageGenerator extends SimpleAutoTask { +public class TranslationPageGenerator implements AutoToolTask { private static final String DOCS_PAGE = ToolsConstants.DOCS_FOLDER + "translations.md"; private static final String TEMPLATE_FILE = ToolsConstants.TOOLS_SOURCE_ROOT + "docs/translations/translations.tpl.md"; diff --git a/src/test/java/tools/docs/translations/translations.tpl.md b/src/test/java/tools/docs/translations/translations.tpl.md index 199d4029..5308b655 100644 --- a/src/test/java/tools/docs/translations/translations.tpl.md +++ b/src/test/java/tools/docs/translations/translations.tpl.md @@ -1,5 +1,5 @@ - + # AuthMe Translations The following translations are available in AuthMe. Set `messagesLanguage` to the language code diff --git a/src/test/java/tools/filegeneration/GeneratePluginYml.java b/src/test/java/tools/filegeneration/GeneratePluginYml.java index 633c5aac..3b5737be 100644 --- a/src/test/java/tools/filegeneration/GeneratePluginYml.java +++ b/src/test/java/tools/filegeneration/GeneratePluginYml.java @@ -9,8 +9,8 @@ import fr.xephi.authme.permission.PermissionNode; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import tools.docs.permissions.PermissionNodesGatherer; +import tools.utils.AutoToolTask; import tools.utils.FileUtils; -import tools.utils.SimpleAutoTask; import tools.utils.ToolsConstants; import java.io.StringReader; @@ -26,7 +26,7 @@ import java.util.stream.Collectors; /** * Generates the command and permission section of plugin.yml. */ -public class GeneratePluginYml extends SimpleAutoTask { +public class GeneratePluginYml implements AutoToolTask { private static final String PLUGIN_YML_FILE = ToolsConstants.MAIN_RESOURCES_ROOT + "plugin.yml"; diff --git a/src/test/java/tools/utils/AutoToolTask.java b/src/test/java/tools/utils/AutoToolTask.java index b635fe5f..61b909a5 100644 --- a/src/test/java/tools/utils/AutoToolTask.java +++ b/src/test/java/tools/utils/AutoToolTask.java @@ -1,5 +1,7 @@ package tools.utils; +import java.util.Scanner; + /** * Interface for tasks that can be run automatically, i.e. without any user input. */ @@ -10,4 +12,9 @@ public interface AutoToolTask extends ToolTask { */ void executeDefault(); + @Override + default void execute(Scanner scanner) { + executeDefault(); + } + } diff --git a/src/test/java/tools/utils/SimpleAutoTask.java b/src/test/java/tools/utils/SimpleAutoTask.java deleted file mode 100644 index 4c0c936d..00000000 --- a/src/test/java/tools/utils/SimpleAutoTask.java +++ /dev/null @@ -1,15 +0,0 @@ -package tools.utils; - -import java.util.Scanner; - -/** - * Abstract class for auto tool tasks that perform exactly the same action for - * {@link ToolTask#execute(Scanner)} and {@link AutoToolTask#executeDefault()}. - */ -public abstract class SimpleAutoTask implements AutoToolTask { - - @Override - public final void execute(Scanner scanner) { - executeDefault(); - } -} diff --git a/src/test/java/tools/utils/ToolsConstants.java b/src/test/java/tools/utils/ToolsConstants.java index 5986c378..e7ba3e05 100644 --- a/src/test/java/tools/utils/ToolsConstants.java +++ b/src/test/java/tools/utils/ToolsConstants.java @@ -9,9 +9,6 @@ public final class ToolsConstants { public static final String MAIN_RESOURCES_ROOT = "src/main/resources/"; - // Add specific `fr.xephi.authme` package as not to include the tool tasks in the `tools` package - public static final String TEST_SOURCE_ROOT = "src/test/java/fr/xephi/authme"; - public static final String TOOLS_SOURCE_ROOT = "src/test/java/tools/"; public static final String DOCS_FOLDER = "docs/"; From b7a7d5b3bd5583dced41681096577451c1c8e86b Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 23 Oct 2016 18:29:00 +0200 Subject: [PATCH 07/67] #989 Create configuration docs page - Create tool task to generate a doc page with the generated config.yml - Rename tools.utils.FileUtils to FileIoUtils to avoid naming conflict with fr.xephi.authme.utils.FileUtils - Make all doc tasks output a success message at the end - Update all docs pages that have changed --- docs/commands.md | 8 +- docs/config.md | 451 ++++++++++++++++++ docs/translations.md | 52 +- .../docs/commands/CommandPageCreater.java | 4 +- .../docs/config/UpdateConfigPageTask.java | 49 ++ src/test/java/tools/docs/config/config.tpl.md | 16 + .../HashAlgorithmsDescriptionTask.java | 5 +- .../permissions/PermissionNodesGatherer.java | 4 +- .../permissions/PermissionsListWriter.java | 5 +- .../TranslationPageGenerator.java | 5 +- .../filegeneration/GeneratePluginYml.java | 6 +- .../tools/messages/MessageFileVerifier.java | 6 +- .../translation/ImportMessagesTask.java | 6 +- .../translation/WriteAllExportsTask.java | 4 +- .../{FileUtils.java => FileIoUtils.java} | 12 +- 15 files changed, 577 insertions(+), 56 deletions(-) create mode 100644 docs/config.md create mode 100644 src/test/java/tools/docs/config/UpdateConfigPageTask.java create mode 100644 src/test/java/tools/docs/config/config.tpl.md rename src/test/java/tools/utils/{FileUtils.java => FileIoUtils.java} (86%) diff --git a/docs/commands.md b/docs/commands.md index 4dd070fd..b9f68054 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -1,5 +1,5 @@ - + ## AuthMe Commands You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >` @@ -63,7 +63,8 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`). - **/changepassword** <oldPassword> <newPassword>: Command to change your password using AuthMeReloaded.
Requires `authme.player.changepassword` - **/changepassword help** [query]: View detailed help for /changepassword commands. -- **/email**: The AuthMeReloaded Email command base. +- **/email**: The AuthMeReloaded email command base. +- **/email show**: Show your current email address. - **/email add** <email> <verifyEmail>: Add a new email address to your account.
Requires `authme.player.email.add` - **/email change** <oldEmail> <newEmail>: Change an email address of your account. @@ -75,7 +76,6 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
Requires `authme.player.captcha` - **/captcha help** [query]: View detailed help for /captcha commands. - --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 16 21:39:08 CEST 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 23 18:25:12 CEST 2016 diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 00000000..95e1de39 --- /dev/null +++ b/docs/config.md @@ -0,0 +1,451 @@ + + + +## AuthMe Configuration +The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, +with which you can configure various settings. This following is the initial contents of +the generated config.yml file. + +```yml + +DataSource: + # What type of database do you want to use? + # Valid values: sqlite, mysql + backend: 'SQLITE' + # Enable database caching, should improve database performance + caching: true + # Database host address + mySQLHost: '127.0.0.1' + # Database port + mySQLPort: '3306' + # Username about Database Connection Infos + mySQLUsername: 'authme' + # Password about Database Connection Infos + mySQLPassword: '12345' + # Database Name, use with converters or as SQLITE database name + mySQLDatabase: 'authme' + # Table of the database + mySQLTablename: 'authme' + # Column of IDs to sort data + mySQLColumnId: 'id' + # Column for storing or checking players nickname + mySQLColumnName: 'username' + # Column for storing or checking players RealName + mySQLRealName: 'realname' + # Column for storing players passwords + mySQLColumnPassword: 'password' + # Column for storing players emails + mySQLColumnEmail: 'email' + # Column for storing if a player is logged in or not + mySQLColumnLogged: 'isLogged' + # Column for storing players ips + mySQLColumnIp: 'ip' + # Column for storing players lastlogins + mySQLColumnLastLogin: 'lastlogin' + # Column for storing player LastLocation - X + mySQLlastlocX: 'x' + # Column for storing player LastLocation - Y + mySQLlastlocY: 'y' + # Column for storing player LastLocation - Z + mySQLlastlocZ: 'z' + # Column for storing player LastLocation - World Name + mySQLlastlocWorld: 'world' + # Overrides the size of the DB Connection Pool, -1 = Auto + poolSize: -1 +ExternalBoardOptions: + # Column for storing players passwords salts + mySQLColumnSalt: '' + # Column for storing players groups + mySQLColumnGroup: '' + # -1 means disabled. If you want that only activated players + # can log into your server, you can set here the group number + # of unactivated users, needed for some forum/CMS support + nonActivedUserGroup: -1 + # Other MySQL columns where we need to put the username (case-sensitive) + mySQLOtherUsernameColumns: [] + # How much log2 rounds needed in BCrypt (do not change if you do not know what it does) + bCryptLog2Round: 10 + # phpBB table prefix defined during the phpBB installation process + phpbbTablePrefix: 'phpbb_' + # phpBB activated group ID; 2 is the default registered group defined by phpBB + phpbbActivatedGroupId: 2 + # Wordpress prefix defined during WordPress installation + wordpressTablePrefix: 'wp_' +Converter: + Rakamak: + # Rakamak file name + fileName: 'users.rak' + # Rakamak use IP? + useIP: false + # Rakamak IP file name + ipFileName: 'UsersIp.rak' + CrazyLogin: + # CrazyLogin database file name + fileName: 'accounts.db' +settings: + sessions: + # Do you want to enable the session feature? + # If enabled, when a player authenticates successfully, + # his IP and his nickname is saved. + # The next time the player joins the server, if his IP + # is the same as last time and the timeout hasn't + # expired, he will not need to authenticate. + enabled: false + # After how many minutes should a session expire? + # Remember that sessions will end only after the timeout, and + # if the player's IP has changed but the timeout hasn't expired, + # the player will be kicked from the server due to invalid session + timeout: 10 + # Should the session expire if the player tries to log in with + # another IP address? + sessionExpireOnIpChange: true + # Message language, available: en, de, br, cz, pl, fr, ru, hu, sk, es, zhtw, fi, zhcn, lt, it, ko, pt + messagesLanguage: 'en' + restrictions: + # Keeps collisions disabled for logged players + # Works only with MC 1.9 + keepCollisionsDisabled: false + # Can not authenticated players chat? + # Keep in mind that this feature also blocks all commands not + # listed in the list below. + allowChat: false + # Hide the chat log from players who are not authenticated? + hideChat: false + # Allowed commands for unauthenticated players + allowCommands: + - '/login' + - '/register' + - '/l' + - '/reg' + - '/email' + - '/captcha' + # Max number of allowed registrations per IP + # The value 0 means an unlimited number of registrations! + maxRegPerIp: 1 + # Minimum allowed username length + minNicknameLength: 4 + # Maximum allowed username length + maxNicknameLength: 16 + # When this setting is enabled, online players can't be kicked out + # due to "Logged in from another Location" + # This setting will prevent potential security exploits. + ForceSingleSession: true + ForceSpawnLocOnJoin: + # If enabled, every player that spawn in one of the world listed in "ForceSpawnLocOnJoin.worlds" + # will be teleported to the spawnpoint after successful authentication. + # The quit location of the player will be overwritten. + # This is different from "teleportUnAuthedToSpawn" that teleport player + # to the spawnpoint on join. + enabled: false + # WorldNames where we need to force the spawn location + # Case-sensitive! + worlds: + - 'world' + - 'world_nether' + - 'world_the_end' + # This option will save the quit location of the players. + SaveQuitLocation: false + # To activate the restricted user feature you need + # to enable this option and configure the AllowedRestrictedUser field. + AllowRestrictedUser: false + # The restricted user feature will kick players listed below + # if they don't match the defined IP address. + # Example: + # AllowedRestrictedUser: + # - playername;127.0.0.1 + AllowedRestrictedUser: [] + # Should unregistered players be kicked immediately? + kickNonRegistered: false + # Should players be kicked on wrong password? + kickOnWrongPassword: false + # Should not logged in players be teleported to the spawn? + # After the authentication they will be teleported back to + # their normal position. + teleportUnAuthedToSpawn: false + # Can unregistered players walk around? + allowMovement: false + # Should not authenticated players have speed = 0? + # This will reset the fly/walk speed to default value after the login. + removeSpeed: true + # After how many seconds should players who fail to login or register + # be kicked? Set to 0 to disable. + timeout: 30 + # Regex syntax of allowed characters in the player name. + allowedNicknameCharacters: '[a-zA-Z0-9_]*' + # How far can unregistered players walk? + # Set to 0 for unlimited radius + allowedMovementRadius: 100 + # Enable double check of password when you register + # when it's true, registration requires that kind of command: + # /register + enablePasswordConfirmation: true + # Should we protect the player inventory before logging in? Requires ProtocolLib. + ProtectInventoryBeforeLogIn: true + # Should we deny the tabcomplete feature before logging in? Requires ProtocolLib. + DenyTabCompleteBeforeLogin: true + # Should we display all other accounts from a player when he joins? + # permission: /authme.admin.accounts + displayOtherAccounts: true + # Ban ip when the ip is not the ip registered in database + banUnsafedIP: false + # Spawn priority; values: authme, essentials, multiverse, default + spawnPriority: 'authme,essentials,multiverse,default' + # Maximum Login authorized by IP + maxLoginPerIp: 0 + # Maximum Join authorized by IP + maxJoinPerIp: 0 + # AuthMe will NEVER teleport players if set to true! + noTeleport: false + # Regex syntax for allowed chars in passwords + allowedPasswordCharacters: '[\x21-\x7E]*' + # Log level: INFO, FINE, DEBUG. Use INFO for general messages, + # FINE for some additional detailed ones (like password failed), + # and DEBUG for debugging + logLevel: 'FINE' + # By default we schedule async tasks when talking to the database + # If you want typical communication with the database to happen synchronously, set this to false + useAsyncTasks: true + GameMode: + # Force survival gamemode when player joins? + ForceSurvivalMode: false + unrestrictions: + # Below you can list all account names that + # AuthMe will ignore for registration or login, configure it + # at your own risk!! Remember that if you are going to add + # nickname with [], you have to delimit name with ' '. + # this option add compatibility with BuildCraft and some + # other mods. + # It is case-sensitive! + UnrestrictedName: [] + security: + # Minimum length of password + minPasswordLength: 5 + # Maximum length of password + passwordMaxLength: 30 + # This is a very important option: every time a player joins the server, + # if they are registered, AuthMe will switch him to unLoggedInGroup. + # This should prevent all major exploits. + # You can set up your permission plugin with this special group to have no permissions, + # or only permission to chat (or permission to send private messages etc.). + # The better way is to set up this group with few permissions, so if a player + # tries to exploit an account they can do only what you've defined for the group. + # After, a logged in player will be moved to his correct permissions group! + # Please note that the group name is case-sensitive, so 'admin' is different from 'Admin' + # Otherwise your group will be wiped and the player will join in the default group []! + # Example unLoggedinGroup: NotLogged + unLoggedinGroup: 'unLoggedinGroup' + # Possible values: MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB, + # MYBB, IPB3, PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512, + # DOUBLEMD5, PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only) + passwordHash: 'SHA256' + # Salt length for the SALTED2MD5 MD5(MD5(password)+salt) + doubleMD5SaltLength: 8 + # If password checking return false, do we need to check with all + # other password algorithm to check an old password? + # AuthMe will update the password to the new password hash + supportOldPasswordHash: false + # Prevent unsafe passwords from being used; put them in lowercase! + # unsafePasswords: + # - '123456' + # - 'password' + unsafePasswords: + - '123456' + - 'password' + - 'qwerty' + - '12345' + - '54321' + - '123456789' + registration: + # Enable registration on the server? + enabled: true + # Send every X seconds a message to a player to + # remind him that he has to login/register + messageInterval: 5 + # Only registered and logged in players can play. + # See restrictions for exceptions + force: true + # Do we replace password registration by an email registration method? + enableEmailRegistrationSystem: false + # Enable double check of email when you register + # when it's true, registration requires that kind of command: + # /register + doubleEmailCheck: false + # Do we force kick a player after a successful registration? + # Do not use with login feature below + forceKickAfterRegister: false + # Does AuthMe need to enforce a /login after a successful registration? + forceLoginAfterRegister: false + # Force these commands after /login, without any '/', use %p to replace with player name + forceCommands: [] + # Force these commands after /login as service console, without any '/'. Use %p to replace with player name + forceCommandsAsConsole: [] + # Force these commands after /register, without any '/', use %p to replace with player name + forceRegisterCommands: [] + # Force these commands after /register as a server console, without any '/'. Use %p to replace with player name + forceRegisterCommandsAsConsole: [] + # Enable to display the welcome message (welcome.txt) after a login + # You can use colors in this welcome.txt + some replaced strings: + # {PLAYER}: player name, {ONLINE}: display number of online players, {MAXPLAYERS}: display server slots, + # {IP}: player ip, {LOGINS}: number of players logged, {WORLD}: player current world, {SERVER}: server name + # {VERSION}: get current bukkit version, {COUNTRY}: player country + useWelcomeMessage: true + # Do we need to broadcast the welcome message to all server or only to the player? set true for server or false for player + broadcastWelcomeMessage: false + # Should we delay the join message and display it once the player has logged in? + delayJoinMessage: false + # Should we remove the leave messages of unlogged users? + removeUnloggedLeaveMessage: false + # Should we remove join messages altogether? + removeJoinMessage: false + # Should we remove leave messages altogether? + removeLeaveMessage: false + # Do we need to add potion effect Blinding before login/reigster? + applyBlindEffect: false + # Do we need to prevent people to login with another case? + # If Xephi is registered, then Xephi can login, but not XEPHI/xephi/XePhI + preventOtherCase: false +permission: + # Take care with this option; if you want + # to use group switching of AuthMe + # for unloggedIn players, set this setting to true. + # Default is false. + EnablePermissionCheck: false +Email: + # Email SMTP server host + mailSMTP: 'smtp.gmail.com' + # Email SMTP server port + mailPort: 465 + # Email account which sends the mails + mailAccount: '' + # Email account password + mailPassword: '' + # Custom sender name, replacing the mailAccount name in the email + mailSenderName: '' + # Recovery password length + RecoveryPasswordLength: 8 + # Mail Subject + mailSubject: 'Your new AuthMe password' + # Like maxRegPerIP but with email + maxRegPerEmail: 1 + # Recall players to add an email? + recallPlayers: false + # Delay in minute for the recall scheduler + delayRecall: 5 + # Blacklist these domains for emails + emailBlacklisted: + - '10minutemail.com' + # Whitelist ONLY these domains for emails + emailWhitelisted: [] + # Send the new password drawn in an image? + generateImage: false + # The OAuth2 token + emailOauth2Token: '' +Hooks: + # Do we need to hook with multiverse for spawn checking? + multiverse: true + # Do we need to hook with BungeeCord? + bungeecord: false + # Send player to this BungeeCord server after register/login + sendPlayerTo: '' + # Do we need to disable Essentials SocialSpy on join? + disableSocialSpy: true + # Do we need to force /motd Essentials command on join? + useEssentialsMotd: false +GroupOptions: + # Unregistered permission group + UnregisteredPlayerGroup: '' + # Registered permission group + RegisteredPlayerGroup: '' +Protection: + # Enable some servers protection (country based login, antibot) + enableProtection: false + # Apply the protection also to registered usernames + enableProtectionRegistered: true + # Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes + # PLEASE USE QUOTES! + countries: + - 'US' + - 'GB' + # Countries not allowed to join the server and register + # PLEASE USE QUOTES! + countriesBlacklist: + - 'A1' + # Do we need to enable automatic antibot system? + enableAntiBot: true + # Max number of players allowed to login in 5 secs before the AntiBot system is enabled automatically + antiBotSensibility: 10 + # Duration in minutes of the antibot automatic system + antiBotDuration: 10 + # Delay in seconds before the antibot activation + antiBotDelay: 60 +Purge: + # If enabled, AuthMe automatically purges old, unused accounts + useAutoPurge: false + # Number of Days an account become Unused + daysBeforeRemovePlayer: 60 + # Do we need to remove the player.dat file during purge process? + removePlayerDat: false + # Do we need to remove the Essentials/userdata/player.yml file during purge process? + removeEssentialsFile: false + # World where are players.dat stores + defaultWorld: 'world' + # Do we need to remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge process ? + removeLimitedCreativesInventories: false + # Do we need to remove the AntiXRayData/PlayerData/player file during purge process? + removeAntiXRayFile: false + # Do we need to remove permissions? + removePermissions: false +Security: + SQLProblem: + # Stop the server if we can't contact the sql database + # Take care with this, if you set this to false, + # AuthMe will automatically disable and the server won't be protected! + stopServer: true + ReloadCommand: + # /reload support + useReloadCommandSupport: true + console: + # Remove passwords from console? + removePassword: true + # Copy AuthMe log output in a separate file as well? + logConsole: true + captcha: + # Enable captcha when a player uses wrong password too many times + useCaptcha: false + # Max allowed tries before a captcha is required + maxLoginTry: 5 + # Captcha length + captchaLength: 5 + tempban: + # Tempban a user's IP address if they enter the wrong password too many times + enableTempban: false + # How many times a user can attempt to login before their IP being tempbanned + maxLoginTries: 10 + # The length of time a IP address will be tempbanned in minutes + # Default: 480 minutes, or 8 hours + tempbanLength: 480 + # How many minutes before resetting the count for failed logins by IP and username + # Default: 480 minutes (8 hours) + minutesBeforeCounterReset: 480 + recoveryCode: + # Number of characters a recovery code should have (0 to disable) + length: 8 + # How many hours is a recovery code valid for? + validForHours: 4 +BackupSystem: + # Enable or disable automatic backup + ActivateBackup: false + # Set backup at every start of server + OnServerStart: false + # Set backup at every stop of server + OnServerStop: true + # Windows only mysql installation Path + MysqlWindowsPath: 'C:\Program Files\MySQL\MySQL Server 5.1\' +``` + +To change settings on a running server, save your changes to config.yml and use +`/authme reload`. + +--- + +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 23 18:25:12 CEST 2016 diff --git a/docs/translations.md b/docs/translations.md index c261bb8f..c4288f15 100644 --- a/docs/translations.md +++ b/docs/translations.md @@ -1,5 +1,5 @@ - + # AuthMe Translations The following translations are available in AuthMe. Set `messagesLanguage` to the language code @@ -8,32 +8,32 @@ in your config.yml to use the language, or use another language code to start a Code | Language | Translated |   ---- | -------- | ---------: | ------ [en](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_en.yml) | English | 100% | bar -[bg](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_bg.yml) | Bulgarian | 73% | bar -[br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 100% | bar -[cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 91% | bar -[de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 97% | bar -[es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 100% | bar -[eu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eu.yml) | Basque | 66% | bar -[fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 70% | bar -[fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 97% | bar -[gl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_gl.yml) | Galician | 74% | bar -[hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 100% | bar -[id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 74% | bar +[bg](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_bg.yml) | Bulgarian | 71% | bar +[br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 97% | bar +[cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 88% | bar +[de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 95% | bar +[es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 97% | bar +[eu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eu.yml) | Basque | 64% | bar +[fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 68% | bar +[fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 95% | bar +[gl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_gl.yml) | Galician | 72% | bar +[hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 97% | bar +[id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 72% | bar [it](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_it.yml) | Italian | 100% | bar -[ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 76% | bar -[lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Latvian | 57% | bar -[nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 80% | bar -[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 95% | bar -[pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 91% | bar -[ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 97% | bar -[sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 50% | bar -[tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 85% | bar -[uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 97% | bar -[vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 85% | bar -[zhcn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhcn.yml) | Chinese (China) | 85% | bar -[zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 85% | bar -[zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 85% | bar +[ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 74% | bar +[lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Latvian | 55% | bar +[nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 78% | bar +[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 92% | bar +[pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 88% | bar +[ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 95% | bar +[sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 49% | bar +[tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 83% | bar +[uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 95% | bar +[vn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_vn.yml) | Vietnamese | 83% | bar +[zhcn](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhcn.yml) | Chinese (China) | 83% | bar +[zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 83% | bar +[zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 83% | bar --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 09 09:42:48 CEST 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 23 18:25:14 CEST 2016 diff --git a/src/test/java/tools/docs/commands/CommandPageCreater.java b/src/test/java/tools/docs/commands/CommandPageCreater.java index ecf98466..ff1500a7 100644 --- a/src/test/java/tools/docs/commands/CommandPageCreater.java +++ b/src/test/java/tools/docs/commands/CommandPageCreater.java @@ -6,7 +6,7 @@ import fr.xephi.authme.command.CommandInitializer; import fr.xephi.authme.command.CommandUtils; import fr.xephi.authme.permission.PermissionNode; import tools.utils.AutoToolTask; -import tools.utils.FileUtils; +import tools.utils.FileIoUtils; import tools.utils.TagValue.NestedTagValue; import tools.utils.TagValueHolder; import tools.utils.ToolsConstants; @@ -29,7 +29,7 @@ public class CommandPageCreater implements AutoToolTask { NestedTagValue commandTags = new NestedTagValue(); addCommandsInfo(commandTags, baseCommands); - FileUtils.generateFileFromTemplate( + FileIoUtils.generateFileFromTemplate( ToolsConstants.TOOLS_SOURCE_ROOT + "docs/commands/commands.tpl.md", OUTPUT_FILE, TagValueHolder.create().put("commands", commandTags)); diff --git a/src/test/java/tools/docs/config/UpdateConfigPageTask.java b/src/test/java/tools/docs/config/UpdateConfigPageTask.java new file mode 100644 index 00000000..f9a249a7 --- /dev/null +++ b/src/test/java/tools/docs/config/UpdateConfigPageTask.java @@ -0,0 +1,49 @@ +package tools.docs.config; + +import com.github.authme.configme.SettingsManager; +import com.github.authme.configme.resource.YamlFileResource; +import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever; +import fr.xephi.authme.util.FileUtils; +import tools.utils.AutoToolTask; +import tools.utils.FileIoUtils; +import tools.utils.TagValueHolder; +import tools.utils.ToolsConstants; + +import java.io.File; +import java.io.IOException; + +/** + * Task for updating the config docs page. + */ +public class UpdateConfigPageTask implements AutoToolTask { + + private static final String TEMPLATE_FILE = ToolsConstants.TOOLS_SOURCE_ROOT + "docs/config/config.tpl.md"; + private static final String OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "config.md"; + + @Override + public String getTaskName() { + return "updateConfigPage"; + } + + @Override + public void executeDefault() { + File config = null; + try { + // Create empty temporary .yml file and save the config to it + config = File.createTempFile("authme-config-", ".yml"); + SettingsManager settingsManager = new SettingsManager( + new YamlFileResource(config), null, AuthMeSettingsRetriever.buildConfigurationData()); + settingsManager.save(); + + // Get the contents and generate template file + TagValueHolder tagValueHolder = TagValueHolder.create() + .put("config", FileIoUtils.readFromFile(config.toPath())); + FileIoUtils.generateFileFromTemplate(TEMPLATE_FILE, OUTPUT_FILE, tagValueHolder); + System.out.println("Wrote to '" + OUTPUT_FILE + "'"); + } catch (IOException e) { + throw new IllegalStateException(e); + } finally { + FileUtils.delete(config); + } + } +} diff --git a/src/test/java/tools/docs/config/config.tpl.md b/src/test/java/tools/docs/config/config.tpl.md new file mode 100644 index 00000000..25cf8c2c --- /dev/null +++ b/src/test/java/tools/docs/config/config.tpl.md @@ -0,0 +1,16 @@ + + + +## AuthMe Configuration +The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, +with which you can configure various settings. This following is the initial contents of +the generated config.yml file. + +```yml +{config} +``` + +To change settings on a running server, save your changes to config.yml and use +`/authme reload`. + +{gen_footer} diff --git a/src/test/java/tools/docs/hashmethods/HashAlgorithmsDescriptionTask.java b/src/test/java/tools/docs/hashmethods/HashAlgorithmsDescriptionTask.java index 998214cf..b21d7fda 100644 --- a/src/test/java/tools/docs/hashmethods/HashAlgorithmsDescriptionTask.java +++ b/src/test/java/tools/docs/hashmethods/HashAlgorithmsDescriptionTask.java @@ -2,7 +2,7 @@ package tools.docs.hashmethods; import fr.xephi.authme.security.HashAlgorithm; import tools.utils.AutoToolTask; -import tools.utils.FileUtils; +import tools.utils.FileIoUtils; import tools.utils.TagValue.NestedTagValue; import tools.utils.TagValueHolder; import tools.utils.ToolsConstants; @@ -28,7 +28,8 @@ public class HashAlgorithmsDescriptionTask implements AutoToolTask { // Write to the docs file TagValueHolder tags = TagValueHolder.create().put("algorithms", methodRows); - FileUtils.generateFileFromTemplate(CUR_FOLDER + "hash_algorithms.tpl.md", OUTPUT_FILE, tags); + FileIoUtils.generateFileFromTemplate(CUR_FOLDER + "hash_algorithms.tpl.md", OUTPUT_FILE, tags); + System.out.println("Wrote to '" + OUTPUT_FILE + "'"); } private static NestedTagValue constructMethodRows(Map descriptions) { diff --git a/src/test/java/tools/docs/permissions/PermissionNodesGatherer.java b/src/test/java/tools/docs/permissions/PermissionNodesGatherer.java index 034677cb..e3635512 100644 --- a/src/test/java/tools/docs/permissions/PermissionNodesGatherer.java +++ b/src/test/java/tools/docs/permissions/PermissionNodesGatherer.java @@ -2,7 +2,7 @@ package tools.docs.permissions; import fr.xephi.authme.ClassCollector; import fr.xephi.authme.permission.PermissionNode; -import tools.utils.FileUtils; +import tools.utils.FileIoUtils; import tools.utils.ToolsConstants; import java.util.EnumSet; @@ -103,7 +103,7 @@ public class PermissionNodesGatherer { */ private static & PermissionNode> String getSourceForClass(Class clazz) { String classFile = ToolsConstants.MAIN_SOURCE_ROOT + clazz.getName().replace(".", "/") + ".java"; - return FileUtils.readFromFile(classFile); + return FileIoUtils.readFromFile(classFile); } } diff --git a/src/test/java/tools/docs/permissions/PermissionsListWriter.java b/src/test/java/tools/docs/permissions/PermissionsListWriter.java index 4e2197ee..797e26e7 100644 --- a/src/test/java/tools/docs/permissions/PermissionsListWriter.java +++ b/src/test/java/tools/docs/permissions/PermissionsListWriter.java @@ -1,7 +1,7 @@ package tools.docs.permissions; import tools.utils.AutoToolTask; -import tools.utils.FileUtils; +import tools.utils.FileIoUtils; import tools.utils.TagValue.NestedTagValue; import tools.utils.TagValueHolder; import tools.utils.ToolsConstants; @@ -27,9 +27,8 @@ public class PermissionsListWriter implements AutoToolTask { final NestedTagValue permissionsTagValue = generatePermissionsList(); TagValueHolder tags = TagValueHolder.create().put("nodes", permissionsTagValue); - FileUtils.generateFileFromTemplate(TEMPLATE_FILE, PERMISSIONS_OUTPUT_FILE, tags); + FileIoUtils.generateFileFromTemplate(TEMPLATE_FILE, PERMISSIONS_OUTPUT_FILE, tags); System.out.println("Wrote to '" + PERMISSIONS_OUTPUT_FILE + "'"); - System.out.println("Before committing, please verify the output!"); } private static NestedTagValue generatePermissionsList() { diff --git a/src/test/java/tools/docs/translations/TranslationPageGenerator.java b/src/test/java/tools/docs/translations/TranslationPageGenerator.java index 75232d28..240e7a64 100644 --- a/src/test/java/tools/docs/translations/TranslationPageGenerator.java +++ b/src/test/java/tools/docs/translations/TranslationPageGenerator.java @@ -3,7 +3,7 @@ package tools.docs.translations; import com.google.common.collect.ImmutableMap; import tools.docs.translations.TranslationsGatherer.TranslationInfo; import tools.utils.AutoToolTask; -import tools.utils.FileUtils; +import tools.utils.FileIoUtils; import tools.utils.TagValue.NestedTagValue; import tools.utils.TagValueHolder; import tools.utils.ToolsConstants; @@ -57,7 +57,8 @@ public class TranslationPageGenerator implements AutoToolTask { } TagValueHolder tags = TagValueHolder.create().put("languages", translationValuesHolder); - FileUtils.generateFileFromTemplate(TEMPLATE_FILE, DOCS_PAGE, tags); + FileIoUtils.generateFileFromTemplate(TEMPLATE_FILE, DOCS_PAGE, tags); + System.out.println("Wrote to '" + DOCS_PAGE + "'"); } /** diff --git a/src/test/java/tools/filegeneration/GeneratePluginYml.java b/src/test/java/tools/filegeneration/GeneratePluginYml.java index 3b5737be..b4a017c6 100644 --- a/src/test/java/tools/filegeneration/GeneratePluginYml.java +++ b/src/test/java/tools/filegeneration/GeneratePluginYml.java @@ -10,7 +10,7 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import tools.docs.permissions.PermissionNodesGatherer; import tools.utils.AutoToolTask; -import tools.utils.FileUtils; +import tools.utils.FileIoUtils; import tools.utils.ToolsConstants; import java.io.StringReader; @@ -46,7 +46,7 @@ public class GeneratePluginYml implements AutoToolTask { configuration.set("commands", generateCommands()); configuration.set("permissions", generatePermissions()); - FileUtils.writeToFile(PLUGIN_YML_FILE, + FileIoUtils.writeToFile(PLUGIN_YML_FILE, pluginYmlStart + "\n" + configuration.saveToString()); } @@ -63,7 +63,7 @@ public class GeneratePluginYml implements AutoToolTask { * @return file configuration with the lower part of the plugin.yml file */ private FileConfiguration loadPartialPluginYmlFile() { - List pluginYmlLines = FileUtils.readLinesFromFile(Paths.get(PLUGIN_YML_FILE)); + List pluginYmlLines = FileIoUtils.readLinesFromFile(Paths.get(PLUGIN_YML_FILE)); int lineNr = 0; for (String line : pluginYmlLines) { if (line.equals("commands:")) { diff --git a/src/test/java/tools/messages/MessageFileVerifier.java b/src/test/java/tools/messages/MessageFileVerifier.java index f0be6bb4..b151228c 100644 --- a/src/test/java/tools/messages/MessageFileVerifier.java +++ b/src/test/java/tools/messages/MessageFileVerifier.java @@ -8,7 +8,7 @@ import com.google.common.collect.Multimap; import fr.xephi.authme.message.MessageKey; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import tools.utils.FileUtils; +import tools.utils.FileIoUtils; import java.io.File; import java.util.ArrayList; @@ -104,7 +104,7 @@ public class MessageFileVerifier { * @param defaultMessages The collection of default messages */ public void addMissingKeys(FileConfiguration defaultMessages) { - final List fileLines = FileUtils.readLinesFromFile(messagesFile.toPath()); + final List fileLines = FileIoUtils.readLinesFromFile(messagesFile.toPath()); List keysToAdd = new ArrayList<>(); for (MissingKey entry : missingKeys) { @@ -135,7 +135,7 @@ public class MessageFileVerifier { addCommentForMissingTags(fileLines, key, entry.getValue()); } - FileUtils.writeToFile(messagesFile.toPath(), String.join("\n", fileLines)); + FileIoUtils.writeToFile(messagesFile.toPath(), String.join("\n", fileLines)); } /** diff --git a/src/test/java/tools/messages/translation/ImportMessagesTask.java b/src/test/java/tools/messages/translation/ImportMessagesTask.java index c70caaa3..765c49f1 100644 --- a/src/test/java/tools/messages/translation/ImportMessagesTask.java +++ b/src/test/java/tools/messages/translation/ImportMessagesTask.java @@ -7,7 +7,7 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import tools.messages.MessageFileVerifier; import tools.messages.VerifyMessagesTask; -import tools.utils.FileUtils; +import tools.utils.FileIoUtils; import tools.utils.ToolTask; import tools.utils.ToolsConstants; @@ -108,9 +108,9 @@ public class ImportMessagesTask implements ToolTask { * @param file The file whose to-do comments should be removed */ private static void removeAllTodoComments(String file) { - String contents = FileUtils.readFromFile(file); + String contents = FileIoUtils.readFromFile(file); String regex = "^# TODO .*$"; contents = Pattern.compile(regex, Pattern.MULTILINE).matcher(contents).replaceAll(""); - FileUtils.writeToFile(file, contents); + FileIoUtils.writeToFile(file, contents); } } diff --git a/src/test/java/tools/messages/translation/WriteAllExportsTask.java b/src/test/java/tools/messages/translation/WriteAllExportsTask.java index f5f3825b..f0faf3b0 100644 --- a/src/test/java/tools/messages/translation/WriteAllExportsTask.java +++ b/src/test/java/tools/messages/translation/WriteAllExportsTask.java @@ -2,7 +2,7 @@ package tools.messages.translation; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import tools.utils.FileUtils; +import tools.utils.FileIoUtils; import tools.utils.ToolsConstants; import java.io.File; @@ -31,7 +31,7 @@ public class WriteAllExportsTask extends ExportMessagesTask { for (File file : messageFiles) { String code = file.getName().substring("messages_".length(), file.getName().length() - ".yml".length()); String json = convertToJson(code, defaultMessages, YamlConfiguration.loadConfiguration(file)); - FileUtils.writeToFile(OUTPUT_FOLDER + "messages_" + code + ".json", json); + FileIoUtils.writeToFile(OUTPUT_FOLDER + "messages_" + code + ".json", json); } } } diff --git a/src/test/java/tools/utils/FileUtils.java b/src/test/java/tools/utils/FileIoUtils.java similarity index 86% rename from src/test/java/tools/utils/FileUtils.java rename to src/test/java/tools/utils/FileIoUtils.java index 44bf5a29..4683633f 100644 --- a/src/test/java/tools/utils/FileUtils.java +++ b/src/test/java/tools/utils/FileIoUtils.java @@ -9,11 +9,11 @@ import java.nio.file.StandardOpenOption; import java.util.List; /** - * Utility class for reading from and writing to files. + * Utility class for I/O operations on files. */ -public final class FileUtils { +public final class FileIoUtils { - private FileUtils() { + private FileIoUtils() { } public static void generateFileFromTemplate(String templateFile, String destinationFile, TagValueHolder tags) { @@ -43,8 +43,12 @@ public final class FileUtils { } public static String readFromFile(String file) { + return readFromFile(Paths.get(file)); + } + + public static String readFromFile(Path file) { try { - return new String(Files.readAllBytes(Paths.get(file)), StandardCharsets.UTF_8); + return new String(Files.readAllBytes(file), StandardCharsets.UTF_8); } catch (IOException e) { throw new UnsupportedOperationException("Could not read from file '" + file + "'", e); } From 9466577993ccea0d74d5f4a72947aa8ba4988193 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 23 Oct 2016 21:12:49 +0200 Subject: [PATCH 08/67] #989 Ensure config comments never exceed 90 chars - Prevents horizontal scrollbar on markdown page (and in users' editors) - Add test that each property is accompanied with a comment --- docs/config.md | 41 ++++++----- .../settings/properties/PluginSettings.java | 9 ++- .../properties/ProtectionSettings.java | 15 ++-- .../settings/properties/PurgeSettings.java | 4 +- .../properties/RegistrationSettings.java | 20 +++--- .../properties/RestrictionSettings.java | 6 +- .../settings/SettingsConsistencyTest.java | 69 +++++++++++++++++++ 7 files changed, 126 insertions(+), 38 deletions(-) create mode 100644 src/test/java/fr/xephi/authme/settings/SettingsConsistencyTest.java diff --git a/docs/config.md b/docs/config.md index 95e1de39..10980d8a 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,5 +1,5 @@ - + ## AuthMe Configuration The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, @@ -99,7 +99,8 @@ settings: # Should the session expire if the player tries to log in with # another IP address? sessionExpireOnIpChange: true - # Message language, available: en, de, br, cz, pl, fr, ru, hu, sk, es, zhtw, fi, zhcn, lt, it, ko, pt + # Message language, available languages: + # https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/translations.md messagesLanguage: 'en' restrictions: # Keeps collisions disabled for logged players @@ -131,9 +132,9 @@ settings: # This setting will prevent potential security exploits. ForceSingleSession: true ForceSpawnLocOnJoin: - # If enabled, every player that spawn in one of the world listed in "ForceSpawnLocOnJoin.worlds" - # will be teleported to the spawnpoint after successful authentication. - # The quit location of the player will be overwritten. + # If enabled, every player that spawn in one of the world listed in + # "ForceSpawnLocOnJoin.worlds" will be teleported to the spawnpoint after successful + # authentication. The quit location of the player will be overwritten. # This is different from "teleportUnAuthedToSpawn" that teleport player # to the spawnpoint on join. enabled: false @@ -202,8 +203,8 @@ settings: # FINE for some additional detailed ones (like password failed), # and DEBUG for debugging logLevel: 'FINE' - # By default we schedule async tasks when talking to the database - # If you want typical communication with the database to happen synchronously, set this to false + # By default we schedule async tasks when talking to the database. If you want + # typical communication with the database to happen synchronously, set this to false useAsyncTasks: true GameMode: # Force survival gamemode when player joins? @@ -277,19 +278,23 @@ settings: forceLoginAfterRegister: false # Force these commands after /login, without any '/', use %p to replace with player name forceCommands: [] - # Force these commands after /login as service console, without any '/'. Use %p to replace with player name + # Force these commands after /login as service console, without any '/'. + # Use %p to replace with player name forceCommandsAsConsole: [] # Force these commands after /register, without any '/', use %p to replace with player name forceRegisterCommands: [] - # Force these commands after /register as a server console, without any '/'. Use %p to replace with player name + # Force these commands after /register as a server console, without any '/'. + # Use %p to replace with player name forceRegisterCommandsAsConsole: [] # Enable to display the welcome message (welcome.txt) after a login # You can use colors in this welcome.txt + some replaced strings: - # {PLAYER}: player name, {ONLINE}: display number of online players, {MAXPLAYERS}: display server slots, - # {IP}: player ip, {LOGINS}: number of players logged, {WORLD}: player current world, {SERVER}: server name + # {PLAYER}: player name, {ONLINE}: display number of online players, + # {MAXPLAYERS}: display server slots, {IP}: player ip, {LOGINS}: number of players logged, + # {WORLD}: player current world, {SERVER}: server name # {VERSION}: get current bukkit version, {COUNTRY}: player country useWelcomeMessage: true - # Do we need to broadcast the welcome message to all server or only to the player? set true for server or false for player + # Broadcast the welcome message to the server or only to the player? + # set true for server or false for player broadcastWelcomeMessage: false # Should we delay the join message and display it once the player has logged in? delayJoinMessage: false @@ -361,7 +366,8 @@ Protection: enableProtection: false # Apply the protection also to registered usernames enableProtectionRegistered: true - # Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes + # Countries allowed to join the server and register. For country codes, see + # http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ # PLEASE USE QUOTES! countries: - 'US' @@ -372,7 +378,8 @@ Protection: - 'A1' # Do we need to enable automatic antibot system? enableAntiBot: true - # Max number of players allowed to login in 5 secs before the AntiBot system is enabled automatically + # Max number of players allowed to login in 5 secs + # before the AntiBot system is enabled automatically antiBotSensibility: 10 # Duration in minutes of the antibot automatic system antiBotDuration: 10 @@ -381,7 +388,7 @@ Protection: Purge: # If enabled, AuthMe automatically purges old, unused accounts useAutoPurge: false - # Number of Days an account become Unused + # Number of days after which an account should be purged daysBeforeRemovePlayer: 60 # Do we need to remove the player.dat file during purge process? removePlayerDat: false @@ -389,7 +396,7 @@ Purge: removeEssentialsFile: false # World where are players.dat stores defaultWorld: 'world' - # Do we need to remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge process ? + # Remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge? removeLimitedCreativesInventories: false # Do we need to remove the AntiXRayData/PlayerData/player file during purge process? removeAntiXRayFile: false @@ -448,4 +455,4 @@ To change settings on a running server, save your changes to config.yml and use --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 23 18:25:12 CEST 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 23 21:08:57 CEST 2016 diff --git a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java b/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java index bfb56533..094a3d5b 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java @@ -36,7 +36,10 @@ public class PluginSettings implements SettingsHolder { public static final Property SESSIONS_EXPIRE_ON_IP_CHANGE = newProperty("settings.sessions.sessionExpireOnIpChange", true); - @Comment("Message language, available: en, de, br, cz, pl, fr, ru, hu, sk, es, zhtw, fi, zhcn, lt, it, ko, pt") + @Comment({ + "Message language, available languages:", + "https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/translations.md" + }) public static final Property MESSAGES_LANGUAGE = newProperty("settings.messagesLanguage", "en"); @@ -65,8 +68,8 @@ public class PluginSettings implements SettingsHolder { newProperty(LogLevel.class, "settings.logLevel", LogLevel.FINE); @Comment({ - "By default we schedule async tasks when talking to the database", - "If you want typical communication with the database to happen synchronously, set this to false" + "By default we schedule async tasks when talking to the database. If you want", + "typical communication with the database to happen synchronously, set this to false" }) public static final Property USE_ASYNC_TASKS = newProperty("settings.useAsyncTasks", true); diff --git a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java index cdd760bd..834b7dd9 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java @@ -20,13 +20,16 @@ public class ProtectionSettings implements SettingsHolder { public static final Property ENABLE_PROTECTION_REGISTERED = newProperty("Protection.enableProtectionRegistered", true); - @Comment({"Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes", - "PLEASE USE QUOTES!"}) + @Comment({ + "Countries allowed to join the server and register. For country codes, see", + "http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/", + "PLEASE USE QUOTES!"}) public static final Property> COUNTRIES_WHITELIST = newListProperty("Protection.countries", "US", "GB"); - @Comment({"Countries not allowed to join the server and register", - "PLEASE USE QUOTES!"}) + @Comment({ + "Countries not allowed to join the server and register", + "PLEASE USE QUOTES!"}) public static final Property> COUNTRIES_BLACKLIST = newListProperty("Protection.countriesBlacklist", "A1"); @@ -34,7 +37,9 @@ public class ProtectionSettings implements SettingsHolder { public static final Property ENABLE_ANTIBOT = newProperty("Protection.enableAntiBot", true); - @Comment("Max number of players allowed to login in 5 secs before the AntiBot system is enabled automatically") + @Comment({ + "Max number of players allowed to login in 5 secs", + "before the AntiBot system is enabled automatically"}) public static final Property ANTIBOT_SENSIBILITY = newProperty("Protection.antiBotSensibility", 10); diff --git a/src/main/java/fr/xephi/authme/settings/properties/PurgeSettings.java b/src/main/java/fr/xephi/authme/settings/properties/PurgeSettings.java index f23a3eb1..b3733b5a 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/PurgeSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/PurgeSettings.java @@ -12,7 +12,7 @@ public class PurgeSettings implements SettingsHolder { public static final Property USE_AUTO_PURGE = newProperty("Purge.useAutoPurge", false); - @Comment("Number of Days an account become Unused") + @Comment("Number of days after which an account should be purged") public static final Property DAYS_BEFORE_REMOVE_PLAYER = newProperty("Purge.daysBeforeRemovePlayer", 60); @@ -28,7 +28,7 @@ public class PurgeSettings implements SettingsHolder { public static final Property DEFAULT_WORLD = newProperty("Purge.defaultWorld", "world"); - @Comment("Do we need to remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge process ?") + @Comment("Remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge?") public static final Property REMOVE_LIMITED_CREATIVE_INVENTORIES = newProperty("Purge.removeLimitedCreativesInventories", false); diff --git a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java index b593869a..487039ba 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java @@ -52,8 +52,9 @@ public class RegistrationSettings implements SettingsHolder { public static final Property> FORCE_COMMANDS = newListProperty("settings.forceCommands"); - @Comment("Force these commands after /login as service console, without any '/'. " - + "Use %p to replace with player name") + @Comment({ + "Force these commands after /login as service console, without any '/'.", + "Use %p to replace with player name"}) public static final Property> FORCE_COMMANDS_AS_CONSOLE = newListProperty("settings.forceCommandsAsConsole"); @@ -61,22 +62,25 @@ public class RegistrationSettings implements SettingsHolder { public static final Property> FORCE_REGISTER_COMMANDS = newListProperty("settings.forceRegisterCommands"); - @Comment("Force these commands after /register as a server console, without any '/'. " - + "Use %p to replace with player name") + @Comment({ + "Force these commands after /register as a server console, without any '/'.", + "Use %p to replace with player name"}) public static final Property> FORCE_REGISTER_COMMANDS_AS_CONSOLE = newListProperty("settings.forceRegisterCommandsAsConsole"); @Comment({ "Enable to display the welcome message (welcome.txt) after a login", "You can use colors in this welcome.txt + some replaced strings:", - "{PLAYER}: player name, {ONLINE}: display number of online players, {MAXPLAYERS}: display server slots,", - "{IP}: player ip, {LOGINS}: number of players logged, {WORLD}: player current world, {SERVER}: server name", + "{PLAYER}: player name, {ONLINE}: display number of online players,", + "{MAXPLAYERS}: display server slots, {IP}: player ip, {LOGINS}: number of players logged,", + "{WORLD}: player current world, {SERVER}: server name", "{VERSION}: get current bukkit version, {COUNTRY}: player country"}) public static final Property USE_WELCOME_MESSAGE = newProperty("settings.useWelcomeMessage", true); - @Comment("Do we need to broadcast the welcome message to all server or only to the player? set true for " - + "server or false for player") + @Comment({ + "Broadcast the welcome message to the server or only to the player?", + "set true for server or false for player"}) public static final Property BROADCAST_WELCOME_MESSAGE = newProperty("settings.broadcastWelcomeMessage", false); diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index 9e16714d..4cd321f6 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -50,9 +50,9 @@ public class RestrictionSettings implements SettingsHolder { newProperty("settings.restrictions.ForceSingleSession", true); @Comment({ - "If enabled, every player that spawn in one of the world listed in \"ForceSpawnLocOnJoin.worlds\"", - "will be teleported to the spawnpoint after successful authentication.", - "The quit location of the player will be overwritten.", + "If enabled, every player that spawn in one of the world listed in", + "\"ForceSpawnLocOnJoin.worlds\" will be teleported to the spawnpoint after successful", + "authentication. The quit location of the player will be overwritten.", "This is different from \"teleportUnAuthedToSpawn\" that teleport player", "to the spawnpoint on join."}) public static final Property FORCE_SPAWN_LOCATION_AFTER_LOGIN = diff --git a/src/test/java/fr/xephi/authme/settings/SettingsConsistencyTest.java b/src/test/java/fr/xephi/authme/settings/SettingsConsistencyTest.java new file mode 100644 index 00000000..7123ac26 --- /dev/null +++ b/src/test/java/fr/xephi/authme/settings/SettingsConsistencyTest.java @@ -0,0 +1,69 @@ +package fr.xephi.authme.settings; + +import com.github.authme.configme.knownproperties.ConfigurationData; +import com.github.authme.configme.properties.Property; +import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.Assert.fail; + +/** + * Tests the consistency of the settings configuration. + */ +public class SettingsConsistencyTest { + + /** + * Maximum characters one comment line may have (prevents horizontal scrolling). + */ + private static final int MAX_COMMENT_LENGTH = 90; + + private static ConfigurationData configurationData; + + @BeforeClass + public static void buildConfigurationData() { + configurationData = AuthMeSettingsRetriever.buildConfigurationData(); + } + + @Test + public void shouldHaveCommentOnEachProperty() { + // given + List> properties = configurationData.getProperties(); + + // when / then + for (Property property : properties) { + if (configurationData.getCommentsForSection(property.getPath()).length == 0) { + fail("No comment defined for '" + property + "'"); + } + } + } + + @Test + public void shouldNotHaveVeryLongCommentLines() { + // given + List> properties = configurationData.getProperties(); + List> badProperties = new ArrayList<>(); + + // when + for (Property property : properties) { + for (String comment : configurationData.getCommentsForSection(property.getPath())) { + if (comment.length() > MAX_COMMENT_LENGTH) { + badProperties.add(property); + break; + } + } + } + + // then + if (!badProperties.isEmpty()) { + fail("Comment lines should not be longer than " + MAX_COMMENT_LENGTH + " chars, " + + "but found too long comments for:\n- " + + badProperties.stream().map(Property::getPath).collect(Collectors.joining("\n- "))); + } + } + +} From 3216a7ab27ca066a926bb7d9dcca0976c1acb4a3 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 23 Oct 2016 21:39:54 +0200 Subject: [PATCH 09/67] #987 Add "help" as default unsafe password --- .../authme/settings/properties/SecuritySettings.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java index 7d91f818..92ce2e5e 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java @@ -18,10 +18,6 @@ public class SecuritySettings implements SettingsHolder { public static final Property STOP_SERVER_ON_PROBLEM = newProperty("Security.SQLProblem.stopServer", true); - @Comment("/reload support") - public static final Property USE_RELOAD_COMMAND_SUPPORT = - newProperty("Security.ReloadCommand.useReloadCommandSupport", true); - @Comment("Remove passwords from console?") public static final Property REMOVE_PASSWORD_FROM_CONSOLE = newProperty("Security.console.removePassword", true); @@ -85,11 +81,13 @@ public class SecuritySettings implements SettingsHolder { newProperty("settings.security.supportOldPasswordHash", false); @Comment({"Prevent unsafe passwords from being used; put them in lowercase!", + "You should always set 'help' as unsafePassword due to possible conflicts.", "unsafePasswords:", "- '123456'", - "- 'password'"}) + "- 'password'", + "- 'help'"}) public static final Property> UNSAFE_PASSWORDS = - newLowercaseListProperty("settings.security.unsafePasswords", "123456", "password", "qwerty", "12345", "54321", "123456789"); + newLowercaseListProperty("settings.security.unsafePasswords", "123456", "password", "qwerty", "12345", "54321", "123456789", "help"); @Comment("Tempban a user's IP address if they enter the wrong password too many times") public static final Property TEMPBAN_ON_MAX_LOGINS = From 0fc04e2bcfa06baae322edd4bbee0b3a2562a9be Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 23 Oct 2016 21:45:12 +0200 Subject: [PATCH 10/67] #823 Change default minimum username length to 3 --- .../xephi/authme/settings/properties/RestrictionSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index 4cd321f6..c05efa4b 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -36,7 +36,7 @@ public class RestrictionSettings implements SettingsHolder { @Comment("Minimum allowed username length") public static final Property MIN_NICKNAME_LENGTH = - newProperty("settings.restrictions.minNicknameLength", 4); + newProperty("settings.restrictions.minNicknameLength", 3); @Comment("Maximum allowed username length") public static final Property MAX_NICKNAME_LENGTH = From 50610f630541feb53165deb2ebf2ea4433c2f8da Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 23 Oct 2016 21:50:44 +0200 Subject: [PATCH 11/67] #979 Provide more succinct error messages for missing command entries - Show only one error message if a command section is missing altogether - Remove "commands." prefix in missing command errors --- .../HelpTranslationVerifier.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/test/java/tools/helptranslation/HelpTranslationVerifier.java b/src/test/java/tools/helptranslation/HelpTranslationVerifier.java index 2ed130fa..9cbf12b5 100644 --- a/src/test/java/tools/helptranslation/HelpTranslationVerifier.java +++ b/src/test/java/tools/helptranslation/HelpTranslationVerifier.java @@ -55,11 +55,15 @@ public class HelpTranslationVerifier { } public List getMissingCommands() { - return missingCommands; + // All entries start with "command.", so remove that + return missingCommands.stream() + .map(s -> s.substring(9)).collect(Collectors.toList()); } public List getUnknownCommands() { - return unknownCommands; + // All entries start with "command.", so remove that + return unknownCommands.stream() + .map(s -> s.substring(9)).collect(Collectors.toList()); } /** @@ -89,14 +93,14 @@ public class HelpTranslationVerifier { Set commandPaths = buildCommandPaths(); Set existingKeys = getLeafKeys("commands"); if (existingKeys.isEmpty()) { - missingCommands.addAll(commandPaths); + missingCommands.addAll(commandPaths); // commandPaths should be empty in this case } else { missingCommands.addAll(Sets.difference(commandPaths, existingKeys)); unknownCommands.addAll(Sets.difference(existingKeys, commandPaths)); } } - private static Set buildCommandPaths() { + private Set buildCommandPaths() { Set commandPaths = new LinkedHashSet<>(); for (CommandDescription command : new CommandInitializer().getCommands()) { commandPaths.addAll(getYamlPaths(command)); @@ -105,11 +109,16 @@ public class HelpTranslationVerifier { return commandPaths; } - private static List getYamlPaths(CommandDescription command) { + private List getYamlPaths(CommandDescription command) { // e.g. commands.authme.register String commandPath = "commands." + CommandUtils.constructParentList(command).stream() .map(cmd -> cmd.getLabels().get(0)) .collect(Collectors.joining(".")); + // The entire command is not present, so just add it as a missing command and don't return any YAML path + if (!configuration.contains(commandPath)) { + missingCommands.add(commandPath); + return Collections.emptyList(); + } // Entries each command can have List paths = newArrayList(commandPath + ".description", commandPath + ".detailedDescription"); From 31d8b38fe5d0197aa51a7add59e5c20f3861444a Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 23 Oct 2016 22:05:07 +0200 Subject: [PATCH 12/67] #826 add setting to define the antibot interval --- src/main/java/fr/xephi/authme/service/AntiBotService.java | 4 +++- .../authme/settings/properties/ProtectionSettings.java | 6 +++++- .../java/fr/xephi/authme/service/AntiBotServiceTest.java | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/xephi/authme/service/AntiBotService.java b/src/main/java/fr/xephi/authme/service/AntiBotService.java index 24118d40..c0d8b439 100644 --- a/src/main/java/fr/xephi/authme/service/AntiBotService.java +++ b/src/main/java/fr/xephi/authme/service/AntiBotService.java @@ -30,6 +30,7 @@ public class AntiBotService implements SettingsDependent { private int duration; private int sensibility; private int delay; + private int interval; // Service status private AntiBotStatus antiBotStatus; @@ -60,6 +61,7 @@ public class AntiBotService implements SettingsDependent { duration = settings.getProperty(ProtectionSettings.ANTIBOT_DURATION); sensibility = settings.getProperty(ProtectionSettings.ANTIBOT_SENSIBILITY); delay = settings.getProperty(ProtectionSettings.ANTIBOT_DELAY); + interval = settings.getProperty(ProtectionSettings.ANTIBOT_INTERVAL); // Stop existing protection stopProtection(); @@ -174,7 +176,7 @@ public class AntiBotService implements SettingsDependent { public void run() { antibotPlayers--; } - }, 5 * TICKS_PER_SECOND); + }, interval * TICKS_PER_SECOND); } /** diff --git a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java index 834b7dd9..b725172f 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java @@ -37,8 +37,12 @@ public class ProtectionSettings implements SettingsHolder { public static final Property ENABLE_ANTIBOT = newProperty("Protection.enableAntiBot", true); + @Comment("The interval in seconds") + public static final Property ANTIBOT_INTERVAL = + newProperty("Protection.antiBotInterval", 5); + @Comment({ - "Max number of players allowed to login in 5 secs", + "Max number of players allowed to login in the interval", "before the AntiBot system is enabled automatically"}) public static final Property ANTIBOT_SENSIBILITY = newProperty("Protection.antiBotSensibility", 10); diff --git a/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java b/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java index e40d5ca7..36531395 100644 --- a/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java @@ -52,6 +52,7 @@ public class AntiBotServiceTest { @BeforeInjecting public void initSettings() { given(settings.getProperty(ProtectionSettings.ANTIBOT_DURATION)).willReturn(10); + given(settings.getProperty(ProtectionSettings.ANTIBOT_INTERVAL)).willReturn(5); given(settings.getProperty(ProtectionSettings.ANTIBOT_SENSIBILITY)).willReturn(5); given(settings.getProperty(ProtectionSettings.ENABLE_ANTIBOT)).willReturn(true); given(settings.getProperty(ProtectionSettings.ANTIBOT_DELAY)).willReturn(8); From 75425b439a6a4f9c6102e9f1893f7099c6e0af3e Mon Sep 17 00:00:00 2001 From: DeathrushW Date: Thu, 27 Oct 2016 02:03:06 -0200 Subject: [PATCH 13/67] Updating Translation BR! messages_br: show_no_email and email_show added help_br added --- src/main/resources/messages/help_br.yml | 45 +++++++++++++++++++++ src/main/resources/messages/messages_br.yml | 4 +- 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/messages/help_br.yml diff --git a/src/main/resources/messages/help_br.yml b/src/main/resources/messages/help_br.yml new file mode 100644 index 00000000..fb33f375 --- /dev/null +++ b/src/main/resources/messages/help_br.yml @@ -0,0 +1,45 @@ +# Translation config for the AuthMe help, e.g. when /authme help or /authme help register is called + +# ------------------------------------------------------- +# List of texts used in the help section +common: + header: '==========[ CraftSkull HELP ]==========' + optional: 'Opcional' + hasPermission: 'Você tem permissão' + noPermission: 'Sem Permissão' + default: 'Default' + result: 'Resultado' + defaultPermissions: + notAllowed: 'Sem Permissão' + opOnly: 'OP''s only' + allowed: 'Todos podem' + +# ------------------------------------------------------- +# Titles of the individual help sections +# Set the translation text to empty text to disable the section, e.g. to hide alternatives: +# alternatives: '' +section: + command: 'Comando' + description: 'Pequena descrição' + detailedDescription: 'Descrição detalhada' + arguments: 'Argumentos' + permissions: 'Permissões' + alternatives: 'Alternativas' + children: 'Comandos' + +# ------------------------------------------------------- +# You can translate the data for all commands using the below pattern. +# For example to translate /authme reload, create a section "authme.reload", or "login" for /login +# If the command has arguments, you can use arg1 as below to translate the first argument, and so forth +# Translations don't need to be complete; any missing section will be taken from the default silently +# Important: Put main commands like "authme" before their children (e.g. "authme.reload") +commands: + authme.register: + description: 'Registra um jogador' + detailedDescription: 'Registra um esprecifico jogador com uma senha especifica.' + arg1: + label: 'player' + description: 'Nome do player' + arg2: + label: 'password' + description: 'Senha' diff --git a/src/main/resources/messages/messages_br.yml b/src/main/resources/messages/messages_br.yml index 8002a7a1..8181658c 100644 --- a/src/main/resources/messages/messages_br.yml +++ b/src/main/resources/messages/messages_br.yml @@ -61,6 +61,8 @@ email_confirm: '&cPor favor confirme seu endereço de email!' email_changed: '&2Troca de email com sucesso.!' email_send: '&2Recuperação de email enviada com sucesso! Por favor, verifique sua caixa de entrada de e-mail!' email_exists: '&cUm e-mail de recuperação já foi enviado! Você pode descartá-lo e enviar um novo usando o comando abaixo:' +email_show: '&2O seu endereço de e-mail atual é: &f%email' +show_no_email: '&2Você atualmente não têm endereço de e-mail associado a esta conta.' country_banned: '&4O seu país está banido neste servidor!' antibot_auto_enabled: '&4[AntiBotService] habilitado devido ao enorme número de conexões!' antibot_auto_disabled: '&2[AntiBotService] AntiBot desativada após %m minutos!' @@ -75,5 +77,3 @@ kicked_admin_registered: 'Um administrador registrou você; por favor faça logi incomplete_email_settings: 'Erro: Nem todas as configurações necessárias estão definidas para o envio de e-mails. Entre em contato com um administrador.' recovery_code_sent: 'Um código de recuperação para redefinir sua senha foi enviada para o seu e-mail.' recovery_code_incorrect: 'O código de recuperação esta incorreto! Use /email recovery [email] para gerar um novo!' -# TODO email_show: '&2Your current email address is: &f%email' -# TODO show_no_email: '&2You currently don''t have email address associated with this account.' \ No newline at end of file From b3e276d277765ca4fd2f007236caf7b08e9e8b6e Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sat, 29 Oct 2016 14:00:51 +0200 Subject: [PATCH 14/67] Remove wrong header from BR help file --- src/main/resources/messages/help_br.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/messages/help_br.yml b/src/main/resources/messages/help_br.yml index fb33f375..90fc6cc0 100644 --- a/src/main/resources/messages/help_br.yml +++ b/src/main/resources/messages/help_br.yml @@ -3,7 +3,6 @@ # ------------------------------------------------------- # List of texts used in the help section common: - header: '==========[ CraftSkull HELP ]==========' optional: 'Opcional' hasPermission: 'Você tem permissão' noPermission: 'Sem Permissão' From 195e409efde09131f3f9bd0958f2d0328d208e31 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 30 Oct 2016 09:24:31 +0100 Subject: [PATCH 15/67] Add configurable antibot interval (#826) lost while merging master - Add interval configuration - Small refactoring: make OnJoinVerifier not call antibot if a PlayerAuth is available --- .../xephi/authme/listener/OnJoinVerifier.java | 4 +-- .../xephi/authme/service/AntiBotService.java | 14 +++++----- .../authme/listener/OnJoinVerifierTest.java | 27 ++++++++++++++----- .../authme/service/AntiBotServiceTest.java | 21 +++------------ 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java index 755d2a6e..7e68aae4 100644 --- a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java +++ b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java @@ -68,10 +68,10 @@ class OnJoinVerifier implements Reloadable { * @param isAuthAvailable whether or not the player is registered */ public void checkAntibot(Player player, boolean isAuthAvailable) throws FailedVerificationException { - if (permissionsManager.hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT)) { + if (isAuthAvailable || permissionsManager.hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT)) { return; } - if (antiBotService.shouldKick(isAuthAvailable)) { + if (antiBotService.shouldKick()) { antiBotService.addPlayerKick(player.getName()); throw new FailedVerificationException(MessageKey.KICK_ANTIBOT); } diff --git a/src/main/java/fr/xephi/authme/service/AntiBotService.java b/src/main/java/fr/xephi/authme/service/AntiBotService.java index a329e5de..91f80041 100644 --- a/src/main/java/fr/xephi/authme/service/AntiBotService.java +++ b/src/main/java/fr/xephi/authme/service/AntiBotService.java @@ -31,6 +31,7 @@ public class AntiBotService implements SettingsDependent { private int duration; private int sensibility; private int delay; + private int interval; // Service status private AntiBotStatus antiBotStatus; private boolean startup; @@ -60,6 +61,7 @@ public class AntiBotService implements SettingsDependent { duration = settings.getProperty(ProtectionSettings.ANTIBOT_DURATION); sensibility = settings.getProperty(ProtectionSettings.ANTIBOT_SENSIBILITY); delay = settings.getProperty(ProtectionSettings.ANTIBOT_DELAY); + interval = settings.getProperty(ProtectionSettings.ANTIBOT_INTERVAL); // Stop existing protection stopProtection(); @@ -145,23 +147,19 @@ public class AntiBotService implements SettingsDependent { /** * Returns if a player should be kicked due to antibot service. * - * @param isAuthAvailable if the player is registered - * * @return if the player should be kicked */ - public boolean shouldKick(boolean isAuthAvailable) { - if (antiBotStatus == AntiBotStatus.DISABLED || isAuthAvailable) { + public boolean shouldKick() { + if (antiBotStatus == AntiBotStatus.DISABLED) { return false; - } - - if (antiBotStatus == AntiBotStatus.ACTIVE) { + } else if (antiBotStatus == AntiBotStatus.ACTIVE) { return true; } if (lastFlaggedJoin == null) { lastFlaggedJoin = Instant.now(); } - if (ChronoUnit.SECONDS.between(lastFlaggedJoin, Instant.now()) <= 5) { + if (ChronoUnit.SECONDS.between(lastFlaggedJoin, Instant.now()) <= interval) { flagged++; } else { // reset to 1 because this player is also count as not registered diff --git a/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java b/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java index 6271f092..3b764bd7 100644 --- a/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java +++ b/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java @@ -8,12 +8,12 @@ import fr.xephi.authme.message.Messages; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.service.AntiBotService; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.ProtectionSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; -import fr.xephi.authme.service.BukkitService; -import fr.xephi.authme.service.ValidationService; import org.bukkit.Server; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerLoginEvent; @@ -381,14 +381,27 @@ public class OnJoinVerifierTest { Player player = newPlayerWithName("Bobby"); boolean isAuthAvailable = false; given(permissionsManager.hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT)).willReturn(false); - given(antiBotService.shouldKick(isAuthAvailable)).willReturn(false); + given(antiBotService.shouldKick()).willReturn(false); // when onJoinVerifier.checkAntibot(player, isAuthAvailable); // then verify(permissionsManager).hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT); - verify(antiBotService).shouldKick(isAuthAvailable); + verify(antiBotService).shouldKick(); + } + + @Test + public void shouldAllowUserWithAuth() throws FailedVerificationException { + // given + Player player = newPlayerWithName("Lacey"); + boolean isAuthAvailable = true; + + // when + onJoinVerifier.checkAntibot(player, isAuthAvailable); + + // then + verifyZeroInteractions(permissionsManager, antiBotService); } @Test @@ -397,13 +410,13 @@ public class OnJoinVerifierTest { Player player = newPlayerWithName("Steward"); boolean isAuthAvailable = false; given(permissionsManager.hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT)).willReturn(true); - given(antiBotService.shouldKick(isAuthAvailable)).willReturn(true); // when onJoinVerifier.checkAntibot(player, isAuthAvailable); // then verify(permissionsManager).hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT); + verifyZeroInteractions(antiBotService); } @Test @@ -412,7 +425,7 @@ public class OnJoinVerifierTest { Player player = newPlayerWithName("D3"); boolean isAuthAvailable = false; given(permissionsManager.hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT)).willReturn(false); - given(antiBotService.shouldKick(isAuthAvailable)).willReturn(true); + given(antiBotService.shouldKick()).willReturn(true); // when / then try { @@ -420,7 +433,7 @@ public class OnJoinVerifierTest { fail("Expected exception to be thrown"); } catch (FailedVerificationException e) { verify(permissionsManager).hasPermission(player, PlayerStatePermission.BYPASS_ANTIBOT); - verify(antiBotService).shouldKick(isAuthAvailable); + verify(antiBotService).shouldKick(); } } diff --git a/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java b/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java index 7dfa0b0d..db7f3e7d 100644 --- a/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java @@ -131,27 +131,12 @@ public class AntiBotServiceTest { runSyncDelayedTaskWithDelay(bukkitService); // when - boolean result = antiBotService.shouldKick(false); + boolean result = antiBotService.shouldKick(); // then assertThat(result, equalTo(false)); } - @Test - public void shouldRejectPlayerWithoutAuth() { - // given - active antibot - runSyncDelayedTaskWithDelay(bukkitService); - antiBotService.overrideAntiBotStatus(true); - - // when - boolean kickWithoutAuth = antiBotService.shouldKick(false); - boolean kickWithAuth = antiBotService.shouldKick(true); - - // then - assertThat(kickWithoutAuth, equalTo(true)); - assertThat(kickWithAuth, equalTo(false)); - } - @Test public void shouldActivateAntibotAfterThreshold() { // given @@ -162,12 +147,12 @@ public class AntiBotServiceTest { runSyncDelayedTaskWithDelay(bukkitService); for (int i = 0; i < sensitivity; ++i) { - antiBotService.shouldKick(false); + antiBotService.shouldKick(); } assertThat(antiBotService.getAntiBotStatus(), equalTo(AntiBotService.AntiBotStatus.LISTENING)); // when - antiBotService.shouldKick(false); + antiBotService.shouldKick(); // then assertThat(antiBotService.getAntiBotStatus(), equalTo(AntiBotService.AntiBotStatus.ACTIVE)); From 46af922fba3d6c5af872f13b205f66e0bfeafb64 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 30 Oct 2016 10:43:59 +0100 Subject: [PATCH 16/67] Minor refactoring for tool tasks - Don't scan for translations on initialization in TranslationPageGenerator in order to speed up startup time of ToolsRunner - Extract checking for null / empty array of File#listFiles into a separate method - Move single method of RuntimeUtils into Utils class --- .../fr/xephi/authme/datasource/MySQL.java | 9 +++------ .../fr/xephi/authme/util/RuntimeUtils.java | 20 ------------------- src/main/java/fr/xephi/authme/util/Utils.java | 9 +++++++++ .../message/YamlTextFileCheckerTest.java | 15 ++++---------- .../TranslationPageGenerator.java | 3 +-- .../translations/TranslationsGatherer.java | 7 +++---- .../VerifyHelpTranslations.java | 7 +++---- .../tools/messages/VerifyMessagesTask.java | 9 +++------ .../translation/WriteAllExportsTask.java | 8 +++----- src/test/java/tools/utils/FileIoUtils.java | 16 +++++++++++++++ 10 files changed, 45 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/fr/xephi/authme/util/RuntimeUtils.java diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index 9da225b9..a099ff44 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -5,9 +5,6 @@ import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.datasource.Columns; -import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.datasource.DataSourceType; import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.security.crypts.XFBCRYPT; @@ -15,8 +12,8 @@ import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.SecuritySettings; -import fr.xephi.authme.util.RuntimeUtils; import fr.xephi.authme.util.StringUtils; +import fr.xephi.authme.util.Utils; import java.sql.Blob; import java.sql.Connection; @@ -100,8 +97,8 @@ public class MySQL implements DataSource { this.phpBbGroup = settings.getProperty(HooksSettings.PHPBB_ACTIVATED_GROUP_ID); this.wordpressPrefix = settings.getProperty(HooksSettings.WORDPRESS_TABLE_PREFIX); this.poolSize = settings.getProperty(DatabaseSettings.MYSQL_POOL_SIZE); - if(poolSize == -1) { - poolSize = RuntimeUtils.getCoreCount(); + if (poolSize == -1) { + poolSize = Utils.getCoreCount(); } } diff --git a/src/main/java/fr/xephi/authme/util/RuntimeUtils.java b/src/main/java/fr/xephi/authme/util/RuntimeUtils.java deleted file mode 100644 index 6af0c457..00000000 --- a/src/main/java/fr/xephi/authme/util/RuntimeUtils.java +++ /dev/null @@ -1,20 +0,0 @@ -package fr.xephi.authme.util; - -/** - * Runtime utilities. - */ -public class RuntimeUtils { - - // Utility class - private RuntimeUtils() { - } - - /** - * Return the available core count of the JVM. - * - * @return the core count - */ - public static int getCoreCount() { - return Runtime.getRuntime().availableProcessors(); - } -} diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java index 1136854d..5fef8a95 100644 --- a/src/main/java/fr/xephi/authme/util/Utils.java +++ b/src/main/java/fr/xephi/authme/util/Utils.java @@ -48,4 +48,13 @@ public final class Utils { return false; } } + + /** + * Return the available core count of the JVM. + * + * @return the core count + */ + public static int getCoreCount() { + return Runtime.getRuntime().availableProcessors(); + } } diff --git a/src/test/java/fr/xephi/authme/message/YamlTextFileCheckerTest.java b/src/test/java/fr/xephi/authme/message/YamlTextFileCheckerTest.java index 7fa6fecb..1499c976 100644 --- a/src/test/java/fr/xephi/authme/message/YamlTextFileCheckerTest.java +++ b/src/test/java/fr/xephi/authme/message/YamlTextFileCheckerTest.java @@ -13,6 +13,7 @@ import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; +import static tools.utils.FileIoUtils.listFilesOrThrow; import static org.junit.Assert.fail; /** @@ -28,11 +29,7 @@ public class YamlTextFileCheckerTest { @BeforeClass public static void loadMessagesFiles() { File folder = TestHelper.getJarFile(MESSAGES_FOLDER); - File[] files = folder.listFiles(); - if (files == null || files.length == 0) { - throw new IllegalStateException("Could not read folder '" + folder.getName() + "'"); - } - messageFiles = Arrays.asList(files); + messageFiles = Arrays.asList(listFilesOrThrow(folder)); } @Test @@ -82,17 +79,13 @@ public class YamlTextFileCheckerTest { * @param errors collection of errors to add to if the verification fails */ private void checkFile(File file, String mandatoryKey, List errors) { - String error = null; try { YamlConfiguration configuration = YamlConfiguration.loadConfiguration(file); if (StringUtils.isEmpty(configuration.getString(mandatoryKey))) { - error = "Message for '" + mandatoryKey + "' is empty"; + errors.add("Message for '" + mandatoryKey + "' is empty"); } } catch (Exception e) { - error = "Could not load file: " + StringUtils.formatException(e); - } - if (!StringUtils.isEmpty(error)) { - errors.add(file.getName() + ": " + error); + errors.add("Could not load file: " + StringUtils.formatException(e)); } } } diff --git a/src/test/java/tools/docs/translations/TranslationPageGenerator.java b/src/test/java/tools/docs/translations/TranslationPageGenerator.java index 240e7a64..83277927 100644 --- a/src/test/java/tools/docs/translations/TranslationPageGenerator.java +++ b/src/test/java/tools/docs/translations/TranslationPageGenerator.java @@ -34,8 +34,6 @@ public class TranslationPageGenerator implements AutoToolTask { private static final int[] COLOR_1 = {12, 9, 0}; private static final int[] COLOR_2 = { 6, 15, 6}; - private final TranslationsGatherer gatherer = new TranslationsGatherer(); - @Override public String getTaskName() { return "updateTranslations"; @@ -43,6 +41,7 @@ public class TranslationPageGenerator implements AutoToolTask { @Override public void executeDefault() { + TranslationsGatherer gatherer = new TranslationsGatherer(); NestedTagValue translationValuesHolder = new NestedTagValue(); for (TranslationInfo translation : gatherer.getTranslationInfo()) { diff --git a/src/test/java/tools/docs/translations/TranslationsGatherer.java b/src/test/java/tools/docs/translations/TranslationsGatherer.java index 233b9332..f54843a9 100644 --- a/src/test/java/tools/docs/translations/TranslationsGatherer.java +++ b/src/test/java/tools/docs/translations/TranslationsGatherer.java @@ -11,6 +11,8 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static tools.utils.FileIoUtils.listFilesOrThrow; + /** * Gathers all available translations of AuthMe. */ @@ -31,10 +33,7 @@ public class TranslationsGatherer { } private void gatherTranslations() { - File[] files = new File(MESSAGES_FOLDER).listFiles(); - if (files == null) { - throw new IllegalStateException("Cannot read files of '" + MESSAGES_FOLDER + "'"); - } + File[] files = listFilesOrThrow(new File(MESSAGES_FOLDER)); for (File file : files) { String code = getLanguageCode(file.getName()); if (code != null) { diff --git a/src/test/java/tools/helptranslation/VerifyHelpTranslations.java b/src/test/java/tools/helptranslation/VerifyHelpTranslations.java index f97447bf..a8a8daa9 100644 --- a/src/test/java/tools/helptranslation/VerifyHelpTranslations.java +++ b/src/test/java/tools/helptranslation/VerifyHelpTranslations.java @@ -10,6 +10,8 @@ import java.util.Scanner; import java.util.regex.Pattern; import java.util.stream.Collectors; +import static tools.utils.FileIoUtils.listFilesOrThrow; + /** * Verifies the help translations for validity and completeness. */ @@ -57,10 +59,7 @@ public class VerifyHelpTranslations implements ToolTask { } private static List getHelpTranslations() { - File[] files = new File(FOLDER).listFiles(); - if (files == null) { - throw new IllegalStateException("Could not get files from '" + FOLDER + "'"); - } + File[] files = listFilesOrThrow(new File(FOLDER)); List helpFiles = Arrays.stream(files) .filter(file -> HELP_MESSAGE_PATTERN.matcher(file.getName()).matches()) .collect(Collectors.toList()); diff --git a/src/test/java/tools/messages/VerifyMessagesTask.java b/src/test/java/tools/messages/VerifyMessagesTask.java index 5343d231..661ff9d8 100644 --- a/src/test/java/tools/messages/VerifyMessagesTask.java +++ b/src/test/java/tools/messages/VerifyMessagesTask.java @@ -17,6 +17,8 @@ import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; +import static tools.utils.FileIoUtils.listFilesOrThrow; + /** * Task to verify the keys in the messages files. */ @@ -124,12 +126,7 @@ public final class VerifyMessagesTask implements ToolTask { } private static List getMessagesFiles() { - File folder = new File(MESSAGES_FOLDER); - File[] files = folder.listFiles(); - if (files == null) { - throw new IllegalStateException("Could not read files from folder '" + folder.getName() + "'"); - } - + File[] files = listFilesOrThrow(new File(MESSAGES_FOLDER)); List messageFiles = new ArrayList<>(); for (File file : files) { if (MESSAGE_FILE_PATTERN.matcher(file.getName()).matches()) { diff --git a/src/test/java/tools/messages/translation/WriteAllExportsTask.java b/src/test/java/tools/messages/translation/WriteAllExportsTask.java index f0faf3b0..f59d31ef 100644 --- a/src/test/java/tools/messages/translation/WriteAllExportsTask.java +++ b/src/test/java/tools/messages/translation/WriteAllExportsTask.java @@ -8,6 +8,8 @@ import tools.utils.ToolsConstants; import java.io.File; import java.util.Scanner; +import static tools.utils.FileIoUtils.listFilesOrThrow; + /** * Task which exports all messages to a local folder. */ @@ -22,11 +24,7 @@ public class WriteAllExportsTask extends ExportMessagesTask { @Override public void execute(Scanner scanner) { - File[] messageFiles = new File(MESSAGES_FOLDER).listFiles(); - if (messageFiles == null || messageFiles.length == 0) { - throw new IllegalStateException("Could not read messages folder"); - } - + final File[] messageFiles = listFilesOrThrow(new File(MESSAGES_FOLDER)); final FileConfiguration defaultMessages = loadDefaultMessages(); for (File file : messageFiles) { String code = file.getName().substring("messages_".length(), file.getName().length() - ".yml".length()); diff --git a/src/test/java/tools/utils/FileIoUtils.java b/src/test/java/tools/utils/FileIoUtils.java index 4683633f..eadefd2d 100644 --- a/src/test/java/tools/utils/FileIoUtils.java +++ b/src/test/java/tools/utils/FileIoUtils.java @@ -1,5 +1,6 @@ package tools.utils; +import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -62,4 +63,19 @@ public final class FileIoUtils { } } + /** + * Returns a folder's files or throws an exception if the folder could not be read or if it is empty. + * + * @param folder the folder to read + * @return the files in the folder + */ + public static File[] listFilesOrThrow(File folder) { + File[] files = folder.listFiles(); + if (files == null) { + throw new IllegalStateException("Could not read folder '" + folder + "'"); + } else if (files.length == 0) { + throw new IllegalStateException("Folder '" + folder + "' is empty"); + } + return files; + } } From 265178645662cd4dd9e25ee1184179c878f9e533 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 30 Oct 2016 13:01:22 +0100 Subject: [PATCH 17/67] #459 Add other accounts command + Update config docs --- docs/config.md | 20 ++++++++----- .../process/login/AsynchronousLogin.java | 29 ++++++++++++++++--- .../xephi/authme/service/BukkitService.java | 8 +++++ .../properties/RestrictionSettings.java | 9 ++++++ 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/docs/config.md b/docs/config.md index 10980d8a..4bf54286 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,5 +1,5 @@ - + ## AuthMe Configuration The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, @@ -124,7 +124,7 @@ settings: # The value 0 means an unlimited number of registrations! maxRegPerIp: 1 # Minimum allowed username length - minNicknameLength: 4 + minNicknameLength: 3 # Maximum allowed username length maxNicknameLength: 16 # When this setting is enabled, online players can't be kicked out @@ -199,6 +199,10 @@ settings: noTeleport: false # Regex syntax for allowed chars in passwords allowedPasswordCharacters: '[\x21-\x7E]*' + # Threshold of the other accounts command, a value less than 1 means disabled. + otherAccountsCmdThreshold: 0 + # The other accounts command, available variables: %playername%, %playerip% + otherAccountsCmd: 'say The player %playername% with ip %playerip% has multiple accounts!' # Log level: INFO, FINE, DEBUG. Use INFO for general messages, # FINE for some additional detailed ones (like password failed), # and DEBUG for debugging @@ -246,9 +250,11 @@ settings: # AuthMe will update the password to the new password hash supportOldPasswordHash: false # Prevent unsafe passwords from being used; put them in lowercase! + # You should always set 'help' as unsafePassword due to possible conflicts. # unsafePasswords: # - '123456' # - 'password' + # - 'help' unsafePasswords: - '123456' - 'password' @@ -256,6 +262,7 @@ settings: - '12345' - '54321' - '123456789' + - 'help' registration: # Enable registration on the server? enabled: true @@ -378,7 +385,9 @@ Protection: - 'A1' # Do we need to enable automatic antibot system? enableAntiBot: true - # Max number of players allowed to login in 5 secs + # The interval in seconds + antiBotInterval: 5 + # Max number of players allowed to login in the interval # before the AntiBot system is enabled automatically antiBotSensibility: 10 # Duration in minutes of the antibot automatic system @@ -408,9 +417,6 @@ Security: # Take care with this, if you set this to false, # AuthMe will automatically disable and the server won't be protected! stopServer: true - ReloadCommand: - # /reload support - useReloadCommandSupport: true console: # Remove passwords from console? removePassword: true @@ -455,4 +461,4 @@ To change settings on a running server, save your changes to config.yml and use --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 23 21:08:57 CEST 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 30 12:57:15 CET 2016 diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java index ee91971b..2002232d 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -223,7 +223,11 @@ public class AsynchronousLogin implements AsynchronousProcess { player.setNoDamageTicks(0); service.send(player, MessageKey.LOGIN_SUCCESS); - displayOtherAccounts(auth, player); + + // Other auths + List auths = dataSource.getAllAuthsByIp(auth.getIp()); + runCommandOtherAccounts(auths, player, auth.getIp()); + displayOtherAccounts(auths, player); final String email = auth.getEmail(); if (service.getProperty(EmailSettings.RECALL_PLAYERS) @@ -251,12 +255,29 @@ public class AsynchronousLogin implements AsynchronousProcess { } } - private void displayOtherAccounts(PlayerAuth auth, Player player) { - if (!service.getProperty(RestrictionSettings.DISPLAY_OTHER_ACCOUNTS) || auth == null) { + private void runCommandOtherAccounts(List auths, Player player, String ip) { + int threshold = service.getProperty(RestrictionSettings.OTHER_ACCOUNTS_CMD_THRESHOLD); + String command = service.getProperty(RestrictionSettings.OTHER_ACCOUNTS_CMD); + + if(threshold <= 1 || command.isEmpty()) { + return; + } + + if (auths.size() >= threshold) { + return; + } + + bukkitService.dispatchConsoleCommand(command + .replaceAll("%playername%", player.getName()) + .replaceAll("%playerip%", ip) + ); + } + + private void displayOtherAccounts(List auths, Player player) { + if (!service.getProperty(RestrictionSettings.DISPLAY_OTHER_ACCOUNTS)) { return; } - List auths = dataSource.getAllAuthsByIp(auth.getIp()); if (auths.size() <= 1) { return; } diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index cd5595ff..e94d68cb 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -308,4 +308,12 @@ public class BukkitService implements SettingsDependent { return Bukkit.getServer().getBanList(BanList.Type.IP).addBan(ip, reason, expires, source); } + /** + * Dispatch a command as console + * + * @param command the command + */ + public void dispatchConsoleCommand(String command) { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); + } } diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index c05efa4b..87e0419e 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -4,6 +4,7 @@ import com.github.authme.configme.Comment; import com.github.authme.configme.SettingsHolder; import com.github.authme.configme.properties.Property; +import javax.inject.Inject; import java.util.List; import static com.github.authme.configme.properties.PropertyInitializer.newListProperty; @@ -187,6 +188,14 @@ public class RestrictionSettings implements SettingsHolder { public static final Property> UNRESTRICTED_NAMES = newLowercaseListProperty("settings.unrestrictions.UnrestrictedName"); + @Comment("Threshold of the other accounts command, a value less than 1 means disabled.") + public static final Property OTHER_ACCOUNTS_CMD_THRESHOLD = + newProperty("settings.restrictions.otherAccountsCmdThreshold", 0); + + @Comment("The other accounts command, available variables: %playername%, %playerip%") + public static final Property OTHER_ACCOUNTS_CMD = + newProperty("settings.restrictions.otherAccountsCmd", + "say The player %playername% with ip %playerip% has multiple accounts!"); private RestrictionSettings() { } From 5cce7e1faefa6bdc72cd8fcbd545bfcd69b77175 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 30 Oct 2016 13:44:13 +0100 Subject: [PATCH 18/67] Update version of ConfigMe, Mockito and sqlite-jdbc --- pom.xml | 6 +-- .../xephi/authme/service/MessageUpdater.java | 2 +- .../fr/xephi/authme/task/purge/PurgeTask.java | 2 +- .../authme/AuthMeInitializationTest.java | 2 - .../fr/xephi/authme/ConsoleLoggerTest.java | 2 +- src/test/java/fr/xephi/authme/TestHelper.java | 2 +- .../authme/command/CommandHandlerTest.java | 29 ++++++------ .../authme/command/CommandMapperTest.java | 7 +-- .../authme/command/PlayerCommandTest.java | 6 +-- .../command/executable/HelpCommandTest.java | 4 +- .../authme/AccountsCommandTest.java | 5 +-- .../ChangePasswordAdminCommandTest.java | 5 +-- .../authme/ConverterCommandTest.java | 4 +- .../authme/FirstSpawnCommandTest.java | 4 +- .../authme/ForceLoginCommandTest.java | 15 +++---- .../authme/GetEmailCommandTest.java | 4 +- .../executable/authme/GetIpCommandTest.java | 4 +- .../authme/PurgeBannedPlayersCommandTest.java | 6 +-- .../executable/authme/PurgeCommandTest.java | 4 +- .../authme/PurgeLastPositionCommandTest.java | 4 +- .../authme/RegisterAdminCommandTest.java | 4 +- .../executable/authme/ReloadCommandTest.java | 6 +-- .../authme/SetEmailCommandTest.java | 4 +- .../authme/SetFirstSpawnCommandTest.java | 2 +- .../authme/SetSpawnCommandTest.java | 6 +-- .../executable/authme/SpawnCommandTest.java | 4 +- .../authme/SwitchAntiBotCommandTest.java | 6 +-- .../authme/UnregisterAdminCommandTest.java | 2 - .../ChangePasswordCommandTest.java | 19 ++------ .../executable/email/AddEmailCommandTest.java | 7 +-- .../email/RecoverEmailCommandTest.java | 18 +++----- .../executable/login/LoginCommandTest.java | 4 +- .../executable/logout/LogoutCommandTest.java | 2 +- .../register/RegisterCommandTest.java | 7 +-- .../command/help/HelpMessagesServiceTest.java | 2 +- .../authme/command/help/HelpProviderTest.java | 4 +- .../xephi/authme/data/TempbanManagerTest.java | 4 +- .../AbstractResourceClosingTest.java | 12 ++--- .../datasource/MySqlIntegrationTest.java | 5 +-- .../datasource/SQLiteIntegrationTest.java | 5 +-- .../AbstractDataSourceConverterTest.java | 6 +-- .../converter/CrazyLoginConverterTest.java | 2 +- .../authme/initialization/TaskCloserTest.java | 2 +- .../authme/listener/EntityListenerTest.java | 2 +- .../authme/listener/OnJoinVerifierTest.java | 9 +--- .../authme/listener/PlayerListenerTest.java | 5 +-- .../message/MessagesIntegrationTest.java | 6 +-- .../permission/PermissionsManagerTest.java | 2 - .../process/email/AsyncAddEmailTest.java | 3 +- .../process/email/AsyncChangeEmailTest.java | 4 +- .../process/login/AsynchronousLoginTest.java | 9 ++-- .../AsynchronousUnregisterTest.java | 11 ++--- .../authme/security/PasswordSecurityTest.java | 7 ++- .../authme/service/AntiBotServiceTest.java | 6 ++- .../authme/service/GeoIpServiceTest.java | 3 +- .../authme/service/MigrationServiceTest.java | 8 ++-- .../authme/service/PluginHookServiceTest.java | 3 +- .../service/TeleportationServiceTest.java | 22 +-------- .../task/LimboPlayerTaskManagerTest.java | 13 ++---- .../authme/task/purge/PurgeServiceTest.java | 45 ++++++------------- .../authme/task/purge/PurgeTaskTest.java | 10 ++--- .../EncryptionMethodInfoGatherer.java | 2 +- 62 files changed, 160 insertions(+), 260 deletions(-) diff --git a/pom.xml b/pom.xml index 60fb7c40..a4bd0a9a 100644 --- a/pom.xml +++ b/pom.xml @@ -873,7 +873,7 @@ com.github.authme configme - 0.2 + 0.2.1 compile true @@ -904,7 +904,7 @@ org.mockito mockito-core test - 2.0.5-beta + 2.2.9 hamcrest-core @@ -917,7 +917,7 @@ org.xerial sqlite-jdbc - 3.8.11.2 + 3.14.2.1 test diff --git a/src/main/java/fr/xephi/authme/service/MessageUpdater.java b/src/main/java/fr/xephi/authme/service/MessageUpdater.java index 129a47b8..3aa5aaa6 100644 --- a/src/main/java/fr/xephi/authme/service/MessageUpdater.java +++ b/src/main/java/fr/xephi/authme/service/MessageUpdater.java @@ -57,7 +57,7 @@ public class MessageUpdater { properties = buildPropertyEntriesForMessageKeys(); settingsManager = new SettingsManager( - new YamlFileResource(userFile), (r, p) -> true, new ConfigurationData((List) properties)); + new YamlFileResource(userFile), null, new ConfigurationData(properties)); } /** diff --git a/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java b/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java index a69c5fee..712f81a3 100644 --- a/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java +++ b/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java @@ -81,7 +81,7 @@ class PurgeTask extends BukkitRunnable { } if (!toPurge.isEmpty() && playerPortion.isEmpty()) { - ConsoleLogger.info("Finished lookup up offlinePlayers. Begin looking purging player names only"); + ConsoleLogger.info("Finished lookup of offlinePlayers. Begin looking purging player names only"); //we went through all offlineplayers but there are still names remaining for (String name : toPurge) { diff --git a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java index ba7f7606..a41dc588 100644 --- a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java +++ b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java @@ -21,7 +21,6 @@ import org.bukkit.Server; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginLoader; import org.bukkit.plugin.PluginManager; -import org.bukkit.scheduler.BukkitScheduler; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -80,7 +79,6 @@ public class AuthMeInitializationTest { // Mock / wire various Bukkit components given(server.getLogger()).willReturn(mock(Logger.class)); ReflectionTestUtils.setField(Bukkit.class, null, "server", server); - given(server.getScheduler()).willReturn(mock(BukkitScheduler.class)); given(server.getPluginManager()).willReturn(pluginManager); // PluginDescriptionFile is final: need to create a sample one diff --git a/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java b/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java index 6ae87df6..cb95bef6 100644 --- a/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java +++ b/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java @@ -26,8 +26,8 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; diff --git a/src/test/java/fr/xephi/authme/TestHelper.java b/src/test/java/fr/xephi/authme/TestHelper.java index d16bd31f..5017c476 100644 --- a/src/test/java/fr/xephi/authme/TestHelper.java +++ b/src/test/java/fr/xephi/authme/TestHelper.java @@ -18,8 +18,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.logging.Logger; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; diff --git a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java index cfcb00f5..8723e70c 100644 --- a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java @@ -29,18 +29,18 @@ import static fr.xephi.authme.command.FoundResultStatus.UNKNOWN_LABEL; import static java.util.Arrays.asList; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyListOf; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link CommandHandler}. @@ -85,7 +85,7 @@ public class CommandHandlerTest { given(injector.newInstance(any(Class.class))).willAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { - Class clazz = (Class) invocation.getArguments()[0]; + Class clazz = invocation.getArgument(0); if (ExecutableCommand.class.isAssignableFrom(clazz)) { Class commandClass = (Class) clazz; ExecutableCommand mock = mock(commandClass); @@ -108,7 +108,7 @@ public class CommandHandlerTest { CommandSender sender = mock(CommandSender.class); CommandDescription command = mock(CommandDescription.class); doReturn(TestLoginCommand.class).when(command).getExecutableCommand(); - given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))) + given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyList())) .willReturn(new FoundCommandResult(command, asList("Authme", "Login"), asList("myPass"), 0.0, SUCCESS)); // when @@ -129,7 +129,7 @@ public class CommandHandlerTest { String[] bukkitArgs = {"testPlayer"}; CommandSender sender = mock(CommandSender.class); CommandDescription command = mock(CommandDescription.class); - given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))) + given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyList())) .willReturn(new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.0, NO_PERMISSION)); // when @@ -148,7 +148,7 @@ public class CommandHandlerTest { String[] bukkitArgs = {"testPlayer"}; CommandSender sender = mock(CommandSender.class); CommandDescription command = mock(CommandDescription.class); - given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn( + given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyList())).willReturn( new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.0, INCORRECT_ARGUMENTS)); given(permissionsManager.hasPermission(sender, command.getPermission())).willReturn(true); @@ -170,7 +170,7 @@ public class CommandHandlerTest { String[] bukkitArgs = {"testPlayer"}; CommandSender sender = mock(CommandSender.class); CommandDescription command = mock(CommandDescription.class); - given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn( + given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyList())).willReturn( new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.0, INCORRECT_ARGUMENTS)); given(permissionsManager.hasPermission(sender, command.getPermission())).willReturn(false); @@ -192,7 +192,7 @@ public class CommandHandlerTest { String[] bukkitArgs = {"testPlayer"}; CommandSender sender = mock(CommandSender.class); CommandDescription command = mock(CommandDescription.class); - given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn( + given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyList())).willReturn( new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.0, MISSING_BASE_COMMAND)); // when @@ -212,7 +212,7 @@ public class CommandHandlerTest { CommandSender sender = mock(CommandSender.class); CommandDescription command = mock(CommandDescription.class); given(command.getLabels()).willReturn(Collections.singletonList("test_cmd")); - given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn( + given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyList())).willReturn( new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 0.01, UNKNOWN_LABEL)); // when @@ -237,8 +237,7 @@ public class CommandHandlerTest { String[] bukkitArgs = {"testPlayer"}; CommandSender sender = mock(CommandSender.class); CommandDescription command = mock(CommandDescription.class); - given(command.getLabels()).willReturn(Collections.singletonList("test_cmd")); - given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyListOf(String.class))).willReturn( + given(commandMapper.mapPartsToCommand(any(CommandSender.class), anyList())).willReturn( new FoundCommandResult(command, asList("unreg"), asList("testPlayer"), 1.0, UNKNOWN_LABEL)); // when @@ -263,7 +262,7 @@ public class CommandHandlerTest { CommandDescription command = mock(CommandDescription.class); doReturn(TestRegisterCommand.class).when(command).getExecutableCommand(); - given(commandMapper.mapPartsToCommand(eq(sender), anyListOf(String.class))) + given(commandMapper.mapPartsToCommand(eq(sender), anyList())) .willReturn(new FoundCommandResult(command, asList("AuthMe", "REGISTER"), asList("testArg"), 0.0, SUCCESS)); // when diff --git a/src/test/java/fr/xephi/authme/command/CommandMapperTest.java b/src/test/java/fr/xephi/authme/command/CommandMapperTest.java index 46efdaec..dd7bad6e 100644 --- a/src/test/java/fr/xephi/authme/command/CommandMapperTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandMapperTest.java @@ -28,9 +28,10 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; /** @@ -257,7 +258,7 @@ public class CommandMapperTest { // given List parts = asList("email", "helptest", "arg1"); CommandSender sender = mock(CommandSender.class); - given(permissionsManager.hasPermission(eq(sender), any(PermissionNode.class))).willReturn(true); + given(permissionsManager.hasPermission(eq(sender), isNull())).willReturn(true); // when FoundCommandResult result = mapper.mapPartsToCommand(sender, parts); diff --git a/src/test/java/fr/xephi/authme/command/PlayerCommandTest.java b/src/test/java/fr/xephi/authme/command/PlayerCommandTest.java index 815d8a21..4f0c9997 100644 --- a/src/test/java/fr/xephi/authme/command/PlayerCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/PlayerCommandTest.java @@ -10,10 +10,10 @@ import java.util.Collections; import java.util.List; import static org.hamcrest.Matchers.containsString; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link PlayerCommand}. @@ -27,7 +27,7 @@ public class PlayerCommandTest { PlayerCommandImpl command = new PlayerCommandImpl(); // when - command.executeCommand(sender, Collections.emptyList()); + command.executeCommand(sender, Collections.emptyList()); // then verify(sender).sendMessage(argThat(containsString("only for players"))); @@ -54,7 +54,7 @@ public class PlayerCommandTest { PlayerCommandWithAlt command = new PlayerCommandWithAlt(); // when - command.executeCommand(sender, Collections.emptyList()); + command.executeCommand(sender, Collections.emptyList()); // then verify(sender, times(1)).sendMessage(argThat(containsString("use /authme test instead"))); diff --git a/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java index 3c57e214..37efa2e7 100644 --- a/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java @@ -28,13 +28,13 @@ import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link HelpCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java index 9c645e4d..81e606a9 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java @@ -1,7 +1,7 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.command.CommandService; +import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.service.BukkitService; @@ -20,8 +20,8 @@ import java.util.List; import static fr.xephi.authme.TestHelper.runInnerRunnable; import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -83,7 +83,6 @@ public class AccountsCommandTest { CommandSender sender = mock(CommandSender.class); List arguments = Collections.singletonList("SomeUser"); given(dataSource.getAuth("someuser")).willReturn(mock(PlayerAuth.class)); - given(dataSource.getAllAuthsByIp(anyString())).willReturn(Collections.emptyList()); // when command.executeCommand(sender, arguments); 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 af8f4e96..cdc3c978 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 @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.TestHelper; +import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.security.PasswordSecurity; @@ -22,8 +22,8 @@ import org.mockito.runners.MockitoJUnitRunner; import java.util.Arrays; import static fr.xephi.authme.TestHelper.runOptionallyAsyncTask; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -84,7 +84,6 @@ public class ChangePasswordAdminCommandTest { String player = "player"; String password = "password"; given(playerCache.isAuthenticated(player)).willReturn(false); - given(dataSource.getAuth(player)).willReturn(null); given(validationService.validatePassword(password, player)).willReturn(new ValidationResult()); // when diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java index 32cc6489..dbbf3b71 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java @@ -23,14 +23,14 @@ import java.util.Set; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link ConverterCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java index 000c7922..84556cb9 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java @@ -12,13 +12,13 @@ import org.mockito.runners.MockitoJUnitRunner; import java.util.Collections; import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link FirstSpawnCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java index fc2602bb..8746f01b 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java @@ -17,10 +17,10 @@ import java.util.Collections; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link ForceLoginCommand}. @@ -44,7 +44,7 @@ public class ForceLoginCommandTest { public void shouldRejectOfflinePlayer() { // given String playerName = "Bobby"; - Player player = mockPlayer(false, playerName); + Player player = mockPlayer(false); given(bukkitService.getPlayerExact(playerName)).willReturn(player); CommandSender sender = mock(CommandSender.class); @@ -77,7 +77,7 @@ public class ForceLoginCommandTest { public void shouldRejectPlayerWithMissingPermission() { // given String playerName = "testTest"; - Player player = mockPlayer(true, playerName); + Player player = mockPlayer(true); given(bukkitService.getPlayerExact(playerName)).willReturn(player); given(permissionsManager.hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)).willReturn(false); CommandSender sender = mock(CommandSender.class); @@ -95,7 +95,7 @@ public class ForceLoginCommandTest { public void shouldForceLoginPlayer() { // given String playerName = "tester23"; - Player player = mockPlayer(true, playerName); + Player player = mockPlayer(true); given(bukkitService.getPlayerExact(playerName)).willReturn(player); given(permissionsManager.hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)).willReturn(true); CommandSender sender = mock(CommandSender.class); @@ -112,24 +112,23 @@ public class ForceLoginCommandTest { public void shouldForceLoginSenderSelf() { // given String senderName = "tester23"; - Player player = mockPlayer(true, senderName); + Player player = mockPlayer(true); given(bukkitService.getPlayerExact(senderName)).willReturn(player); given(permissionsManager.hasPermission(player, PlayerPermission.CAN_LOGIN_BE_FORCED)).willReturn(true); CommandSender sender = mock(CommandSender.class); given(sender.getName()).willReturn(senderName); // when - command.executeCommand(sender, Collections.emptyList()); + command.executeCommand(sender, Collections.emptyList()); // then verify(bukkitService).getPlayerExact(senderName); verify(management).forceLogin(player); } - private static Player mockPlayer(boolean isOnline, String name) { + private static Player mockPlayer(boolean isOnline) { Player player = mock(Player.class); given(player.isOnline()).willReturn(isOnline); - given(player.getName()).willReturn(name); return player; } } diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java index f7d32260..6f9d4d12 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java @@ -1,7 +1,7 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.command.CommandService; +import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import org.bukkit.command.CommandSender; @@ -15,9 +15,9 @@ import java.util.Collections; import static org.hamcrest.Matchers.containsString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link GetEmailCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java index 75d8953a..4c681a14 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java @@ -14,11 +14,11 @@ import java.util.Collections; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link GetIpCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java index 1927854e..05695a34 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java @@ -1,7 +1,7 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.task.purge.PurgeService; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.task.purge.PurgeService; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.junit.Test; @@ -16,11 +16,11 @@ import java.util.Set; import static com.google.common.collect.Sets.newHashSet; import static org.hamcrest.Matchers.arrayContainingInAnyOrder; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link PurgeBannedPlayersCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java index 63e1008a..1464a2ca 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java @@ -17,11 +17,11 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link PurgeCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java index 54a31734..75d132ee 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java @@ -1,7 +1,7 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.command.CommandService; +import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import org.bukkit.command.CommandSender; @@ -16,9 +16,9 @@ import java.util.Collections; import static org.hamcrest.Matchers.containsString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link PurgeLastPositionCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java index 508010cf..343515d9 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.TestHelper; +import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.limbo.LimboCache; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.security.PasswordSecurity; @@ -26,8 +26,8 @@ import java.util.Arrays; import static fr.xephi.authme.TestHelper.runSyncTaskFromOptionallyAsyncTask; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java index 07424e15..64915887 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java @@ -8,8 +8,8 @@ import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSourceType; import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.SettingsDependent; -import fr.xephi.authme.output.LogLevel; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.output.LogLevel; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.PluginSettings; @@ -29,13 +29,13 @@ import java.util.Collections; import java.util.List; import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link ReloadCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java index 033bd881..a0c6eea7 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java @@ -1,8 +1,8 @@ package fr.xephi.authme.command.executable.authme; +import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.service.BukkitService; @@ -16,8 +16,8 @@ import org.mockito.runners.MockitoJUnitRunner; import java.util.Arrays; import static fr.xephi.authme.TestHelper.runOptionallyAsyncTask; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SetFirstSpawnCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SetFirstSpawnCommandTest.java index 0974da72..f9d466c1 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SetFirstSpawnCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SetFirstSpawnCommandTest.java @@ -13,9 +13,9 @@ import java.util.Collections; import static org.hamcrest.Matchers.containsString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link SetFirstSpawnCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SetSpawnCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SetSpawnCommandTest.java index 8522f997..8eb9f785 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SetSpawnCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SetSpawnCommandTest.java @@ -13,9 +13,9 @@ import java.util.Collections; import static org.hamcrest.Matchers.containsString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link SetSpawnCommand}. @@ -39,7 +39,7 @@ public class SetSpawnCommandTest { given(spawnLoader.setSpawn(location)).willReturn(true); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(spawnLoader).setSpawn(location); @@ -55,7 +55,7 @@ public class SetSpawnCommandTest { given(spawnLoader.setSpawn(location)).willReturn(false); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(spawnLoader).setSpawn(location); diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SpawnCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SpawnCommandTest.java index 81a7f416..4605f495 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SpawnCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SpawnCommandTest.java @@ -12,13 +12,13 @@ import org.mockito.runners.MockitoJUnitRunner; import java.util.Collections; import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link SpawnCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommandTest.java index 239ba33d..606e1ab6 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommandTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.service.AntiBotService; import fr.xephi.authme.command.CommandMapper; import fr.xephi.authme.command.FoundCommandResult; import fr.xephi.authme.command.help.HelpProvider; +import fr.xephi.authme.service.AntiBotService; import org.bukkit.command.CommandSender; import org.junit.Test; import org.junit.runner.RunWith; @@ -15,12 +15,12 @@ import java.util.Collections; import static java.util.Arrays.asList; import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link SwitchAntiBotCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java index fd2e3688..4b2a0516 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java @@ -61,7 +61,6 @@ public class UnregisterAdminCommandTest { // given String user = "personaNonGrata"; given(dataSource.isAuthAvailable(user)).willReturn(true); - given(dataSource.removeAuth(user)).willReturn(false); Player player = mock(Player.class); given(bukkitService.getPlayerExact(user)).willReturn(player); CommandSender sender = mock(CommandSender.class); @@ -80,7 +79,6 @@ public class UnregisterAdminCommandTest { // given String user = "personaNonGrata"; given(dataSource.isAuthAvailable(user)).willReturn(true); - given(dataSource.removeAuth(user)).willReturn(false); given(bukkitService.getPlayerExact(user)).willReturn(null); CommandSender sender = mock(CommandSender.class); diff --git a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java index 7ca0510b..2329c233 100644 --- a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java @@ -1,36 +1,32 @@ package fr.xephi.authme.command.executable.changepassword; -import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.command.CommandService; +import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; -import fr.xephi.authme.settings.properties.RestrictionSettings; -import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.service.ValidationService.ValidationResult; import org.bukkit.command.BlockCommandSender; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import static org.hamcrest.Matchers.containsString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link ChangePasswordCommand}. @@ -53,22 +49,13 @@ public class ChangePasswordCommandTest { @Mock private Management management; - @Before - public void setSettings() { - when(commandService.getProperty(SecuritySettings.MIN_PASSWORD_LENGTH)).thenReturn(2); - when(commandService.getProperty(SecuritySettings.MAX_PASSWORD_LENGTH)).thenReturn(50); - // Only allow passwords with alphanumerical characters for the test - when(commandService.getProperty(RestrictionSettings.ALLOWED_PASSWORD_REGEX)).thenReturn("[a-zA-Z0-9]+"); - when(commandService.getProperty(SecuritySettings.UNSAFE_PASSWORDS)).thenReturn(Collections.emptyList()); - } - @Test public void shouldRejectNonPlayerSender() { // given CommandSender sender = mock(BlockCommandSender.class); // when - command.executeCommand(sender, new ArrayList()); + command.executeCommand(sender, Collections.emptyList()); // then verify(sender).sendMessage(argThat(containsString("only for players"))); diff --git a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java index 985ce815..217d63c3 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java @@ -12,10 +12,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; -import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; @@ -41,7 +40,7 @@ public class AddEmailCommandTest { CommandSender sender = mock(BlockCommandSender.class); // when - command.executeCommand(sender, new ArrayList()); + command.executeCommand(sender, Collections.emptyList()); // then verifyZeroInteractions(management); @@ -52,7 +51,6 @@ public class AddEmailCommandTest { // given Player sender = mock(Player.class); String email = "mail@example"; - given(commandService.validateEmail(email)).willReturn(true); // when command.executeCommand(sender, Arrays.asList(email, email)); @@ -66,7 +64,6 @@ public class AddEmailCommandTest { // given Player sender = mock(Player.class); String email = "asdfasdf@example.com"; - given(commandService.validateEmail(email)).willReturn(true); // when command.executeCommand(sender, Arrays.asList(email, "wrongConf")); diff --git a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java index 8a3dfcf4..24c93c47 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.email; import fr.xephi.authme.TestHelper; +import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.message.MessageKey; @@ -11,7 +11,6 @@ import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.service.RecoveryCodeService; import fr.xephi.authme.settings.properties.EmailSettings; -import fr.xephi.authme.settings.properties.SecuritySettings; import org.bukkit.entity.Player; import org.junit.BeforeClass; import org.junit.Test; @@ -26,10 +25,10 @@ import java.util.Collections; import static fr.xephi.authme.AuthMeMatchers.stringWithLength; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.only; import static org.mockito.Mockito.verify; @@ -172,10 +171,6 @@ public class RecoverEmailCommandTest { given(playerCache.isAuthenticated(name)).willReturn(false); String email = "v@example.com"; given(dataSource.getAuth(name)).willReturn(newAuthWithEmail(email)); - int codeLength = 7; - given(commandService.getProperty(SecuritySettings.RECOVERY_CODE_LENGTH)).willReturn(codeLength); - int hoursValid = 12; - given(commandService.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)).willReturn(hoursValid); String code = "a94f37"; given(recoveryCodeService.isRecoveryCodeNeeded()).willReturn(true); given(recoveryCodeService.generateCode(name)).willReturn(code); @@ -202,7 +197,6 @@ public class RecoverEmailCommandTest { String email = "vulture@example.com"; PlayerAuth auth = newAuthWithEmail(email); given(dataSource.getAuth(name)).willReturn(auth); - given(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH)).willReturn(20); given(recoveryCodeService.isRecoveryCodeNeeded()).willReturn(true); given(recoveryCodeService.isCodeValid(name, "bogus")).willReturn(false); @@ -230,7 +224,7 @@ public class RecoverEmailCommandTest { given(dataSource.getAuth(name)).willReturn(auth); given(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH)).willReturn(20); given(passwordSecurity.computeHash(anyString(), eq(name))) - .willAnswer(invocation -> new HashedPassword((String) invocation.getArguments()[0])); + .willAnswer(invocation -> new HashedPassword(invocation.getArgument(0))); given(recoveryCodeService.isRecoveryCodeNeeded()).willReturn(true); given(recoveryCodeService.isCodeValid(name, code)).willReturn(true); @@ -263,7 +257,7 @@ public class RecoverEmailCommandTest { given(dataSource.getAuth(name)).willReturn(auth); given(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH)).willReturn(20); given(passwordSecurity.computeHash(anyString(), eq(name))) - .willAnswer(invocation -> new HashedPassword((String) invocation.getArguments()[0])); + .willAnswer(invocation -> new HashedPassword(invocation.getArgument(0))); given(recoveryCodeService.isRecoveryCodeNeeded()).willReturn(false); // when diff --git a/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java index 5e02b4b2..1e6a4a47 100644 --- a/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java @@ -14,11 +14,11 @@ import java.util.ArrayList; import java.util.Collections; import static org.hamcrest.Matchers.containsString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link LoginCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java index 7bc9eeb1..35457c31 100644 --- a/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java @@ -14,10 +14,10 @@ import java.util.ArrayList; import java.util.Collections; import static org.hamcrest.Matchers.containsString; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link LogoutCommand}. diff --git a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java index a4dfe8f7..7e7b23c9 100644 --- a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java @@ -27,12 +27,12 @@ import java.util.Collections; import static fr.xephi.authme.AuthMeMatchers.stringWithLength; import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link RegisterCommand}. @@ -158,7 +158,6 @@ public class RegisterCommandTest { given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true); given(commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL)).willReturn(true); - given(commandService.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("server@example.com"); given(sendMailSsl.hasAllInformation()).willReturn(true); Player player = mock(Player.class); @@ -179,7 +178,6 @@ public class RegisterCommandTest { given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true); given(commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL)).willReturn(true); - given(commandService.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("server@example.com"); given(sendMailSsl.hasAllInformation()).willReturn(true); Player player = mock(Player.class); @@ -202,7 +200,6 @@ public class RegisterCommandTest { given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true); given(commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL)).willReturn(true); - given(commandService.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("server@example.com"); given(sendMailSsl.hasAllInformation()).willReturn(true); Player player = mock(Player.class); diff --git a/src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java b/src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java index 150bb42f..292b0ec9 100644 --- a/src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java +++ b/src/test/java/fr/xephi/authme/command/help/HelpMessagesServiceTest.java @@ -21,8 +21,8 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.sameInstance; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; /** * Test for {@link HelpMessagesService}. diff --git a/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java b/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java index e90a7612..99ec921c 100644 --- a/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java +++ b/src/test/java/fr/xephi/authme/command/help/HelpProviderTest.java @@ -39,9 +39,9 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; diff --git a/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java b/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java index 70aa11c7..73d48ac3 100644 --- a/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java +++ b/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java @@ -5,9 +5,9 @@ import fr.xephi.authme.TestHelper; import fr.xephi.authme.data.TempbanManager.TimedCounter; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.Messages; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.SecuritySettings; -import fr.xephi.authme.service.BukkitService; import org.bukkit.entity.Player; import org.junit.Test; import org.junit.runner.RunWith; @@ -25,8 +25,8 @@ import static org.hamcrest.Matchers.anEmptyMap; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.lessThan; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; diff --git a/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java b/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java index c8aeb796..0b8d7bde 100644 --- a/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java +++ b/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java @@ -37,11 +37,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -98,14 +98,14 @@ public abstract class AbstractResourceClosingTest { } /** Initialize the settings mock and makes it return the default of any given property by default. */ - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings("unchecked") @BeforeClass public static void initializeSettings() throws IOException, ClassNotFoundException { settings = mock(Settings.class); given(settings.getProperty(any(Property.class))).willAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) { - return ((Property) invocation.getArguments()[0]).getDefaultValue(); + return ((Property) invocation.getArguments()[0]).getDefaultValue(); } }); TestHelper.setupLogger(); diff --git a/src/test/java/fr/xephi/authme/datasource/MySqlIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/MySqlIntegrationTest.java index 5484bd5e..0edc804f 100644 --- a/src/test/java/fr/xephi/authme/datasource/MySqlIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/datasource/MySqlIntegrationTest.java @@ -4,9 +4,6 @@ import com.github.authme.configme.properties.Property; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import fr.xephi.authme.TestHelper; -import fr.xephi.authme.datasource.AbstractDataSourceIntegrationTest; -import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.datasource.MySQL; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; import org.junit.After; @@ -22,7 +19,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/fr/xephi/authme/datasource/SQLiteIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/SQLiteIntegrationTest.java index 9398e4ed..6caca39c 100644 --- a/src/test/java/fr/xephi/authme/datasource/SQLiteIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/datasource/SQLiteIntegrationTest.java @@ -3,9 +3,6 @@ package fr.xephi.authme.datasource; import com.github.authme.configme.properties.Property; import fr.xephi.authme.TestHelper; import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.datasource.AbstractDataSourceIntegrationTest; -import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.datasource.SQLite; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; import org.junit.After; @@ -25,7 +22,7 @@ import java.sql.Statement; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverterTest.java b/src/test/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverterTest.java index 897f36e9..14e59dff 100644 --- a/src/test/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverterTest.java +++ b/src/test/java/fr/xephi/authme/datasource/converter/AbstractDataSourceConverterTest.java @@ -13,10 +13,9 @@ import java.util.Arrays; import java.util.List; import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.only; @@ -24,6 +23,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link AbstractDataSourceConverter}. diff --git a/src/test/java/fr/xephi/authme/datasource/converter/CrazyLoginConverterTest.java b/src/test/java/fr/xephi/authme/datasource/converter/CrazyLoginConverterTest.java index e24953b9..453ede99 100644 --- a/src/test/java/fr/xephi/authme/datasource/converter/CrazyLoginConverterTest.java +++ b/src/test/java/fr/xephi/authme/datasource/converter/CrazyLoginConverterTest.java @@ -23,11 +23,11 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link CrazyLoginConverter}. diff --git a/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java b/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java index d474ac6f..7f677e0c 100644 --- a/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java +++ b/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java @@ -24,8 +24,8 @@ import java.util.concurrent.Executors; import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; diff --git a/src/test/java/fr/xephi/authme/listener/EntityListenerTest.java b/src/test/java/fr/xephi/authme/listener/EntityListenerTest.java index 1f36fa8d..4d678cf7 100644 --- a/src/test/java/fr/xephi/authme/listener/EntityListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/EntityListenerTest.java @@ -19,8 +19,8 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.only; diff --git a/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java b/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java index 3b764bd7..f27e9614 100644 --- a/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java +++ b/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java @@ -175,10 +175,7 @@ public class OnJoinVerifierTest { @Test public void shouldNotKickRegisteredPlayer() throws FailedVerificationException { - // given - given(settings.getProperty(RestrictionSettings.KICK_NON_REGISTERED)).willReturn(true); - - // when + // given / when / then onJoinVerifier.checkKickNonRegistered(true); } @@ -206,7 +203,6 @@ public class OnJoinVerifierTest { @Test public void shouldRejectTooLongName() throws FailedVerificationException { // given - given(settings.getProperty(RestrictionSettings.MIN_NICKNAME_LENGTH)).willReturn(4); given(settings.getProperty(RestrictionSettings.MAX_NICKNAME_LENGTH)).willReturn(8); given(settings.getProperty(RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS)).willReturn("[a-zA-Z0-9]+"); onJoinVerifier.reload(); // @PostConstruct method @@ -324,7 +320,6 @@ public class OnJoinVerifierTest { // given Player player = newPlayerWithName("MyPlayer"); PlayerAuth auth = null; - given(settings.getProperty(RegistrationSettings.PREVENT_OTHER_CASE)).willReturn(true); // when onJoinVerifier.checkNameCasing(player, auth); @@ -460,7 +455,6 @@ public class OnJoinVerifierTest { // given String ip = "192.168.0.1"; given(settings.getProperty(ProtectionSettings.ENABLE_PROTECTION)).willReturn(true); - given(settings.getProperty(ProtectionSettings.ENABLE_PROTECTION_REGISTERED)).willReturn(false); given(validationService.isCountryAdmitted(ip)).willReturn(true); // when @@ -490,7 +484,6 @@ public class OnJoinVerifierTest { // given String ip = "192.168.40.0"; given(settings.getProperty(ProtectionSettings.ENABLE_PROTECTION)).willReturn(true); - given(settings.getProperty(ProtectionSettings.ENABLE_PROTECTION_REGISTERED)).willReturn(true); given(validationService.isCountryAdmitted(ip)).willReturn(false); // expect diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java index 992752f9..437cb250 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java @@ -50,9 +50,9 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -379,7 +379,6 @@ public class PlayerListenerTest { Location to = new Location(world, 199, 70, 199); PlayerMoveEvent event = spy(new PlayerMoveEvent(player, from, to)); given(listenerService.shouldCancelEvent(player)).willReturn(true); - given(settings.getProperty(RestrictionSettings.REMOVE_SPEED)).willReturn(false); // when listener.onPlayerMove(event); diff --git a/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java b/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java index a8ff7ddb..04004634 100644 --- a/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java @@ -19,14 +19,14 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link Messages}. diff --git a/src/test/java/fr/xephi/authme/permission/PermissionsManagerTest.java b/src/test/java/fr/xephi/authme/permission/PermissionsManagerTest.java index 8ede82b6..8d562d9d 100644 --- a/src/test/java/fr/xephi/authme/permission/PermissionsManagerTest.java +++ b/src/test/java/fr/xephi/authme/permission/PermissionsManagerTest.java @@ -62,7 +62,6 @@ public class PermissionsManagerTest { // given PermissionNode node = TestPermissions.WORLD_DOMINATION; CommandSender sender = mock(CommandSender.class); - given(sender.isOp()).willReturn(true); // when boolean result = permissionsManager.hasPermission(sender, node); @@ -116,7 +115,6 @@ public class PermissionsManagerTest { // given PermissionNode node = TestPermissions.WORLD_DOMINATION; Player player = mock(Player.class); - given(player.isOp()).willReturn(true); // when boolean result = permissionsManager.hasPermission(player, node); diff --git a/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java b/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java index e14c69f5..10fdc0c5 100644 --- a/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java +++ b/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java @@ -15,8 +15,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -79,7 +79,6 @@ public class AsyncAddEmailTest { PlayerAuth auth = mock(PlayerAuth.class); given(auth.getEmail()).willReturn(null); given(playerCache.getAuth("tester")).willReturn(auth); - given(dataSource.countAuthsByEmail(email)).willReturn(0); given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(false); given(service.validateEmail(email)).willReturn(true); given(service.isEmailFreeForRegistration(email, player)).willReturn(true); diff --git a/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java b/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java index ea18f86b..330384cf 100644 --- a/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java +++ b/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java @@ -13,8 +13,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -128,8 +128,6 @@ public class AsyncChangeEmailTest { PlayerAuth auth = authWithMail("other@address.email"); given(playerCache.getAuth("bobby")).willReturn(auth); given(service.validateEmail(newEmail)).willReturn(true); - given(service.isEmailFreeForRegistration(newEmail, player)).willReturn(true); - // when process.changeEmail(player, "old@mail.tld", newEmail); diff --git a/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java b/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java index 33e8f05b..33e9b1aa 100644 --- a/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java +++ b/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java @@ -9,12 +9,12 @@ import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.task.LimboPlayerTaskManager; -import fr.xephi.authme.service.BukkitService; import org.bukkit.entity.Player; import org.junit.BeforeClass; import org.junit.Test; @@ -31,9 +31,9 @@ import java.util.Collection; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -162,7 +162,7 @@ public class AsynchronousLoginTest { doAnswer(new Answer() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { - invocation.getArgumentAt(0, AuthMeAsyncPreLoginEvent.class).setCanLogin(false); + ((AuthMeAsyncPreLoginEvent) invocation.getArgument(0)).setCanLogin(false); return null; } }).when(bukkitService).callEvent(any(AuthMeAsyncPreLoginEvent.class)); @@ -271,7 +271,6 @@ public class AsynchronousLoginTest { // 192.168.0.0: france (offline) Player playerF = mockPlayer("france"); TestHelper.mockPlayerIp(playerF, "192.168.0.0"); - given(dataSource.isLogged(playerF.getName())).willReturn(false); Collection onlinePlayers = Arrays.asList(playerA, playerB, playerC, playerD, playerE, playerF); given(bukkitService.getOnlinePlayers()).willReturn(onlinePlayers); diff --git a/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java b/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java index 318b782a..10978579 100644 --- a/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java +++ b/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java @@ -11,11 +11,11 @@ import fr.xephi.authme.permission.AuthGroupType; import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.HashedPassword; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.TeleportationService; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.task.LimboPlayerTaskManager; -import fr.xephi.authme.service.BukkitService; -import fr.xephi.authme.service.TeleportationService; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.junit.BeforeClass; @@ -25,8 +25,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.only; @@ -185,7 +185,6 @@ public class AsynchronousUnregisterTest { Player player = mock(Player.class); String name = "Frank21"; given(player.getName()).willReturn(name); - given(player.isOnline()).willReturn(true); PlayerAuth auth = mock(PlayerAuth.class); given(playerCache.getAuth(name)).willReturn(auth); HashedPassword password = new HashedPassword("password", "in_auth_obj"); @@ -218,9 +217,6 @@ public class AsynchronousUnregisterTest { String userPassword = "pass"; given(passwordSecurity.comparePassword(userPassword, password, name)).willReturn(true); given(dataSource.removeAuth(name)).willReturn(true); - given(service.getProperty(RegistrationSettings.FORCE)).willReturn(true); - given(service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)).willReturn(true); - given(service.getProperty(RestrictionSettings.TIMEOUT)).willReturn(12); // when asynchronousUnregister.unregister(player, userPassword); @@ -238,7 +234,6 @@ public class AsynchronousUnregisterTest { // given Player player = mock(Player.class); String name = "Frank21"; - given(player.getName()).willReturn(name); given(player.isOnline()).willReturn(true); given(dataSource.removeAuth(name)).willReturn(true); given(service.getProperty(RegistrationSettings.FORCE)).willReturn(true); diff --git a/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java b/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java index 2e6adff4..1911bb39 100644 --- a/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java +++ b/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java @@ -27,14 +27,14 @@ import org.mockito.stubbing.Answer; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link PasswordSecurity}. @@ -233,7 +233,6 @@ public class PasswordSecurityTest { String password = "?topSecretPass\\"; String username = "someone12"; HashedPassword hashedPassword = new HashedPassword("~T!est#Hash"); - given(method.computeHash(password, username)).willReturn(hashedPassword); given(method.hasSeparateSalt()).willReturn(true); initSettings(HashAlgorithm.XAUTH, false); PasswordSecurity security = newPasswordSecurity(); diff --git a/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java b/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java index db7f3e7d..dd6b6c78 100644 --- a/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/AntiBotServiceTest.java @@ -11,6 +11,7 @@ import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.ProtectionSettings; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitTask; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -21,9 +22,9 @@ import java.util.List; import static fr.xephi.authme.TestHelper.runSyncDelayedTaskWithDelay; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.only; import static org.mockito.Mockito.reset; @@ -81,6 +82,7 @@ public class AntiBotServiceTest { } @Test + @Ignore // TODO ljacqu 20161030: Fix test public void shouldActivateAntibot() { // given - listening antibot runSyncDelayedTaskWithDelay(bukkitService); diff --git a/src/test/java/fr/xephi/authme/service/GeoIpServiceTest.java b/src/test/java/fr/xephi/authme/service/GeoIpServiceTest.java index 5d1d9681..62f00776 100644 --- a/src/test/java/fr/xephi/authme/service/GeoIpServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/GeoIpServiceTest.java @@ -2,7 +2,6 @@ package fr.xephi.authme.service; import com.maxmind.geoip.Country; import com.maxmind.geoip.LookupService; -import fr.xephi.authme.service.GeoIpService; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -16,8 +15,8 @@ import java.io.IOException; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; diff --git a/src/test/java/fr/xephi/authme/service/MigrationServiceTest.java b/src/test/java/fr/xephi/authme/service/MigrationServiceTest.java index 7283a468..cccefa00 100644 --- a/src/test/java/fr/xephi/authme/service/MigrationServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/MigrationServiceTest.java @@ -21,13 +21,13 @@ import java.util.Arrays; import static fr.xephi.authme.AuthMeMatchers.equalToHash; import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link MigrationService}. @@ -126,7 +126,7 @@ public class MigrationServiceTest { given(sha256.computeHash(anyString(), anyString())).willAnswer(new Answer() { @Override public HashedPassword answer(InvocationOnMock invocation) { - String plainPassword = (String) invocation.getArguments()[0]; + String plainPassword = invocation.getArgument(0); return new HashedPassword(plainPassword.toUpperCase(), null); } }); diff --git a/src/test/java/fr/xephi/authme/service/PluginHookServiceTest.java b/src/test/java/fr/xephi/authme/service/PluginHookServiceTest.java index 970bcef4..d4e3f8cd 100644 --- a/src/test/java/fr/xephi/authme/service/PluginHookServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/PluginHookServiceTest.java @@ -5,7 +5,6 @@ import com.earth2me.essentials.User; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MultiverseWorld; -import fr.xephi.authme.service.PluginHookService; import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.TestHelper; import org.bukkit.Location; @@ -22,8 +21,8 @@ import java.io.File; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; diff --git a/src/test/java/fr/xephi/authme/service/TeleportationServiceTest.java b/src/test/java/fr/xephi/authme/service/TeleportationServiceTest.java index 30af5b0b..318a5a33 100644 --- a/src/test/java/fr/xephi/authme/service/TeleportationServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/TeleportationServiceTest.java @@ -26,9 +26,9 @@ import java.util.Arrays; import static fr.xephi.authme.TestHelper.runSyncDelayedTask; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -127,11 +127,6 @@ public class TeleportationServiceTest { public void shouldNotTeleportNewPlayer() { // given Player player = mock(Player.class); - given(player.hasPlayedBefore()).willReturn(false); - given(player.isOnline()).willReturn(true); - given(player.getWorld()).willReturn(mock(World.class)); - given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(false); - given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false); given(spawnLoader.getFirstSpawn()).willReturn(null); // when @@ -148,7 +143,6 @@ public class TeleportationServiceTest { public void shouldNotTeleportPlayerToFirstSpawnIfNoTeleportEnabled() { // given Player player = mock(Player.class); - given(player.hasPlayedBefore()).willReturn(false); given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(true); // when @@ -163,7 +157,6 @@ public class TeleportationServiceTest { public void shouldNotTeleportNotNewPlayerToFirstSpawn() { // given Player player = mock(Player.class); - given(player.hasPlayedBefore()).willReturn(true); given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(false); // when @@ -273,9 +266,7 @@ public class TeleportationServiceTest { given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(true); given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(false); Player player = mock(Player.class); - given(player.isOnline()).willReturn(true); Location spawn = mockLocation(); - given(spawnLoader.getSpawnLocation(player)).willReturn(spawn); PlayerAuth auth = mock(PlayerAuth.class); LimboPlayer limbo = mock(LimboPlayer.class); Location limboLocation = mockLocation(); @@ -293,7 +284,6 @@ public class TeleportationServiceTest { @Test public void shouldTeleportBackToPlayerAuthLocation() { // given - given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false); given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true); given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(true); @@ -321,7 +311,6 @@ public class TeleportationServiceTest { @Test public void shouldTeleportAccordingToPlayerAuthAndPlayerWorldAsFallback() { // given - given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false); given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true); given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(true); @@ -350,7 +339,6 @@ public class TeleportationServiceTest { @Test public void shouldTeleportWithLimboPlayerIfAuthYCoordIsNotSet() { // given - given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false); given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true); given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(true); @@ -359,8 +347,6 @@ public class TeleportationServiceTest { auth.setWorld("authWorld"); Player player = mock(Player.class); given(player.isOnline()).willReturn(true); - World world = mock(World.class); - given(player.getWorld()).willReturn(world); LimboPlayer limbo = mock(LimboPlayer.class); Location location = mockLocation(); given(limbo.getLocation()).willReturn(location); @@ -377,15 +363,12 @@ public class TeleportationServiceTest { @Test public void shouldTeleportWithLimboPlayerIfSaveQuitLocIsDisabled() { // given - given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false); given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true); given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(false); PlayerAuth auth = createAuthWithLocation(); Player player = mock(Player.class); given(player.isOnline()).willReturn(true); - World world = mock(World.class); - given(player.getWorld()).willReturn(world); LimboPlayer limbo = mock(LimboPlayer.class); Location location = mockLocation(); given(limbo.getLocation()).willReturn(location); @@ -403,7 +386,6 @@ public class TeleportationServiceTest { // given given(settings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)).willReturn(false); given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true); - given(settings.getProperty(RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN)).willReturn(false); PlayerAuth auth = PlayerAuth.builder().name("bobby").build(); Player player = mock(Player.class); diff --git a/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java b/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java index 7a2f9eeb..c479c344 100644 --- a/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java +++ b/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java @@ -6,10 +6,10 @@ import fr.xephi.authme.data.limbo.LimboCache; import fr.xephi.authme.data.limbo.LimboPlayer; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.Messages; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; -import fr.xephi.authme.service.BukkitService; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitTask; import org.junit.BeforeClass; @@ -19,10 +19,10 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; @@ -98,9 +98,6 @@ public class LimboPlayerTaskManagerTest { // given String name = "Tester1"; LimboPlayer limboPlayer = mock(LimboPlayer.class); - given(limboCache.getPlayerData(name)).willReturn(limboPlayer); - BukkitTask bukkiTask = mock(BukkitTask.class); - given(bukkitService.runTask(any(MessageTask.class))).willReturn(bukkiTask); given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(0); // when @@ -178,9 +175,7 @@ public class LimboPlayerTaskManagerTest { // given String name = "snail"; Player player = mock(Player.class); - given(player.getName()).willReturn(name); LimboPlayer limboPlayer = mock(LimboPlayer.class); - given(limboCache.getPlayerData(name)).willReturn(limboPlayer); given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(0); // when diff --git a/src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java b/src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java index d6fe5b57..c0c952e9 100644 --- a/src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java +++ b/src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java @@ -4,9 +4,9 @@ import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.TestHelper; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.permission.PermissionsManager; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.PurgeSettings; -import fr.xephi.authme.service.BukkitService; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -32,15 +32,15 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.anyCollectionOf; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link PurgeService}. @@ -100,7 +100,6 @@ public class PurgeServiceTest { given(settings.getProperty(PurgeSettings.DAYS_BEFORE_REMOVE_PLAYER)).willReturn(60); Set playerNames = newHashSet("alpha", "bravo", "charlie", "delta"); given(dataSource.getRecordsToPurge(anyLong(), eq(false))).willReturn(playerNames); - mockReturnedOfflinePlayers(); // when purgeService.runAutoPurge(); @@ -119,7 +118,7 @@ public class PurgeServiceTest { // given final long delay = 123012301L; final boolean includeLastLoginZeroEntries = true; - given(dataSource.getRecordsToPurge(delay, includeLastLoginZeroEntries)).willReturn(Collections.emptySet()); + given(dataSource.getRecordsToPurge(delay, includeLastLoginZeroEntries)).willReturn(Collections.emptySet()); CommandSender sender = mock(CommandSender.class); // when @@ -127,7 +126,7 @@ public class PurgeServiceTest { // then verify(dataSource).getRecordsToPurge(delay, includeLastLoginZeroEntries); - verify(dataSource, never()).purgeRecords(anyCollectionOf(String.class)); + verify(dataSource, never()).purgeRecords(anyCollection()); verify(sender).sendMessage("No players to purge"); verifyZeroInteractions(bukkitService, permissionsManager); } @@ -139,7 +138,6 @@ public class PurgeServiceTest { final boolean includeLastLoginZeroEntries = false; Set playerNames = newHashSet("charlie", "delta", "echo", "foxtrot"); given(dataSource.getRecordsToPurge(delay, includeLastLoginZeroEntries)).willReturn(playerNames); - mockReturnedOfflinePlayers(); Player sender = mock(Player.class); UUID uuid = UUID.randomUUID(); given(sender.getUniqueId()).willReturn(uuid); @@ -157,10 +155,10 @@ public class PurgeServiceTest { // given purgeService.setPurging(true); CommandSender sender = mock(CommandSender.class); - OfflinePlayer[] players = mockReturnedOfflinePlayers(); + OfflinePlayer[] offlinePlayers = new OfflinePlayer[]{mock(OfflinePlayer.class), mock(OfflinePlayer.class)}; // when - purgeService.purgePlayers(sender, newHashSet("test", "names"), players); + purgeService.purgePlayers(sender, newHashSet("test", "names"), offlinePlayers); // then verify(sender).sendMessage(argThat(containsString("Purge is already in progress"))); @@ -170,32 +168,15 @@ public class PurgeServiceTest { @Test public void shouldExecutePurgeActions() { // given - List players = Arrays.asList(mockReturnedOfflinePlayers()); List names = Arrays.asList("alpha", "bravo", "foxtrot"); + List offlinePlayers = Arrays.asList( + mock(OfflinePlayer.class), mock(OfflinePlayer.class), mock(OfflinePlayer.class)); // when - purgeService.executePurge(players, names); + purgeService.executePurge(offlinePlayers, names); // then - verify(executor).executePurge(players, names); - } - - /** - * Returns mock OfflinePlayer objects with names corresponding to A - G of the NATO phonetic alphabet, - * in various casing. - * - * @return list of offline players BukkitService is mocked to return - */ - private OfflinePlayer[] mockReturnedOfflinePlayers() { - String[] names = { "alfa", "Bravo", "charLIE", "delta", "ECHO", "Foxtrot", "golf" }; - OfflinePlayer[] players = new OfflinePlayer[names.length]; - for (int i = 0; i < names.length; ++i) { - OfflinePlayer player = mock(OfflinePlayer.class); - given(player.getName()).willReturn(names[i]); - players[i] = player; - } - given(bukkitService.getOfflinePlayers()).willReturn(players); - return players; + verify(executor).executePurge(offlinePlayers, names); } private void assertCorrectPurgeTimestamp(long timestamp, int configuredDays) { diff --git a/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java b/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java index 2168756d..728669f7 100644 --- a/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java +++ b/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java @@ -35,16 +35,16 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.empty; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.mockito.hamcrest.MockitoHamcrest.argThat; /** * Test for {@link PurgeTask}. @@ -191,7 +191,7 @@ public class PurgeTaskTest { .willAnswer(new Answer() { @Override public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable { - OfflinePlayer player = (OfflinePlayer) invocationOnMock.getArguments()[0]; + OfflinePlayer player = invocationOnMock.getArgument(0); Boolean hasPermission = playerBypassAssignments.get(player); if (hasPermission == null) { throw new IllegalStateException("Unexpected check of '" + BYPASS_NODE diff --git a/src/test/java/tools/docs/hashmethods/EncryptionMethodInfoGatherer.java b/src/test/java/tools/docs/hashmethods/EncryptionMethodInfoGatherer.java index 00809a73..9cf98f33 100644 --- a/src/test/java/tools/docs/hashmethods/EncryptionMethodInfoGatherer.java +++ b/src/test/java/tools/docs/hashmethods/EncryptionMethodInfoGatherer.java @@ -20,7 +20,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; From 1b1f6786daf5ada66b8ff7928169570f886c8c43 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Wed, 2 Nov 2016 14:46:24 +0100 Subject: [PATCH 19/67] #974 Improve plugin.yml consistency test checking of permission children --- .../permission/PermissionConsistencyTest.java | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/test/java/fr/xephi/authme/permission/PermissionConsistencyTest.java b/src/test/java/fr/xephi/authme/permission/PermissionConsistencyTest.java index f44ef222..757319d5 100644 --- a/src/test/java/fr/xephi/authme/permission/PermissionConsistencyTest.java +++ b/src/test/java/fr/xephi/authme/permission/PermissionConsistencyTest.java @@ -2,6 +2,9 @@ package fr.xephi.authme.permission; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import fr.xephi.authme.ClassCollector; +import fr.xephi.authme.TestHelper; import org.bukkit.configuration.MemorySection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -12,9 +15,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import static fr.xephi.authme.TestHelper.getJarFile; import static org.junit.Assert.fail; @@ -24,10 +29,6 @@ import static org.junit.Assert.fail; */ public class PermissionConsistencyTest { - /** All classes defining permission nodes. */ - private static final Set> PERMISSION_CLASSES = ImmutableSet - .of(PlayerPermission.class, AdminPermission.class, PlayerStatePermission.class); - /** Wildcard permissions (present in plugin.yml but not in the codebase). */ private static final Set PLUGIN_YML_PERMISSIONS_WILDCARDS = ImmutableSet.of("authme.admin.*", "authme.player.*", "authme.player.email"); @@ -35,6 +36,9 @@ public class PermissionConsistencyTest { /** Name of the fields that make up a permission entry in plugin.yml. */ private static final Set PERMISSION_FIELDS = ImmutableSet.of("description", "default", "children"); + /** All classes defining permission nodes. */ + private static List> permissionClasses; + /** All known PermissionNode objects. */ private static List permissionNodes; @@ -43,6 +47,10 @@ public class PermissionConsistencyTest { @BeforeClass public static void gatherPermissionNodes() { + permissionClasses = new ClassCollector(TestHelper.SOURCES_FOLDER, TestHelper.PROJECT_ROOT + "permission") + .collectClasses(PermissionNode.class).stream() + .filter(clz -> !clz.isInterface()) + .collect(Collectors.toList()); permissionNodes = getPermissionsFromClasses(); pluginYmlPermissions = getPermissionsFromPluginYmlFile(); } @@ -109,7 +117,7 @@ public class PermissionConsistencyTest { */ private static List getPermissionsFromClasses() { List nodes = new ArrayList<>(); - for (Class clazz : PERMISSION_CLASSES) { + for (Class clazz : permissionClasses) { nodes.addAll(Arrays.asList(clazz.getEnumConstants())); } return Collections.unmodifiableList(nodes); @@ -163,15 +171,16 @@ public class PermissionConsistencyTest { // Replace ending .* in path if present, e.g. authme.player.* -> authme.player // Add ending '.' since we want all children to be children, i.e. authme.playertest would not be OK String root = definition.node.replaceAll("\\.\\*$", "") + "."; - List badChildren = new ArrayList<>(); - for (String child : definition.children) { - if (!child.startsWith(root)) { - badChildren.add(child); - } + Set expectedChildren = permissionNodes.stream().map(PermissionNode::getNode) + .filter(n -> n.startsWith(root)).collect(Collectors.toSet()); + Set missingChildren = Sets.difference(expectedChildren, definition.children); + Set unexpectedChildren = Sets.difference(definition.children, expectedChildren); + + if (!missingChildren.isEmpty()) { + errorList.add("Node '" + definition.node + "' has missing children: " + missingChildren); } - if (!badChildren.isEmpty()) { - errorList.add("Permission '" + definition.node + "' has children that are not logically below it: " - + String.join(", ", badChildren)); + if (!unexpectedChildren.isEmpty()) { + errorList.add("Node '" + definition.node + "' has unexpected children: " + unexpectedChildren); } } @@ -181,7 +190,7 @@ public class PermissionConsistencyTest { private static final class PermissionDefinition { private final String node; - private final List children; + private final Set children; private final DefaultPermission expectedDefault; PermissionDefinition(MemorySection memorySection) { @@ -193,7 +202,7 @@ public class PermissionConsistencyTest { collectChildren((MemorySection) memorySection.get("children"), children); this.children = removeStart(memorySection.getCurrentPath() + ".children.", children); } else { - this.children = Collections.emptyList(); + this.children = Collections.emptySet(); } } @@ -243,6 +252,10 @@ public class PermissionConsistencyTest { if (entry.getValue() instanceof MemorySection) { collectChildren((MemorySection) entry.getValue(), children); } else if (entry.getValue() instanceof Boolean) { + if (!Boolean.TRUE.equals(entry.getValue())) { + throw new IllegalStateException("Child entry '" + entry.getKey() + + "' has unexpected value '" + entry.getValue() + "'"); + } children.add(parentSection.getCurrentPath() + "." + entry.getKey()); } else { throw new IllegalStateException("Found child entry at '" + entry.getKey() + "' with value " @@ -258,8 +271,8 @@ public class PermissionConsistencyTest { * @param list the entries to modify * @return list with shortened entries */ - private static List removeStart(String start, List list) { - List result = new ArrayList<>(list.size()); + private static Set removeStart(String start, List list) { + Set result = new HashSet<>(list.size()); for (String entry : list) { result.add(entry.substring(start.length())); } From dd89851604ac012febab47ef309c6d88309906f8 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Wed, 2 Nov 2016 18:24:54 +0100 Subject: [PATCH 20/67] Run task closer on the main thread #992 --- src/main/java/fr/xephi/authme/AuthMe.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index b52caf32..7a78a745 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -343,10 +343,7 @@ public class AuthMe extends JavaPlugin { } // Wait for tasks and close data source - new Thread( - new TaskCloser(this, database), - "AuthMe-DataSource#close" - ).start(); + new TaskCloser(this, database).run(); // Disabled correctly ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " disabled!"); From 969d660965fd750acfdad375749cd4e208326ed0 Mon Sep 17 00:00:00 2001 From: Den Date: Sat, 5 Nov 2016 16:17:27 +0300 Subject: [PATCH 21/67] Update messages_ru.yml Translated some expressions --- src/main/resources/messages/messages_ru.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/messages/messages_ru.yml b/src/main/resources/messages/messages_ru.yml index 01374ae8..f37f3a41 100644 --- a/src/main/resources/messages/messages_ru.yml +++ b/src/main/resources/messages/messages_ru.yml @@ -72,7 +72,7 @@ kicked_admin_registered: 'Администратор зарегистриров tempban_max_logins: '&cВы были временно забанены, потому что вы пытались войти в систему слишком много раз.' accounts_owned_self: 'Вы являетесь владельцем %count аккаунтов:' incomplete_email_settings: 'Ошибка: не все необходимые параметры установлены для отправки электронной почты. Пожалуйста, обратитесь к администратору.' -# TODO email_show: '&2Your current email address is: &f%email' -# TODO show_no_email: '&2You currently don''t have email address associated with this account.' -# TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' \ No newline at end of file +email_show: '&2Ваш текущий адрес электронной почты: &f%email' +show_no_email: '&2В данный момент к вашему аккаунте не привязана электронная почта.' +recovery_code_sent: 'Код восстановления для сброса пароля был отправлен на вашу электронную почту.' +recovery_code_incorrect: 'Код восстановления неверный! Введите /email recovery [email], чтобы отправить новый код' From 72853a382fd636f0933d15b2c0b94a75525fc11b Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 6 Nov 2016 18:51:07 +0100 Subject: [PATCH 22/67] Initialization cleanup: use provider classes for Settings and DataSource - Separate provider methods from other tasks performed on startup - No longer requires BukkitService to be instantiated manually - Merge MetricsManager and Initializer into OnStartUpTasks --- src/main/java/fr/xephi/authme/AuthMe.java | 52 +++--- .../initialization/DataSourceProvider.java | 123 ++++++++++++ .../authme/initialization/HasCleanup.java | 2 + .../authme/initialization/Initializer.java | 176 ------------------ .../authme/initialization/MetricsManager.java | 47 ----- .../authme/initialization/OnStartupTasks.java | 127 +++++++++++++ .../authme/initialization/Reloadable.java | 2 + .../initialization/SettingsDependent.java | 2 + .../initialization/SettingsProvider.java | 44 +++++ .../xephi/authme/service/BukkitService.java | 4 +- .../java/fr/xephi/authme/util/FileUtils.java | 16 ++ 11 files changed, 340 insertions(+), 255 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java delete mode 100644 src/main/java/fr/xephi/authme/initialization/Initializer.java delete mode 100644 src/main/java/fr/xephi/authme/initialization/MetricsManager.java create mode 100644 src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java create mode 100644 src/main/java/fr/xephi/authme/initialization/SettingsProvider.java diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 7a78a745..78620307 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -5,13 +5,14 @@ import ch.jalu.injector.InjectorBuilder; import com.google.common.annotations.VisibleForTesting; import fr.xephi.authme.api.API; import fr.xephi.authme.api.NewAPI; -import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.command.CommandHandler; +import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.initialization.DataFolder; -import fr.xephi.authme.initialization.Initializer; -import fr.xephi.authme.initialization.MetricsManager; +import fr.xephi.authme.initialization.DataSourceProvider; import fr.xephi.authme.initialization.OnShutdownPlayerSaver; +import fr.xephi.authme.initialization.OnStartupTasks; +import fr.xephi.authme.initialization.SettingsProvider; import fr.xephi.authme.initialization.TaskCloser; import fr.xephi.authme.listener.BlockListener; import fr.xephi.authme.listener.EntityListener; @@ -20,20 +21,19 @@ import fr.xephi.authme.listener.PlayerListener16; import fr.xephi.authme.listener.PlayerListener18; import fr.xephi.authme.listener.PlayerListener19; import fr.xephi.authme.listener.ServerListener; -import fr.xephi.authme.message.Messages; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionsSystemType; import fr.xephi.authme.security.crypts.SHA256; import fr.xephi.authme.service.BackupService; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.GeoIpService; +import fr.xephi.authme.service.MigrationService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.SecuritySettings; import fr.xephi.authme.task.CleanupTask; import fr.xephi.authme.task.purge.PurgeService; -import fr.xephi.authme.service.BukkitService; -import fr.xephi.authme.service.MigrationService; import fr.xephi.authme.util.PlayerUtils; import org.bukkit.Server; import org.bukkit.command.Command; @@ -68,7 +68,6 @@ public class AuthMe extends JavaPlugin { private CommandHandler commandHandler; private PermissionsManager permsMan; private Settings settings; - private Messages messages; private DataSource database; private BukkitService bukkitService; private Injector injector; @@ -156,7 +155,7 @@ public class AuthMe extends JavaPlugin { new BackupService(this, settings).doBackup(BackupService.BackupCause.START); // Set up Metrics - MetricsManager.sendMetrics(this, settings); + OnStartupTasks.sendMetrics(this, settings); // Sponsor messages ConsoleLogger.info("Development builds are available on our jenkins, thanks to f14stelt."); @@ -202,37 +201,27 @@ public class AuthMe extends JavaPlugin { // Create plugin folder getDataFolder().mkdir(); - // Load settings and set up the console and console filter - settings = Initializer.createSettings(this); - bukkitService = new BukkitService(this, settings); - Initializer initializer = new Initializer(this, bukkitService); - - ConsoleLogger.setLoggingOptions(settings); - initializer.setupConsoleFilter(settings, getLogger()); - - // Connect to the database and set up tables - database = initializer.setupDatabase(settings); - - // Convert deprecated PLAINTEXT hash entries - MigrationService.changePlainTextToSha256(settings, database, new SHA256()); - - // Injector initialization + // Create injector, provide elements from the Bukkit environment and register providers injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme").create(); - - // Register elements of the Bukkit / JavaPlugin environment injector.register(AuthMe.class, this); injector.register(Server.class, getServer()); injector.register(PluginManager.class, getServer().getPluginManager()); injector.register(BukkitScheduler.class, getServer().getScheduler()); injector.provide(DataFolder.class, getDataFolder()); + injector.registerProvider(Settings.class, SettingsProvider.class); + injector.registerProvider(DataSource.class, DataSourceProvider.class); - // Register elements we instantiate manually - injector.register(Settings.class, settings); - injector.register(DataSource.class, database); - injector.register(BukkitService.class, bukkitService); + // Get settings and set up logger + settings = injector.getSingleton(Settings.class); + ConsoleLogger.setLoggingOptions(settings); + OnStartupTasks.setupConsoleFilter(settings, getLogger()); + // Set all service fields on the AuthMe class instantiateServices(injector); + // Convert deprecated PLAINTEXT hash entries + MigrationService.changePlainTextToSha256(settings, database, new SHA256()); + // TODO: does this still make sense? -sgdc3 // If the server is empty (fresh start) just set all the players as unlogged if (bukkitService.getOnlinePlayers().size() == 0) { @@ -243,7 +232,8 @@ public class AuthMe extends JavaPlugin { registerEventListeners(injector); // Start Email recall task if needed - initializer.scheduleRecallEmailTask(settings, database, messages); + OnStartupTasks onStartupTasks = injector.newInstance(OnStartupTasks.class); + onStartupTasks.scheduleRecallEmailTask(); } /** @@ -256,7 +246,7 @@ public class AuthMe extends JavaPlugin { playerCache = PlayerCache.getInstance(); injector.register(PlayerCache.class, playerCache); - messages = injector.getSingleton(Messages.class); + database = injector.getSingleton(DataSource.class); permsMan = injector.getSingleton(PermissionsManager.class); bukkitService = injector.getSingleton(BukkitService.class); commandHandler = injector.getSingleton(CommandHandler.class); diff --git a/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java b/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java new file mode 100644 index 00000000..68605953 --- /dev/null +++ b/src/main/java/fr/xephi/authme/initialization/DataSourceProvider.java @@ -0,0 +1,123 @@ +package fr.xephi.authme.initialization; + +import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.datasource.CacheDataSource; +import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.datasource.DataSourceType; +import fr.xephi.authme.datasource.FlatFile; +import fr.xephi.authme.datasource.MySQL; +import fr.xephi.authme.datasource.SQLite; +import fr.xephi.authme.datasource.converter.ForceFlatToSqlite; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.DatabaseSettings; + +import javax.inject.Inject; +import javax.inject.Provider; +import java.io.File; +import java.io.IOException; +import java.sql.SQLException; + +/** + * Creates the AuthMe data source. + */ +public class DataSourceProvider implements Provider { + + private static final String FLATFILE_FILENAME = "auths.db"; + private static final int SQLITE_MAX_SIZE = 4000; + + @Inject + @DataFolder + private File dataFolder; + @Inject + private Settings settings; + @Inject + private BukkitService bukkitService; + + DataSourceProvider() { + } + + @Override + public DataSource get() { + try { + return createDataSource(); + } catch (Exception e) { + ConsoleLogger.logException("Could not create data source:", e); + throw new IllegalStateException("Error during initialization of data source", e); + } + } + + /** + * Sets up the data source. + * + * @return the constructed datasource + * @throws ClassNotFoundException if no driver could be found for the datasource + * @throws SQLException when initialization of a SQL datasource failed + * @throws IOException if flat file cannot be read + */ + private DataSource createDataSource() throws ClassNotFoundException, SQLException, IOException { + DataSourceType dataSourceType = settings.getProperty(DatabaseSettings.BACKEND); + DataSource dataSource; + switch (dataSourceType) { + case FILE: + File source = new File(dataFolder, FLATFILE_FILENAME); + dataSource = new FlatFile(source); + break; + case MYSQL: + dataSource = new MySQL(settings); + break; + case SQLITE: + dataSource = new SQLite(settings); + break; + default: + throw new UnsupportedOperationException("Unknown data source type '" + dataSourceType + "'"); + } + + dataSource = convertFlatfileToSqlite(dataSource); + + if (settings.getProperty(DatabaseSettings.USE_CACHING)) { + dataSource = new CacheDataSource(dataSource); + } + if (DataSourceType.SQLITE.equals(dataSourceType)) { + checkDataSourceSize(dataSource, bukkitService); + } + return dataSource; + } + + private void checkDataSourceSize(final DataSource dataSource, BukkitService bukkitService) { + bukkitService.runTaskAsynchronously(() -> { + int accounts = dataSource.getAccountsRegistered(); + if (accounts >= SQLITE_MAX_SIZE) { + ConsoleLogger.warning("YOU'RE USING THE SQLITE DATABASE WITH " + + accounts + "+ ACCOUNTS; FOR BETTER PERFORMANCE, PLEASE UPGRADE TO MYSQL!!"); + } + }); + } + + /** + * Converts the data source from the deprecated FLATFILE type to SQLITE. + * + * @param dataSource the data source to convert if necessary + * @return the data source to use: the converted datasource (SQLite), + * or the same data source if no conversion was performed + */ + private DataSource convertFlatfileToSqlite(DataSource dataSource) { + if (DataSourceType.FILE == settings.getProperty(DatabaseSettings.BACKEND)) { + ConsoleLogger.warning("FlatFile backend has been detected and is now deprecated; it will be changed " + + "to SQLite... Connection will be impossible until conversion is done!"); + FlatFile flatFile = (FlatFile) dataSource; + try { + SQLite sqlite = new SQLite(settings); + ForceFlatToSqlite converter = new ForceFlatToSqlite(flatFile, sqlite); + converter.execute(null); + settings.setProperty(DatabaseSettings.BACKEND, DataSourceType.SQLITE); + settings.save(); + return sqlite; + } catch (Exception e) { + ConsoleLogger.logException("Error during conversion from Flatfile to SQLite", e); + throw new IllegalStateException(e); + } + } + return dataSource; + } +} diff --git a/src/main/java/fr/xephi/authme/initialization/HasCleanup.java b/src/main/java/fr/xephi/authme/initialization/HasCleanup.java index db047d84..351df4f6 100644 --- a/src/main/java/fr/xephi/authme/initialization/HasCleanup.java +++ b/src/main/java/fr/xephi/authme/initialization/HasCleanup.java @@ -3,6 +3,8 @@ package fr.xephi.authme.initialization; /** * Common interface for types which have data that becomes outdated * and that can be cleaned up periodically. + * + * @see fr.xephi.authme.task.CleanupTask */ public interface HasCleanup { diff --git a/src/main/java/fr/xephi/authme/initialization/Initializer.java b/src/main/java/fr/xephi/authme/initialization/Initializer.java deleted file mode 100644 index 525334c2..00000000 --- a/src/main/java/fr/xephi/authme/initialization/Initializer.java +++ /dev/null @@ -1,176 +0,0 @@ -package fr.xephi.authme.initialization; - -import com.github.authme.configme.knownproperties.ConfigurationData; -import com.github.authme.configme.resource.PropertyResource; -import com.github.authme.configme.resource.YamlFileResource; -import fr.xephi.authme.AuthMe; -import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.datasource.CacheDataSource; -import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.datasource.DataSourceType; -import fr.xephi.authme.datasource.FlatFile; -import fr.xephi.authme.datasource.MySQL; -import fr.xephi.authme.datasource.SQLite; -import fr.xephi.authme.message.MessageKey; -import fr.xephi.authme.message.Messages; -import fr.xephi.authme.output.ConsoleFilter; -import fr.xephi.authme.output.Log4JFilter; -import fr.xephi.authme.service.BukkitService; -import fr.xephi.authme.service.MigrationService; -import fr.xephi.authme.settings.Settings; -import fr.xephi.authme.settings.SettingsMigrationService; -import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever; -import fr.xephi.authme.settings.properties.DatabaseSettings; -import fr.xephi.authme.settings.properties.EmailSettings; -import fr.xephi.authme.settings.properties.SecuritySettings; -import fr.xephi.authme.util.FileUtils; -import fr.xephi.authme.util.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.io.File; -import java.io.IOException; -import java.sql.SQLException; -import java.util.logging.Logger; - -import static fr.xephi.authme.service.BukkitService.TICKS_PER_MINUTE; -import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS; - -/** - * Initializes various services. - */ -public class Initializer { - - private static final String FLATFILE_FILENAME = "auths.db"; - private static final int SQLITE_MAX_SIZE = 4000; - - private AuthMe authMe; - private BukkitService bukkitService; - - public Initializer(AuthMe authMe, BukkitService bukkitService) { - this.authMe = authMe; - this.bukkitService = bukkitService; - } - - /** - * Loads the plugin's settings. - * - * @param authMe the plugin instance - * @return the settings instance, or null if it could not be constructed - */ - public static Settings createSettings(AuthMe authMe) throws Exception { - File configFile = new File(authMe.getDataFolder(), "config.yml"); - if(!configFile.exists()) { - configFile.createNewFile(); - } - PropertyResource resource = new YamlFileResource(configFile); - SettingsMigrationService migrationService = new SettingsMigrationService(authMe.getDataFolder()); - ConfigurationData configurationData = AuthMeSettingsRetriever.buildConfigurationData(); - return new Settings(authMe.getDataFolder(), resource, migrationService, configurationData); - } - - /** - * Sets up the data source. - * - * @param settings the settings - * @return the constructed datasource - * @throws ClassNotFoundException if no driver could be found for the datasource - * @throws SQLException when initialization of a SQL datasource failed - * @throws IOException if flat file cannot be read - */ - public DataSource setupDatabase(Settings settings) throws ClassNotFoundException, SQLException, IOException { - DataSourceType dataSourceType = settings.getProperty(DatabaseSettings.BACKEND); - DataSource dataSource; - switch (dataSourceType) { - case FILE: - File source = new File(authMe.getDataFolder(), FLATFILE_FILENAME); - dataSource = new FlatFile(source); - break; - case MYSQL: - dataSource = new MySQL(settings); - break; - case SQLITE: - dataSource = new SQLite(settings); - break; - default: - throw new UnsupportedOperationException("Unknown data source type '" + dataSourceType + "'"); - } - - DataSource convertedSource = MigrationService.convertFlatfileToSqlite(settings, dataSource); - dataSource = convertedSource == null ? dataSource : convertedSource; - - if (settings.getProperty(DatabaseSettings.USE_CACHING)) { - dataSource = new CacheDataSource(dataSource); - } - if (DataSourceType.SQLITE.equals(dataSourceType)) { - checkDataSourceSize(dataSource); - } - return dataSource; - } - - private void checkDataSourceSize(final DataSource dataSource) { - bukkitService.runTaskAsynchronously(new Runnable() { - @Override - public void run() { - int accounts = dataSource.getAccountsRegistered(); - if (accounts >= SQLITE_MAX_SIZE) { - ConsoleLogger.warning("YOU'RE USING THE SQLITE DATABASE WITH " - + accounts + "+ ACCOUNTS; FOR BETTER PERFORMANCE, PLEASE UPGRADE TO MYSQL!!"); - } - } - }); - } - - /** - * Sets up the console filter if enabled. - * - * @param settings the settings - * @param logger the plugin logger - */ - public void setupConsoleFilter(Settings settings, Logger logger) { - if (!settings.getProperty(SecuritySettings.REMOVE_PASSWORD_FROM_CONSOLE)) { - return; - } - // Try to set the log4j filter - try { - Class.forName("org.apache.logging.log4j.core.filter.AbstractFilter"); - setLog4JFilter(); - } catch (ClassNotFoundException | NoClassDefFoundError e) { - // log4j is not available - ConsoleLogger.info("You're using Minecraft 1.6.x or older, Log4J support will be disabled"); - ConsoleFilter filter = new ConsoleFilter(); - logger.setFilter(filter); - Bukkit.getLogger().setFilter(filter); - Logger.getLogger("Minecraft").setFilter(filter); - } - } - - // Set the console filter to remove the passwords - private static void setLog4JFilter() { - org.apache.logging.log4j.core.Logger logger; - logger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger(); - logger.addFilter(new Log4JFilter()); - } - - public void scheduleRecallEmailTask(Settings settings, final DataSource dataSource, final Messages messages) { - if (!settings.getProperty(RECALL_PLAYERS)) { - return; - } - bukkitService.runTaskTimerAsynchronously(new Runnable() { - @Override - public void run() { - for (PlayerAuth auth : dataSource.getLoggedPlayers()) { - String email = auth.getEmail(); - if (StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email)) { - Player player = bukkitService.getPlayerExact(auth.getRealName()); - if (player != null) { - messages.send(player, MessageKey.ADD_EMAIL_MESSAGE); - } - } - } - } - }, 1, TICKS_PER_MINUTE * settings.getProperty(EmailSettings.DELAY_RECALL)); - } -} diff --git a/src/main/java/fr/xephi/authme/initialization/MetricsManager.java b/src/main/java/fr/xephi/authme/initialization/MetricsManager.java deleted file mode 100644 index e22e742e..00000000 --- a/src/main/java/fr/xephi/authme/initialization/MetricsManager.java +++ /dev/null @@ -1,47 +0,0 @@ -package fr.xephi.authme.initialization; - -import fr.xephi.authme.AuthMe; -import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.settings.Settings; -import fr.xephi.authme.settings.properties.DatabaseSettings; -import fr.xephi.authme.settings.properties.PluginSettings; -import org.mcstats.Metrics; -import org.mcstats.Metrics.Graph; - -import java.io.IOException; - -public class MetricsManager { - - private MetricsManager() { - } - - public static void sendMetrics(AuthMe plugin, Settings settings) { - try { - final Metrics metrics = new Metrics(plugin); - - final Graph languageGraph = metrics.createGraph("Messages Language"); - final String messagesLanguage = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE); - languageGraph.addPlotter(new Metrics.Plotter(messagesLanguage) { - @Override - public int getValue() { - return 1; - } - }); - - final Graph databaseBackend = metrics.createGraph("Database Backend"); - final String dataSource = settings.getProperty(DatabaseSettings.BACKEND).toString(); - databaseBackend.addPlotter(new Metrics.Plotter(dataSource) { - @Override - public int getValue() { - return 1; - } - }); - - // Submit metrics - metrics.start(); - } catch (IOException e) { - // Failed to submit the metrics data - ConsoleLogger.logException("Can't send Metrics data! The plugin will work anyway...", e); - } - } -} diff --git a/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java b/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java new file mode 100644 index 00000000..0dd42181 --- /dev/null +++ b/src/main/java/fr/xephi/authme/initialization/OnStartupTasks.java @@ -0,0 +1,127 @@ +package fr.xephi.authme.initialization; + +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.data.auth.PlayerAuth; +import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.message.Messages; +import fr.xephi.authme.output.ConsoleFilter; +import fr.xephi.authme.output.Log4JFilter; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.DatabaseSettings; +import fr.xephi.authme.settings.properties.EmailSettings; +import fr.xephi.authme.settings.properties.PluginSettings; +import fr.xephi.authme.settings.properties.SecuritySettings; +import fr.xephi.authme.util.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.mcstats.Metrics; + +import javax.inject.Inject; +import java.io.IOException; +import java.util.logging.Logger; + +import static fr.xephi.authme.service.BukkitService.TICKS_PER_MINUTE; +import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS; + +/** + * Contains actions such as migrations that should be performed on startup. + */ +public class OnStartupTasks { + + @Inject + private DataSource dataSource; + @Inject + private Settings settings; + @Inject + private BukkitService bukkitService; + @Inject + private Messages messages; + + OnStartupTasks() { + } + + public static void sendMetrics(AuthMe plugin, Settings settings) { + try { + final Metrics metrics = new Metrics(plugin); + + final Metrics.Graph languageGraph = metrics.createGraph("Messages Language"); + final String messagesLanguage = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE); + languageGraph.addPlotter(new Metrics.Plotter(messagesLanguage) { + @Override + public int getValue() { + return 1; + } + }); + + final Metrics.Graph databaseBackend = metrics.createGraph("Database Backend"); + final String dataSource = settings.getProperty(DatabaseSettings.BACKEND).toString(); + databaseBackend.addPlotter(new Metrics.Plotter(dataSource) { + @Override + public int getValue() { + return 1; + } + }); + + // Submit metrics + metrics.start(); + } catch (IOException e) { + // Failed to submit the metrics data + ConsoleLogger.logException("Can't send Metrics data! The plugin will work anyway...", e); + } + } + + /** + * Sets up the console filter if enabled. + * + * @param settings the settings + * @param logger the plugin logger + */ + public static void setupConsoleFilter(Settings settings, Logger logger) { + if (!settings.getProperty(SecuritySettings.REMOVE_PASSWORD_FROM_CONSOLE)) { + return; + } + // Try to set the log4j filter + try { + Class.forName("org.apache.logging.log4j.core.filter.AbstractFilter"); + setLog4JFilter(); + } catch (ClassNotFoundException | NoClassDefFoundError e) { + // log4j is not available + ConsoleLogger.info("You're using Minecraft 1.6.x or older, Log4J support will be disabled"); + ConsoleFilter filter = new ConsoleFilter(); + logger.setFilter(filter); + Bukkit.getLogger().setFilter(filter); + Logger.getLogger("Minecraft").setFilter(filter); + } + } + + // Set the console filter to remove the passwords + private static void setLog4JFilter() { + org.apache.logging.log4j.core.Logger logger; + logger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger(); + logger.addFilter(new Log4JFilter()); + } + + public void scheduleRecallEmailTask() { + if (!settings.getProperty(RECALL_PLAYERS)) { + return; + } + bukkitService.runTaskTimerAsynchronously(new Runnable() { + @Override + public void run() { + for (PlayerAuth auth : dataSource.getLoggedPlayers()) { + String email = auth.getEmail(); + if (StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email)) { + Player player = bukkitService.getPlayerExact(auth.getRealName()); + if (player != null) { + messages.send(player, MessageKey.ADD_EMAIL_MESSAGE); + } + } + } + } + }, 1, TICKS_PER_MINUTE * settings.getProperty(EmailSettings.DELAY_RECALL)); + } +} diff --git a/src/main/java/fr/xephi/authme/initialization/Reloadable.java b/src/main/java/fr/xephi/authme/initialization/Reloadable.java index 6b28fc7d..65c3a337 100644 --- a/src/main/java/fr/xephi/authme/initialization/Reloadable.java +++ b/src/main/java/fr/xephi/authme/initialization/Reloadable.java @@ -2,6 +2,8 @@ package fr.xephi.authme.initialization; /** * Interface for reloadable entities. + * + * @see fr.xephi.authme.command.executable.authme.ReloadCommand */ public interface Reloadable { diff --git a/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java b/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java index 487f70d5..89d18318 100644 --- a/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java +++ b/src/main/java/fr/xephi/authme/initialization/SettingsDependent.java @@ -4,6 +4,8 @@ import fr.xephi.authme.settings.Settings; /** * Interface for classes that keep a local copy of certain settings. + * + * @see fr.xephi.authme.command.executable.authme.ReloadCommand */ public interface SettingsDependent { diff --git a/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java b/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java new file mode 100644 index 00000000..5d98cac3 --- /dev/null +++ b/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java @@ -0,0 +1,44 @@ +package fr.xephi.authme.initialization; + +import com.github.authme.configme.knownproperties.ConfigurationData; +import com.github.authme.configme.resource.PropertyResource; +import com.github.authme.configme.resource.YamlFileResource; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.SettingsMigrationService; +import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever; +import fr.xephi.authme.util.FileUtils; + +import javax.inject.Inject; +import javax.inject.Provider; +import java.io.File; + +/** + * Initializes the settings. + */ +public class SettingsProvider implements Provider { + + @Inject + @DataFolder + private File dataFolder; + + SettingsProvider() { + } + + /** + * Loads the plugin's settings. + * + * @return the settings instance, or null if it could not be constructed + */ + @Override + public Settings get() { + File configFile = new File(dataFolder, "config.yml"); + if (!configFile.exists()) { + FileUtils.create(configFile); + } + PropertyResource resource = new YamlFileResource(configFile); + SettingsMigrationService migrationService = new SettingsMigrationService(dataFolder); + ConfigurationData configurationData = AuthMeSettingsRetriever.buildConfigurationData(); + return new Settings(dataFolder, resource, migrationService, configurationData); + } + +} diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index e94d68cb..20aa23c2 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -17,6 +17,7 @@ import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitTask; +import javax.inject.Inject; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; @@ -40,7 +41,8 @@ public class BukkitService implements SettingsDependent { private Method getOnlinePlayers; private boolean useAsyncTasks; - public BukkitService(AuthMe authMe, Settings settings) { + @Inject + BukkitService(AuthMe authMe, Settings settings) { this.authMe = authMe; getOnlinePlayersIsCollection = initializeOnlinePlayersIsCollectionField(); reload(settings); diff --git a/src/main/java/fr/xephi/authme/util/FileUtils.java b/src/main/java/fr/xephi/authme/util/FileUtils.java index 86c8cae4..c9edcf73 100644 --- a/src/main/java/fr/xephi/authme/util/FileUtils.java +++ b/src/main/java/fr/xephi/authme/util/FileUtils.java @@ -98,6 +98,22 @@ public final class FileUtils { } } + /** + * Creates the given file or throws an exception. + * + * @param file the file to create + */ + public static void create(File file) { + try { + boolean result = file.createNewFile(); + if (!result) { + throw new IllegalStateException("Could not create file '" + file + "'"); + } + } catch (IOException e) { + throw new IllegalStateException("Error while creating file '" + file + "'", e); + } + } + /** * Construct a file path from the given elements, i.e. separate the given elements by the file separator. * From a574245bb9e6760724d32c5ba61bbe25a50ada94 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Mon, 7 Nov 2016 00:47:07 +0100 Subject: [PATCH 23/67] Use custom async thread execution pool The new pool has a limited thread size (cpu core count - 1) and should avoid bot attacks to crash the machine. --- src/main/java/fr/xephi/authme/AuthMe.java | 2 +- .../authme/initialization/TaskCloser.java | 18 +++++++++- .../xephi/authme/service/BukkitService.java | 33 +++++++++++++++++-- .../authme/initialization/TaskCloserTest.java | 7 ++-- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 78620307..7c722b22 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -333,7 +333,7 @@ public class AuthMe extends JavaPlugin { } // Wait for tasks and close data source - new TaskCloser(this, database).run(); + new TaskCloser(this, database, bukkitService).run(); // Disabled correctly ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " disabled!"); diff --git a/src/main/java/fr/xephi/authme/initialization/TaskCloser.java b/src/main/java/fr/xephi/authme/initialization/TaskCloser.java index c1126975..105e4dbd 100644 --- a/src/main/java/fr/xephi/authme/initialization/TaskCloser.java +++ b/src/main/java/fr/xephi/authme/initialization/TaskCloser.java @@ -3,6 +3,7 @@ package fr.xephi.authme.initialization; import com.google.common.annotations.VisibleForTesting; import fr.xephi.authme.AuthMe; import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.service.BukkitService; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitWorker; @@ -22,22 +23,27 @@ public class TaskCloser implements Runnable { private final Logger logger; private final AuthMe plugin; private final DataSource dataSource; + private final BukkitService bukkitService; /** * Constructor. * * @param plugin the plugin instance * @param dataSource the data source (nullable) + * @param bukkitService the bukkit service instance (nullable) */ - public TaskCloser(AuthMe plugin, DataSource dataSource) { + public TaskCloser(AuthMe plugin, DataSource dataSource, BukkitService bukkitService) { this.scheduler = plugin.getServer().getScheduler(); this.logger = plugin.getLogger(); this.plugin = plugin; this.dataSource = dataSource; + this.bukkitService = bukkitService; } @Override public void run() { + logger.info("Closing scheduled tasks:"); + List pendingTasks = getPendingTasks(); logger.log(Level.INFO, "Waiting for {0} tasks to finish", pendingTasks.size()); int progress = 0; @@ -69,6 +75,16 @@ public class TaskCloser implements Runnable { tries--; } + logger.info("Closing async tasks..."); + if(bukkitService != null) { + try { + bukkitService.closeAsyncPool(); + } catch (InterruptedException e) { + logger.log(Level.WARNING, "Unable to close some async task", e); + } + } + + logger.info("Closing datasource..."); if (dataSource != null) { dataSource.close(); } diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index 20aa23c2..188b7c42 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -5,6 +5,7 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.PluginSettings; +import fr.xephi.authme.util.Utils; import org.bukkit.BanEntry; import org.bukkit.BanList; import org.bukkit.Bukkit; @@ -25,6 +26,10 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; /** * Service for operations requiring the Bukkit API, such as for scheduling. @@ -41,13 +46,35 @@ public class BukkitService implements SettingsDependent { private Method getOnlinePlayers; private boolean useAsyncTasks; + // Async executor + private ThreadPoolExecutor asyncExecutor; + @Inject BukkitService(AuthMe authMe, Settings settings) { this.authMe = authMe; getOnlinePlayersIsCollection = initializeOnlinePlayersIsCollectionField(); + + int coreCount = Utils.getCoreCount(); + // Keep 1 free core for the main thread and the OS + if(coreCount != 1) { + coreCount--; + } + asyncExecutor = new ThreadPoolExecutor(coreCount, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, + new SynchronousQueue<>()); + reload(settings); } + /** + * Wait the shutdown of the async execution pool. + * + * @throws InterruptedException if the shutdown is interrupted + */ + public void closeAsyncPool() throws InterruptedException { + asyncExecutor.shutdown(); + asyncExecutor.awaitTermination(30, TimeUnit.SECONDS); + } + /** * Schedules a once off task to occur as soon as possible. *

@@ -135,12 +162,12 @@ public class BukkitService implements SettingsDependent { * Returns a task that will run asynchronously. * * @param task the task to be run - * @return a BukkitTask that contains the id number * @throws IllegalArgumentException if plugin is null * @throws IllegalArgumentException if task is null */ - public BukkitTask runTaskAsynchronously(Runnable task) { - return Bukkit.getScheduler().runTaskAsynchronously(authMe, task); + public void runTaskAsynchronously(Runnable task) { + asyncExecutor.execute(task); + //Bukkit.getScheduler().runTaskAsynchronously(authMe, task); } /** diff --git a/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java b/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java index 7f677e0c..a76aedd6 100644 --- a/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java +++ b/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java @@ -3,6 +3,7 @@ package fr.xephi.authme.initialization; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.service.BukkitService; import org.bukkit.Server; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginLogger; @@ -49,6 +50,8 @@ public class TaskCloserTest { private BukkitScheduler bukkitScheduler; @Mock private DataSource dataSource; + @Mock + private BukkitService bukkitService; @Before public void initAuthMe() { @@ -56,7 +59,7 @@ public class TaskCloserTest { given(server.getScheduler()).willReturn(bukkitScheduler); ReflectionTestUtils.setField(JavaPlugin.class, authMe, "server", server); ReflectionTestUtils.setField(JavaPlugin.class, authMe, "logger", logger); - taskCloser = spy(new TaskCloser(authMe, dataSource)); + taskCloser = spy(new TaskCloser(authMe, dataSource, bukkitService)); } @Test @@ -120,7 +123,7 @@ public class TaskCloserTest { /** Test implementation for {@link #shouldStopForInterruptedThread()}. */ private void shouldStopForInterruptedThread0() throws InterruptedException { // given - taskCloser = spy(new TaskCloser(authMe, null)); + taskCloser = spy(new TaskCloser(authMe, null, bukkitService)); // First two times do nothing, third time throw exception when we sleep doNothing().doNothing().doThrow(InterruptedException.class).when(taskCloser).sleep(); mockActiveWorkers(); From 5e0ee51692e9f66f4e892e9e79e0b50c8950fc2f Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Mon, 7 Nov 2016 00:48:50 +0100 Subject: [PATCH 24/67] Revert "Use custom async thread execution pool" This reverts commit a574245bb9e6760724d32c5ba61bbe25a50ada94. --- src/main/java/fr/xephi/authme/AuthMe.java | 2 +- .../authme/initialization/TaskCloser.java | 18 +--------- .../xephi/authme/service/BukkitService.java | 33 ++----------------- .../authme/initialization/TaskCloserTest.java | 7 ++-- 4 files changed, 7 insertions(+), 53 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 7c722b22..78620307 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -333,7 +333,7 @@ public class AuthMe extends JavaPlugin { } // Wait for tasks and close data source - new TaskCloser(this, database, bukkitService).run(); + new TaskCloser(this, database).run(); // Disabled correctly ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " disabled!"); diff --git a/src/main/java/fr/xephi/authme/initialization/TaskCloser.java b/src/main/java/fr/xephi/authme/initialization/TaskCloser.java index 105e4dbd..c1126975 100644 --- a/src/main/java/fr/xephi/authme/initialization/TaskCloser.java +++ b/src/main/java/fr/xephi/authme/initialization/TaskCloser.java @@ -3,7 +3,6 @@ package fr.xephi.authme.initialization; import com.google.common.annotations.VisibleForTesting; import fr.xephi.authme.AuthMe; import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.service.BukkitService; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitWorker; @@ -23,27 +22,22 @@ public class TaskCloser implements Runnable { private final Logger logger; private final AuthMe plugin; private final DataSource dataSource; - private final BukkitService bukkitService; /** * Constructor. * * @param plugin the plugin instance * @param dataSource the data source (nullable) - * @param bukkitService the bukkit service instance (nullable) */ - public TaskCloser(AuthMe plugin, DataSource dataSource, BukkitService bukkitService) { + public TaskCloser(AuthMe plugin, DataSource dataSource) { this.scheduler = plugin.getServer().getScheduler(); this.logger = plugin.getLogger(); this.plugin = plugin; this.dataSource = dataSource; - this.bukkitService = bukkitService; } @Override public void run() { - logger.info("Closing scheduled tasks:"); - List pendingTasks = getPendingTasks(); logger.log(Level.INFO, "Waiting for {0} tasks to finish", pendingTasks.size()); int progress = 0; @@ -75,16 +69,6 @@ public class TaskCloser implements Runnable { tries--; } - logger.info("Closing async tasks..."); - if(bukkitService != null) { - try { - bukkitService.closeAsyncPool(); - } catch (InterruptedException e) { - logger.log(Level.WARNING, "Unable to close some async task", e); - } - } - - logger.info("Closing datasource..."); if (dataSource != null) { dataSource.close(); } diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index 188b7c42..20aa23c2 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -5,7 +5,6 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.PluginSettings; -import fr.xephi.authme.util.Utils; import org.bukkit.BanEntry; import org.bukkit.BanList; import org.bukkit.Bukkit; @@ -26,10 +25,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Set; -import java.util.concurrent.Executor; -import java.util.concurrent.SynchronousQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; /** * Service for operations requiring the Bukkit API, such as for scheduling. @@ -46,35 +41,13 @@ public class BukkitService implements SettingsDependent { private Method getOnlinePlayers; private boolean useAsyncTasks; - // Async executor - private ThreadPoolExecutor asyncExecutor; - @Inject BukkitService(AuthMe authMe, Settings settings) { this.authMe = authMe; getOnlinePlayersIsCollection = initializeOnlinePlayersIsCollectionField(); - - int coreCount = Utils.getCoreCount(); - // Keep 1 free core for the main thread and the OS - if(coreCount != 1) { - coreCount--; - } - asyncExecutor = new ThreadPoolExecutor(coreCount, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, - new SynchronousQueue<>()); - reload(settings); } - /** - * Wait the shutdown of the async execution pool. - * - * @throws InterruptedException if the shutdown is interrupted - */ - public void closeAsyncPool() throws InterruptedException { - asyncExecutor.shutdown(); - asyncExecutor.awaitTermination(30, TimeUnit.SECONDS); - } - /** * Schedules a once off task to occur as soon as possible. *

@@ -162,12 +135,12 @@ public class BukkitService implements SettingsDependent { * Returns a task that will run asynchronously. * * @param task the task to be run + * @return a BukkitTask that contains the id number * @throws IllegalArgumentException if plugin is null * @throws IllegalArgumentException if task is null */ - public void runTaskAsynchronously(Runnable task) { - asyncExecutor.execute(task); - //Bukkit.getScheduler().runTaskAsynchronously(authMe, task); + public BukkitTask runTaskAsynchronously(Runnable task) { + return Bukkit.getScheduler().runTaskAsynchronously(authMe, task); } /** diff --git a/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java b/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java index a76aedd6..7f677e0c 100644 --- a/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java +++ b/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java @@ -3,7 +3,6 @@ package fr.xephi.authme.initialization; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.service.BukkitService; import org.bukkit.Server; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginLogger; @@ -50,8 +49,6 @@ public class TaskCloserTest { private BukkitScheduler bukkitScheduler; @Mock private DataSource dataSource; - @Mock - private BukkitService bukkitService; @Before public void initAuthMe() { @@ -59,7 +56,7 @@ public class TaskCloserTest { given(server.getScheduler()).willReturn(bukkitScheduler); ReflectionTestUtils.setField(JavaPlugin.class, authMe, "server", server); ReflectionTestUtils.setField(JavaPlugin.class, authMe, "logger", logger); - taskCloser = spy(new TaskCloser(authMe, dataSource, bukkitService)); + taskCloser = spy(new TaskCloser(authMe, dataSource)); } @Test @@ -123,7 +120,7 @@ public class TaskCloserTest { /** Test implementation for {@link #shouldStopForInterruptedThread()}. */ private void shouldStopForInterruptedThread0() throws InterruptedException { // given - taskCloser = spy(new TaskCloser(authMe, null, bukkitService)); + taskCloser = spy(new TaskCloser(authMe, null)); // First two times do nothing, third time throw exception when we sleep doNothing().doNothing().doThrow(InterruptedException.class).when(taskCloser).sleep(); mockActiveWorkers(); From 0a9afbe457d816feddee1b30a36f214d571ad175 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 12 Nov 2016 20:05:48 +0100 Subject: [PATCH 25/67] #999 Mail: explicitly map MIME types to Java classes --- src/main/java/fr/xephi/authme/mail/SendMailSSL.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/mail/SendMailSSL.java b/src/main/java/fr/xephi/authme/mail/SendMailSSL.java index e629402f..2076c1d1 100644 --- a/src/main/java/fr/xephi/authme/mail/SendMailSSL.java +++ b/src/main/java/fr/xephi/authme/mail/SendMailSSL.java @@ -2,18 +2,20 @@ package fr.xephi.authme.mail; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.SecuritySettings; -import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.util.FileUtils; import fr.xephi.authme.util.StringUtils; import org.apache.commons.mail.EmailConstants; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.HtmlEmail; +import javax.activation.CommandMap; import javax.activation.DataSource; import javax.activation.FileDataSource; +import javax.activation.MailcapCommandMap; import javax.imageio.ImageIO; import javax.inject.Inject; import javax.mail.Session; @@ -147,6 +149,15 @@ public class SendMailSSL { private static boolean sendEmail(String content, HtmlEmail email) { Thread.currentThread().setContextClassLoader(SendMailSSL.class.getClassLoader()); + // Issue #999: Prevent UnsupportedDataTypeException: no object DCH for MIME type multipart/alternative + // cf. http://stackoverflow.com/questions/21856211/unsupporteddatatypeexception-no-object-dch-for-mime-type + MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); + mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); + mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); + mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); + mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); + mc.addMailcap("message/rfc822;; x-java-content- handler=com.sun.mail.handlers.message_rfc822"); + try { email.setHtmlMsg(content); email.setTextMsg(content); From bb89a59a8a3db9be6a2c0a0f8eab5a22f1b10abb Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 13 Nov 2016 10:37:01 +0100 Subject: [PATCH 26/67] #850 Add setting specifying which password hashes should be checked --- docs/config.md | 14 +++--- .../authme/security/PasswordSecurity.java | 21 +++++---- .../authme/settings/EnumSetProperty.java | 43 +++++++++++++++++++ .../settings/SettingsMigrationService.java | 12 ++++++ .../settings/properties/SecuritySettings.java | 16 ++++--- .../authme/security/PasswordSecurityTest.java | 35 ++++++++------- 6 files changed, 104 insertions(+), 37 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/settings/EnumSetProperty.java diff --git a/docs/config.md b/docs/config.md index 4bf54286..efe739cd 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,5 +1,5 @@ - + ## AuthMe Configuration The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, @@ -245,10 +245,12 @@ settings: passwordHash: 'SHA256' # Salt length for the SALTED2MD5 MD5(MD5(password)+salt) doubleMD5SaltLength: 8 - # If password checking return false, do we need to check with all - # other password algorithm to check an old password? - # AuthMe will update the password to the new password hash - supportOldPasswordHash: false + # If a password check fails, AuthMe will also try to check with the following hash methods. + # Use this setting when you change from one hash method to another. + # AuthMe will update the password to the new hash. Example: + # legacyHashes: + # - 'SHA1' + legacyHashes: [] # Prevent unsafe passwords from being used; put them in lowercase! # You should always set 'help' as unsafePassword due to possible conflicts. # unsafePasswords: @@ -461,4 +463,4 @@ To change settings on a running server, save your changes to config.yml and use --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 30 12:57:15 CET 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Nov 13 10:33:55 CET 2016 diff --git a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java index 521decfa..8549b388 100644 --- a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java +++ b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java @@ -12,6 +12,7 @@ import org.bukkit.plugin.PluginManager; import javax.annotation.PostConstruct; import javax.inject.Inject; +import java.util.Collection; /** * Manager class for password-related operations. @@ -31,7 +32,7 @@ public class PasswordSecurity implements Reloadable { private Injector injector; private HashAlgorithm algorithm; - private boolean supportOldAlgorithm; + private Collection legacyAlgorithms; /** * Load or reload the configuration. @@ -40,7 +41,7 @@ public class PasswordSecurity implements Reloadable { @Override public void reload() { this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH); - this.supportOldAlgorithm = settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH); + this.legacyAlgorithms = settings.getProperty(SecuritySettings.LEGACY_HASHES); } /** @@ -83,7 +84,7 @@ public class PasswordSecurity implements Reloadable { EncryptionMethod method = initializeEncryptionMethodWithEvent(algorithm, playerName); String playerLowerCase = playerName.toLowerCase(); return methodMatches(method, password, hashedPassword, playerLowerCase) - || supportOldAlgorithm && compareWithAllEncryptionMethods(password, hashedPassword, playerLowerCase); + || compareWithLegacyHashes(password, hashedPassword, playerLowerCase); } /** @@ -97,14 +98,12 @@ public class PasswordSecurity implements Reloadable { * * @return True if there was a password match with another encryption method, false otherwise */ - private boolean compareWithAllEncryptionMethods(String password, HashedPassword hashedPassword, String playerName) { - for (HashAlgorithm algorithm : HashAlgorithm.values()) { - if (!HashAlgorithm.CUSTOM.equals(algorithm)) { - EncryptionMethod method = initializeEncryptionMethod(algorithm); - if (methodMatches(method, password, hashedPassword, playerName)) { - hashPasswordForNewAlgorithm(password, playerName); - return true; - } + private boolean compareWithLegacyHashes(String password, HashedPassword hashedPassword, String playerName) { + for (HashAlgorithm algorithm : legacyAlgorithms) { + EncryptionMethod method = initializeEncryptionMethod(algorithm); + if (methodMatches(method, password, hashedPassword, playerName)) { + hashPasswordForNewAlgorithm(password, playerName); + return true; } } return false; diff --git a/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java b/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java new file mode 100644 index 00000000..4ca284d7 --- /dev/null +++ b/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java @@ -0,0 +1,43 @@ +package fr.xephi.authme.settings; + +import com.github.authme.configme.properties.Property; +import com.github.authme.configme.resource.PropertyResource; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * Property whose value is a set of entries of a given enum. + */ +// TODO https://github.com/AuthMe/ConfigMe/issues/27: Should be a Property of Set type +public class EnumSetProperty> extends Property> { + + private final Class enumClass; + + public EnumSetProperty(Class enumClass, String path, List defaultValue) { + super(path, defaultValue); + this.enumClass = enumClass; + } + + @Override + protected List getFromResource(PropertyResource resource) { + List elements = resource.getList(getPath()); + if (elements != null) { + return elements.stream() + .map(val -> toEnum(String.valueOf(val))) + .filter(e -> e != null) + .distinct() + .collect(Collectors.toList()); + } + return null; + } + + private E toEnum(String str) { + for (E e : enumClass.getEnumConstants()) { + if (str.equalsIgnoreCase(e.name())) { + return e; + } + } + return null; + } +} diff --git a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java index 30163bf0..954116a4 100644 --- a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java +++ b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java @@ -7,6 +7,7 @@ import com.google.common.base.Objects; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.output.LogLevel; import fr.xephi.authme.settings.properties.PluginSettings; +import fr.xephi.authme.settings.properties.SecuritySettings; import java.io.File; import java.io.FileWriter; @@ -49,6 +50,7 @@ public class SettingsMigrationService extends PlainMigrationService { | migrateForceSpawnSettings(resource) | changeBooleanSettingToLogLevelProperty(resource) | hasOldHelpHeaderProperty(resource) + | hasSupportOldPasswordProperty(resource) || hasDeprecatedProperties(resource); } @@ -163,6 +165,16 @@ public class SettingsMigrationService extends PlainMigrationService { return false; } + private static boolean hasSupportOldPasswordProperty(PropertyResource resource) { + String path = "settings.security.supportOldPasswordHash"; + if (resource.contains(path)) { + ConsoleLogger.warning("Property '" + path + "' is no longer supported. " + + "Use '" + SecuritySettings.LEGACY_HASHES.getPath() + "' instead."); + return true; + } + return false; + } + /** * Checks for an old property path and moves it to a new path if present. * diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java index 92ce2e5e..e8035491 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java @@ -4,7 +4,9 @@ import com.github.authme.configme.Comment; import com.github.authme.configme.SettingsHolder; import com.github.authme.configme.properties.Property; import fr.xephi.authme.security.HashAlgorithm; +import fr.xephi.authme.settings.EnumSetProperty; +import java.util.Collections; import java.util.List; import static com.github.authme.configme.properties.PropertyInitializer.newLowercaseListProperty; @@ -74,11 +76,15 @@ public class SecuritySettings implements SettingsHolder { public static final Property DOUBLE_MD5_SALT_LENGTH = newProperty("settings.security.doubleMD5SaltLength", 8); - @Comment({"If password checking return false, do we need to check with all", - "other password algorithm to check an old password?", - "AuthMe will update the password to the new password hash"}) - public static final Property SUPPORT_OLD_PASSWORD_HASH = - newProperty("settings.security.supportOldPasswordHash", false); + @Comment({ + "If a password check fails, AuthMe will also try to check with the following hash methods.", + "Use this setting when you change from one hash method to another.", + "AuthMe will update the password to the new hash. Example:", + "legacyHashes:", + "- 'SHA1'" + }) + public static final Property> LEGACY_HASHES = + new EnumSetProperty<>(HashAlgorithm.class, "settings.security.legacyHashes", Collections.emptyList()); @Comment({"Prevent unsafe passwords from being used; put them in lowercase!", "You should always set 'help' as unsafePassword due to possible conflicts.", diff --git a/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java b/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java index 1911bb39..ec206c86 100644 --- a/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java +++ b/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java @@ -24,6 +24,10 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; +import java.util.Collections; +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.junit.Assert.assertThat; @@ -97,7 +101,7 @@ public class PasswordSecurityTest { given(dataSource.getPassword(playerName)).willReturn(password); given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(true); - initSettings(HashAlgorithm.BCRYPT, false); + initSettings(HashAlgorithm.BCRYPT); PasswordSecurity security = newPasswordSecurity(); // when @@ -120,7 +124,7 @@ public class PasswordSecurityTest { given(dataSource.getPassword(playerName)).willReturn(password); given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false); - initSettings(HashAlgorithm.CUSTOM, false); + initSettings(HashAlgorithm.CUSTOM); PasswordSecurity security = newPasswordSecurity(); // when @@ -140,7 +144,7 @@ public class PasswordSecurityTest { String clearTextPass = "tables"; given(dataSource.getPassword(playerName)).willReturn(null); - initSettings(HashAlgorithm.MD5, false); + initSettings(HashAlgorithm.MD5); PasswordSecurity security = newPasswordSecurity(); // when @@ -168,7 +172,8 @@ public class PasswordSecurityTest { given(dataSource.getPassword(argThat(equalToIgnoringCase(playerName)))).willReturn(password); given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false); given(method.computeHash(clearTextPass, playerLowerCase)).willReturn(newPassword); - initSettings(HashAlgorithm.MD5, true); + initSettings(HashAlgorithm.MD5); + given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(newArrayList(HashAlgorithm.BCRYPT)); PasswordSecurity security = newPasswordSecurity(); // when @@ -193,7 +198,7 @@ public class PasswordSecurityTest { String clearTextPass = "someInvalidPassword"; given(dataSource.getPassword(playerName)).willReturn(password); given(method.comparePassword(clearTextPass, password, playerName)).willReturn(false); - initSettings(HashAlgorithm.MD5, true); + initSettings(HashAlgorithm.MD5); PasswordSecurity security = newPasswordSecurity(); // when @@ -212,7 +217,7 @@ public class PasswordSecurityTest { String usernameLowerCase = username.toLowerCase(); HashedPassword hashedPassword = new HashedPassword("$T$est#Hash", "__someSalt__"); given(method.computeHash(password, usernameLowerCase)).willReturn(hashedPassword); - initSettings(HashAlgorithm.JOOMLA, true); + initSettings(HashAlgorithm.JOOMLA); PasswordSecurity security = newPasswordSecurity(); // when @@ -234,7 +239,7 @@ public class PasswordSecurityTest { String username = "someone12"; HashedPassword hashedPassword = new HashedPassword("~T!est#Hash"); given(method.hasSeparateSalt()).willReturn(true); - initSettings(HashAlgorithm.XAUTH, false); + initSettings(HashAlgorithm.XAUTH); PasswordSecurity security = newPasswordSecurity(); // when @@ -250,19 +255,20 @@ public class PasswordSecurityTest { @Test public void shouldReloadSettings() { // given - initSettings(HashAlgorithm.BCRYPT, false); + initSettings(HashAlgorithm.BCRYPT); PasswordSecurity passwordSecurity = newPasswordSecurity(); given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.MD5); - given(settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH)).willReturn(true); + List legacyHashes = newArrayList(HashAlgorithm.CUSTOM, HashAlgorithm.BCRYPT); + given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(legacyHashes); // when passwordSecurity.reload(); // then assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "algorithm"), - equalTo((Object) HashAlgorithm.MD5)); - assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "supportOldAlgorithm"), - equalTo((Object) Boolean.TRUE)); + equalTo(HashAlgorithm.MD5)); + assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "legacyAlgorithms"), + equalTo(legacyHashes)); } private PasswordSecurity newPasswordSecurity() { @@ -275,11 +281,10 @@ public class PasswordSecurityTest { return passwordSecurity; } - private void initSettings(HashAlgorithm algorithm, boolean supportOldPassword) { + private void initSettings(HashAlgorithm algorithm) { given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(algorithm); - given(settings.getProperty(SecuritySettings.SUPPORT_OLD_PASSWORD_HASH)).willReturn(supportOldPassword); + given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(Collections.emptyList()); given(settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND)).willReturn(8); - given(settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH)).willReturn(16); } } From 5dda439bede04ad62af846606beca457072cce01 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 13 Nov 2016 10:49:51 +0100 Subject: [PATCH 27/67] Move RandomStringUtilsTest to correct package --- .../xephi/authme/{security => util}/RandomStringUtilsTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename src/test/java/fr/xephi/authme/{security => util}/RandomStringUtilsTest.java (96%) diff --git a/src/test/java/fr/xephi/authme/security/RandomStringUtilsTest.java b/src/test/java/fr/xephi/authme/util/RandomStringUtilsTest.java similarity index 96% rename from src/test/java/fr/xephi/authme/security/RandomStringUtilsTest.java rename to src/test/java/fr/xephi/authme/util/RandomStringUtilsTest.java index 217bc927..c0f9cd0b 100644 --- a/src/test/java/fr/xephi/authme/security/RandomStringUtilsTest.java +++ b/src/test/java/fr/xephi/authme/util/RandomStringUtilsTest.java @@ -1,6 +1,5 @@ -package fr.xephi.authme.security; +package fr.xephi.authme.util; -import fr.xephi.authme.util.RandomStringUtils; import org.junit.Test; import java.util.regex.Pattern; From ed29ae231880a6db08a4b8b91caf4361c9ff8485 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 13 Nov 2016 12:27:52 +0100 Subject: [PATCH 28/67] Update readme and name (un)restriction setting comments (#652) - Add missing language code to readme - Remove Gource video from readme (now over a year old) - Improve property comments for name restrictions and unrestrictions --- README.md | 14 +++++-------- docs/config.md | 20 +++++++++---------- .../properties/RestrictionSettings.java | 17 ++++++++-------- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index a5fa9fb5..ceb5b85b 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,6 @@ McStats: http://mcstats.org/plugin/AuthMe -#####Development history: -Outdated! -[![Gource AuthMe History Video](http://img.youtube.com/vi/hJRzNfYyd9k/hqdefault.jpg)](https://www.youtube.com/watch?v=hJRzNfYyd9k) -


#####Compiling Requirements: @@ -104,11 +100,11 @@ You can also create your own translation file and, if you want, you can share it
  • Cached database queries!
  • Fully compatible with Citizens2, CombatTag, CombatTagPlus and ChestShop!
  • Compatible with Minecraft mods like BuildCraft or RedstoneCraft
  • -
  • Restricted users (associate a Username with an IP)
  • -
  • Protect player's inventory until a correct Authentication
  • +
  • Restricted users (associate a username with an IP)
  • +
  • Protect player's inventory until correct authentication
  • Saves the quit location of the player
  • -
  • Automatic database Backup
  • -
  • Available languages: en, de, br, cz, pl, fr, uk, ru, hu, sk, es, fi, zhtw, zhhk, zhcn, lt, it, ko, pt, nl, gl, bg, eu, tr, vn (feel free to send new translations)
  • +
  • Automatic database backup
  • +
  • Available languages: en, de, br, cz, pl, fr, uk, ru, hu, sk, es, fi, id, zhtw, zhhk, zhcn, lt, it, ko, pt, nl, gl, bg, eu, tr, vn (feel free to send new translations)
  • Built-in Deprecated FlatFile (auths.db) to SQL (authme.sql) converter!
  • Import your old database from other plugins like Rakamak, xAuth, CrazyLogin, RoyalAuth and vAuth!
  • @@ -130,7 +126,7 @@ You can also create your own translation file and, if you want, you can share it - [Website integration](http://dev.bukkit.org/server-mods/authme-reloaded/pages/web-site-integration/) - [Click here for an example of the config file](https://raw.githubusercontent.com/Xephi/AuthMeReloaded/master/src/main/resources/config.yml) - [How to convert from Rakamak](http://dev.bukkit.org/server-mods/authme-reloaded/pages/how-to-import-database-from-rakamak/) -- Convert from FlatFile (auths.db but not the sqlite one) to MySQL: /authme converter +- Convert between database types (e.g. SQLite to MySQL): /authme converter
    diff --git a/docs/config.md b/docs/config.md index efe739cd..99e428df 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,5 +1,5 @@ - + ## AuthMe Configuration The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, @@ -150,7 +150,7 @@ settings: # to enable this option and configure the AllowedRestrictedUser field. AllowRestrictedUser: false # The restricted user feature will kick players listed below - # if they don't match the defined IP address. + # if they don't match the defined IP address. Names are case-insensitive. # Example: # AllowedRestrictedUser: # - playername;127.0.0.1 @@ -214,13 +214,13 @@ settings: # Force survival gamemode when player joins? ForceSurvivalMode: false unrestrictions: - # Below you can list all account names that - # AuthMe will ignore for registration or login, configure it - # at your own risk!! Remember that if you are going to add - # nickname with [], you have to delimit name with ' '. - # this option add compatibility with BuildCraft and some - # other mods. - # It is case-sensitive! + # Below you can list all account names that AuthMe will ignore + # for registration or login. Configure it at your own risk!! + # This option adds compatibility with BuildCraft and some other mods. + # It is case-insensitive! Example: + # UnrestrictedName: + # - 'npcPlayer' + # - 'npcPlayer2' UnrestrictedName: [] security: # Minimum length of password @@ -463,4 +463,4 @@ To change settings on a running server, save your changes to config.yml and use --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Nov 13 10:33:55 CET 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Nov 13 12:06:04 CET 2016 diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index 87e0419e..3fb68191 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -4,7 +4,6 @@ import com.github.authme.configme.Comment; import com.github.authme.configme.SettingsHolder; import com.github.authme.configme.properties.Property; -import javax.inject.Inject; import java.util.List; import static com.github.authme.configme.properties.PropertyInitializer.newListProperty; @@ -78,7 +77,7 @@ public class RestrictionSettings implements SettingsHolder { @Comment({ "The restricted user feature will kick players listed below", - "if they don't match the defined IP address.", + "if they don't match the defined IP address. Names are case-insensitive.", "Example:", " AllowedRestrictedUser:", " - playername;127.0.0.1"}) @@ -177,13 +176,13 @@ public class RestrictionSettings implements SettingsHolder { newProperty("settings.GameMode.ForceSurvivalMode", false); @Comment({ - "Below you can list all account names that", - "AuthMe will ignore for registration or login, configure it", - "at your own risk!! Remember that if you are going to add", - "nickname with [], you have to delimit name with ' '.", - "this option add compatibility with BuildCraft and some", - "other mods.", - "It is case-sensitive!" + "Below you can list all account names that AuthMe will ignore", + "for registration or login. Configure it at your own risk!!", + "This option adds compatibility with BuildCraft and some other mods.", + "It is case-insensitive! Example:", + "UnrestrictedName:", + "- 'npcPlayer'", + "- 'npcPlayer2'" }) public static final Property> UNRESTRICTED_NAMES = newLowercaseListProperty("settings.unrestrictions.UnrestrictedName"); From cf04ec608213ae2a342e649430d1c5dd2efa20cb Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 13 Nov 2016 13:35:19 +0100 Subject: [PATCH 29/67] Fix wrong config description for #459 --- docs/config.md | 9 +++++---- .../fr/xephi/authme/process/login/AsynchronousLogin.java | 2 +- .../authme/settings/properties/RestrictionSettings.java | 7 +++++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/config.md b/docs/config.md index 99e428df..212d83a7 100644 --- a/docs/config.md +++ b/docs/config.md @@ -1,5 +1,5 @@ - + ## AuthMe Configuration The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder, @@ -199,9 +199,10 @@ settings: noTeleport: false # Regex syntax for allowed chars in passwords allowedPasswordCharacters: '[\x21-\x7E]*' - # Threshold of the other accounts command, a value less than 1 means disabled. + # Threshold of the other accounts command, a value less than 2 means disabled. otherAccountsCmdThreshold: 0 - # The other accounts command, available variables: %playername%, %playerip% + # Command to run when a user has more accounts than the configured threshold. + # Available variables: %playername%, %playerip% otherAccountsCmd: 'say The player %playername% with ip %playerip% has multiple accounts!' # Log level: INFO, FINE, DEBUG. Use INFO for general messages, # FINE for some additional detailed ones (like password failed), @@ -463,4 +464,4 @@ To change settings on a running server, save your changes to config.yml and use --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Nov 13 12:06:04 CET 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Nov 13 13:34:49 CET 2016 diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java index 2002232d..a3fa7010 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -259,7 +259,7 @@ public class AsynchronousLogin implements AsynchronousProcess { int threshold = service.getProperty(RestrictionSettings.OTHER_ACCOUNTS_CMD_THRESHOLD); String command = service.getProperty(RestrictionSettings.OTHER_ACCOUNTS_CMD); - if(threshold <= 1 || command.isEmpty()) { + if(threshold < 2 || command.isEmpty()) { return; } diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index 3fb68191..7f426b1d 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -187,11 +187,14 @@ public class RestrictionSettings implements SettingsHolder { public static final Property> UNRESTRICTED_NAMES = newLowercaseListProperty("settings.unrestrictions.UnrestrictedName"); - @Comment("Threshold of the other accounts command, a value less than 1 means disabled.") + @Comment("Threshold of the other accounts command, a value less than 2 means disabled.") public static final Property OTHER_ACCOUNTS_CMD_THRESHOLD = newProperty("settings.restrictions.otherAccountsCmdThreshold", 0); - @Comment("The other accounts command, available variables: %playername%, %playerip%") + @Comment({ + "Command to run when a user has more accounts than the configured threshold.", + "Available variables: %playername%, %playerip%" + }) public static final Property OTHER_ACCOUNTS_CMD = newProperty("settings.restrictions.otherAccountsCmd", "say The player %playername% with ip %playerip% has multiple accounts!"); From 3362cf7b95dadaa371b2dd35101eba18042cb158 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Sun, 13 Nov 2016 13:36:50 +0100 Subject: [PATCH 30/67] Fix wrong logic #459 --- .../java/fr/xephi/authme/process/login/AsynchronousLogin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java index a3fa7010..318b1b30 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -263,7 +263,7 @@ public class AsynchronousLogin implements AsynchronousProcess { return; } - if (auths.size() >= threshold) { + if (auths.size() < threshold) { return; } From fabd77f54835c885d1303f4291de0bc39fdcc7f9 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Mon, 14 Nov 2016 19:07:50 +0100 Subject: [PATCH 31/67] #1006 Player speed workaround --- src/main/java/fr/xephi/authme/data/limbo/LimboCache.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/xephi/authme/data/limbo/LimboCache.java b/src/main/java/fr/xephi/authme/data/limbo/LimboCache.java index 82e42fba..893aba22 100644 --- a/src/main/java/fr/xephi/authme/data/limbo/LimboCache.java +++ b/src/main/java/fr/xephi/authme/data/limbo/LimboCache.java @@ -84,10 +84,10 @@ public class LimboCache { float walkSpeed = data.getWalkSpeed(); float flySpeed = data.getFlySpeed(); // Reset the speed value if it was 0 - if(walkSpeed == 0f) { + if(walkSpeed < 0.01f) { walkSpeed = 0.2f; } - if(flySpeed == 0f) { + if(flySpeed < 0.01f) { flySpeed = 0.2f; } player.setWalkSpeed(walkSpeed); From 15ff9ae4426e7bf1e8b2c9f3287ac69625f6eb1e Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 15 Nov 2016 17:29:00 +0100 Subject: [PATCH 32/67] Update dependencies + update README --- README.md | 73 +++++++++++++++++++++++-------------------------------- pom.xml | 8 +++--- 2 files changed, 34 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index ceb5b85b..e160fc40 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,28 @@

    -

    The most used authentication plugin for CraftBukkit/Spigot!

    +

    The most used authentication plugin for Spigot and CraftBukkit!


    -#####Development tools: +#####Links and Contacts: -- MAIN REPO (**release sources, issue tracker!**): [Github Main Page](https://github.com/Xephi/AuthMeReloaded) +- GitHub pages: + - [Main](https://github.com/Xephi/AuthMeReloaded) (**release sources, issue tracker!**) + - [Development](https://github.com/AuthMe/AuthMeReloaded) (**latest sources, please send PRs here!**): -- DEVELOPMENT TEAM REPO (**latest sources, please send PRs here!**): [Github Development Page](https://github.com/AuthMe/AuthMeReloaded) +- Contacts: + - [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Xephi/AuthMeReloaded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -- Developers ChatRoom: [![Join the chat at https://gitter.im/Xephi/AuthMeReloaded](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Xephi/AuthMeReloaded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +- CI Services: + - [Official Jenkins](http://ci.xephi.fr/job/AuthMeReloaded) (**DEVELOPMENT BUILDS**) + - Travis CI: [![Travis CI](https://travis-ci.org/AuthMe/AuthMeReloaded.svg?branch=master)](https://travis-ci.org/AuthMe/AuthMeReloaded) + - CircleCI: [![CircleCI](https://circleci.com/gh/AuthMe/AuthMeReloaded.svg?style=svg)](https://circleci.com/gh/AuthMe/AuthMeReloaded) -- Build Server (**DEVELOPMENT BUILDS**): [Xephi's Jenkins](http://ci.xephi.fr/job/AuthMeReloaded) +- Project status: + - Dependencies: [![Dependencies status](https://www.versioneye.com/user/projects/57b182e8d6ffcd0032d7cf2d/badge.svg)](https://www.versioneye.com/user/projects/57b182e8d6ffcd0032d7cf2d) + - Test coverage: [![Coverage status](https://coveralls.io/repos/AuthMe-Team/AuthMeReloaded/badge.svg?branch=master&service=github)](https://coveralls.io/github/AuthMe-Team/AuthMeReloaded?branch=master) -- Build status: [![Build Status](https://travis-ci.org/AuthMe/AuthMeReloaded.svg?branch=master)](https://travis-ci.org/AuthMe/AuthMeReloaded) - -- Dependencies: [![Dependency Status](https://www.versioneye.com/user/projects/57b182e8d6ffcd0032d7cf2d/badge.svg)](https://www.versioneye.com/user/projects/57b182e8d6ffcd0032d7cf2d) - -- Build status (CircleCI): [![Circle CI](https://circleci.com/gh/AuthMe/AuthMeReloaded.svg?style=svg)](https://circleci.com/gh/AuthMe/AuthMeReloaded) -- Alternative Dev Build download link (via CircleCi): Download -- JitPack (just in case): [![](https://jitpack.io/v/AuthMe/AuthMeReloaded.svg)](https://jitpack.io/#AuthMe/AuthMeReloaded) - -- Code Coverage: [![Coverage Status](https://coveralls.io/repos/AuthMe-Team/AuthMeReloaded/badge.svg?branch=master&service=github)](https://coveralls.io/github/AuthMe-Team/AuthMeReloaded?branch=master) - -- Issue Tracking : [![Stories in Ready](https://badge.waffle.io/Xephi/AuthMeReloaded.png?label=ready&title=Ready)](https://waffle.io/Xephi/AuthMeReloaded) [![Stories in Bugs](https://badge.waffle.io/Xephi/AuthMeReloaded.png?label=bugs&title=Bugs)](https://waffle.io/Xephi/AuthMeReloaded) [![Stories in In%20Progress](https://badge.waffle.io/Xephi/AuthMeReloaded.png?label=in%20progress&title=In%20Progress)](https://waffle.io/Xephi/AuthMeReloaded) - -- JavaDoc: AuthMe Javadoc - -- Maven Repo: AuthMe Repo +- Development resources: + - JavaDocs + - Maven Repository #####Statistics: @@ -40,19 +36,19 @@ McStats: http://mcstats.org/plugin/AuthMe
    -#####Compiling Requirements: +#####Compiling requirements: >- JDK 1.8 >- Maven >- Git/Github (Optional) #####How to compile the project: >- Clone the project with Git/Github ->- Execute command "mvn clean install" +>- Execute command "mvn clean package" -#####Running Requirements: +#####Running requirements: >- Java 1.8 ->- PaperSpigot, Spigot or CraftBukkit (1.7.10, 1.8.X, 1.9.X, 1.10.X) ->- ProtocolLib (optional, required by the protectInventory feature) +>- TacoSpigot, PaperSpigot, Spigot or CraftBukkit (1.7.10, 1.8.X, 1.9.X, 1.10.X, 1.11.X) +>- ProtocolLib (optional, required by some features)
    ###Plugin Description: @@ -98,19 +94,19 @@ You can also create your own translation file and, if you want, you can share it
  • Custom MySQL tables/columns names (useful with forums databases)
  • Cached database queries!
  • -
  • Fully compatible with Citizens2, CombatTag, CombatTagPlus and ChestShop!
  • +
  • Fully compatible with Citizens2, CombatTag, CombatTagPlus!
  • Compatible with Minecraft mods like BuildCraft or RedstoneCraft
  • Restricted users (associate a username with an IP)
  • -
  • Protect player's inventory until correct authentication
  • +
  • Protect player's inventory until correct authentication (requires ProtocolLib)
  • Saves the quit location of the player
  • Automatic database backup
  • -
  • Available languages: en, de, br, cz, pl, fr, uk, ru, hu, sk, es, fi, id, zhtw, zhhk, zhcn, lt, it, ko, pt, nl, gl, bg, eu, tr, vn (feel free to send new translations)
  • +
  • Available languages: translations
  • Built-in Deprecated FlatFile (auths.db) to SQL (authme.sql) converter!
  • Import your old database from other plugins like Rakamak, xAuth, CrazyLogin, RoyalAuth and vAuth!
  • ####Configuration -How to Configure Authme +How to configure Authme ####Email Recovery Dependency How to configure email recovery system? ####Commands @@ -121,30 +117,21 @@ You can also create your own translation file and, if you want, you can share it - [List of all permission nodes](http://github.com/AuthMe-Team/AuthMeReloaded/blob/master/docs/permission_nodes.md) ####How To -- [How to install and set up](http://dev.bukkit.org/server-mods/authme-reloaded/pages/how-to-install-and-initial-configuration/) - [How to import database from xAuth](http://dev.bukkit.org/server-mods/authme-reloaded/pages/how-to-import-database-from-xauth/) - [Website integration](http://dev.bukkit.org/server-mods/authme-reloaded/pages/web-site-integration/) -- [Click here for an example of the config file](https://raw.githubusercontent.com/Xephi/AuthMeReloaded/master/src/main/resources/config.yml) - [How to convert from Rakamak](http://dev.bukkit.org/server-mods/authme-reloaded/pages/how-to-import-database-from-rakamak/) - Convert between database types (e.g. SQLite to MySQL): /authme converter
    -#####GeoIP -This product uses data from the GeoLite API created by MaxMind, available at http://www.maxmind.com - -
    - -#####Donate -

    Do you like our work? Do you want to buy us a coffee? :)
    -EUR: -USD:

    - #####Sponsor GameHosting.it is leader in Italy as Game Server Provider. With its own DataCenter offers Anti-DDoS solutions at affordable prices. Game Server of Minecraft based on Multicraft are equipped with the latest technology in hardware. [![GameHosting](http://www.gamehosting.it/images/bn3.png)](http://www.gamehosting.it) #####Credits -

    Team members: look at the team.txt file +

    Team members: look at the member list

    Credit for old version of the plugin to: d4rkwarriors, fabe1337, Whoami2 and pomo4ka

    Thanks also to: AS1LV3RN1NJA, Hoeze and eprimex

    + +#####GeoIP License +This product uses data from the GeoLite API created by MaxMind, available at http://www.maxmind.com diff --git a/pom.xml b/pom.xml index a4bd0a9a..edf73b76 100644 --- a/pom.xml +++ b/pom.xml @@ -196,7 +196,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.5.1 + 3.6.0 ${project.jdkVersion} ${project.jdkVersion} @@ -904,7 +904,7 @@ org.mockito mockito-core test - 2.2.9 + 2.2.15 hamcrest-core @@ -917,13 +917,13 @@ org.xerial sqlite-jdbc - 3.14.2.1 + 3.15.1 test com.h2database h2 - 1.4.192 + 1.4.193 test From b53f71706a55ab3083cf2a9a84aeecdee8444458 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 15 Nov 2016 18:41:27 +0100 Subject: [PATCH 33/67] Join process cleanup, change some default settings (should improve performance and security with default settings) --- .../xephi/authme/listener/PlayerListener.java | 8 +++++--- .../authme/process/join/AsynchronousJoin.java | 18 +----------------- .../process/login/ProcessSyncPlayerLogin.java | 10 ---------- .../fr/xephi/authme/service/GeoIpService.java | 4 +++- .../settings/properties/HooksSettings.java | 2 +- .../settings/properties/PluginSettings.java | 7 ------- .../properties/RegistrationSettings.java | 2 +- .../properties/RestrictionSettings.java | 4 ++-- 8 files changed, 13 insertions(+), 42 deletions(-) diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index 73a552f0..92cf6a84 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -208,9 +208,11 @@ public class PlayerListener implements Listener { final String name = player.getName(); if (validationService.isUnrestricted(name)) { return; - } else if (onJoinVerifier.refusePlayerForFullServer(event)) { + } + if (onJoinVerifier.refusePlayerForFullServer(event)) { return; - } else if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { + } + if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { return; } @@ -223,8 +225,8 @@ public class PlayerListener implements Listener { // Slow stuff final PlayerAuth auth = dataSource.getAuth(name); final boolean isAuthAvailable = (auth != null); - onJoinVerifier.checkAntibot(player, isAuthAvailable); onJoinVerifier.checkKickNonRegistered(isAuthAvailable); + onJoinVerifier.checkAntibot(player, isAuthAvailable); onJoinVerifier.checkNameCasing(player, auth); onJoinVerifier.checkPlayerCountry(isAuthAvailable, event.getAddress().getHostAddress()); } catch (FailedVerificationException e) { diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index 89e7a671..490bc9ba 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -22,9 +22,7 @@ import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.task.LimboPlayerTaskManager; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.util.PlayerUtils; -import org.apache.commons.lang.reflect.MethodUtils; import org.bukkit.GameMode; -import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; @@ -39,9 +37,6 @@ import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND; */ public class AsynchronousJoin implements AsynchronousProcess { - private static final boolean DISABLE_COLLISIONS = MethodUtils - .getAccessibleMethod(LivingEntity.class, "setCollidable", new Class[]{}) != null; - @Inject private AuthMe plugin; @@ -75,20 +70,14 @@ public class AsynchronousJoin implements AsynchronousProcess { AsynchronousJoin() { } - public void processJoin(final Player player) { final String name = player.getName().toLowerCase(); final String ip = PlayerUtils.getPlayerIp(player); - if (isPlayerUnrestricted(name)) { + if (service.getProperty(RestrictionSettings.UNRESTRICTED_NAMES).contains(name)) { return; } - // Prevent player collisions in 1.9 - if (DISABLE_COLLISIONS) { - player.setCollidable(false); - } - if (service.getProperty(RestrictionSettings.FORCE_SURVIVAL_MODE) && !service.hasPermission(player, PlayerStatePermission.BYPASS_FORCE_SURVIVAL)) { bukkitService.runTask(() -> player.setGameMode(GameMode.SURVIVAL)); @@ -115,7 +104,6 @@ public class AsynchronousJoin implements AsynchronousProcess { return; } - final boolean isAuthAvailable = database.isAuthAvailable(name); if (isAuthAvailable) { @@ -189,10 +177,6 @@ public class AsynchronousJoin implements AsynchronousProcess { limboPlayerTaskManager.registerMessageTask(name, isAuthAvailable); } - private boolean isPlayerUnrestricted(String name) { - return service.getProperty(RestrictionSettings.UNRESTRICTED_NAMES).contains(name); - } - /** * Returns whether the name is restricted based on the restriction settings. * diff --git a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java index a31f4d28..2488be8a 100644 --- a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java @@ -14,23 +14,17 @@ import fr.xephi.authme.service.BungeeService; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.TeleportationService; -import org.apache.commons.lang.reflect.MethodUtils; import org.bukkit.Bukkit; -import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginManager; import org.bukkit.potion.PotionEffectType; import javax.inject.Inject; -import static fr.xephi.authme.settings.properties.PluginSettings.KEEP_COLLISIONS_DISABLED; import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN; public class ProcessSyncPlayerLogin implements SynchronousProcess { - private static final boolean RESTORE_COLLISIONS = MethodUtils - .getAccessibleMethod(LivingEntity.class, "setCollidable", new Class[]{}) != null; - @Inject private AuthMe plugin; @@ -88,10 +82,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { // because LimboCache#restoreData teleport player to last location. } - if (RESTORE_COLLISIONS && !service.getProperty(KEEP_COLLISIONS_DISABLED)) { - player.setCollidable(true); - } - if (service.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) { restoreInventory(player); } diff --git a/src/main/java/fr/xephi/authme/service/GeoIpService.java b/src/main/java/fr/xephi/authme/service/GeoIpService.java index f1335c7d..22e9af2c 100644 --- a/src/main/java/fr/xephi/authme/service/GeoIpService.java +++ b/src/main/java/fr/xephi/authme/service/GeoIpService.java @@ -17,6 +17,8 @@ import java.net.URLConnection; import java.util.concurrent.TimeUnit; import java.util.zip.GZIPInputStream; +import static com.maxmind.geoip.LookupService.GEOIP_MEMORY_CACHE; + public class GeoIpService { private static final String LICENSE = "[LICENSE] This product uses data from the GeoLite API created by MaxMind, available at http://www.maxmind.com"; @@ -57,7 +59,7 @@ public class GeoIpService { boolean dataIsOld = (System.currentTimeMillis() - dataFile.lastModified()) > TimeUnit.DAYS.toMillis(30); if (!dataIsOld) { try { - lookupService = new LookupService(dataFile); + lookupService = new LookupService(dataFile, GEOIP_MEMORY_CACHE); ConsoleLogger.info(LICENSE); return true; } catch (IOException e) { diff --git a/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java b/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java index 77b1767e..68d2ad73 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/HooksSettings.java @@ -25,7 +25,7 @@ public class HooksSettings implements SettingsHolder { @Comment("Do we need to disable Essentials SocialSpy on join?") public static final Property DISABLE_SOCIAL_SPY = - newProperty("Hooks.disableSocialSpy", true); + newProperty("Hooks.disableSocialSpy", false); @Comment("Do we need to force /motd Essentials command on join?") public static final Property USE_ESSENTIALS_MOTD = diff --git a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java b/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java index 094a3d5b..91d71d7f 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/PluginSettings.java @@ -52,13 +52,6 @@ public class PluginSettings implements SettingsHolder { public static final Property ENABLE_PERMISSION_CHECK = newProperty("permission.EnablePermissionCheck", false); - @Comment({ - "Keeps collisions disabled for logged players", - "Works only with MC 1.9" - }) - public static final Property KEEP_COLLISIONS_DISABLED = - newProperty("settings.restrictions.keepCollisionsDisabled", false); - @Comment({ "Log level: INFO, FINE, DEBUG. Use INFO for general messages,", "FINE for some additional detailed ones (like password failed),", diff --git a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java index 487039ba..bf250e1f 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java @@ -108,7 +108,7 @@ public class RegistrationSettings implements SettingsHolder { "Do we need to prevent people to login with another case?", "If Xephi is registered, then Xephi can login, but not XEPHI/xephi/XePhI"}) public static final Property PREVENT_OTHER_CASE = - newProperty("settings.preventOtherCase", false); + newProperty("settings.preventOtherCase", true); private RegistrationSettings() { diff --git a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java index 7f426b1d..c62b93e3 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RestrictionSettings.java @@ -90,7 +90,7 @@ public class RestrictionSettings implements SettingsHolder { @Comment("Should players be kicked on wrong password?") public static final Property KICK_ON_WRONG_PASSWORD = - newProperty("settings.restrictions.kickOnWrongPassword", false); + newProperty("settings.restrictions.kickOnWrongPassword", true); @Comment({ "Should not logged in players be teleported to the spawn?", @@ -139,7 +139,7 @@ public class RestrictionSettings implements SettingsHolder { @Comment("Should we deny the tabcomplete feature before logging in? Requires ProtocolLib.") public static final Property DENY_TABCOMPLETE_BEFORE_LOGIN = - newProperty("settings.restrictions.DenyTabCompleteBeforeLogin", true); + newProperty("settings.restrictions.DenyTabCompleteBeforeLogin", false); @Comment({ "Should we display all other accounts from a player when he joins?", From e9f274aa89550de98e0fcd119b732185790c6d64 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 15 Nov 2016 19:00:00 +0100 Subject: [PATCH 34/67] Cleanup --- src/main/java/fr/xephi/authme/service/MessageUpdater.java | 1 - .../fr/xephi/authme/datasource/AbstractResourceClosingTest.java | 2 +- .../java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/fr/xephi/authme/service/MessageUpdater.java b/src/main/java/fr/xephi/authme/service/MessageUpdater.java index 3aa5aaa6..036ad9fd 100644 --- a/src/main/java/fr/xephi/authme/service/MessageUpdater.java +++ b/src/main/java/fr/xephi/authme/service/MessageUpdater.java @@ -85,7 +85,6 @@ public class MessageUpdater { } } - @SuppressWarnings("unchecked") private void copyMissingMessages() { for (Property property : properties) { String message = userConfiguration.getString(property.getPath()); diff --git a/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java b/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java index 0b8d7bde..35ea12e3 100644 --- a/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java +++ b/src/test/java/fr/xephi/authme/datasource/AbstractResourceClosingTest.java @@ -98,7 +98,7 @@ public abstract class AbstractResourceClosingTest { } /** Initialize the settings mock and makes it return the default of any given property by default. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) @BeforeClass public static void initializeSettings() throws IOException, ClassNotFoundException { settings = mock(Settings.class); diff --git a/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java b/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java index c479c344..98801153 100644 --- a/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java +++ b/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java @@ -173,7 +173,6 @@ public class LimboPlayerTaskManagerTest { @Test public void shouldNotRegisterTimeoutTaskForZeroTimeout() { // given - String name = "snail"; Player player = mock(Player.class); LimboPlayer limboPlayer = mock(LimboPlayer.class); given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(0); From 92c4c18da4097d5b6803275887ab3037230d168a Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Thu, 17 Nov 2016 13:22:12 +0100 Subject: [PATCH 35/67] 1.11: does it compile? I'm from mobile but i'm curious :P --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index edf73b76..44196e87 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ Xephi, sgdc3, DNx5, timvisee, games647, ljacqu, Gnat008 - 1.10.2-R0.1-SNAPSHOT + 1.11-R0.1-SNAPSHOT From 44a8764115756517c55d1d50eccea99080494b56 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 17 Nov 2016 20:42:55 +0100 Subject: [PATCH 36/67] Do not use master for experiments that break the build --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 44196e87..edf73b76 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ Xephi, sgdc3, DNx5, timvisee, games647, ljacqu, Gnat008 - 1.11-R0.1-SNAPSHOT + 1.10.2-R0.1-SNAPSHOT From 40cf79d2c190b4b30cda8911d9877991eb028ef2 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 17 Nov 2016 20:48:53 +0100 Subject: [PATCH 37/67] Copy surefire xml files to CircleCI junit folder cf. https://circleci.com/docs/test-metadata/#maven-surefire-plugin-for-java-junit-results --- circle.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/circle.yml b/circle.yml index 80201e5e..3359eb2a 100644 --- a/circle.yml +++ b/circle.yml @@ -11,6 +11,8 @@ test: - cp ./target/AuthMe-*-SNAPSHOT-spigot.jar $CIRCLE_ARTIFACTS - cp ./target/AuthMe-*-SNAPSHOT-legacy.jar $CIRCLE_ARTIFACTS - cp ./target/AuthMe-*-SNAPSHOT-spigot.jar $CIRCLE_ARTIFACTS/AuthMe.jar + - mkdir -p $CIRCLE_TEST_REPORTS/junit/ + - find . -type f -regex ".*/target/surefire-reports/.*xml" -exec cp {} $CIRCLE_TEST_REPORTS/junit/ \; notify: webhooks: - url: https://webhooks.gitter.im/e/7b92ac1a1741748b26bf From 4214c6dc80579fe9e8dfca94366125b4cdca6d1f Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 17 Nov 2016 21:02:01 +0100 Subject: [PATCH 38/67] #411 Forced commands: initial implementation --- .../register/ProcessSyncPasswordRegister.java | 17 ++--- .../xephi/authme/service/BukkitService.java | 31 ++++++--- .../settings/commandconfig/Command.java | 28 ++++++++ .../settings/commandconfig/CommandConfig.java | 40 ++++++++++++ .../commandconfig/CommandManager.java | 65 +++++++++++++++++++ .../commandconfig/CommandSettingsHolder.java | 51 +++++++++++++++ .../settings/commandconfig/Executor.java | 14 ++++ src/main/resources/commands.yml | 24 +++++++ .../datasource/FlatFileIntegrationTest.java | 2 - .../authme/service/BukkitServiceTest.java | 52 +++++++++++++-- .../filegeneration/GenerateCommandsYml.java | 57 ++++++++++++++++ 11 files changed, 351 insertions(+), 30 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/settings/commandconfig/Command.java create mode 100644 src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java create mode 100644 src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java create mode 100644 src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java create mode 100644 src/main/java/fr/xephi/authme/settings/commandconfig/Executor.java create mode 100644 src/main/resources/commands.yml create mode 100644 src/test/java/tools/filegeneration/GenerateCommandsYml.java diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java index cc190a3c..efc4f1b1 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java @@ -7,12 +7,12 @@ import fr.xephi.authme.permission.AuthGroupType; import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.service.BungeeService; +import fr.xephi.authme.settings.commandconfig.CommandManager; import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.task.LimboPlayerTaskManager; import fr.xephi.authme.util.PlayerUtils; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -33,17 +33,10 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess { @Inject private LimboPlayerTaskManager limboPlayerTaskManager; - ProcessSyncPasswordRegister() { - } + @Inject + private CommandManager commandManager; - private void forceCommands(Player player) { - for (String command : service.getProperty(RegistrationSettings.FORCE_REGISTER_COMMANDS)) { - player.performCommand(command.replace("%p", player.getName())); - } - for (String command : service.getProperty(RegistrationSettings.FORCE_REGISTER_COMMANDS_AS_CONSOLE)) { - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), - command.replace("%p", player.getName())); - } + ProcessSyncPasswordRegister() { } /** @@ -83,7 +76,7 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess { } // Register is now finished; we can force all commands - forceCommands(player); + commandManager.runCommandsOnRegister(player); // Request login after registration if (service.getProperty(RegistrationSettings.FORCE_LOGIN_AFTER_REGISTER)) { diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index 20aa23c2..603e3975 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -10,6 +10,7 @@ import org.bukkit.BanList; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.World; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.bukkit.plugin.Plugin; @@ -273,6 +274,27 @@ public class BukkitService implements SettingsDependent { return Bukkit.getWorld(name); } + /** + * Dispatches a command on this server, and executes it if found. + * + * @param sender the apparent sender of the command + * @param commandLine the command + arguments. Example: test abc 123 + * @return returns false if no target is found + */ + public boolean dispatchCommand(CommandSender sender, String commandLine) { + return Bukkit.dispatchCommand(sender, commandLine); + } + + /** + * Dispatches a command to be run as console user on this server, and executes it if found. + * + * @param commandLine the command + arguments. Example: test abc 123 + * @return returns false if no target is found + */ + public boolean dispatchConsoleCommand(String commandLine) { + return Bukkit.dispatchCommand(Bukkit.getConsoleSender(), commandLine); + } + @Override public void reload(Settings settings) { useAsyncTasks = settings.getProperty(PluginSettings.USE_ASYNC_TASKS); @@ -309,13 +331,4 @@ public class BukkitService implements SettingsDependent { public BanEntry banIp(String ip, String reason, Date expires, String source) { return Bukkit.getServer().getBanList(BanList.Type.IP).addBan(ip, reason, expires, source); } - - /** - * Dispatch a command as console - * - * @param command the command - */ - public void dispatchConsoleCommand(String command) { - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command); - } } diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java b/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java new file mode 100644 index 00000000..38bb5991 --- /dev/null +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java @@ -0,0 +1,28 @@ +package fr.xephi.authme.settings.commandconfig; + +/** + * Command to be run. + */ +public class Command { + + /** The command to execute. */ + private String command; + /** The executor of the command. */ + private Executor executor = Executor.PLAYER; + + public String getCommand() { + return command; + } + + public void setCommand(String command) { + this.command = command; + } + + public Executor getExecutor() { + return executor; + } + + public void setExecutor(Executor executor) { + this.executor = executor; + } +} diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java new file mode 100644 index 00000000..00d35e2d --- /dev/null +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java @@ -0,0 +1,40 @@ +package fr.xephi.authme.settings.commandconfig; + +import java.util.Collections; +import java.util.Map; + +/** + * Command configuration. + * + * @see CommandManager + */ +public class CommandConfig { + + private Map onJoin = Collections.emptyMap(); + private Map onLogin = Collections.emptyMap(); + private Map onRegister = Collections.emptyMap(); + + public Map getOnJoin() { + return onJoin; + } + + public void setOnJoin(Map onJoin) { + this.onJoin = onJoin; + } + + public Map getOnLogin() { + return onLogin; + } + + public void setOnLogin(Map onLogin) { + this.onLogin = onLogin; + } + + public Map getOnRegister() { + return onRegister; + } + + public void setOnRegister(Map onRegister) { + this.onRegister = onRegister; + } +} diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java new file mode 100644 index 00000000..ebfcce2a --- /dev/null +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java @@ -0,0 +1,65 @@ +package fr.xephi.authme.settings.commandconfig; + +import com.github.authme.configme.SettingsManager; +import com.github.authme.configme.resource.YamlFileResource; +import fr.xephi.authme.initialization.DataFolder; +import fr.xephi.authme.initialization.Reloadable; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.util.FileUtils; +import org.bukkit.entity.Player; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.io.File; +import java.util.Map; + +/** + * Manages configurable commands to be run when various events occur. + */ +public class CommandManager implements Reloadable { + + private CommandConfig commandConfig; + + @Inject + @DataFolder + private File dataFolder; + + @Inject + private BukkitService bukkitService; + + + CommandManager() { + } + + public void runCommandsOnJoin(Player player) { + executeCommands(player, commandConfig.getOnJoin()); + } + + public void runCommandsOnRegister(Player player) { + executeCommands(player, commandConfig.getOnRegister()); + } + + private void executeCommands(Player player, Map commands) { + for (Command command : commands.values()) { + final String execution = command.getCommand().replace("%p", player.getName()); + if (Executor.CONSOLE.equals(command.getExecutor())) { + bukkitService.dispatchConsoleCommand(execution); + } else { + bukkitService.dispatchCommand(player, execution); + } + } + } + + @PostConstruct + @Override + public void reload() { + File file = new File(dataFolder, "commands.yml"); + FileUtils.copyFileFromResource(file, "commands.yml"); + + SettingsManager settingsManager = new SettingsManager( + new YamlFileResource(file), null, CommandSettingsHolder.class); + commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); + } + + +} diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java new file mode 100644 index 00000000..4de2de5e --- /dev/null +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java @@ -0,0 +1,51 @@ +package fr.xephi.authme.settings.commandconfig; + +import com.github.authme.configme.SectionComments; +import com.github.authme.configme.SettingsHolder; +import com.github.authme.configme.beanmapper.BeanProperty; +import com.github.authme.configme.properties.Property; + +import java.util.HashMap; +import java.util.Map; + +/** + * Settings holder class for the commands.yml settings. + */ +public final class CommandSettingsHolder implements SettingsHolder { + + public static final Property COMMANDS = + new BeanProperty<>(CommandConfig.class, "", new CommandConfig()); + + + private CommandSettingsHolder() { + } + + @SectionComments + public static Map sectionComments() { + String[] comments = { + "This configuration file allows you to execute commands on various events.", + "%p in commands will be replaced with the player name.", + "For example, if you want to message a welcome message to a player who just registered:", + "onRegister:", + " welcome:", + " command: 'msg %p Welcome to the server!'", + " as: CONSOLE", + "", + "This will make the console execute the msg command to the player.", + "Each command under an event has a name you can choose freely (e.g. 'welcome' as above),", + "after which a mandatory 'command' field defines the command to run, ", + "and 'as' defines who will run the command (either PLAYER or CONSOLE). Longer example:", + "onLogin:", + " welcome:", + " command: 'msg %p Welcome back!'", + " # as: PLAYER # player is the default, you can leave this out if you want", + " broadcast:", + " command: 'broadcast %p has joined, welcome back!'", + " as: CONSOLE" + }; + Map commentMap = new HashMap<>(); + commentMap.put("onLogin", comments); + return commentMap; + } + +} diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/Executor.java b/src/main/java/fr/xephi/authme/settings/commandconfig/Executor.java new file mode 100644 index 00000000..c7043de2 --- /dev/null +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/Executor.java @@ -0,0 +1,14 @@ +package fr.xephi.authme.settings.commandconfig; + +/** + * The executor of the command. + */ +public enum Executor { + + /** The player of the event. */ + PLAYER, + + /** The console user. */ + CONSOLE + +} diff --git a/src/main/resources/commands.yml b/src/main/resources/commands.yml new file mode 100644 index 00000000..a7c70359 --- /dev/null +++ b/src/main/resources/commands.yml @@ -0,0 +1,24 @@ + +# This configuration file allows you to execute commands on various events. +# %p in commands will be replaced with the player name. +# For example, if you want to message a welcome message to a player who just registered: +# onRegister: +# welcome: +# command: 'msg %p Welcome to the server!' +# as: CONSOLE +# +# This will make the console execute the msg command to the player. +# Each command under an event has a name you can choose freely (e.g. 'welcome' as above), +# after which a mandatory 'command' field defines the command to run, +# and 'as' defines who will run the command (either PLAYER or CONSOLE). Longer example: +# onLogin: +# welcome: +# command: 'msg %p Welcome back!' +# # as: PLAYER # player is the default, you can leave this out if you want +# broadcast: +# command: 'broadcast %p has joined, welcome back!' +# as: CONSOLE +onLogin: + welcome: + command: 'msg %p Welcome back!' + executor: 'PLAYER' \ No newline at end of file diff --git a/src/test/java/fr/xephi/authme/datasource/FlatFileIntegrationTest.java b/src/test/java/fr/xephi/authme/datasource/FlatFileIntegrationTest.java index 7ce72f15..7e0bb1a5 100644 --- a/src/test/java/fr/xephi/authme/datasource/FlatFileIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/datasource/FlatFileIntegrationTest.java @@ -3,8 +3,6 @@ package fr.xephi.authme.datasource; import com.google.common.io.Files; import fr.xephi.authme.TestHelper; import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.datasource.FlatFile; import org.junit.Before; import org.junit.Rule; import org.junit.Test; diff --git a/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java b/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java index d43f3c53..923d73e6 100644 --- a/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java @@ -4,7 +4,12 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.PluginSettings; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -17,6 +22,7 @@ import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; /** * Test for {@link BukkitService}. @@ -24,10 +30,21 @@ import static org.mockito.Mockito.mock; @RunWith(MockitoJUnitRunner.class) public class BukkitServiceTest { + private BukkitService bukkitService; + @Mock private AuthMe authMe; @Mock private Settings settings; + @Mock + private Server server; + + @Before + public void constructBukkitService() { + ReflectionTestUtils.setField(Bukkit.class, null, "server", server); + given(settings.getProperty(PluginSettings.USE_ASYNC_TASKS)).willReturn(true); + bukkitService = new BukkitService(authMe, settings); + } /** * Checks that {@link BukkitService#getOnlinePlayersIsCollection} is initialized to {@code true} on startup; @@ -35,11 +52,7 @@ public class BukkitServiceTest { */ @Test public void shouldHavePlayerListAsCollectionMethod() { - // given - given(settings.getProperty(PluginSettings.USE_ASYNC_TASKS)).willReturn(true); - BukkitService bukkitService = new BukkitService(authMe, settings); - - // when + // given / when boolean doesMethodReturnCollection = ReflectionTestUtils .getFieldValue(BukkitService.class, bukkitService, "getOnlinePlayersIsCollection"); @@ -50,8 +63,6 @@ public class BukkitServiceTest { @Test public void shouldRetrieveListOfOnlinePlayersFromReflectedMethod() { // given - given(settings.getProperty(PluginSettings.USE_ASYNC_TASKS)).willReturn(true); - BukkitService bukkitService = new BukkitService(authMe, settings); ReflectionTestUtils.setField(BukkitService.class, bukkitService, "getOnlinePlayersIsCollection", false); ReflectionTestUtils.setField(BukkitService.class, bukkitService, "getOnlinePlayers", ReflectionTestUtils.getMethod(BukkitServiceTest.class, "onlinePlayersImpl")); @@ -63,6 +74,33 @@ public class BukkitServiceTest { assertThat(players, hasSize(2)); } + @Test + public void shouldDispatchCommand() { + // given + CommandSender sender = mock(CommandSender.class); + String command = "help test abc"; + + // when + bukkitService.dispatchCommand(sender, command); + + // then + verify(server).dispatchCommand(sender, command); + } + + @Test + public void shouldDispatchConsoleCommand() { + // given + ConsoleCommandSender consoleSender = mock(ConsoleCommandSender.class); + given(server.getConsoleSender()).willReturn(consoleSender); + String command = "my command"; + + // when + bukkitService.dispatchConsoleCommand(command); + + // then + verify(server).dispatchCommand(consoleSender, command); + } + // Note: This method is used through reflections public static Player[] onlinePlayersImpl() { return new Player[]{ diff --git a/src/test/java/tools/filegeneration/GenerateCommandsYml.java b/src/test/java/tools/filegeneration/GenerateCommandsYml.java new file mode 100644 index 00000000..e6e69133 --- /dev/null +++ b/src/test/java/tools/filegeneration/GenerateCommandsYml.java @@ -0,0 +1,57 @@ +package tools.filegeneration; + +import com.github.authme.configme.SettingsManager; +import com.github.authme.configme.resource.YamlFileResource; +import com.google.common.collect.ImmutableMap; +import fr.xephi.authme.settings.commandconfig.Command; +import fr.xephi.authme.settings.commandconfig.CommandConfig; +import fr.xephi.authme.settings.commandconfig.CommandSettingsHolder; +import fr.xephi.authme.settings.commandconfig.Executor; +import tools.utils.AutoToolTask; +import tools.utils.ToolsConstants; + +import java.io.File; +import java.util.Scanner; + +/** + * Generates the commands.yml file that corresponds to the default in the code. + */ +public class GenerateCommandsYml implements AutoToolTask { + + private static final String COMMANDS_YML_FILE = ToolsConstants.MAIN_RESOURCES_ROOT + "commands.yml"; + + @Override + public void execute(Scanner scanner) { + executeDefault(); + } + + @Override + public void executeDefault() { + File file = new File(COMMANDS_YML_FILE); + + // Get default and add sample entry + CommandConfig commandConfig = CommandSettingsHolder.COMMANDS.getDefaultValue(); + commandConfig.setOnLogin( + ImmutableMap.of("welcome", newCommand("msg %p Welcome back!", Executor.PLAYER))); + + // Export the value to the file + SettingsManager settingsManager = new SettingsManager( + new YamlFileResource(file), null, CommandSettingsHolder.class); + settingsManager.setProperty(CommandSettingsHolder.COMMANDS, commandConfig); + settingsManager.save(); + + System.out.println("Updated " + COMMANDS_YML_FILE); + } + + @Override + public String getTaskName() { + return "generateCommandsYml"; + } + + private static Command newCommand(String commandLine, Executor executor) { + Command command = new Command(); + command.setCommand(commandLine); + command.setExecutor(executor); + return command; + } +} From 2fbf8b6c7107d5c93875cfd23a8007ed7224a4f6 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Thu, 17 Nov 2016 21:53:28 +0100 Subject: [PATCH 39/67] Use 1.11 --- pom.xml | 2 +- src/main/java/fr/xephi/authme/AuthMe.java | 6 +++--- src/test/java/fr/xephi/authme/AuthMeInitializationTest.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index edf73b76..44196e87 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ Xephi, sgdc3, DNx5, timvisee, games647, ljacqu, Gnat008 - 1.10.2-R0.1-SNAPSHOT + 1.11-R0.1-SNAPSHOT diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 78620307..c10954cf 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -40,9 +40,9 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.plugin.PluginLoader; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.scheduler.BukkitScheduler; import java.io.File; @@ -85,9 +85,9 @@ public class AuthMe extends JavaPlugin { */ @VisibleForTesting @SuppressWarnings("deprecation") // the super constructor is deprecated to mark it for unit testing only - protected AuthMe(final PluginLoader loader, final Server server, final PluginDescriptionFile description, + protected AuthMe(final JavaPluginLoader loader, final Server server, final PluginDescriptionFile description, final File dataFolder, final File file) { - super(loader, server, description, dataFolder, file); + super(loader, description, dataFolder, file); } /** diff --git a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java index a41dc588..df339b35 100644 --- a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java +++ b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java @@ -19,8 +19,8 @@ import fr.xephi.authme.task.purge.PurgeService; import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.plugin.PluginLoader; import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPluginLoader; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -50,7 +50,7 @@ import static org.mockito.Mockito.mock; public class AuthMeInitializationTest { @Mock - private PluginLoader pluginLoader; + private JavaPluginLoader pluginLoader; @Mock private Server server; From a196420eca0ed633216b8badc8320fea9e232e86 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 17 Nov 2016 22:07:39 +0100 Subject: [PATCH 40/67] Fix AuthMe initialization test after update to 1.11 --- src/main/java/fr/xephi/authme/AuthMe.java | 3 +-- .../java/fr/xephi/authme/AuthMeInitializationTest.java | 9 +++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index c10954cf..1adad034 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -85,8 +85,7 @@ public class AuthMe extends JavaPlugin { */ @VisibleForTesting @SuppressWarnings("deprecation") // the super constructor is deprecated to mark it for unit testing only - protected AuthMe(final JavaPluginLoader loader, final Server server, final PluginDescriptionFile description, - final File dataFolder, final File file) { + protected AuthMe(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { super(loader, description, dataFolder, file); } diff --git a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java index df339b35..fd26e3da 100644 --- a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java +++ b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java @@ -49,9 +49,6 @@ import static org.mockito.Mockito.mock; @RunWith(MockitoJUnitRunner.class) public class AuthMeInitializationTest { - @Mock - private JavaPluginLoader pluginLoader; - @Mock private Server server; @@ -60,7 +57,6 @@ public class AuthMeInitializationTest { private AuthMe authMe; private File dataFolder; - private File settingsFile; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -73,7 +69,8 @@ public class AuthMeInitializationTest { @Before public void initAuthMe() throws IOException { dataFolder = temporaryFolder.newFolder(); - settingsFile = new File(dataFolder, "config.yml"); + File settingsFile = new File(dataFolder, "config.yml"); + JavaPluginLoader pluginLoader = new JavaPluginLoader(server); Files.copy(TestHelper.getJarFile(TestHelper.PROJECT_ROOT + "config.test.yml"), settingsFile); // Mock / wire various Bukkit components @@ -86,7 +83,7 @@ public class AuthMeInitializationTest { "AuthMe", "N/A", AuthMe.class.getCanonicalName()); // Initialize AuthMe - authMe = new AuthMe(pluginLoader, server, descriptionFile, dataFolder, null); + authMe = new AuthMe(pluginLoader, descriptionFile, dataFolder, null); } @Test From 5b51ecb0dd966ec585a2d0ae39da7670991b0e8d Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 19 Nov 2016 11:04:12 +0100 Subject: [PATCH 41/67] Minor: pass null as migration service in tests if no migration should occur --- .../authme/AuthMeInitializationTest.java | 3 +-- .../settings/SettingsIntegrationTest.java | 3 +-- .../xephi/authme/settings/SettingsTest.java | 6 ++---- .../TestSettingsMigrationServices.java | 21 ------------------- 4 files changed, 4 insertions(+), 29 deletions(-) delete mode 100644 src/test/java/fr/xephi/authme/settings/TestSettingsMigrationServices.java diff --git a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java index fd26e3da..9e4ffd4e 100644 --- a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java +++ b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java @@ -34,7 +34,6 @@ import java.io.File; import java.io.IOException; import java.util.logging.Logger; -import static fr.xephi.authme.settings.TestSettingsMigrationServices.alwaysFulfilled; import static fr.xephi.authme.settings.properties.AuthMeSettingsRetriever.buildConfigurationData; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; @@ -90,7 +89,7 @@ public class AuthMeInitializationTest { public void shouldInitializeAllServices() { // given Settings settings = - new Settings(dataFolder, mock(PropertyResource.class), alwaysFulfilled(), buildConfigurationData()); + new Settings(dataFolder, mock(PropertyResource.class), null, buildConfigurationData()); Injector injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme").create(); injector.provide(DataFolder.class, dataFolder); diff --git a/src/test/java/fr/xephi/authme/settings/SettingsIntegrationTest.java b/src/test/java/fr/xephi/authme/settings/SettingsIntegrationTest.java index 9a644197..d0d2c36a 100644 --- a/src/test/java/fr/xephi/authme/settings/SettingsIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/settings/SettingsIntegrationTest.java @@ -121,8 +121,7 @@ public class SettingsIntegrationTest { // given File configFile = temporaryFolder.newFile(); PropertyResource resource = new YamlFileResource(configFile); - Settings settings = new Settings(testPluginFolder, resource, - TestSettingsMigrationServices.alwaysFulfilled(), CONFIG_DATA); + Settings settings = new Settings(testPluginFolder, resource, null, CONFIG_DATA); // when assertThat(settings.getProperty(TestConfiguration.RATIO_ORDER), equalTo(TestEnum.SECOND)); // default value diff --git a/src/test/java/fr/xephi/authme/settings/SettingsTest.java b/src/test/java/fr/xephi/authme/settings/SettingsTest.java index e839bb39..137d5a56 100644 --- a/src/test/java/fr/xephi/authme/settings/SettingsTest.java +++ b/src/test/java/fr/xephi/authme/settings/SettingsTest.java @@ -55,8 +55,7 @@ public class SettingsTest { PropertyResource resource = mock(PropertyResource.class); given(resource.getBoolean(RegistrationSettings.USE_WELCOME_MESSAGE.getPath())).willReturn(true); - Settings settings = new Settings(testPluginFolder, resource, - TestSettingsMigrationServices.alwaysFulfilled(), CONFIG_DATA); + Settings settings = new Settings(testPluginFolder, resource, null, CONFIG_DATA); // when String[] result = settings.getWelcomeMessage(); @@ -75,8 +74,7 @@ public class SettingsTest { Files.write(emailFile.toPath(), emailMessage.getBytes()); PropertyResource resource = mock(PropertyResource.class); - Settings settings = new Settings(testPluginFolder, resource, - TestSettingsMigrationServices.alwaysFulfilled(), CONFIG_DATA); + Settings settings = new Settings(testPluginFolder, resource, null, CONFIG_DATA); // when String result = settings.getPasswordEmailMessage(); diff --git a/src/test/java/fr/xephi/authme/settings/TestSettingsMigrationServices.java b/src/test/java/fr/xephi/authme/settings/TestSettingsMigrationServices.java deleted file mode 100644 index f14a4783..00000000 --- a/src/test/java/fr/xephi/authme/settings/TestSettingsMigrationServices.java +++ /dev/null @@ -1,21 +0,0 @@ -package fr.xephi.authme.settings; - -import com.github.authme.configme.migration.MigrationService; - -/** - * Provides {@link MigrationService} implementations for testing. - */ -public final class TestSettingsMigrationServices { - - private TestSettingsMigrationServices() { - } - - /** - * Returns a settings migration service which always answers that all data is up-to-date. - * - * @return test settings migration service - */ - public static MigrationService alwaysFulfilled() { - return (propertyResource, knownProperties) -> false; - } -} From b20d2fcd691209afc4325769f4bf77b0a10f6e8e Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 19 Nov 2016 11:45:07 +0100 Subject: [PATCH 42/67] #1000 Add Polish messages by @RikoDEV --- docs/translations.md | 13 +++--- src/main/resources/messages/help_pl.yml | 45 +++++++++++++++++++++ src/main/resources/messages/messages_pl.yml | 10 ++--- 3 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 src/main/resources/messages/help_pl.yml diff --git a/docs/translations.md b/docs/translations.md index c4288f15..42170005 100644 --- a/docs/translations.md +++ b/docs/translations.md @@ -1,5 +1,5 @@ - + # AuthMe Translations The following translations are available in AuthMe. Set `messagesLanguage` to the language code @@ -9,7 +9,7 @@ Code | Language | Translated |   ---- | -------- | ---------: | ------ [en](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_en.yml) | English | 100% | bar [bg](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_bg.yml) | Bulgarian | 71% | bar -[br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 97% | bar +[br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 100% | bar [cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 88% | bar [de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 95% | bar [es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 97% | bar @@ -17,15 +17,15 @@ Code | Language | Translated |   [fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 68% | bar [fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 95% | bar [gl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_gl.yml) | Galician | 72% | bar -[hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 97% | bar +[hu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_hu.yml) | Hungarian | 100% | bar [id](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_id.yml) | Indonesian | 72% | bar [it](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_it.yml) | Italian | 100% | bar [ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 74% | bar [lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Latvian | 55% | bar [nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 78% | bar -[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 92% | bar +[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 99% | bar [pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 88% | bar -[ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 95% | bar +[ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 100% | bar [sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 49% | bar [tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 83% | bar [uk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_uk.yml) | Ukrainian | 95% | bar @@ -34,6 +34,7 @@ Code | Language | Translated |   [zhhk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhhk.yml) | Chinese (Hong Kong) | 83% | bar [zhtw](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_zhtw.yml) | Chinese (Taiwan) | 83% | bar + --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 23 18:25:14 CEST 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sat Nov 19 11:44:25 CET 2016 diff --git a/src/main/resources/messages/help_pl.yml b/src/main/resources/messages/help_pl.yml new file mode 100644 index 00000000..a5f59a2e --- /dev/null +++ b/src/main/resources/messages/help_pl.yml @@ -0,0 +1,45 @@ +# Tlumaczenie configu dla AuthMe pomoc, kiedy wpiszesz /authme help lub /authme help register podana wiadomosc zostanie wyslana + +# ------------------------------------------------------- +# Lista tekstu uzyta w pomocy. +common: + header: '==========[ AuthMeReloaded - Pomoc ]==========' + optional: 'Opcjonalnie' + hasPermission: 'Nie posidasz permisji' + noPermission: 'Brak permisji' + default: 'Domyslnie' + result: 'Wynik' + defaultPermissions: + notAllowed: 'Nie posiadasz permisji' + opOnly: 'Tylko OP' + allowed: 'Dozwolone dla wszyskich' + +# ------------------------------------------------------- +# Tytuly z inwidualnych stref w pomoc. +# Zostaw tlumaczenie puste aby wylaczyc dana komende. Np.: +# alternatives: '' +section: + command: 'Komenda' + description: 'Krotki opis' + detailedDescription: 'Dlugi opis' + arguments: 'Argumenty' + permissions: 'Permisje' + alternatives: 'Alternatywy' + children: 'Komendy' + +# ------------------------------------------------------- +# Mozesz przetlumaczyc wszystkie komendy uzywajac tego wzoru. +# Na przyklad jesli chcesz przetlumaczyc /authme reload, utworz selekcje "authme.reload", lub "login" dla /login +# Jesli komenda posiada argumenty, mozesz uzyc arg1 aby przetlumaczyc pierwszy argument, i nastepne +# Tlumaczenia nie musza byc kompletne; kazde braki beda uzupelniane domyslnymi wiadomosciami z pluginu. +# Uwaga: Postaw glowna klase (np. "authme") przed ich dziecmi (np. "authme.reload") +commands: + authme.register: + description: 'Rejestracja gracza' + detailedDescription: 'Rerejestracja gracza z okreslonym haslem' + arg1: + label: 'player' + description: 'Nazwa gracza' + arg2: + label: 'password' + description: 'Haslo' diff --git a/src/main/resources/messages/messages_pl.yml b/src/main/resources/messages/messages_pl.yml index 777ced5f..fd9a9bf1 100644 --- a/src/main/resources/messages/messages_pl.yml +++ b/src/main/resources/messages/messages_pl.yml @@ -69,9 +69,9 @@ antibot_auto_enabled: '&4[AntiBotService] AntyBot wlaczony z powodu duzej liczby accounts_owned_self: 'Posiadasz %count kont:' two_factor_create: '&2Twoj sekretny kod to %code. Mozesz zeskanowac go tutaj %url' not_owner_error: 'Nie jestes wlascicielem tego konta, wybierz inny nick!' -# TODO email_show: '&2Your current email address is: &f%email' -# TODO show_no_email: '&2You currently don''t have email address associated with this account.' +email_show: '&2Twoj aktualny adres email to: &f%email' +show_no_email: '&2Nie posiadasz adresu email przypisanego do tego konta.' # TODO kicked_admin_registered: 'An admin just registered you; please log in again' -# TODO incomplete_email_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.' -# TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' \ No newline at end of file +incomplete_email_settings: 'Error: Nie wszystkie opcje odpowiedzialne za wysylanie emaili zostaly ustawione. Skontaktuj sie z administracja.' +recovery_code_sent: 'Kod odzyskiwania hasla zostal wyslany na adres email przypisany do konta.' +recovery_code_incorrect: 'Kod odzyskiwania hasla jest bledny! Uzyj /email recovery [email] aby wygenerowac nowy.' From 91aa5dc251de99157b5f8e2257940345f7a7b455 Mon Sep 17 00:00:00 2001 From: RatchetCinemaESP Date: Sat, 19 Nov 2016 14:23:38 +0100 Subject: [PATCH 43/67] Update messages_es.yml (#183) I have translated: 77 #email_show 78 #show_no_email A greeting! --- src/main/resources/messages/messages_es.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/messages/messages_es.yml b/src/main/resources/messages/messages_es.yml index 8e001478..bc5bcb0f 100644 --- a/src/main/resources/messages/messages_es.yml +++ b/src/main/resources/messages/messages_es.yml @@ -74,5 +74,5 @@ accounts_owned_other: 'El jugador %name tiene %count cuentas:' incomplete_email_settings: 'Error: no todos los ajustes necesario se han configurado para enviar correos. Por favor, contacta con un administrador.' recovery_code_sent: 'El código de recuperación para recuperar tu contraseña se ha enviado a tu correo.' invalid_name_case: 'Solo puedes unirte mediante el nombre de usuario %valid, no %invalid.' -# TODO email_show: '&2Your current email address is: &f%email' -# TODO show_no_email: '&2You currently don''t have email address associated with this account.' \ No newline at end of file +email_show: '&2Tu dirección de E-Mail actual es: &f%email' +show_no_email: '&2No tienes ningun E-Mail asociado en esta cuenta.' From 30343d75872939bdaef101db0f0404be242f728f Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 19 Nov 2016 14:01:21 +0100 Subject: [PATCH 44/67] Do not modify player's air level before he logs in --- src/main/java/fr/xephi/authme/AuthMe.java | 6 ++++ .../authme/listener/PlayerListener111.java | 24 +++++++++++++++ .../listener/PlayerListener111Test.java | 30 +++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 src/main/java/fr/xephi/authme/listener/PlayerListener111.java create mode 100644 src/test/java/fr/xephi/authme/listener/PlayerListener111Test.java diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 1adad034..6c87fcbe 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -17,6 +17,7 @@ import fr.xephi.authme.initialization.TaskCloser; import fr.xephi.authme.listener.BlockListener; import fr.xephi.authme.listener.EntityListener; import fr.xephi.authme.listener.PlayerListener; +import fr.xephi.authme.listener.PlayerListener111; import fr.xephi.authme.listener.PlayerListener16; import fr.xephi.authme.listener.PlayerListener18; import fr.xephi.authme.listener.PlayerListener19; @@ -301,6 +302,11 @@ public class AuthMe extends JavaPlugin { if (isClassLoaded("org.bukkit.event.player.PlayerSwapHandItemsEvent")) { pluginManager.registerEvents(injector.getSingleton(PlayerListener19.class), this); } + + // Register listener for 1.11 events if available + if (isClassLoaded("org.bukkit.event.entity.EntityAirChangeEvent")) { + pluginManager.registerEvents(injector.getSingleton(PlayerListener111.class), this); + } } /** diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener111.java b/src/main/java/fr/xephi/authme/listener/PlayerListener111.java new file mode 100644 index 00000000..43b4ca33 --- /dev/null +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener111.java @@ -0,0 +1,24 @@ +package fr.xephi.authme.listener; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityAirChangeEvent; + +import javax.inject.Inject; + +/** + * Listener of player events for events introduced in Minecraft 1.11. + */ +public class PlayerListener111 implements Listener { + + @Inject + private ListenerService listenerService; + + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) + public void onPlayerAirChange(EntityAirChangeEvent event) { + if (listenerService.shouldCancelEvent(event)) { + event.setCancelled(true); + } + } +} diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListener111Test.java b/src/test/java/fr/xephi/authme/listener/PlayerListener111Test.java new file mode 100644 index 00000000..8f479a71 --- /dev/null +++ b/src/test/java/fr/xephi/authme/listener/PlayerListener111Test.java @@ -0,0 +1,30 @@ +package fr.xephi.authme.listener; + +import org.bukkit.event.entity.EntityAirChangeEvent; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock; + +/** + * Test for {@link PlayerListener111}. + */ +@RunWith(MockitoJUnitRunner.class) +public class PlayerListener111Test { + + @InjectMocks + private PlayerListener111 listener; + + @Mock + private ListenerService listenerService; + + @Test + public void shouldCancelEvent() { + withServiceMock(listenerService) + .check(listener::onPlayerAirChange, EntityAirChangeEvent.class); + } + +} From dda7bd5cb5f4c0e27f8aa3078aeb0d18b1b8524a Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 19 Nov 2016 17:36:05 +0100 Subject: [PATCH 45/67] #1008 Check that OfflinePlayer's name is not null - Add check - Create test --- .../fr/xephi/authme/task/purge/PurgeTask.java | 2 +- .../authme/task/purge/PurgeTaskTest.java | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java b/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java index 712f81a3..92391af9 100644 --- a/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java +++ b/src/main/java/fr/xephi/authme/task/purge/PurgeTask.java @@ -72,7 +72,7 @@ class PurgeTask extends BukkitRunnable { } OfflinePlayer offlinePlayer = offlinePlayers[nextPosition]; - if (toPurge.remove(offlinePlayer.getName().toLowerCase())) { + if (offlinePlayer.getName() != null && toPurge.remove(offlinePlayer.getName().toLowerCase())) { if (!permissionsManager.hasPermissionOffline(offlinePlayer, PlayerStatePermission.BYPASS_PURGE)) { playerPortion.add(offlinePlayer); namePortion.add(offlinePlayer.getName()); diff --git a/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java b/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java index 728669f7..286e0124 100644 --- a/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java +++ b/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java @@ -124,6 +124,27 @@ public class PurgeTaskTest { assertRanPurgeWithNames("foxtrot"); } + /** + * #1008: OfflinePlayer#getName may return null. + */ + @Test + public void shouldHandleOfflinePlayerWithNullName() { + // given + Set names = newHashSet("name1", "name2"); + OfflinePlayer[] players = asArray( + mockOfflinePlayer(null, false), mockOfflinePlayer("charlie", false), mockOfflinePlayer("name1", false)); + reset(purgeService, permissionsManager); + setPermissionsBehavior(); + + PurgeTask task = new PurgeTask(purgeService, permissionsManager, null, names, players); + + // when + task.run(); + + // then + assertRanPurgeWithPlayers(players[2]); + } + @Test public void shouldStopTaskAndInformSenderUponCompletion() { // given From 8685e50988a85689a4cab3693612848390bba84f Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 20 Nov 2016 17:45:29 +0100 Subject: [PATCH 46/67] Update Polish translations (TODO) All translations are correct. (cherry picked from commit b3882ed) --- src/main/resources/messages/messages_pl.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/messages/messages_pl.yml b/src/main/resources/messages/messages_pl.yml index fd9a9bf1..cd3c55ac 100644 --- a/src/main/resources/messages/messages_pl.yml +++ b/src/main/resources/messages/messages_pl.yml @@ -71,7 +71,7 @@ two_factor_create: '&2Twoj sekretny kod to %code. Mozesz zeskanowac go tutaj %ur not_owner_error: 'Nie jestes wlascicielem tego konta, wybierz inny nick!' email_show: '&2Twoj aktualny adres email to: &f%email' show_no_email: '&2Nie posiadasz adresu email przypisanego do tego konta.' -# TODO kicked_admin_registered: 'An admin just registered you; please log in again' +kicked_admin_registered: 'Administrator zarejestrowal Ciebie, mozesz sie zalogowac.' incomplete_email_settings: 'Error: Nie wszystkie opcje odpowiedzialne za wysylanie emaili zostaly ustawione. Skontaktuj sie z administracja.' recovery_code_sent: 'Kod odzyskiwania hasla zostal wyslany na adres email przypisany do konta.' recovery_code_incorrect: 'Kod odzyskiwania hasla jest bledny! Uzyj /email recovery [email] aby wygenerowac nowy.' From 7d65d2a7c44756ebaba3163296efd013536fa0a4 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Tue, 22 Nov 2016 18:19:46 +0100 Subject: [PATCH 47/67] Fix various code issues as detected by Sonar Mostly minor changes: - Add deprecated javadoc tag on deprecated members - Reduce duplication (FlatFile, BackupService, ...) - Make methods static - Reduce size of anonymous classes - Replace name with displayName in PermissionsSystemType (avoids confusing with Enum name()) - Tabs to spaces - Merge if statements Code from third-party sources (BCryptService, BinTools, PHPBB) not modified. --- src/main/java/fr/xephi/authme/AuthMe.java | 15 +++-- src/main/java/fr/xephi/authme/api/API.java | 30 ++++------ src/main/java/fr/xephi/authme/api/NewAPI.java | 4 +- .../xephi/authme/command/CommandMapper.java | 8 +-- .../authme/ChangePasswordAdminCommand.java | 55 +++++++++++-------- .../executable/authme/LastLoginCommand.java | 2 +- .../executable/email/ShowEmailCommand.java | 2 +- .../fr/xephi/authme/data/auth/PlayerAuth.java | 2 +- .../fr/xephi/authme/datasource/FlatFile.java | 28 +--------- .../fr/xephi/authme/datasource/MySQL.java | 8 +-- .../fr/xephi/authme/datasource/SQLite.java | 11 ++-- .../converter/CrazyLoginConverter.java | 37 ++++++++----- .../initialization/OnShutdownPlayerSaver.java | 6 +- .../xephi/authme/listener/OnJoinVerifier.java | 5 +- .../xephi/authme/listener/PlayerListener.java | 9 +-- .../fr/xephi/authme/output/Log4JFilter.java | 7 +-- .../authme/permission/AuthGroupHandler.java | 3 +- .../authme/permission/PermissionsManager.java | 8 +-- .../permission/PermissionsSystemType.java | 16 +++--- .../handlers/BPermissionsHandler.java | 2 +- .../handlers/PermissionsBukkitHandler.java | 2 +- .../handlers/PermissionsExHandler.java | 2 +- .../changepassword/AsyncChangePassword.java | 3 +- .../process/login/ProcessSyncPlayerLogin.java | 14 ++--- .../register/ProcessSyncEmailRegister.java | 4 +- .../authme/security/crypts/PLAINTEXT.java | 5 ++ .../xephi/authme/security/crypts/XAUTH.java | 4 +- .../xephi/authme/service/BackupService.java | 54 +++++++++--------- .../authme/service/ValidationService.java | 3 +- .../fr/xephi/authme/settings/SpawnLoader.java | 4 +- src/main/java/fr/xephi/authme/util/Utils.java | 6 +- .../permission/PermissionsSystemTypeTest.java | 10 ++-- 32 files changed, 172 insertions(+), 197 deletions(-) diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index 6c87fcbe..74a98654 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -61,7 +61,7 @@ public class AuthMe extends JavaPlugin { private static final String LOG_FILENAME = "authme.log"; private static final int CLEANUP_INTERVAL = 5 * TICKS_PER_MINUTE; - // Default version and build number values; + // Default version and build number values private static String pluginVersion = "N/D"; private static String pluginBuildNumber = "Unknown"; @@ -132,7 +132,7 @@ public class AuthMe extends JavaPlugin { @Override public void onEnable() { // Load the plugin version data from the plugin description file - loadPluginInfo(); + loadPluginInfo(getDescription().getVersion()); // Initialize the plugin try { @@ -175,9 +175,10 @@ public class AuthMe extends JavaPlugin { /** * Load the version and build number of the plugin from the description file. + * + * @param versionRaw the version as given by the plugin description file */ - private void loadPluginInfo() { - String versionRaw = this.getDescription().getVersion(); + private static void loadPluginInfo(String versionRaw) { int index = versionRaw.lastIndexOf("-"); if (index != -1) { pluginVersion = versionRaw.substring(0, index); @@ -190,10 +191,8 @@ public class AuthMe extends JavaPlugin { /** * Initialize the plugin and all the services. - * - * @throws Exception if the initialization fails */ - private void initialize() throws Exception { + private void initialize() { // Set the Logger instance and log file path ConsoleLogger.setLogger(getLogger()); ConsoleLogger.setLogFile(new File(getDataFolder(), LOG_FILENAME)); @@ -224,7 +223,7 @@ public class AuthMe extends JavaPlugin { // TODO: does this still make sense? -sgdc3 // If the server is empty (fresh start) just set all the players as unlogged - if (bukkitService.getOnlinePlayers().size() == 0) { + if (bukkitService.getOnlinePlayers().isEmpty()) { database.purgeLogged(); } diff --git a/src/main/java/fr/xephi/authme/api/API.java b/src/main/java/fr/xephi/authme/api/API.java index 7fa02788..d05fbe6b 100644 --- a/src/main/java/fr/xephi/authme/api/API.java +++ b/src/main/java/fr/xephi/authme/api/API.java @@ -19,12 +19,13 @@ import javax.inject.Inject; /** * Deprecated API of AuthMe. Please use {@link NewAPI} instead. + * + * @deprecated Use {@link NewAPI} */ @Deprecated public class API { - public static final String newline = System.getProperty("line.separator"); - public static AuthMe instance; + private static AuthMe instance; private static DataSource dataSource; private static PasswordSecurity passwordSecurity; private static Management management; @@ -83,28 +84,17 @@ public class API { } public static Location getLastLocation(Player player) { - try { - PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName().toLowerCase()); + PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName().toLowerCase()); - if (auth != null) { - Location loc = new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ()); - return loc; - } else { - return null; - } - - } catch (NullPointerException ex) { - return null; + if (auth != null) { + return new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ()); } + return null; } - public static void setPlayerInventory(Player player, ItemStack[] content, - ItemStack[] armor) { - try { - player.getInventory().setContents(content); - player.getInventory().setArmorContents(armor); - } catch (NullPointerException ignored) { - } + public static void setPlayerInventory(Player player, ItemStack[] content, ItemStack[] armor) { + player.getInventory().setContents(content); + player.getInventory().setArmorContents(armor); } /** diff --git a/src/main/java/fr/xephi/authme/api/NewAPI.java b/src/main/java/fr/xephi/authme/api/NewAPI.java index 5805e4af..82a2483b 100644 --- a/src/main/java/fr/xephi/authme/api/NewAPI.java +++ b/src/main/java/fr/xephi/authme/api/NewAPI.java @@ -25,8 +25,8 @@ import java.util.List; */ public class NewAPI { - public static NewAPI singleton; - public final AuthMe plugin; + private static NewAPI singleton; + private final AuthMe plugin; private final PluginHookService pluginHookService; private final DataSource dataSource; private final PasswordSecurity passwordSecurity; diff --git a/src/main/java/fr/xephi/authme/command/CommandMapper.java b/src/main/java/fr/xephi/authme/command/CommandMapper.java index e3666492..8e2b1bdc 100644 --- a/src/main/java/fr/xephi/authme/command/CommandMapper.java +++ b/src/main/java/fr/xephi/authme/command/CommandMapper.java @@ -87,10 +87,10 @@ public class CommandMapper { return classes; } - private FoundCommandResult getCommandWithSmallestDifference(CommandDescription base, List parts) { + private static FoundCommandResult getCommandWithSmallestDifference(CommandDescription base, List parts) { // Return the base command with incorrect arg count error if we only have one part if (parts.size() <= 1) { - return new FoundCommandResult(base, parts, new ArrayList(), 0.0, INCORRECT_ARGUMENTS); + return new FoundCommandResult(base, parts, new ArrayList<>(), 0.0, INCORRECT_ARGUMENTS); } final String childLabel = parts.get(1); @@ -115,7 +115,7 @@ public class CommandMapper { final int partsSize = parts.size(); List labels = parts.subList(0, Math.min(closestCommand.getLabelCount(), partsSize)); List arguments = (labels.size() == partsSize) - ? new ArrayList() + ? new ArrayList<>() : parts.subList(labels.size(), partsSize); return new FoundCommandResult(closestCommand, labels, arguments, minDifference, status); @@ -141,7 +141,7 @@ public class CommandMapper { * * @return A command if there was a complete match (including proper argument count), null otherwise */ - private CommandDescription getSuitableChild(CommandDescription baseCommand, List parts) { + private static CommandDescription getSuitableChild(CommandDescription baseCommand, List parts) { if (CollectionUtils.isEmpty(parts)) { return null; } 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 9842b9f8..8f3a2b0a 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 @@ -54,33 +54,40 @@ public class ChangePasswordAdminCommand implements ExecutableCommand { } // Set the password - final String playerNameLowerCase = playerName.toLowerCase(); - bukkitService.runTaskOptionallyAsync(new Runnable() { + bukkitService.runTaskOptionallyAsync(() -> changePassword(playerName.toLowerCase(), playerPass, sender)); + } - @Override - public void run() { - PlayerAuth auth = null; - if (playerCache.isAuthenticated(playerNameLowerCase)) { - auth = playerCache.getAuth(playerNameLowerCase); - } else if (dataSource.isAuthAvailable(playerNameLowerCase)) { - auth = dataSource.getAuth(playerNameLowerCase); - } - if (auth == null) { - commandService.send(sender, MessageKey.UNKNOWN_USER); - return; - } + /** + * 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) { + PlayerAuth auth = getAuth(nameLowercase); + if (auth == null) { + commandService.send(sender, MessageKey.UNKNOWN_USER); + return; + } - HashedPassword hashedPassword = passwordSecurity.computeHash(playerPass, playerNameLowerCase); - auth.setPassword(hashedPassword); + HashedPassword hashedPassword = passwordSecurity.computeHash(password, nameLowercase); + auth.setPassword(hashedPassword); - if (dataSource.updatePassword(auth)) { - commandService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS); - ConsoleLogger.info(sender.getName() + " changed password of " + playerNameLowerCase); - } else { - commandService.send(sender, MessageKey.ERROR); - } - } + if (dataSource.updatePassword(auth)) { + commandService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS); + ConsoleLogger.info(sender.getName() + " changed password of " + nameLowercase); + } else { + commandService.send(sender, MessageKey.ERROR); + } + } - }); + private PlayerAuth getAuth(String nameLowercase) { + if (playerCache.isAuthenticated(nameLowercase)) { + return playerCache.getAuth(nameLowercase); + } else if (dataSource.isAuthAvailable(nameLowercase)) { + return dataSource.getAuth(nameLowercase); + } + return null; } } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java index 3c2b8cd5..67fb2591 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java @@ -25,7 +25,7 @@ public class LastLoginCommand implements ExecutableCommand { @Override public void executeCommand(CommandSender sender, List arguments) { // Get the player - String playerName = (arguments.size() >= 1) ? arguments.get(0) : sender.getName(); + String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0); PlayerAuth auth = dataSource.getAuth(playerName); if (auth == null) { diff --git a/src/main/java/fr/xephi/authme/command/executable/email/ShowEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/ShowEmailCommand.java index ae55c628..68bc06dd 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/ShowEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/ShowEmailCommand.java @@ -23,7 +23,7 @@ public class ShowEmailCommand extends PlayerCommand { @Override public void runCommand(Player player, List arguments) { PlayerAuth auth = playerCache.getAuth(player.getName()); - if (auth.getEmail() != null && !auth.getEmail().equalsIgnoreCase("your@email.com")) { + if (auth.getEmail() != null && !"your@email.com".equalsIgnoreCase(auth.getEmail())) { commandService.send(player, MessageKey.EMAIL_SHOW, auth.getEmail()); } else { commandService.send(player, MessageKey.SHOW_NO_EMAIL); diff --git a/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java b/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java index e4fd9230..f6ef65a7 100644 --- a/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java +++ b/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java @@ -189,7 +189,7 @@ public class PlayerAuth { * @return String */ public String serialize() { - StringBuffer str = new StringBuffer(); + StringBuilder str = new StringBuilder(); char d = ';'; str.append(this.nickname).append(d); str.append(this.realName).append(d); diff --git a/src/main/java/fr/xephi/authme/datasource/FlatFile.java b/src/main/java/fr/xephi/authme/datasource/FlatFile.java index 49b5442d..8c1ecf4b 100644 --- a/src/main/java/fr/xephi/authme/datasource/FlatFile.java +++ b/src/main/java/fr/xephi/authme/datasource/FlatFile.java @@ -9,7 +9,6 @@ import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.Closeable; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; @@ -295,19 +294,11 @@ public class FlatFile implements DataSource { break; } } - } catch (FileNotFoundException ex) { - ConsoleLogger.warning(ex.getMessage()); - return false; } catch (IOException ex) { ConsoleLogger.warning(ex.getMessage()); return false; } finally { - if (br != null) { - try { - br.close(); - } catch (IOException ignored) { - } - } + silentClose(br); } if (newAuth != null) { removeAuth(auth.getNickname()); @@ -330,19 +321,11 @@ public class FlatFile implements DataSource { } } return countIp; - } catch (FileNotFoundException ex) { - ConsoleLogger.warning(ex.getMessage()); - return new ArrayList<>(); } catch (IOException ex) { ConsoleLogger.warning(ex.getMessage()); return new ArrayList<>(); } finally { - if (br != null) { - try { - br.close(); - } catch (IOException ignored) { - } - } + silentClose(br); } } @@ -363,12 +346,7 @@ public class FlatFile implements DataSource { } catch (IOException ex) { ConsoleLogger.warning(ex.getMessage()); } finally { - if (br != null) { - try { - br.close(); - } catch (IOException ignored) { - } - } + silentClose(br); } return 0; } diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index a099ff44..20ffa6d5 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -47,7 +47,7 @@ public class MySQL implements DataSource { private int phpBbGroup; private String wordpressPrefix; - public MySQL(Settings settings) throws ClassNotFoundException, SQLException, PoolInitializationException { + public MySQL(Settings settings) throws ClassNotFoundException, SQLException { setParameters(settings); // Set the connection arguments (and check if connection is ok) @@ -102,12 +102,12 @@ public class MySQL implements DataSource { } } - private void setConnectionArguments() throws RuntimeException { + private void setConnectionArguments() { ds = new HikariDataSource(); ds.setPoolName("AuthMeMYSQLPool"); // Pool size - ds.setMaximumPoolSize(poolSize); + ds.setMaximumPoolSize(poolSize); // Database URL ds.setJdbcUrl("jdbc:mysql://" + this.host + ":" + this.port + "/" + this.database); @@ -134,7 +134,7 @@ public class MySQL implements DataSource { } @Override - public void reload() throws RuntimeException { + public void reload() { if (ds != null) { ds.close(); } diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/src/main/java/fr/xephi/authme/datasource/SQLite.java index d19c4aa2..fdb9c919 100644 --- a/src/main/java/fr/xephi/authme/datasource/SQLite.java +++ b/src/main/java/fr/xephi/authme/datasource/SQLite.java @@ -3,9 +3,6 @@ package fr.xephi.authme.datasource; import com.google.common.annotations.VisibleForTesting; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.datasource.Columns; -import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.datasource.DataSourceType; import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; @@ -397,7 +394,7 @@ public class SQLite implements DataSource { } } - private void close(Statement st) { + private static void close(Statement st) { if (st != null) { try { st.close(); @@ -407,7 +404,7 @@ public class SQLite implements DataSource { } } - private void close(Connection con) { + private static void close(Connection con) { if (con != null) { try { con.close(); @@ -417,7 +414,7 @@ public class SQLite implements DataSource { } } - private void close(ResultSet rs) { + private static void close(ResultSet rs) { if (rs != null) { try { rs.close(); @@ -479,7 +476,7 @@ public class SQLite implements DataSource { pst.setString(1, user); rs = pst.executeQuery(); if (rs.next()) - return (rs.getInt(col.IS_LOGGED) == 1); + return rs.getInt(col.IS_LOGGED) == 1; } catch (SQLException ex) { logSqlException(ex); } finally { diff --git a/src/main/java/fr/xephi/authme/datasource/converter/CrazyLoginConverter.java b/src/main/java/fr/xephi/authme/datasource/converter/CrazyLoginConverter.java index 535c0eba..13266a89 100644 --- a/src/main/java/fr/xephi/authme/datasource/converter/CrazyLoginConverter.java +++ b/src/main/java/fr/xephi/authme/datasource/converter/CrazyLoginConverter.java @@ -43,20 +43,7 @@ public class CrazyLoginConverter implements Converter { try (BufferedReader users = new BufferedReader(new FileReader(source))) { while ((line = users.readLine()) != null) { if (line.contains("|")) { - String[] args = line.split("\\|"); - if (args.length < 2 || "name".equalsIgnoreCase(args[0])) { - continue; - } - String playerName = args[0]; - String password = args[1]; - if (password != null) { - PlayerAuth auth = PlayerAuth.builder() - .name(playerName.toLowerCase()) - .realName(playerName) - .password(password, null) - .build(); - database.saveAuth(auth); - } + migrateAccount(line); } } ConsoleLogger.info("CrazyLogin database has been imported correctly"); @@ -66,4 +53,26 @@ public class CrazyLoginConverter implements Converter { } } + /** + * Moves an account from CrazyLogin to the AuthMe database. + * + * @param line line read from the CrazyLogin file (one account) + */ + private void migrateAccount(String line) { + String[] args = line.split("\\|"); + if (args.length < 2 || "name".equalsIgnoreCase(args[0])) { + return; + } + String playerName = args[0]; + String password = args[1]; + if (password != null) { + PlayerAuth auth = PlayerAuth.builder() + .name(playerName.toLowerCase()) + .realName(playerName) + .password(password, null) + .build(); + database.saveAuth(auth); + } + } + } diff --git a/src/main/java/fr/xephi/authme/initialization/OnShutdownPlayerSaver.java b/src/main/java/fr/xephi/authme/initialization/OnShutdownPlayerSaver.java index 6141e47e..1e786244 100644 --- a/src/main/java/fr/xephi/authme/initialization/OnShutdownPlayerSaver.java +++ b/src/main/java/fr/xephi/authme/initialization/OnShutdownPlayerSaver.java @@ -76,10 +76,8 @@ public class OnShutdownPlayerSaver { dataSource.updateQuitLoc(auth); } if (settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN) - && !settings.getProperty(RestrictionSettings.NO_TELEPORT)) { - if (!limboPlayerStorage.hasData(player)) { - limboPlayerStorage.saveData(player); - } + && !settings.getProperty(RestrictionSettings.NO_TELEPORT) && !limboPlayerStorage.hasData(player)) { + limboPlayerStorage.saveData(player); } } } diff --git a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java index 7e68aae4..e3ff4ec5 100644 --- a/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java +++ b/src/main/java/fr/xephi/authme/listener/OnJoinVerifier.java @@ -170,10 +170,9 @@ class OnJoinVerifier implements Reloadable { public void checkPlayerCountry(boolean isAuthAvailable, String playerIp) throws FailedVerificationException { if ((!isAuthAvailable || settings.getProperty(ProtectionSettings.ENABLE_PROTECTION_REGISTERED)) - && settings.getProperty(ProtectionSettings.ENABLE_PROTECTION)) { - if (!validationService.isCountryAdmitted(playerIp)) { + && settings.getProperty(ProtectionSettings.ENABLE_PROTECTION) + && !validationService.isCountryAdmitted(playerIp)) { throw new FailedVerificationException(MessageKey.COUNTRY_BANNED_ERROR); - } } } diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index 92cf6a84..9b3eda8e 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -42,6 +42,7 @@ import org.bukkit.event.player.PlayerShearEntityEvent; import javax.inject.Inject; import java.util.Iterator; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -53,7 +54,7 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAU */ public class PlayerListener implements Listener { - public static final ConcurrentHashMap joinMessage = new ConcurrentHashMap<>(); + public static final Map joinMessage = new ConcurrentHashMap<>(); @Inject private Settings settings; @@ -81,7 +82,7 @@ public class PlayerListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { String cmd = event.getMessage().split(" ")[0].toLowerCase(); - if (settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD) && cmd.equals("/motd")) { + if (settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD) && "/motd".equals(cmd)) { return; } if (settings.getProperty(RestrictionSettings.ALLOW_COMMANDS).contains(cmd)) { @@ -113,7 +114,7 @@ public class PlayerListener implements Listener { iter.remove(); } } - if (recipients.size() == 0) { + if (recipients.isEmpty()) { event.setCancelled(true); } } @@ -224,7 +225,7 @@ public class PlayerListener implements Listener { // Get the auth later as this may cause the single session check to fail // Slow stuff final PlayerAuth auth = dataSource.getAuth(name); - final boolean isAuthAvailable = (auth != null); + final boolean isAuthAvailable = auth != null; onJoinVerifier.checkKickNonRegistered(isAuthAvailable); onJoinVerifier.checkAntibot(player, isAuthAvailable); onJoinVerifier.checkNameCasing(player, auth); diff --git a/src/main/java/fr/xephi/authme/output/Log4JFilter.java b/src/main/java/fr/xephi/authme/output/Log4JFilter.java index 90b9f0fb..1d044e18 100644 --- a/src/main/java/fr/xephi/authme/output/Log4JFilter.java +++ b/src/main/java/fr/xephi/authme/output/Log4JFilter.java @@ -12,14 +12,9 @@ import org.apache.logging.log4j.message.Message; * * @author Xephi59 */ -@SuppressWarnings("serial") public class Log4JFilter extends AbstractFilter { - /** - * Constructor. - */ - public Log4JFilter() { - } + private static final long serialVersionUID = -5594073755007974254L; /** * Validates a Message instance and returns the {@link Result} value diff --git a/src/main/java/fr/xephi/authme/permission/AuthGroupHandler.java b/src/main/java/fr/xephi/authme/permission/AuthGroupHandler.java index fb4bff48..492c6911 100644 --- a/src/main/java/fr/xephi/authme/permission/AuthGroupHandler.java +++ b/src/main/java/fr/xephi/authme/permission/AuthGroupHandler.java @@ -31,7 +31,8 @@ public class AuthGroupHandler implements Reloadable { private String unregisteredGroup; private String registeredGroup; - AuthGroupHandler() { } + AuthGroupHandler() { + } /** * Set the group of a player, by its AuthMe group type. diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java index c0c6981a..29406be6 100644 --- a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java +++ b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java @@ -78,12 +78,12 @@ public class PermissionsManager implements Reloadable { if (handler != null) { // Show a success message and return this.handler = handler; - ConsoleLogger.info("Hooked into " + type.getName() + "!"); + ConsoleLogger.info("Hooked into " + type.getDisplayName() + "!"); return; } } catch (Exception ex) { // An error occurred, show a warning message - ConsoleLogger.logException("Error while hooking into " + type.getName(), ex); + ConsoleLogger.logException("Error while hooking into " + type.getDisplayName(), ex); } } @@ -101,7 +101,7 @@ public class PermissionsManager implements Reloadable { // Make sure the plugin is enabled before hooking if (!plugin.isEnabled()) { - ConsoleLogger.info("Not hooking into " + type.getName() + " because it's disabled!"); + ConsoleLogger.info("Not hooking into " + type.getDisplayName() + " because it's disabled!"); return null; } @@ -414,7 +414,7 @@ public class PermissionsManager implements Reloadable { */ public boolean setGroups(Player player, List groupNames) { // If no permissions system is used or if there's no group supplied, return false - if (!isEnabled() || groupNames.size() <= 0) + if (!isEnabled() || groupNames.isEmpty()) return false; // Set the main group diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java b/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java index 1410bc66..72a0753c 100644 --- a/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java +++ b/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java @@ -33,21 +33,21 @@ public enum PermissionsSystemType { /** * The display name of the permissions system. */ - public String name; + private String displayName; /** * The name of the permissions system plugin. */ - public String pluginName; + private String pluginName; /** * Constructor for PermissionsSystemType. * - * @param name Display name of the permissions system. + * @param displayName Display name of the permissions system. * @param pluginName Name of the plugin. */ - PermissionsSystemType(String name, String pluginName) { - this.name = name; + PermissionsSystemType(String displayName, String pluginName) { + this.displayName = displayName; this.pluginName = pluginName; } @@ -56,8 +56,8 @@ public enum PermissionsSystemType { * * @return Display name. */ - public String getName() { - return this.name; + public String getDisplayName() { + return this.displayName; } /** @@ -76,7 +76,7 @@ public enum PermissionsSystemType { */ @Override public String toString() { - return getName(); + return getDisplayName(); } /** diff --git a/src/main/java/fr/xephi/authme/permission/handlers/BPermissionsHandler.java b/src/main/java/fr/xephi/authme/permission/handlers/BPermissionsHandler.java index 983e42e2..9f52214b 100644 --- a/src/main/java/fr/xephi/authme/permission/handlers/BPermissionsHandler.java +++ b/src/main/java/fr/xephi/authme/permission/handlers/BPermissionsHandler.java @@ -55,7 +55,7 @@ public class BPermissionsHandler implements PermissionHandler { List groups = getGroups(player); // Make sure there is any group available, or return null - if (groups.size() == 0) + if (groups.isEmpty()) return null; // Return the first group diff --git a/src/main/java/fr/xephi/authme/permission/handlers/PermissionsBukkitHandler.java b/src/main/java/fr/xephi/authme/permission/handlers/PermissionsBukkitHandler.java index 344e0aec..e8e8a21e 100644 --- a/src/main/java/fr/xephi/authme/permission/handlers/PermissionsBukkitHandler.java +++ b/src/main/java/fr/xephi/authme/permission/handlers/PermissionsBukkitHandler.java @@ -54,7 +54,7 @@ public class PermissionsBukkitHandler implements PermissionHandler { List groups = getGroups(player); // Make sure there is any group available, or return null - if (groups.size() == 0) + if (groups.isEmpty()) return null; // Return the first group diff --git a/src/main/java/fr/xephi/authme/permission/handlers/PermissionsExHandler.java b/src/main/java/fr/xephi/authme/permission/handlers/PermissionsExHandler.java index e3e03ee3..b11d0000 100644 --- a/src/main/java/fr/xephi/authme/permission/handlers/PermissionsExHandler.java +++ b/src/main/java/fr/xephi/authme/permission/handlers/PermissionsExHandler.java @@ -77,7 +77,7 @@ public class PermissionsExHandler implements PermissionHandler { PermissionUser user = permissionManager.getUser(player); List groups = user.getParentIdentifiers(null); - if (groups.size() == 0) + if (groups.isEmpty()) return null; return groups.get(0); 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 12471b0e..80d304dd 100644 --- a/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java +++ b/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java @@ -27,7 +27,8 @@ public class AsyncChangePassword implements AsynchronousProcess { @Inject private PlayerCache playerCache; - AsyncChangePassword() { } + AsyncChangePassword() { + } public void changePassword(final Player player, String oldPassword, String newPassword) { diff --git a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java index 2488be8a..12b6152b 100644 --- a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java @@ -14,6 +14,7 @@ import fr.xephi.authme.service.BungeeService; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.TeleportationService; +import fr.xephi.authme.util.StringUtils; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginManager; @@ -90,16 +91,13 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { teleportationService.teleportOnLogin(player, auth, limbo); // We can now display the join message (if delayed) - String jm = PlayerListener.joinMessage.get(name); - if (jm != null) { - if (!jm.isEmpty()) { - for (Player p : bukkitService.getOnlinePlayers()) { - if (p.isOnline()) { - p.sendMessage(jm); - } + String joinMessage = PlayerListener.joinMessage.remove(name); + if (!StringUtils.isEmpty(joinMessage)) { + for (Player p : bukkitService.getOnlinePlayers()) { + if (p.isOnline()) { + p.sendMessage(joinMessage); } } - PlayerListener.joinMessage.remove(name); } if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) { diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java index de77a17d..3347b382 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java @@ -21,8 +21,8 @@ public class ProcessSyncEmailRegister implements SynchronousProcess { @Inject private LimboPlayerTaskManager limboPlayerTaskManager; - ProcessSyncEmailRegister() { } - + ProcessSyncEmailRegister() { + } public void processEmailRegister(Player player) { final String name = player.getName().toLowerCase(); diff --git a/src/main/java/fr/xephi/authme/security/crypts/PLAINTEXT.java b/src/main/java/fr/xephi/authme/security/crypts/PLAINTEXT.java index dc2cb3b4..a294ca91 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/PLAINTEXT.java +++ b/src/main/java/fr/xephi/authme/security/crypts/PLAINTEXT.java @@ -1,5 +1,10 @@ package fr.xephi.authme.security.crypts; +/** + * Plaintext password storage. + * + * @deprecated Using this is no longer supported. AuthMe will migrate to SHA256 on startup. + */ @Deprecated public class PLAINTEXT extends UnsaltedMethod { diff --git a/src/main/java/fr/xephi/authme/security/crypts/XAUTH.java b/src/main/java/fr/xephi/authme/security/crypts/XAUTH.java index 18612874..f2ebf197 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/XAUTH.java +++ b/src/main/java/fr/xephi/authme/security/crypts/XAUTH.java @@ -18,14 +18,14 @@ public class XAUTH extends HexSaltedMethod { @Override public String computeHash(String password, String salt, String name) { String hash = getWhirlpool(salt + password).toLowerCase(); - int saltPos = (password.length() >= hash.length() ? hash.length() - 1 : password.length()); + int saltPos = password.length() >= hash.length() ? hash.length() - 1 : password.length(); return hash.substring(0, saltPos) + salt + hash.substring(saltPos); } @Override public boolean comparePassword(String password, HashedPassword hashedPassword, String playerName) { String hash = hashedPassword.getHash(); - int saltPos = (password.length() >= hash.length() ? hash.length() - 1 : password.length()); + int saltPos = password.length() >= hash.length() ? hash.length() - 1 : password.length(); if (saltPos + 12 > hash.length()) { return false; } diff --git a/src/main/java/fr/xephi/authme/service/BackupService.java b/src/main/java/fr/xephi/authme/service/BackupService.java index b5dfa06d..846e3441 100644 --- a/src/main/java/fr/xephi/authme/service/BackupService.java +++ b/src/main/java/fr/xephi/authme/service/BackupService.java @@ -104,36 +104,22 @@ public class BackupService { dirBackup.mkdir(); } String backupWindowsPath = settings.getProperty(BackupSettings.MYSQL_WINDOWS_PATH); - if (checkWindows(backupWindowsPath)) { - String executeCmd = backupWindowsPath + "\\bin\\mysqldump.exe -u " + dbUserName + " -p" + dbPassword + " " + dbName + " --tables " + tblname + " -r " + path + ".sql"; - Process runtimeProcess; - try { - runtimeProcess = Runtime.getRuntime().exec(executeCmd); - int processComplete = runtimeProcess.waitFor(); - if (processComplete == 0) { - ConsoleLogger.info("Backup created successfully."); - return true; - } else { - ConsoleLogger.warning("Could not create the backup! (Windows)"); - } - } catch (IOException | InterruptedException e) { - ConsoleLogger.logException("Error during Windows backup:", e); - } - } else { - String executeCmd = "mysqldump -u " + dbUserName + " -p" + dbPassword + " " + dbName + " --tables " + tblname + " -r " + path + ".sql"; - Process runtimeProcess; - try { - runtimeProcess = Runtime.getRuntime().exec(executeCmd); - int processComplete = runtimeProcess.waitFor(); - if (processComplete == 0) { - ConsoleLogger.info("Backup created successfully."); - return true; - } else { - ConsoleLogger.warning("Could not create the backup!"); - } - } catch (IOException | InterruptedException e) { - ConsoleLogger.logException("Error during backup:", e); + boolean isUsingWindows = checkWindows(backupWindowsPath); + String backupCommand = isUsingWindows + ? backupWindowsPath + "\\bin\\mysqldump.exe" + buildMysqlDumpArguments() + : "mysqldump" + buildMysqlDumpArguments(); + + try { + Process runtimeProcess = Runtime.getRuntime().exec(backupCommand); + int processComplete = runtimeProcess.waitFor(); + if (processComplete == 0) { + ConsoleLogger.info("Backup created successfully. (Using Windows = " + isUsingWindows + ")"); + return true; + } else { + ConsoleLogger.warning("Could not create the backup! (Using Windows = " + isUsingWindows + ")"); } + } catch (IOException | InterruptedException e) { + ConsoleLogger.logException("Error during backup (using Windows = " + isUsingWindows + "):", e); } return false; } @@ -173,6 +159,16 @@ public class BackupService { return false; } + /** + * Builds the command line arguments to pass along when running the {@code mysqldump} command. + * + * @return the mysqldump command line arguments + */ + private String buildMysqlDumpArguments() { + return " -u " + dbUserName + " -p" + dbPassword + " " + dbName + + " --tables " + tblname + " -r " + path + ".sql"; + } + private static void copy(String src, String dst) throws IOException { InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dst); diff --git a/src/main/java/fr/xephi/authme/service/ValidationService.java b/src/main/java/fr/xephi/authme/service/ValidationService.java index e3a69fc9..c6cdd99a 100644 --- a/src/main/java/fr/xephi/authme/service/ValidationService.java +++ b/src/main/java/fr/xephi/authme/service/ValidationService.java @@ -40,7 +40,8 @@ public class ValidationService implements Reloadable { private Pattern passwordRegex; private Set unrestrictedNames; - ValidationService() { } + ValidationService() { + } @PostConstruct @Override diff --git a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java index b3a06f5e..ac1742fa 100644 --- a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java +++ b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java @@ -48,10 +48,10 @@ public class SpawnLoader implements Reloadable { @Inject SpawnLoader(@DataFolder File pluginFolder, Settings settings, PluginHookService pluginHookService, DataSource dataSource) { - File spawnFile = new File(pluginFolder, "spawn.yml"); // TODO ljacqu 20160312: Check if resource could be copied and handle the case if not + File spawnFile = new File(pluginFolder, "spawn.yml"); FileUtils.copyFileFromResource(spawnFile, "spawn.yml"); - this.authMeConfigurationFile = new File(pluginFolder, "spawn.yml"); + this.authMeConfigurationFile = spawnFile; this.settings = settings; this.pluginHookService = pluginHookService; reload(); diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java index 5fef8a95..39419689 100644 --- a/src/main/java/fr/xephi/authme/util/Utils.java +++ b/src/main/java/fr/xephi/authme/util/Utils.java @@ -54,7 +54,7 @@ public final class Utils { * * @return the core count */ - public static int getCoreCount() { - return Runtime.getRuntime().availableProcessors(); - } + public static int getCoreCount() { + return Runtime.getRuntime().availableProcessors(); + } } diff --git a/src/test/java/fr/xephi/authme/permission/PermissionsSystemTypeTest.java b/src/test/java/fr/xephi/authme/permission/PermissionsSystemTypeTest.java index 809014ad..ec63c588 100644 --- a/src/test/java/fr/xephi/authme/permission/PermissionsSystemTypeTest.java +++ b/src/test/java/fr/xephi/authme/permission/PermissionsSystemTypeTest.java @@ -23,15 +23,15 @@ public class PermissionsSystemTypeTest { List pluginNames = new ArrayList<>(PermissionsSystemType.values().length); for (PermissionsSystemType system : PermissionsSystemType.values()) { - assertThat("Name for enum entry '" + system + "' is not null", - system.getName(), not(nullValue())); + assertThat("Display name for enum entry '" + system + "' is not null", + system.getDisplayName(), not(nullValue())); assertThat("Plugin name for enum entry '" + system + "' is not null", system.getPluginName(), not(nullValue())); - assertThat("Only one enum entry has name '" + system.getName() + "'", - names, not(hasItem(system.getName()))); + assertThat("Only one enum entry has display name '" + system.getDisplayName() + "'", + names, not(hasItem(system.getDisplayName()))); assertThat("Only one enum entry has plugin name '" + system.getPluginName() + "'", pluginNames, not(hasItem(system.getPluginName()))); - names.add(system.getName()); + names.add(system.getDisplayName()); pluginNames.add(system.getPluginName()); } } From 254655abdb4c0797afe41a3a79047704235acbee Mon Sep 17 00:00:00 2001 From: ljacqu Date: Tue, 22 Nov 2016 21:16:56 +0100 Subject: [PATCH 48/67] #411 Migrate settings to new structure (work in progress) - Work in progress: config.yml cannot be loaded after migration --- .../initialization/SettingsProvider.java | 3 +- .../process/login/ProcessSyncPlayerLogin.java | 16 +-- .../fr/xephi/authme/settings/Settings.java | 2 +- .../settings/SettingsMigrationService.java | 57 ++++++++++- .../settings/commandconfig/Command.java | 17 ++++ .../settings/commandconfig/CommandConfig.java | 8 +- .../commandconfig/CommandManager.java | 27 ++++- .../commandconfig/CommandsMigrater.java | 98 +++++++++++++++++++ .../properties/RegistrationSettings.java | 23 ----- 9 files changed, 206 insertions(+), 45 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java diff --git a/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java b/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java index 5d98cac3..f9c8638a 100644 --- a/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java +++ b/src/main/java/fr/xephi/authme/initialization/SettingsProvider.java @@ -20,6 +20,8 @@ public class SettingsProvider implements Provider { @Inject @DataFolder private File dataFolder; + @Inject + private SettingsMigrationService migrationService; SettingsProvider() { } @@ -36,7 +38,6 @@ public class SettingsProvider implements Provider { FileUtils.create(configFile); } PropertyResource resource = new YamlFileResource(configFile); - SettingsMigrationService migrationService = new SettingsMigrationService(dataFolder); ConfigurationData configurationData = AuthMeSettingsRetriever.buildConfigurationData(); return new Settings(dataFolder, resource, migrationService, configurationData); } diff --git a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java index 2488be8a..9c73725e 100644 --- a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java @@ -11,6 +11,7 @@ import fr.xephi.authme.listener.PlayerListener; import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.service.BungeeService; +import fr.xephi.authme.settings.commandconfig.CommandManager; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.TeleportationService; @@ -49,6 +50,9 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { @Inject private DataSource dataSource; + @Inject + private CommandManager commandManager; + ProcessSyncPlayerLogin() { } @@ -60,16 +64,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { } } - private void forceCommands(Player player) { - for (String command : service.getProperty(RegistrationSettings.FORCE_COMMANDS)) { - player.performCommand(command.replace("%p", player.getName())); - } - for (String command : service.getProperty(RegistrationSettings.FORCE_COMMANDS_AS_CONSOLE)) { - Bukkit.getServer().dispatchCommand( - Bukkit.getServer().getConsoleSender(), command.replace("%p", player.getName())); - } - } - public void processPlayerLogin(Player player) { final String name = player.getName().toLowerCase(); @@ -124,7 +118,7 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { } // Login is now finished; we can force all commands - forceCommands(player); + commandManager.runCommandsOnLogin(player); // Send Bungee stuff. The service will check if it is enabled or not. bungeeService.connectPlayer(player); diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index fb4c0624..5bf9d003 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -68,7 +68,7 @@ public class Settings extends SettingsManager { private void loadSettingsFromFiles() { passwordEmailMessage = readFile("email.html"); recoveryCodeEmailMessage = readFile("recovery_code_email.html"); - welcomeMessage = readFile("welcome.txt").split("\n"); + welcomeMessage = readFile("welcome.txt").split("\\n"); } @Override diff --git a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java index 954116a4..07d3531e 100644 --- a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java +++ b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java @@ -2,16 +2,20 @@ package fr.xephi.authme.settings; import com.github.authme.configme.migration.PlainMigrationService; import com.github.authme.configme.properties.Property; +import com.github.authme.configme.properties.StringListProperty; import com.github.authme.configme.resource.PropertyResource; import com.google.common.base.Objects; import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.output.LogLevel; import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.SecuritySettings; +import javax.inject.Inject; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.Collections; import java.util.List; import static com.github.authme.configme.properties.PropertyInitializer.newListProperty; @@ -28,10 +32,20 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAW */ public class SettingsMigrationService extends PlainMigrationService { - private final File pluginFolder; + @Inject + @DataFolder + private File pluginFolder; - public SettingsMigrationService(File pluginFolder) { - this.pluginFolder = pluginFolder; + // Stores old commands that need to be migrated to the new commands configuration + // We need to store it in here for retrieval when we build the CommandConfig. Retrieving it from the config.yml is + // not possible since this migration service may trigger config.yml to be resaved. As the old command settings + // don't exist in the code anymore, as soon as config.yml is resaved we lose this information. + private List onLoginCommands = Collections.emptyList(); + private List onLoginConsoleCommands = Collections.emptyList(); + private List onRegisterCommands = Collections.emptyList(); + private List onRegisterConsoleCommands = Collections.emptyList(); + + SettingsMigrationService() { } @Override @@ -42,6 +56,8 @@ public class SettingsMigrationService extends PlainMigrationService { changes = true; } + gatherOldCommandSettings(resource); + // Note ljacqu 20160211: Concatenating migration methods with | instead of the usual || // ensures that all migrations will be performed return changes @@ -59,7 +75,9 @@ public class SettingsMigrationService extends PlainMigrationService { "Converter.Rakamak.newPasswordHash", "Hooks.chestshop", "Hooks.legacyChestshop", "Hooks.notifications", "Passpartu", "Performances", "settings.restrictions.enablePasswordVerifier", "Xenoforo.predefinedSalt", "VeryGames", "settings.restrictions.allowAllCommandsIfRegistrationIsOptional", "DataSource.mySQLWebsite", - "Hooks.customAttributes", "Security.stop.kickPlayersBeforeStopping"}; + "Hooks.customAttributes", "Security.stop.kickPlayersBeforeStopping", + "settings.restrictions.keepCollisionsDisabled", "settings.forceCommands", "settings.forceCommandsAsConsole", + "settings.forceRegisterCommands", "settings.forceRegisterCommandsAsConsole"}; for (String deprecatedPath : deprecatedProperties) { if (resource.contains(deprecatedPath)) { return true; @@ -68,6 +86,37 @@ public class SettingsMigrationService extends PlainMigrationService { return false; } + // ---------------- + // Forced commands relocation (from config.yml to commands.yml) + // ---------------- + private void gatherOldCommandSettings(PropertyResource resource) { + onLoginCommands = getStringList(resource, "settings.forceCommands"); + onLoginConsoleCommands = getStringList(resource, "settings.forceCommandsAsConsole"); + onRegisterCommands = getStringList(resource, "settings.forceRegisterCommands"); + onRegisterConsoleCommands = getStringList(resource, "settings.forceRegisterCommandsAsConsole"); + } + + private List getStringList(PropertyResource resource, String path) { + List entries = new StringListProperty(path).getFromResource(resource); + return entries == null ? Collections.emptyList() : entries; + } + + public List getOnLoginCommands() { + return onLoginCommands; + } + + public List getOnLoginConsoleCommands() { + return onLoginConsoleCommands; + } + + public List getOnRegisterCommands() { + return onRegisterCommands; + } + + public List getOnRegisterConsoleCommands() { + return onRegisterConsoleCommands; + } + // -------- // Specific migrations // -------- diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java b/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java index 38bb5991..5cb50998 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java @@ -10,6 +10,23 @@ public class Command { /** The executor of the command. */ private Executor executor = Executor.PLAYER; + /** + * Default constructor (for bean mapping). + */ + public Command() { + } + + /** + * Constructor. + * + * @param command the command + * @param executor the executor of the command + */ + public Command(String command, Executor executor) { + this.command = command; + this.executor = executor; + } + public String getCommand() { return command; } diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java index 00d35e2d..53246cdb 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java @@ -1,6 +1,6 @@ package fr.xephi.authme.settings.commandconfig; -import java.util.Collections; +import java.util.HashMap; import java.util.Map; /** @@ -10,9 +10,9 @@ import java.util.Map; */ public class CommandConfig { - private Map onJoin = Collections.emptyMap(); - private Map onLogin = Collections.emptyMap(); - private Map onRegister = Collections.emptyMap(); + private Map onJoin = new HashMap<>(); + private Map onLogin = new HashMap<>(); + private Map onRegister = new HashMap<>(); public Map getOnJoin() { return onJoin; diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java index ebfcce2a..b37e01eb 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java @@ -2,9 +2,11 @@ package fr.xephi.authme.settings.commandconfig; import com.github.authme.configme.SettingsManager; import com.github.authme.configme.resource.YamlFileResource; +import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.FileUtils; import org.bukkit.entity.Player; @@ -27,6 +29,12 @@ public class CommandManager implements Reloadable { @Inject private BukkitService bukkitService; + @Inject + private CommandsMigrater commandsMigrater; + + @Inject + private Settings settings; + CommandManager() { } @@ -39,6 +47,10 @@ public class CommandManager implements Reloadable { executeCommands(player, commandConfig.getOnRegister()); } + public void runCommandsOnLogin(Player player) { + executeCommands(player, commandConfig.getOnLogin()); + } + private void executeCommands(Player player, Map commands) { for (Command command : commands.values()) { final String execution = command.getCommand().replace("%p", player.getName()); @@ -58,7 +70,20 @@ public class CommandManager implements Reloadable { SettingsManager settingsManager = new SettingsManager( new YamlFileResource(file), null, CommandSettingsHolder.class); - commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); + CommandConfig commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); + + if (commandsMigrater.transformOldCommands(commandConfig)) { + ConsoleLogger.warning("Old setting properties (such as settings.forceCommands) were found. " + + "They have been moved to commands.yml"); + settingsManager.setProperty(CommandSettingsHolder.COMMANDS, commandConfig); + settingsManager.save(); + settingsManager.reload(); + settings.save(); + settings.reload(); + + commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); + } + this.commandConfig = commandConfig; } diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java new file mode 100644 index 00000000..5defb4c0 --- /dev/null +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java @@ -0,0 +1,98 @@ +package fr.xephi.authme.settings.commandconfig; + +import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.settings.SettingsMigrationService; +import fr.xephi.authme.util.RandomStringUtils; + +import javax.inject.Inject; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Migrates the commands from their old location, in config.yml, to the dedicated commands configuration file. + */ +class CommandsMigrater { + + @Inject + private SettingsMigrationService settingsMigrationService; + + CommandsMigrater() { + } + + boolean transformOldCommands(CommandConfig commandConfig) { + boolean didMoveCommands = false; + for (MigratableCommandSection section : MigratableCommandSection.values()) { + didMoveCommands |= section.convertCommands(settingsMigrationService, commandConfig); + } + return didMoveCommands; + } + + /** + * Enum defining the forced command settings that should be moved from config.yml to the new commands.yml file. + */ + private enum MigratableCommandSection { + + ON_JOIN( + SettingsMigrationService::getOnLoginCommands, + Executor.PLAYER, + CommandConfig::getOnJoin), + + ON_JOIN_CONSOLE( + SettingsMigrationService::getOnLoginConsoleCommands, + Executor.CONSOLE, + CommandConfig::getOnJoin), + + ON_REGISTER( + SettingsMigrationService::getOnRegisterCommands, + Executor.PLAYER, + CommandConfig::getOnRegister), + + ON_REGISTER_CONSOLE( + SettingsMigrationService::getOnRegisterConsoleCommands, + Executor.CONSOLE, + CommandConfig::getOnRegister); + + private final Function> legacyCommandsGetter; + private final Executor executor; + private final Function> commandMapGetter; + + /** + * Constructor. + * + * @param legacyCommandsGetter getter on MigrationService to get the deprecated command entries + * @param executor the executor of the commands + * @param commandMapGetter the getter for the commands map in the new settings structure to add the old + * settings to after conversion + */ + MigratableCommandSection(Function> legacyCommandsGetter, + Executor executor, + Function> commandMapGetter) { + this.legacyCommandsGetter = legacyCommandsGetter; + this.executor = executor; + this.commandMapGetter = commandMapGetter; + } + + /** + * Adds the commands from the sections' settings migration service to the appropriate place in the new + * command config object. + * + * @param settingsMigrationService settings migration service to read old commands from + * @param commandConfig command config object to add converted commands to + * @return true if there were commands to migrate, false otherwise + */ + boolean convertCommands(SettingsMigrationService settingsMigrationService, CommandConfig commandConfig) { + List commands = legacyCommandsGetter.apply(settingsMigrationService).stream() + .map(cmd -> new Command(cmd, executor)).collect(Collectors.toList()); + + if (commands.isEmpty()) { + return false; + } + Map commandMap = commandMapGetter.apply(commandConfig); + commands.forEach(cmd -> commandMap.put(RandomStringUtils.generate(10), cmd)); + ConsoleLogger.info("Migrated " + commands.size() + " of type " + this); + return true; + } + } +} diff --git a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java index bf250e1f..a3de56b8 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/RegistrationSettings.java @@ -4,9 +4,6 @@ import com.github.authme.configme.Comment; import com.github.authme.configme.SettingsHolder; import com.github.authme.configme.properties.Property; -import java.util.List; - -import static com.github.authme.configme.properties.PropertyInitializer.newListProperty; import static com.github.authme.configme.properties.PropertyInitializer.newProperty; public class RegistrationSettings implements SettingsHolder { @@ -48,26 +45,6 @@ public class RegistrationSettings implements SettingsHolder { public static final Property FORCE_LOGIN_AFTER_REGISTER = newProperty("settings.registration.forceLoginAfterRegister", false); - @Comment("Force these commands after /login, without any '/', use %p to replace with player name") - public static final Property> FORCE_COMMANDS = - newListProperty("settings.forceCommands"); - - @Comment({ - "Force these commands after /login as service console, without any '/'.", - "Use %p to replace with player name"}) - public static final Property> FORCE_COMMANDS_AS_CONSOLE = - newListProperty("settings.forceCommandsAsConsole"); - - @Comment("Force these commands after /register, without any '/', use %p to replace with player name") - public static final Property> FORCE_REGISTER_COMMANDS = - newListProperty("settings.forceRegisterCommands"); - - @Comment({ - "Force these commands after /register as a server console, without any '/'.", - "Use %p to replace with player name"}) - public static final Property> FORCE_REGISTER_COMMANDS_AS_CONSOLE = - newListProperty("settings.forceRegisterCommandsAsConsole"); - @Comment({ "Enable to display the welcome message (welcome.txt) after a login", "You can use colors in this welcome.txt + some replaced strings:", From d2a28bdaedc0183e9799358edf5e81bc62b4079c Mon Sep 17 00:00:00 2001 From: ljacqu Date: Tue, 22 Nov 2016 22:02:34 +0100 Subject: [PATCH 49/67] #850 Fix export of legacy hashes property - Ugly workaround due to #1014: need to have EnumSetProperty extend from StringListProperty type so that it is exported in a proper manner (as a string list). To get an enum Set we need to call a dedicated method on EnumSetProperty for the time being. --- .../authme/security/PasswordSecurity.java | 4 +- .../authme/settings/EnumSetProperty.java | 37 ++++++++++--------- .../settings/properties/SecuritySettings.java | 5 +-- .../authme/security/PasswordSecurityTest.java | 9 +++-- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java index 8549b388..24607058 100644 --- a/src/main/java/fr/xephi/authme/security/PasswordSecurity.java +++ b/src/main/java/fr/xephi/authme/security/PasswordSecurity.java @@ -6,6 +6,7 @@ import fr.xephi.authme.events.PasswordEncryptionEvent; import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.security.crypts.EncryptionMethod; import fr.xephi.authme.security.crypts.HashedPassword; +import fr.xephi.authme.settings.EnumSetProperty; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.SecuritySettings; import org.bukkit.plugin.PluginManager; @@ -41,7 +42,8 @@ public class PasswordSecurity implements Reloadable { @Override public void reload() { this.algorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH); - this.legacyAlgorithms = settings.getProperty(SecuritySettings.LEGACY_HASHES); + // TODO #1014: Need to cast to specific type because ConfigMe ignores fields of child Property types + this.legacyAlgorithms = ((EnumSetProperty) SecuritySettings.LEGACY_HASHES).asEnumSet(settings); } /** diff --git a/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java b/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java index 4ca284d7..8b1fa789 100644 --- a/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java +++ b/src/main/java/fr/xephi/authme/settings/EnumSetProperty.java @@ -1,35 +1,38 @@ package fr.xephi.authme.settings; -import com.github.authme.configme.properties.Property; -import com.github.authme.configme.resource.PropertyResource; +import com.github.authme.configme.SettingsManager; +import com.github.authme.configme.properties.StringListProperty; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; /** * Property whose value is a set of entries of a given enum. */ -// TODO https://github.com/AuthMe/ConfigMe/issues/27: Should be a Property of Set type -public class EnumSetProperty> extends Property> { +// TODO #1014: This property type currently extends StringListProperty with a dedicated method to convert the values +// into a Set of the selected enum due to multiple issues on ConfigMe's side. +public class EnumSetProperty> extends StringListProperty { private final Class enumClass; - public EnumSetProperty(Class enumClass, String path, List defaultValue) { - super(path, defaultValue); + public EnumSetProperty(Class enumClass, String path, String... values) { + super(path, values); this.enumClass = enumClass; } - @Override - protected List getFromResource(PropertyResource resource) { - List elements = resource.getList(getPath()); - if (elements != null) { - return elements.stream() - .map(val -> toEnum(String.valueOf(val))) - .filter(e -> e != null) - .distinct() - .collect(Collectors.toList()); - } - return null; + /** + * Returns the value as a set of enum entries. + * + * @param settings the settings manager to look up the raw value with + * @return the property's value as mapped enum entries + */ + public Set asEnumSet(SettingsManager settings) { + List entries = settings.getProperty(this); + return entries.stream() + .map(str -> toEnum(str)) + .filter(e -> e != null) + .collect(Collectors.toSet()); } private E toEnum(String str) { diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java index e8035491..3711715d 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java @@ -6,7 +6,6 @@ import com.github.authme.configme.properties.Property; import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.settings.EnumSetProperty; -import java.util.Collections; import java.util.List; import static com.github.authme.configme.properties.PropertyInitializer.newLowercaseListProperty; @@ -83,8 +82,8 @@ public class SecuritySettings implements SettingsHolder { "legacyHashes:", "- 'SHA1'" }) - public static final Property> LEGACY_HASHES = - new EnumSetProperty<>(HashAlgorithm.class, "settings.security.legacyHashes", Collections.emptyList()); + public static final Property> LEGACY_HASHES = + new EnumSetProperty<>(HashAlgorithm.class, "settings.security.legacyHashes"); @Comment({"Prevent unsafe passwords from being used; put them in lowercase!", "You should always set 'help' as unsafePassword due to possible conflicts.", diff --git a/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java b/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java index ec206c86..e1c30f43 100644 --- a/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java +++ b/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java @@ -26,8 +26,10 @@ import org.mockito.stubbing.Answer; import java.util.Collections; import java.util.List; +import java.util.Set; import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Sets.newHashSet; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.junit.Assert.assertThat; @@ -173,7 +175,7 @@ public class PasswordSecurityTest { given(method.comparePassword(clearTextPass, password, playerLowerCase)).willReturn(false); given(method.computeHash(clearTextPass, playerLowerCase)).willReturn(newPassword); initSettings(HashAlgorithm.MD5); - given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(newArrayList(HashAlgorithm.BCRYPT)); + given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(newArrayList(HashAlgorithm.BCRYPT.name())); PasswordSecurity security = newPasswordSecurity(); // when @@ -258,7 +260,7 @@ public class PasswordSecurityTest { initSettings(HashAlgorithm.BCRYPT); PasswordSecurity passwordSecurity = newPasswordSecurity(); given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.MD5); - List legacyHashes = newArrayList(HashAlgorithm.CUSTOM, HashAlgorithm.BCRYPT); + List legacyHashes = newArrayList(HashAlgorithm.CUSTOM.name(), HashAlgorithm.BCRYPT.name()); given(settings.getProperty(SecuritySettings.LEGACY_HASHES)).willReturn(legacyHashes); // when @@ -267,8 +269,9 @@ public class PasswordSecurityTest { // then assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "algorithm"), equalTo(HashAlgorithm.MD5)); + Set legacyHashesSet = newHashSet(HashAlgorithm.CUSTOM, HashAlgorithm.BCRYPT); assertThat(ReflectionTestUtils.getFieldValue(PasswordSecurity.class, passwordSecurity, "legacyAlgorithms"), - equalTo(legacyHashes)); + equalTo(legacyHashesSet)); } private PasswordSecurity newPasswordSecurity() { From e883944da261bac5590784757ce56e17196a2369 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Wed, 23 Nov 2016 00:01:35 +0100 Subject: [PATCH 50/67] #411 Create tests for command migration and manager, minor tweaks --- .../settings/commandconfig/Command.java | 5 + .../settings/commandconfig/CommandConfig.java | 8 +- .../commandconfig/CommandManager.java | 28 ++--- .../commandconfig/CommandsMigrater.java | 12 +- .../CommandConfigTestHelper.java | 35 ++++++ .../commandconfig/CommandManagerTest.java | 115 ++++++++++++++++++ .../commandconfig/CommandsMigraterTest.java | 111 +++++++++++++++++ .../commandconfig/commands.complete.yml | 23 ++++ .../commandconfig/commands.incomplete.yml | 20 +++ 9 files changed, 334 insertions(+), 23 deletions(-) create mode 100644 src/test/java/fr/xephi/authme/settings/commandconfig/CommandConfigTestHelper.java create mode 100644 src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java create mode 100644 src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java create mode 100644 src/test/resources/fr/xephi/authme/settings/commandconfig/commands.complete.yml create mode 100644 src/test/resources/fr/xephi/authme/settings/commandconfig/commands.incomplete.yml diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java b/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java index 5cb50998..3828dc0e 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/Command.java @@ -42,4 +42,9 @@ public class Command { public void setExecutor(Executor executor) { this.executor = executor; } + + @Override + public String toString() { + return command + " (" + executor + ")"; + } } diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java index 53246cdb..19c05505 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandConfig.java @@ -1,6 +1,6 @@ package fr.xephi.authme.settings.commandconfig; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; /** @@ -10,9 +10,9 @@ import java.util.Map; */ public class CommandConfig { - private Map onJoin = new HashMap<>(); - private Map onLogin = new HashMap<>(); - private Map onRegister = new HashMap<>(); + private Map onJoin = new LinkedHashMap<>(); + private Map onLogin = new LinkedHashMap<>(); + private Map onRegister = new LinkedHashMap<>(); public Map getOnJoin() { return onJoin; diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java index b37e01eb..015df7f6 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java @@ -10,7 +10,6 @@ import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.FileUtils; import org.bukkit.entity.Player; -import javax.annotation.PostConstruct; import javax.inject.Inject; import java.io.File; import java.util.Map; @@ -20,23 +19,21 @@ import java.util.Map; */ public class CommandManager implements Reloadable { + private final File dataFolder; + private final BukkitService bukkitService; + private final CommandsMigrater commandsMigrater; + private final Settings settings; + private CommandConfig commandConfig; @Inject - @DataFolder - private File dataFolder; - - @Inject - private BukkitService bukkitService; - - @Inject - private CommandsMigrater commandsMigrater; - - @Inject - private Settings settings; - - - CommandManager() { + CommandManager(@DataFolder File dataFolder, BukkitService bukkitService, + CommandsMigrater commandsMigrater, Settings settings) { + this.dataFolder = dataFolder; + this.bukkitService = bukkitService; + this.commandsMigrater = commandsMigrater; + this.settings = settings; + reload(); } public void runCommandsOnJoin(Player player) { @@ -62,7 +59,6 @@ public class CommandManager implements Reloadable { } } - @PostConstruct @Override public void reload() { File file = new File(dataFolder, "commands.yml"); diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java index 5defb4c0..8a2df167 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java @@ -21,6 +21,12 @@ class CommandsMigrater { CommandsMigrater() { } + /** + * Adds command settings from their old location (in config.yml) to the given command configuration object. + * + * @param commandConfig the command config object to move old commands to + * @return true if commands have been moved, false if no migration was necessary + */ boolean transformOldCommands(CommandConfig commandConfig) { boolean didMoveCommands = false; for (MigratableCommandSection section : MigratableCommandSection.values()) { @@ -37,12 +43,12 @@ class CommandsMigrater { ON_JOIN( SettingsMigrationService::getOnLoginCommands, Executor.PLAYER, - CommandConfig::getOnJoin), + CommandConfig::getOnLogin), ON_JOIN_CONSOLE( SettingsMigrationService::getOnLoginConsoleCommands, Executor.CONSOLE, - CommandConfig::getOnJoin), + CommandConfig::getOnLogin), ON_REGISTER( SettingsMigrationService::getOnRegisterCommands, @@ -91,7 +97,7 @@ class CommandsMigrater { } Map commandMap = commandMapGetter.apply(commandConfig); commands.forEach(cmd -> commandMap.put(RandomStringUtils.generate(10), cmd)); - ConsoleLogger.info("Migrated " + commands.size() + " of type " + this); + ConsoleLogger.info("Migrated " + commands.size() + " commands of type " + this); return true; } } diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandConfigTestHelper.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandConfigTestHelper.java new file mode 100644 index 00000000..f9fb4e5f --- /dev/null +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandConfigTestHelper.java @@ -0,0 +1,35 @@ +package fr.xephi.authme.settings.commandconfig; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +/** + * Helper class for tests around the command configuration. + */ +final class CommandConfigTestHelper { + + private CommandConfigTestHelper() { + } + + /** + * Returns a matcher for verifying a {@link Command} object. + * + * @param cmd the expected command line + * @param executor the expected executor + * @return the matcher + */ + public static Matcher isCommand(String cmd, Executor executor) { + return new TypeSafeMatcher() { + @Override + protected boolean matchesSafely(Command item) { + return executor.equals(item.getExecutor()) && cmd.equals(item.getCommand()); + } + + @Override + public void describeTo(Description description) { + description.appendText("Command '" + cmd + "' run by '" + executor + "'"); + } + }; + } +} diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java new file mode 100644 index 00000000..eea0f569 --- /dev/null +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java @@ -0,0 +1,115 @@ +package fr.xephi.authme.settings.commandconfig; + +import com.google.common.io.Files; +import fr.xephi.authme.ReflectionTestUtils; +import fr.xephi.authme.TestHelper; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.settings.Settings; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.File; +import java.io.IOException; + +import static fr.xephi.authme.settings.commandconfig.CommandConfigTestHelper.isCommand; +import static org.hamcrest.Matchers.anEmptyMap; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +/** + * Test for {@link CommandManager}. + */ +@RunWith(MockitoJUnitRunner.class) +public class CommandManagerTest { + + private static final String TEST_FILES_FOLDER = "/fr/xephi/authme/settings/commandconfig/"; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + private CommandManager manager; + @Mock + private BukkitService bukkitService; + @Mock + private Settings settings; + @Mock + private CommandsMigrater commandsMigrater; + private File testFolder; + + @Before + public void setup() throws IOException { + testFolder = temporaryFolder.newFolder(); + } + + @Test + @SuppressWarnings("unchecked") + public void shouldLoadCompleteFile() { + // given + copyJarFileAsCommandsYml(TEST_FILES_FOLDER + "commands.complete.yml"); + + // when + initManager(); + + // then + CommandConfig commandConfig = ReflectionTestUtils.getFieldValue(CommandManager.class, manager, "commandConfig"); + assertThat(commandConfig.getOnJoin().keySet(), contains("broadcast")); + assertThat(commandConfig.getOnJoin().values(), contains(isCommand("broadcast %p has joined", Executor.CONSOLE))); + assertThat(commandConfig.getOnRegister().keySet(), contains("announce", "notify")); + assertThat(commandConfig.getOnRegister().values(), contains( + isCommand("me I just registered", Executor.PLAYER), + isCommand("log %p registered", Executor.CONSOLE))); + assertThat(commandConfig.getOnLogin().keySet(), contains("welcome", "show_motd", "display_list")); + assertThat(commandConfig.getOnLogin().values(), contains( + isCommand("msg %p Welcome back", Executor.CONSOLE), + isCommand("motd", Executor.PLAYER), + isCommand("list", Executor.PLAYER))); + } + + @Test + @Ignore // TODO #411: Implement tested behavior + public void shouldLoadIncompleteFile() { + // given + File configFile = copyJarFileAsCommandsYml(TEST_FILES_FOLDER + "commands.incomplete.yml"); + + // when + initManager(); + + // then + CommandConfig commandConfig = ReflectionTestUtils.getFieldValue(CommandManager.class, manager, "commandConfig"); + assertThat(commandConfig.getOnJoin().values(), contains(isCommand("broadcast %p has joined", Executor.CONSOLE))); + assertThat(commandConfig.getOnLogin().values(), contains( + isCommand("msg %p Welcome back", Executor.CONSOLE), + isCommand("list", Executor.PLAYER))); + assertThat(commandConfig.getOnRegister(), anEmptyMap()); + + // verify that we have rewritten the file with the proper sections + FileConfiguration configuration = YamlConfiguration.loadConfiguration(configFile); + assertThat(configuration.contains("onRegister"), equalTo(true)); + assertThat(configuration.contains("doesNotExist"), equalTo(false)); + } + + private void initManager() { + manager = new CommandManager(testFolder, bukkitService, commandsMigrater, settings); + } + + private File copyJarFileAsCommandsYml(String path) { + File source = TestHelper.getJarFile(path); + File destination = new File(testFolder, "commands.yml"); + try { + Files.copy(source, destination); + return destination; + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + +} diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java new file mode 100644 index 00000000..ee146884 --- /dev/null +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java @@ -0,0 +1,111 @@ +package fr.xephi.authme.settings.commandconfig; + +import fr.xephi.authme.TestHelper; +import fr.xephi.authme.settings.SettingsMigrationService; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static fr.xephi.authme.settings.commandconfig.CommandConfigTestHelper.isCommand; +import static java.util.Collections.emptyList; +import static org.hamcrest.Matchers.anEmptyMap; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.sameInstance; +import static org.junit.Assert.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Test for {@link CommandsMigrater}. + */ +@RunWith(MockitoJUnitRunner.class) +public class CommandsMigraterTest { + + @InjectMocks + private CommandsMigrater commandsMigrater; + + @Mock + private SettingsMigrationService settingsMigrationService; + + private CommandConfig commandConfig = new CommandConfig(); + + @BeforeClass + public static void setUpLogger() { + TestHelper.setupLogger(); + } + + @Test + public void shouldNotPerformAnyMigration() { + // given + given(settingsMigrationService.getOnLoginCommands()).willReturn(emptyList()); + given(settingsMigrationService.getOnLoginConsoleCommands()).willReturn(emptyList()); + given(settingsMigrationService.getOnRegisterCommands()).willReturn(emptyList()); + given(settingsMigrationService.getOnRegisterConsoleCommands()).willReturn(emptyList()); + commandConfig.getOnRegister().put("existing", new Command("existing cmd", Executor.PLAYER)); + CommandConfig configSpy = spy(commandConfig); + + // when + boolean result = commandsMigrater.transformOldCommands(configSpy); + + // then + assertThat(result, equalTo(false)); + verifyZeroInteractions(configSpy); + assertThat(configSpy.getOnRegister().keySet(), contains("existing")); + assertThat(configSpy.getOnLogin(), anEmptyMap()); + } + + @Test + @SuppressWarnings("unchecked") + public void shouldPerformMigration() { + // given + List onLogin = Collections.singletonList("on login command"); + given(settingsMigrationService.getOnLoginCommands()).willReturn(onLogin); + List onLoginConsole = Arrays.asList("cmd1", "cmd2 %p", "cmd3"); + given(settingsMigrationService.getOnLoginConsoleCommands()).willReturn(onLoginConsole); + given(settingsMigrationService.getOnRegisterCommands()).willReturn(emptyList()); + List onRegisterConsole = Arrays.asList("log %p registered", "whois %p"); + given(settingsMigrationService.getOnRegisterConsoleCommands()).willReturn(onRegisterConsole); + + Map onLoginCommands = new LinkedHashMap<>(); + onLoginCommands.put("bcast", new Command("bcast %p returned", Executor.CONSOLE)); + commandConfig.setOnLogin(onLoginCommands); + Map onRegisterCommands = new LinkedHashMap<>(); + onRegisterCommands.put("ex_cmd", new Command("existing", Executor.CONSOLE)); + onRegisterCommands.put("ex_cmd2", new Command("existing2", Executor.PLAYER)); + commandConfig.setOnRegister(onRegisterCommands); + + // when + boolean result = commandsMigrater.transformOldCommands(commandConfig); + + // then + assertThat(result, equalTo(true)); + assertThat(commandConfig.getOnLogin(), sameInstance(onLoginCommands)); + Collection loginCmdList = onLoginCommands.values(); + assertThat(loginCmdList, contains( + equalTo(onLoginCommands.get("bcast")), + isCommand("on login command", Executor.PLAYER), + isCommand("cmd1", Executor.CONSOLE), + isCommand("cmd2 %p", Executor.CONSOLE), + isCommand("cmd3", Executor.CONSOLE))); + + assertThat(commandConfig.getOnRegister(), sameInstance(onRegisterCommands)); + Collection registerCmdList = onRegisterCommands.values(); + assertThat(registerCmdList, contains( + isCommand("existing", Executor.CONSOLE), + isCommand("existing2", Executor.PLAYER), + isCommand("log %p registered", Executor.CONSOLE), + isCommand("whois %p", Executor.CONSOLE))); + } +} diff --git a/src/test/resources/fr/xephi/authme/settings/commandconfig/commands.complete.yml b/src/test/resources/fr/xephi/authme/settings/commandconfig/commands.complete.yml new file mode 100644 index 00000000..8c6bf79d --- /dev/null +++ b/src/test/resources/fr/xephi/authme/settings/commandconfig/commands.complete.yml @@ -0,0 +1,23 @@ +# Sample commands.yml file + +onJoin: + broadcast: + command: 'broadcast %p has joined' + executor: CONSOLE +onRegister: + announce: + command: 'me I just registered' + executor: PLAYER + notify: + command: 'log %p registered' + executor: CONSOLE +onLogin: + welcome: + command: 'msg %p Welcome back' + executor: CONSOLE + show_motd: + command: 'motd' + executor: PLAYER + display_list: + command: 'list' + executor: PLAYER diff --git a/src/test/resources/fr/xephi/authme/settings/commandconfig/commands.incomplete.yml b/src/test/resources/fr/xephi/authme/settings/commandconfig/commands.incomplete.yml new file mode 100644 index 00000000..2eef86b0 --- /dev/null +++ b/src/test/resources/fr/xephi/authme/settings/commandconfig/commands.incomplete.yml @@ -0,0 +1,20 @@ +# Sample commands.yml file with wrong and missing sections + +onJoin: + broadcast: + command: 'broadcast %p has joined' + executor: CONSOLE +onLogin: + welcome: + command: 'msg %p Welcome back' + executor: CONSOLE + show_motd: + # command: 'motd' <-- mandatory property, so entry should be ignored + executor: PLAYER + display_list: + command: 'list' + executor: WRONG_EXECUTOR +doesNotExist: + wrongEntry: + command: 'should be ignored' + executor: PLAYER From 57e7c71d72077f1b2e0903b16c802c9fd4d14c41 Mon Sep 17 00:00:00 2001 From: RatchetCinemaESP Date: Thu, 24 Nov 2016 11:18:14 +0100 Subject: [PATCH 51/67] Mini update messages_es.yml (#185) Fix mini error in: 74# incomplete_email_settings --- src/main/resources/messages/messages_es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/messages/messages_es.yml b/src/main/resources/messages/messages_es.yml index bc5bcb0f..d72c7d44 100644 --- a/src/main/resources/messages/messages_es.yml +++ b/src/main/resources/messages/messages_es.yml @@ -71,7 +71,7 @@ kick_antibot: '¡El modo de protección AntiBot está habilitado! Tienes que esp email_exists: '&c¡El correo de recuperación ya ha sido enviado! Puedes descartarlo y enviar uno nuevo utilizando el siguiente comando:' password_error_nick: '&cNo puedes utilizar tu nombre como contraseña, por favor elige otra...' accounts_owned_other: 'El jugador %name tiene %count cuentas:' -incomplete_email_settings: 'Error: no todos los ajustes necesario se han configurado para enviar correos. Por favor, contacta con un administrador.' +incomplete_email_settings: 'Error: no todos los ajustes necesarios se han configurado para enviar correos. Por favor, contacta con un administrador.' recovery_code_sent: 'El código de recuperación para recuperar tu contraseña se ha enviado a tu correo.' invalid_name_case: 'Solo puedes unirte mediante el nombre de usuario %valid, no %invalid.' email_show: '&2Tu dirección de E-Mail actual es: &f%email' From e83935c11e161e1a5e1b39d9a781112df161f672 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 24 Nov 2016 12:02:22 +0100 Subject: [PATCH 52/67] #1003 Create test for settings migration service --- .../settings/SettingsMigrationService.java | 10 +- .../SettingsMigrationServiceTest.java | 88 ++++ .../fr/xephi/authme/settings/config-old.yml | 414 ++++++++++++++++++ 3 files changed, 507 insertions(+), 5 deletions(-) create mode 100644 src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java create mode 100644 src/test/resources/fr/xephi/authme/settings/config-old.yml diff --git a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java index 07d3531e..52932770 100644 --- a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java +++ b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java @@ -32,9 +32,7 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAW */ public class SettingsMigrationService extends PlainMigrationService { - @Inject - @DataFolder - private File pluginFolder; + private final File pluginFolder; // Stores old commands that need to be migrated to the new commands configuration // We need to store it in here for retrieval when we build the CommandConfig. Retrieving it from the config.yml is @@ -45,7 +43,9 @@ public class SettingsMigrationService extends PlainMigrationService { private List onRegisterCommands = Collections.emptyList(); private List onRegisterConsoleCommands = Collections.emptyList(); - SettingsMigrationService() { + @Inject + SettingsMigrationService(@DataFolder File pluginFolder) { + this.pluginFolder = pluginFolder; } @Override @@ -169,7 +169,7 @@ public class SettingsMigrationService extends PlainMigrationService { } /** - * Detect old "force spawn loc on join" and "force spawn on these worlds" settings and moves them + * Detects old "force spawn loc on join" and "force spawn on these worlds" settings and moves them * to the new paths. * * @param resource The property resource diff --git a/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java b/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java new file mode 100644 index 00000000..af109fbe --- /dev/null +++ b/src/test/java/fr/xephi/authme/settings/SettingsMigrationServiceTest.java @@ -0,0 +1,88 @@ +package fr.xephi.authme.settings; + +import com.github.authme.configme.resource.PropertyResource; +import com.github.authme.configme.resource.YamlFileResource; +import com.google.common.io.Files; +import fr.xephi.authme.TestHelper; +import fr.xephi.authme.output.LogLevel; +import fr.xephi.authme.settings.properties.AuthMeSettingsRetriever; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static fr.xephi.authme.TestHelper.getJarFile; +import static fr.xephi.authme.settings.properties.PluginSettings.LOG_LEVEL; +import static fr.xephi.authme.settings.properties.RegistrationSettings.DELAY_JOIN_MESSAGE; +import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS; +import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAWN_LOCATION_AFTER_LOGIN; +import static fr.xephi.authme.settings.properties.RestrictionSettings.FORCE_SPAWN_ON_WORLDS; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; + +/** + * Test for {@link SettingsMigrationService}. + */ +public class SettingsMigrationServiceTest { + + private static final String OLD_CONFIG_FILE = TestHelper.PROJECT_ROOT + "settings/config-old.yml"; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @BeforeClass + public static void setUpLogger() { + TestHelper.setupLogger(); + } + + @Test + public void shouldPerformMigrations() throws IOException { + // given + File dataFolder = temporaryFolder.newFolder(); + File configFile = new File(dataFolder, "config.yml"); + Files.copy(getJarFile(OLD_CONFIG_FILE), configFile); + PropertyResource resource = new YamlFileResource(configFile); + SettingsMigrationService migrationService = new SettingsMigrationService(dataFolder); + + // when + Settings settings = new Settings( + dataFolder, resource, migrationService, AuthMeSettingsRetriever.buildConfigurationData()); + + // then + assertThat(settings.getProperty(ALLOWED_NICKNAME_CHARACTERS), equalTo(ALLOWED_NICKNAME_CHARACTERS.getDefaultValue())); + assertThat(settings.getProperty(DELAY_JOIN_MESSAGE), equalTo(true)); + assertThat(settings.getProperty(FORCE_SPAWN_LOCATION_AFTER_LOGIN), equalTo(true)); + assertThat(settings.getProperty(FORCE_SPAWN_ON_WORLDS), contains("survival", "survival_nether", "creative")); + assertThat(settings.getProperty(LOG_LEVEL), equalTo(LogLevel.INFO)); + + // Check migration of old setting to email.html + assertThat(Files.readLines(new File(dataFolder, "email.html"), StandardCharsets.UTF_8), + contains("Dear ,

    This is your new AuthMe password for the server " + + "

    :



    Do not forget to " + + "change password after login!
    /changepassword newPassword")); + } + + @Test + public void shouldKeepOldForceCommandSettings() throws IOException { + // given + File dataFolder = temporaryFolder.newFolder(); + File configFile = new File(dataFolder, "config.yml"); + Files.copy(getJarFile(OLD_CONFIG_FILE), configFile); + PropertyResource resource = new YamlFileResource(configFile); + SettingsMigrationService migrationService = new SettingsMigrationService(dataFolder); + + // when + migrationService.performMigrations(resource, AuthMeSettingsRetriever.buildConfigurationData().getProperties()); + + // then + assertThat(migrationService.getOnLoginCommands(), contains("spawn")); + assertThat(migrationService.getOnLoginConsoleCommands(), contains("sethome %p:lastloc", "msg %p Welcome back")); + assertThat(migrationService.getOnRegisterCommands(), contains("me registers", "msg CONSOLE hi")); + assertThat(migrationService.getOnRegisterConsoleCommands(), contains("sethome %p:regloc")); + } +} diff --git a/src/test/resources/fr/xephi/authme/settings/config-old.yml b/src/test/resources/fr/xephi/authme/settings/config-old.yml new file mode 100644 index 00000000..ff2b2918 --- /dev/null +++ b/src/test/resources/fr/xephi/authme/settings/config-old.yml @@ -0,0 +1,414 @@ +# Old default config file, based on commit 1f001f2 (2015-12-06) + +DataSource: + # What type of database do you want to use? + # Valid values: sqlite, mysql + backend: sqlite + # Enable database caching, should improve database performance + caching: true + # Database location + mySQLHost: 127.0.0.1 + # Database Port + mySQLPort: '3306' + # Username about Database Connection Infos + mySQLUsername: authme + # Password about Database Connection Infos + mySQLPassword: '12345' + # Database Name, use with converters or as SQLITE database name + mySQLDatabase: authme + # Table of the database + mySQLTablename: authme + # Column of IDs to sort data + mySQLColumnId: id + # Column for storing or checking players nickname + mySQLColumnName: username + # Column for storing players passwords + mySQLColumnPassword: password + # Column for storing players emails + mySQLColumnEmail: email + # Column for Saving if a player is logged in or not + mySQLColumnLogged: isLogged + # Column for storing players IPs + mySQLColumnIp: ip + # Column for storing players lastlogins + mySQLColumnLastLogin: lastlogin + # Column for SaveQuitLocation - X + mySQLlastlocX: x + # Column for SaveQuitLocation - Y + mySQLlastlocY: y + # Column for SaveQuitLocation - Z + mySQLlastlocZ: z + # Column for SaveQuitLocation - World name + mySQLlastlocWorld: world + # Column for RealName + mySQLRealName: realname + # Enable this when you allow registration through a website + mySQLWebsite: false +settings: + # The name shown in the help messages. + helpHeader: AuthMeReloaded + sessions: + # Do you want to enable the session feature? + # If enabled, when a player authenticates successfully, + # his IP and his nickname is saved. + # The next time the player joins the server, if his IP + # is the same of the last time, and the timeout time + # hasn't expired, he will not need to authenticate. + enabled: false + # After how many minutes a session should expire? + # 0 for unlimited time (Very dangerous, use it at your own risk!) + # Consider that session will end only after the timeout time, and + # if the player's ip has changed but the timeout hasn't expired, + # player will be kicked out of sever due to invalidSession! + timeout: 10 + # Should the session expire if the player try to login with an + # another IP Address? + sessionExpireOnIpChange: true + restrictions: + # Can not authenticated players chat and see the chat log? + # Care that this feature blocks also all the commands not + # listed in the list below. + allowChat: false + # Commands allowed when a player is not authenticated + allowCommands: + - /login + - /register + - /l + - /reg + - /email + - /captcha + # Max number of allowed registrations per IP (default: 1) + maxRegPerIp: 1 + # Max allowed username length + maxNicknameLength: 16 + # When this setting is enabled, online players can't be kicked out + # due to "Logged in from another Location" + # This setting will prevent potetial security exploits. + ForceSingleSession: true + # If enabled, every player will be teleported to the world spawnpoint + # after successful authentication. + # The quit location of the player will be overwritten. + # This is different from "teleportUnAuthedToSpawn" that teleport player + # back to his quit location after the authentication. + ForceSpawnLocOnJoinEnabled: true + # This option will save the quit location of the players. + SaveQuitLocation: false + # To activate the restricted user feature you need + # to enable this option and configure the + # AllowedRestrctedUser field. + AllowRestrictedUser: false + # The restricted user feature will kick players listed below + # if they dont match of the defined ip address. + # Example: + # AllowedRestrictedUser: + # - playername;127.0.0.1 + AllowedRestrictedUser: + - playername;127.0.0.1 + # Should unregistered players be kicked immediatly? + kickNonRegistered: false + # Should players be kicked on wrong password? + kickOnWrongPassword: false + # Should not logged in players be teleported to the spawn? + # After the authentication they will be teleported back to + # their normal position. + teleportUnAuthedToSpawn: false + # Minimum allowed nick length + minNicknameLength: 4 + # Can unregistered players walk around? + allowMovement: false + # Should not authenticated players have speed = 0? + # This will reset the fly/walk speed to default value after the login. + removeSpeed: true + # After how many time players who fail to login or register + # should be kicked? Set to 0 to disable. + timeout: 30 + # Regex sintax of allowed characters in the player name. + allowedNicknameCharacters: '[a-zA-Z0-9_?]*' + # How far can unregistered players walk? Set to 0 + # for unlimited radius + allowedMovementRadius: 100 + # Enable double check of password when you register + # when it's true, registration require that kind of command: + # /register + enablePasswordVerifier: true + # Should we protect the player inventory before logging in? + ProtectInventoryBeforeLogIn: true + # Should we display all other accounts from a player when he joins? + # permission: /authme.admin.accounts + displayOtherAccounts: true + # WorldNames where we need to force the spawn location for ForceSpawnLocOnJoinEnabled + # CASE SENSITIVE + ForceSpawnOnTheseWorlds: + - survival + - survival_nether + - creative + # Ban ip when the ip is not the ip registered in database + banUnsafedIP: false + # Spawn Priority, Values : authme, essentials, multiverse, default + spawnPriority: authme,essentials,multiverse,default + # Maximum Login authorized by IP + maxLoginPerIp: 0 + # Maximum Join authorized by IP + maxJoinPerIp: 0 + # AuthMe will NEVER teleport players ! + noTeleport: false + # Regex sintax for allowed Chars in passwords. + allowedPasswordCharacters: '[\x21-\x7E]*' + GameMode: + # ForceSurvivalMode to player when join ? + ForceSurvivalMode: false + # if player join with CreativeMode and ForceSurvivalMode: true + # inventory will be wipped + ResetInventoryIfCreative: false + # Do we need to force the survival mode ONLY after /login process ? + ForceOnlyAfterLogin: false + security: + # minimum Length of password + minPasswordLength: 5 + # this is very important options, + # every time player join the server, + # if they are registered, AuthMe will switch him + # to unLoggedInGroup, this + # should prevent all major exploit. + # So you can set up on your Permission Plugin + # this special group with 0 permissions, or permissions to chat, + # or permission to + # send private message or all other perms that you want, + # the better way is to set up + # this group with few permissions, + # so if player try to exploit some account, + # they can + # do anything except what you set in perm Group. + # After a correct logged-in player will be + # moved to his correct permissions group! + # Pay attention group name is case sensitive, + # so Admin is different from admin, + # otherwise your group will be wiped, + # and player join in default group []! + # Example unLoggedinGroup: NotLogged + unLoggedinGroup: unLoggedinGroup + # possible values: MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB, + # PLAINTEXT ( unhashed password), + # MYBB, IPB3, PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512, + # DOUBLEMD5, PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM(for developpers only) + passwordHash: SHA256 + # salt length for the SALTED2MD5 MD5(MD5(password)+salt) + doubleMD5SaltLength: 8 + # If password checking return false , do we need to check with all + # other password algorithm to check an old password ? + # AuthMe will update the password to the new passwordHash ! + supportOldPasswordHash: false + # Cancel unsafe passwords for being used, put them on lowercase! + #unsafePasswords: + #- '123456' + #- 'password' + unsafePasswords: + - '123456' + - 'password' + - 'qwerty' + - '12345' + - '54321' + registration: + # enable registration on the server? + enabled: true + # Send every X seconds a message to a player to + # remind him that he has to login/register + messageInterval: 5 + # Only registered and logged in players can play. + # See restrictions for exceptions + force: true + # Does we replace password registration by an Email registration method ? + enableEmailRegistrationSystem: false + # Enable double check of email when you register + # when it's true, registration require that kind of command: + # /register + doubleEmailCheck: false + # Do we force kicking player after a successful registration ? + # Do not use with login feature below + forceKickAfterRegister: false + # Does AuthMe need to enforce a /login after a successful registration ? + forceLoginAfterRegister: false + unrestrictions: + # below you can list all your account name, that + # AuthMe will ignore for registration or login, configure it + # at your own risk!! Remember that if you are going to add + # nickname with [], you have to delimit name with ' '. + # this option add compatibility with BuildCraft and some + # other mods. + # It is CaseSensitive! + UnrestrictedName: [] + # Message language, available : en, de, br, cz, pl, fr, ru, hu, sk, es, zhtw, fi, zhcn, lt, it, ko, pt + messagesLanguage: en + # Force these commands after /login, without any '/', use %p for replace with player name + forceCommands: + - spawn + # Force these commands after /login as a server console, without any '/', use %p for replace with player name + forceCommandsAsConsole: + - sethome %p:lastloc + - msg %p Welcome back + # Force these commands after /register, without any '/', use %p for replace with player name + forceRegisterCommands: + - me registers + - msg CONSOLE hi + # Force these commands after /register as a server console, without any '/', use %p for replace with player name + forceRegisterCommandsAsConsole: + - sethome %p:regloc + # Do we need to display the welcome message (welcome.txt) after a register or a login? + # You can use colors in this welcome.txt + some replaced strings : + # {PLAYER} : player name, {ONLINE} : display number of online players, {MAXPLAYERS} : display server slots, + # {IP} : player ip, {LOGINS} : number of players logged, {WORLD} : player current world, {SERVER} : server name + # {VERSION} : get current bukkit version, {COUNTRY} : player country + useWelcomeMessage: true + # Do we need to broadcast the welcome message to all server or only to the player? set true for server or false for player + broadcastWelcomeMessage: false + # Do we need to delay the join/leave message to be displayed only when the player is authenticated ? + delayJoinLeaveMessages: true + # Do we need to add potion effect Blinding before login/register ? + applyBlindEffect: false +ExternalBoardOptions: + # MySQL column for the salt , needed for some forum/cms support + mySQLColumnSalt: '' + # MySQL column for the group, needed for some forum/cms support + mySQLColumnGroup: '' + # -1 mean disabled. If u want that only + # activated player can login in your server + # u can put in this options the group number + # of unactivated user, needed for some forum/cms support + nonActivedUserGroup: -1 + # Other MySQL columns where we need to put the Username (case sensitive) + mySQLOtherUsernameColumns: [] + # How much Log to Round needed in BCrypt(do not change it if you do not know what's your doing) + bCryptLog2Round: 10 + # phpBB prefix defined during phpbb installation process + phpbbTablePrefix: 'phpbb_' + # phpBB activated group id , 2 is default registered group defined by phpbb + phpbbActivatedGroupId: 2 + # WordPress prefix defined during WordPress installation process + wordpressTablePrefix: 'wp_' +permission: + # Take care with this options, if you dont want + # to use Vault and Group Switching of + # AuthMe for unloggedIn players put true + # below, default is false. + EnablePermissionCheck: false +BackupSystem: + # Enable or Disable Automatic Backup + ActivateBackup: false + # set Backup at every start of Server + OnServerStart: false + # set Backup at every stop of Server + OnServerStop: true + # Windows only mysql installation Path + MysqlWindowsPath: 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\' +Security: + SQLProblem: + # Stop the server if we can't contact the sql database + # Take care with this, if you set that to false, + # AuthMe automatically disable and the server is not protected! + stopServer: true + ReloadCommand: + # /reload support + useReloadCommandSupport: true + console: + # Remove spam console + noConsoleSpam: true + # Replace passwords in the console when player type a command like /login + removePassword: true + captcha: + # Player need to put a captcha when he fails too lot the password + useCaptcha: false + # Max allowed tries before request a captcha + maxLoginTry: 5 + # Captcha length + captchaLength: 5 +Converter: + Rakamak: + # Rakamak file name + fileName: users.rak + # Rakamak use ip ? + useIP: false + # IP file name for rakamak + ipFileName: UsersIp.rak + CrazyLogin: + # CrazyLogin database file + fileName: accounts.db +Email: + # Email SMTP server host + mailSMTP: smtp.gmail.com + # Email SMTP server port + mailPort: 465 + # Email account that send the mail + mailAccount: '' + # Email account password + mailPassword: '' + # Custom SenderName, that replace the mailAccount name in the email + mailSenderName: '' + # Random password length + RecoveryPasswordLength: 8 + # Email subject of password get + mailSubject: 'Your new AuthMe Password' + # Email text here + mailText: 'Dear ,

    This is your new AuthMe password for the server

    %servername% :



    Do not forget to change password after login!
    /changepassword %generatedpass% newPassword' + # Like maxRegPerIp but with email + maxRegPerEmail: 1 + # Recall players to add an email ? + recallPlayers: false + # Delay in minute for the recall scheduler + delayRecall: 5 + # Blacklist these domains for emails + emailBlacklisted: + - 10minutemail.com + # WhiteList only these domains for emails + emailWhitelisted: [] + # Do we need to send new password draw in an image ? + generateImage: false +Hooks: + # Do we need to hook with multiverse for spawn checking? + multiverse: true + # Do we need to hook with BungeeCord for get the real Player ip ? + bungeecord: false + # Do we need to disable Essentials SocialSpy on join ? + disableSocialSpy: true + # Do we need to force /motd Essentials command on join ? + useEssentialsMotd: false + # Do we need to cache custom Attributes ? + customAttributes: false +Purge: + # On Enable , does AuthMe need to purge automatically old accounts unused ? + useAutoPurge: false + # Number of Days an account become Unused + daysBeforeRemovePlayer: 60 + # Do we need to remove the player.dat file during purge process ? + removePlayerDat: false + # Do we need to remove the Essentials/users/player.yml file during purge process ? + removeEssentialsFile: false + # World where are players.dat stores + defaultWorld: 'world' + # Do we need to remove LimitedCreative/inventories/player.yml , player_creative.yml files during purge process ? + removeLimitedCreativesInventories: false + # Do we need to remove the AntiXRayData/PlayerData/player file during purge process ? + removeAntiXRayFile: false + # Do we need to remove permissions ? + removePermissions: false +Protection: + # Enable some servers protection ( country based login, antibot ) + enableProtection: false + # Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes + # PLEASE USE QUOTES! + countries: + - 'US' + - 'GB' + # Countries blacklisted automatically ( without any needed to enable protection ) + # PLEASE USE QUOTES! + countriesBlacklist: + - 'A1' + # Do we need to enable automatic antibot system? + enableAntiBot: false + # Max number of player allowed to login in 5 secs before enable AntiBot system automatically + antiBotSensibility: 5 + # Duration in minutes of the antibot automatic system + antiBotDuration: 10 +VeryGames: + # These features are only available on VeryGames Server Provider + enableIpCheck: false + From f6ed39b118f875715e549d1dc029aa7e1fcdd698 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 24 Nov 2016 17:39:57 +0100 Subject: [PATCH 53/67] #411 Improve command migration handling, write tests --- .../commandconfig/CommandManager.java | 24 +---- .../commandconfig/CommandSettingsHolder.java | 10 +- .../commandconfig/CommandsMigrater.java | 22 ++++- .../properties/AuthMeSettingsRetriever.java | 3 +- src/main/resources/commands.yml | 12 ++- .../authme/ForceLoginCommandTest.java | 5 +- .../message/MessagesIntegrationTest.java | 2 +- .../xephi/authme/settings/SettingsTest.java | 18 ++++ .../CommandConfigTestHelper.java | 2 +- .../commandconfig/CommandManagerTest.java | 95 +++++++++++++++---- .../CommandYmlConsistencyTest.java | 60 ++++++++++++ .../commandconfig/CommandsMigraterTest.java | 20 ++++ .../AuthMeSettingsRetrieverTest.java | 32 +++++++ .../settings/commandconfig/commands.empty.yml | 0 14 files changed, 248 insertions(+), 57 deletions(-) create mode 100644 src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java create mode 100644 src/test/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetrieverTest.java create mode 100644 src/test/resources/fr/xephi/authme/settings/commandconfig/commands.empty.yml diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java index 015df7f6..2b476c4a 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java @@ -2,11 +2,9 @@ package fr.xephi.authme.settings.commandconfig; import com.github.authme.configme.SettingsManager; import com.github.authme.configme.resource.YamlFileResource; -import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.service.BukkitService; -import fr.xephi.authme.settings.Settings; import fr.xephi.authme.util.FileUtils; import org.bukkit.entity.Player; @@ -22,17 +20,14 @@ public class CommandManager implements Reloadable { private final File dataFolder; private final BukkitService bukkitService; private final CommandsMigrater commandsMigrater; - private final Settings settings; private CommandConfig commandConfig; @Inject - CommandManager(@DataFolder File dataFolder, BukkitService bukkitService, - CommandsMigrater commandsMigrater, Settings settings) { + CommandManager(@DataFolder File dataFolder, BukkitService bukkitService, CommandsMigrater commandsMigrater) { this.dataFolder = dataFolder; this.bukkitService = bukkitService; this.commandsMigrater = commandsMigrater; - this.settings = settings; reload(); } @@ -65,21 +60,8 @@ public class CommandManager implements Reloadable { FileUtils.copyFileFromResource(file, "commands.yml"); SettingsManager settingsManager = new SettingsManager( - new YamlFileResource(file), null, CommandSettingsHolder.class); - CommandConfig commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); - - if (commandsMigrater.transformOldCommands(commandConfig)) { - ConsoleLogger.warning("Old setting properties (such as settings.forceCommands) were found. " - + "They have been moved to commands.yml"); - settingsManager.setProperty(CommandSettingsHolder.COMMANDS, commandConfig); - settingsManager.save(); - settingsManager.reload(); - settings.save(); - settings.reload(); - - commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); - } - this.commandConfig = commandConfig; + new YamlFileResource(file), commandsMigrater, CommandSettingsHolder.class); + commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); } diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java index 4de2de5e..75906a32 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java @@ -25,7 +25,7 @@ public final class CommandSettingsHolder implements SettingsHolder { String[] comments = { "This configuration file allows you to execute commands on various events.", "%p in commands will be replaced with the player name.", - "For example, if you want to message a welcome message to a player who just registered:", + "For example, if you want to send a welcome message to a player who just registered:", "onRegister:", " welcome:", " command: 'msg %p Welcome to the server!'", @@ -33,15 +33,17 @@ public final class CommandSettingsHolder implements SettingsHolder { "", "This will make the console execute the msg command to the player.", "Each command under an event has a name you can choose freely (e.g. 'welcome' as above),", - "after which a mandatory 'command' field defines the command to run, ", + "after which a mandatory 'command' field defines the command to run,", "and 'as' defines who will run the command (either PLAYER or CONSOLE). Longer example:", "onLogin:", " welcome:", " command: 'msg %p Welcome back!'", - " # as: PLAYER # player is the default, you can leave this out if you want", + " as: PLAYER", " broadcast:", " command: 'broadcast %p has joined, welcome back!'", - " as: CONSOLE" + " as: CONSOLE", + "", + "Supported command events: onLogin, onJoin, onRegister" }; Map commentMap = new HashMap<>(); commentMap.put("onLogin", comments); diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java index 8a2df167..a64260e0 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java @@ -1,5 +1,9 @@ package fr.xephi.authme.settings.commandconfig; +import com.github.authme.configme.migration.MigrationService; +import com.github.authme.configme.properties.Property; +import com.github.authme.configme.resource.PropertyResource; +import com.google.common.annotations.VisibleForTesting; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.settings.SettingsMigrationService; import fr.xephi.authme.util.RandomStringUtils; @@ -13,7 +17,7 @@ import java.util.stream.Collectors; /** * Migrates the commands from their old location, in config.yml, to the dedicated commands configuration file. */ -class CommandsMigrater { +class CommandsMigrater implements MigrationService { @Inject private SettingsMigrationService settingsMigrationService; @@ -21,12 +25,25 @@ class CommandsMigrater { CommandsMigrater() { } + @Override + public boolean checkAndMigrate(PropertyResource resource, List> properties) { + final CommandConfig commandConfig = CommandSettingsHolder.COMMANDS.getValue(resource); + final boolean didMoveCommands = transformOldCommands(commandConfig); + + if (didMoveCommands) { // TODO ConfigMe/#29: Check that loaded file isn't completely empty + resource.setValue("", commandConfig); + return true; + } + return false; + } + /** * Adds command settings from their old location (in config.yml) to the given command configuration object. * * @param commandConfig the command config object to move old commands to * @return true if commands have been moved, false if no migration was necessary */ + @VisibleForTesting boolean transformOldCommands(CommandConfig commandConfig) { boolean didMoveCommands = false; for (MigratableCommandSection section : MigratableCommandSection.values()) { @@ -97,7 +114,8 @@ class CommandsMigrater { } Map commandMap = commandMapGetter.apply(commandConfig); commands.forEach(cmd -> commandMap.put(RandomStringUtils.generate(10), cmd)); - ConsoleLogger.info("Migrated " + commands.size() + " commands of type " + this); + ConsoleLogger.info("Moving " + commands.size() + " commands of type " + this + + " from config.yml to commands.yml"); return true; } } diff --git a/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java b/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java index 80bd02cf..88b896f6 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java +++ b/src/main/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetriever.java @@ -6,8 +6,7 @@ import com.github.authme.configme.knownproperties.ConfigurationDataBuilder; import com.github.authme.configme.properties.Property; /** - * Utility class responsible for retrieving all {@link Property} fields - * from {@link SettingsHolder} implementations via reflection. + * Utility class responsible for retrieving all {@link Property} fields from {@link SettingsHolder} classes. */ public final class AuthMeSettingsRetriever { diff --git a/src/main/resources/commands.yml b/src/main/resources/commands.yml index a7c70359..c3741a29 100644 --- a/src/main/resources/commands.yml +++ b/src/main/resources/commands.yml @@ -1,24 +1,26 @@ # This configuration file allows you to execute commands on various events. # %p in commands will be replaced with the player name. -# For example, if you want to message a welcome message to a player who just registered: +# For example, if you want to send a welcome message to a player who just registered: # onRegister: # welcome: # command: 'msg %p Welcome to the server!' # as: CONSOLE -# +# # This will make the console execute the msg command to the player. # Each command under an event has a name you can choose freely (e.g. 'welcome' as above), -# after which a mandatory 'command' field defines the command to run, +# after which a mandatory 'command' field defines the command to run, # and 'as' defines who will run the command (either PLAYER or CONSOLE). Longer example: # onLogin: # welcome: # command: 'msg %p Welcome back!' -# # as: PLAYER # player is the default, you can leave this out if you want +# as: PLAYER # broadcast: # command: 'broadcast %p has joined, welcome back!' # as: CONSOLE +# +# Supported command events: onLogin, onJoin, onRegister onLogin: welcome: command: 'msg %p Welcome back!' - executor: 'PLAYER' \ No newline at end of file + executor: 'PLAYER' diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java index 8746f01b..76a73033 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java @@ -15,7 +15,6 @@ import org.mockito.runners.MockitoJUnitRunner; import java.util.Collections; import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -53,7 +52,7 @@ public class ForceLoginCommandTest { // then verify(bukkitService).getPlayerExact(playerName); - verify(sender).sendMessage(argThat(equalTo("Player needs to be online!"))); + verify(sender).sendMessage("Player needs to be online!"); verifyZeroInteractions(management); } @@ -69,7 +68,7 @@ public class ForceLoginCommandTest { // then verify(bukkitService).getPlayerExact(playerName); - verify(sender).sendMessage(argThat(equalTo("Player needs to be online!"))); + verify(sender).sendMessage("Player needs to be online!"); verifyZeroInteractions(management); } diff --git a/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java b/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java index 04004634..12949c5a 100644 --- a/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/message/MessagesIntegrationTest.java @@ -160,7 +160,7 @@ public class MessagesIntegrationTest { messages.send(sender, key); // then - verify(sender).sendMessage(argThat(equalTo("Use /captcha THE_CAPTCHA to solve the captcha"))); + verify(sender).sendMessage("Use /captcha THE_CAPTCHA to solve the captcha"); } @Test diff --git a/src/test/java/fr/xephi/authme/settings/SettingsTest.java b/src/test/java/fr/xephi/authme/settings/SettingsTest.java index 137d5a56..3480bd0c 100644 --- a/src/test/java/fr/xephi/authme/settings/SettingsTest.java +++ b/src/test/java/fr/xephi/authme/settings/SettingsTest.java @@ -83,6 +83,24 @@ public class SettingsTest { assertThat(result, equalTo(emailMessage)); } + @Test + public void shouldLoadRecoveryCodeMessage() throws IOException { + // given + String emailMessage = "Your recovery code is %code."; + File emailFile = new File(testPluginFolder, "recovery_code_email.html"); + createFile(emailFile); + Files.write(emailFile.toPath(), emailMessage.getBytes()); + + PropertyResource resource = mock(PropertyResource.class); + Settings settings = new Settings(testPluginFolder, resource, null, CONFIG_DATA); + + // when + String result = settings.getRecoveryCodeEmailMessage(); + + // then + assertThat(result, equalTo(emailMessage)); + } + private static void createFile(File file) { try { file.getParentFile().mkdirs(); diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandConfigTestHelper.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandConfigTestHelper.java index f9fb4e5f..88ee90f3 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandConfigTestHelper.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandConfigTestHelper.java @@ -19,7 +19,7 @@ final class CommandConfigTestHelper { * @param executor the expected executor * @return the matcher */ - public static Matcher isCommand(String cmd, Executor executor) { + static Matcher isCommand(String cmd, Executor executor) { return new TypeSafeMatcher() { @Override protected boolean matchesSafely(Command item) { diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java index eea0f569..ec03cb19 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java @@ -4,26 +4,33 @@ import com.google.common.io.Files; import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.TestHelper; import fr.xephi.authme.service.BukkitService; -import fr.xephi.authme.settings.Settings; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; +import fr.xephi.authme.settings.SettingsMigrationService; +import org.bukkit.entity.Player; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import java.io.File; import java.io.IOException; +import java.util.function.BiConsumer; import static fr.xephi.authme.settings.commandconfig.CommandConfigTestHelper.isCommand; +import static java.lang.String.format; import static org.hamcrest.Matchers.anEmptyMap; import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.only; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; /** * Test for {@link CommandManager}. @@ -33,16 +40,18 @@ public class CommandManagerTest { private static final String TEST_FILES_FOLDER = "/fr/xephi/authme/settings/commandconfig/"; + private CommandManager manager; + @InjectMocks + private CommandsMigrater commandsMigrater; + @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); - private CommandManager manager; @Mock private BukkitService bukkitService; @Mock - private Settings settings; - @Mock - private CommandsMigrater commandsMigrater; + private SettingsMigrationService settingsMigrationService; + private File testFolder; @Before @@ -75,10 +84,9 @@ public class CommandManagerTest { } @Test - @Ignore // TODO #411: Implement tested behavior public void shouldLoadIncompleteFile() { // given - File configFile = copyJarFileAsCommandsYml(TEST_FILES_FOLDER + "commands.incomplete.yml"); + copyJarFileAsCommandsYml(TEST_FILES_FOLDER + "commands.incomplete.yml"); // when initManager(); @@ -90,23 +98,74 @@ public class CommandManagerTest { isCommand("msg %p Welcome back", Executor.CONSOLE), isCommand("list", Executor.PLAYER))); assertThat(commandConfig.getOnRegister(), anEmptyMap()); + } - // verify that we have rewritten the file with the proper sections - FileConfiguration configuration = YamlConfiguration.loadConfiguration(configFile); - assertThat(configuration.contains("onRegister"), equalTo(true)); - assertThat(configuration.contains("doesNotExist"), equalTo(false)); + @Test + public void shouldExecuteCommandsOnJoin() { + // given + String name = "Bobby1"; + + // when + testCommandExecution(name, CommandManager::runCommandsOnJoin); + + // then + verify(bukkitService, only()).dispatchConsoleCommand(format("broadcast %s has joined", name)); + } + + @Test + public void shouldExecuteCommandsOnRegister() { + // given + String name = "luis"; + + // when + testCommandExecution(name, CommandManager::runCommandsOnRegister); + + // then + verify(bukkitService).dispatchCommand(any(Player.class), eq("me I just registered")); + verify(bukkitService).dispatchConsoleCommand(format("log %s registered", name)); + verifyNoMoreInteractions(bukkitService); + } + + @Test + public void shouldExecuteCommandsOnLogin() { + // given + String name = "plaYer01"; + + // when + testCommandExecution(name, CommandManager::runCommandsOnLogin); + + // then + verify(bukkitService).dispatchConsoleCommand(format("msg %s Welcome back", name)); + verify(bukkitService).dispatchCommand(any(Player.class), eq("motd")); + verify(bukkitService).dispatchCommand(any(Player.class), eq("list")); + verifyNoMoreInteractions(bukkitService); + } + + @Test + public void shouldHaveHiddenConstructorInSettingsHolderClass() { + // given / when / then + TestHelper.validateHasOnlyPrivateEmptyConstructor(CommandSettingsHolder.class); + } + + + private void testCommandExecution(String playerName, BiConsumer testMethod) { + copyJarFileAsCommandsYml(TEST_FILES_FOLDER + "commands.complete.yml"); + initManager(); + Player player = mock(Player.class); + given(player.getName()).willReturn(playerName); + + testMethod.accept(manager, player); } private void initManager() { - manager = new CommandManager(testFolder, bukkitService, commandsMigrater, settings); + manager = new CommandManager(testFolder, bukkitService, commandsMigrater); } - private File copyJarFileAsCommandsYml(String path) { + private void copyJarFileAsCommandsYml(String path) { File source = TestHelper.getJarFile(path); File destination = new File(testFolder, "commands.yml"); try { Files.copy(source, destination); - return destination; } catch (IOException e) { throw new IllegalStateException(e); } diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java new file mode 100644 index 00000000..ff9e51da --- /dev/null +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java @@ -0,0 +1,60 @@ +package fr.xephi.authme.settings.commandconfig; + +import com.github.authme.configme.knownproperties.ConfigurationDataBuilder; +import com.github.authme.configme.resource.PropertyResource; +import com.github.authme.configme.resource.YamlFileResource; +import fr.xephi.authme.TestHelper; +import fr.xephi.authme.settings.SettingsMigrationService; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.io.File; +import java.util.Collections; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.BDDMockito.given; + +/** + * Tests that commands.yml is well-formed. + */ +@RunWith(MockitoJUnitRunner.class) +public class CommandYmlConsistencyTest { + + @InjectMocks + private CommandsMigrater commandsMigrater; + + @Mock + private SettingsMigrationService settingsMigrationService; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Before + public void setUpSettingsMigrationService() { + given(settingsMigrationService.getOnLoginCommands()).willReturn(Collections.emptyList()); + given(settingsMigrationService.getOnLoginConsoleCommands()).willReturn(Collections.emptyList()); + given(settingsMigrationService.getOnRegisterCommands()).willReturn(Collections.emptyList()); + given(settingsMigrationService.getOnRegisterConsoleCommands()).willReturn(Collections.emptyList()); + } + + @Test + public void shouldLoadWithNoMigrations() { + // given + File commandFile = TestHelper.getJarFile("/commands.yml"); + PropertyResource resource = new YamlFileResource(commandFile); + + // when + boolean result = commandsMigrater.checkAndMigrate( + resource, ConfigurationDataBuilder.collectData(CommandSettingsHolder.class).getProperties()); + + // then + assertThat(result, equalTo(false)); + } +} diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java index ee146884..0dae65fe 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java @@ -1,14 +1,19 @@ package fr.xephi.authme.settings.commandconfig; +import com.github.authme.configme.knownproperties.ConfigurationDataBuilder; +import com.github.authme.configme.resource.PropertyResource; +import com.github.authme.configme.resource.YamlFileResource; import fr.xephi.authme.TestHelper; import fr.xephi.authme.settings.SettingsMigrationService; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import java.io.File; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -108,4 +113,19 @@ public class CommandsMigraterTest { isCommand("log %p registered", Executor.CONSOLE), isCommand("whois %p", Executor.CONSOLE))); } + + @Test + @Ignore // TODO ConfigMe/#29: Create PropertyResource#getKeys + public void shouldRewriteForEmptyFile() { + // given + File commandFile = TestHelper.getJarFile("/fr/xephi/authme/settings/commandconfig/commands.empty.yml"); + PropertyResource resource = new YamlFileResource(commandFile); + + // when + boolean result = commandsMigrater.checkAndMigrate( + resource, ConfigurationDataBuilder.collectData(CommandSettingsHolder.class).getProperties()); + + // then + assertThat(result, equalTo(true)); + } } diff --git a/src/test/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetrieverTest.java b/src/test/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetrieverTest.java new file mode 100644 index 00000000..a5bd8c90 --- /dev/null +++ b/src/test/java/fr/xephi/authme/settings/properties/AuthMeSettingsRetrieverTest.java @@ -0,0 +1,32 @@ +package fr.xephi.authme.settings.properties; + +import com.github.authme.configme.knownproperties.ConfigurationData; +import fr.xephi.authme.TestHelper; +import org.junit.Test; + +import static org.hamcrest.Matchers.closeTo; +import static org.junit.Assert.assertThat; + +/** + * Test for {@link AuthMeSettingsRetriever}. + */ +public class AuthMeSettingsRetrieverTest { + + @Test + public void shouldReturnAllProperties() { + // given / when + ConfigurationData configurationData = AuthMeSettingsRetriever.buildConfigurationData(); + + // then + // Note ljacqu 20161123: Check that the number of properties returned corresponds to what we expect with + // an error margin of 10: this prevents us from having to adjust the test every time the config is changed. + // If this test fails, replace the first argument in closeTo() with the new number of properties + assertThat((double) configurationData.getProperties().size(), + closeTo(150, 10)); + } + + @Test + public void shouldHaveHiddenConstructor() { + TestHelper.validateHasOnlyPrivateEmptyConstructor(AuthMeSettingsRetriever.class); + } +} diff --git a/src/test/resources/fr/xephi/authme/settings/commandconfig/commands.empty.yml b/src/test/resources/fr/xephi/authme/settings/commandconfig/commands.empty.yml new file mode 100644 index 00000000..e69de29b From de5324bbc602d28e045fad3edb37373a1caa165c Mon Sep 17 00:00:00 2001 From: ljacqu Date: Fri, 25 Nov 2016 15:51:15 +0100 Subject: [PATCH 54/67] #685 Fix PBKDF2 implementation - Fix our PBKDF2 hash implementation and its test class - Use external dependency as PBKDF2 implementation --- docs/hash_algorithms.md | 8 +- pom.xml | 15 + .../authme/security/crypts/CryptPBKDF2.java | 23 +- .../security/crypts/CryptPBKDF2Django.java | 6 +- .../xephi/authme/security/crypts/JOOMLA.java | 2 +- .../authme/security/pbkdf2/BinTools.java | 114 ------ .../authme/security/pbkdf2/MacBasedPRF.java | 96 ----- .../xephi/authme/security/pbkdf2/PBKDF2.java | 97 ----- .../authme/security/pbkdf2/PBKDF2Engine.java | 346 ------------------ .../security/pbkdf2/PBKDF2Formatter.java | 56 --- .../security/pbkdf2/PBKDF2HexFormatter.java | 62 ---- .../security/pbkdf2/PBKDF2Parameters.java | 139 ------- .../fr/xephi/authme/security/pbkdf2/PRF.java | 60 --- .../crypts/AbstractEncryptionMethodTest.java | 7 + .../authme/security/crypts/BcryptTest.java | 7 - .../crypts/CryptPBKDF2DjangoTest.java | 8 - .../security/crypts/CryptPBKDF2Test.java | 12 +- .../authme/security/crypts/IPB4Test.java | 8 - .../authme/security/crypts/XFBCRYPTTest.java | 8 - 19 files changed, 46 insertions(+), 1028 deletions(-) delete mode 100644 src/main/java/fr/xephi/authme/security/pbkdf2/BinTools.java delete mode 100644 src/main/java/fr/xephi/authme/security/pbkdf2/MacBasedPRF.java delete mode 100644 src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2.java delete mode 100644 src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Engine.java delete mode 100644 src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Formatter.java delete mode 100644 src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2HexFormatter.java delete mode 100644 src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Parameters.java delete mode 100644 src/main/java/fr/xephi/authme/security/pbkdf2/PRF.java diff --git a/docs/hash_algorithms.md b/docs/hash_algorithms.md index e7fd0ae3..02bcafe6 100644 --- a/docs/hash_algorithms.md +++ b/docs/hash_algorithms.md @@ -1,5 +1,5 @@ - + ## Hash Algorithms AuthMe supports the following hash algorithms for storing your passwords safely. @@ -13,11 +13,11 @@ CRAZYCRYPT1 | Do not use | 128 | | | Username | | DOUBLEMD5 | Do not use | 32 | | | None | | IPB3 | Acceptable | 32 | | | Text | 5 | Y IPB4 | Does not work | 60 | | | Text | 22 | Y -JOOMLA | Recommended | 65 | | | Text | 32 | +JOOMLA | Acceptable | 65 | | | Text | 32 | MD5 | Do not use | 32 | | | None | | MD5VB | Acceptable | 56 | | | Text | 16 | MYBB | Acceptable | 32 | | | Text | 8 | Y -PBKDF2 | Does not work | 332 | | | Text | 12 | +PBKDF2 | Recommended | 165 | | | Text | 16 | PBKDF2DJANGO | Acceptable | 77 | Y | | Text | 12 | PHPBB | Acceptable | 34 | | | Text | 16 | PHPFUSION | Do not use | 64 | Y | | | | Y @@ -82,4 +82,4 @@ or bad. --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sat Oct 01 23:42:20 CEST 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Fri Nov 25 15:48:35 CET 2016 diff --git a/pom.xml b/pom.xml index 44196e87..24a20245 100644 --- a/pom.xml +++ b/pom.xml @@ -268,6 +268,10 @@ net.ricecode.similarity fr.xephi.authme.libs.ricecode.similarity + + de.rtner + fr.xephi.authme.libs.de.rtner + javax.inject fr.xephi.authme.libs.javax.inject @@ -319,6 +323,10 @@ net.ricecode.similarity fr.xephi.authme.libs.ricecode.similarity + + de.rtner + fr.xephi.authme.libs.de.rtner + javax.inject fr.xephi.authme.libs.javax.inject @@ -524,6 +532,13 @@ true + + + de.rtner + PBKDF2 + 1.1.2 + + diff --git a/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2.java b/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2.java index 57c13ee6..90cfd809 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2.java +++ b/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2.java @@ -1,22 +1,23 @@ package fr.xephi.authme.security.crypts; +import de.rtner.misc.BinTools; +import de.rtner.security.auth.spi.PBKDF2Engine; +import de.rtner.security.auth.spi.PBKDF2Parameters; import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Usage; -import fr.xephi.authme.security.pbkdf2.PBKDF2Engine; -import fr.xephi.authme.security.pbkdf2.PBKDF2Parameters; -import java.util.Arrays; - -@Recommendation(Usage.DOES_NOT_WORK) +@Recommendation(Usage.RECOMMENDED) public class CryptPBKDF2 extends HexSaltedMethod { + private static final int NUMBER_OF_ITERATIONS = 10_000; + @Override public String computeHash(String password, String salt, String name) { - String result = "pbkdf2_sha256$10000$" + salt + "$"; - PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "ASCII", salt.getBytes(), 10000); + String result = "pbkdf2_sha256$" + NUMBER_OF_ITERATIONS + "$" + salt + "$"; + PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), NUMBER_OF_ITERATIONS); PBKDF2Engine engine = new PBKDF2Engine(params); - return result + Arrays.toString(engine.deriveKey(password, 64)); + return result + BinTools.bin2hex(engine.deriveKey(password, 64)); } @Override @@ -26,15 +27,15 @@ public class CryptPBKDF2 extends HexSaltedMethod { return false; } String salt = line[2]; - String derivedKey = line[3]; - PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "ASCII", salt.getBytes(), 10000, derivedKey.getBytes()); + byte[] derivedKey = BinTools.hex2bin(line[3]); + PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), 10000, derivedKey); PBKDF2Engine engine = new PBKDF2Engine(params); return engine.verifyKey(password); } @Override public int getSaltLength() { - return 12; + return 16; } } diff --git a/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2Django.java b/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2Django.java index 79d06e0a..6628ca91 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2Django.java +++ b/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2Django.java @@ -1,9 +1,9 @@ package fr.xephi.authme.security.crypts; +import de.rtner.security.auth.spi.PBKDF2Engine; +import de.rtner.security.auth.spi.PBKDF2Parameters; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.security.crypts.description.AsciiRestricted; -import fr.xephi.authme.security.pbkdf2.PBKDF2Engine; -import fr.xephi.authme.security.pbkdf2.PBKDF2Parameters; import fr.xephi.authme.util.StringUtils; import javax.xml.bind.DatatypeConverter; @@ -19,7 +19,7 @@ public class CryptPBKDF2Django extends HexSaltedMethod { PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "ASCII", salt.getBytes(), DEFAULT_ITERATIONS); PBKDF2Engine engine = new PBKDF2Engine(params); - return result + String.valueOf(DatatypeConverter.printBase64Binary(engine.deriveKey(password, 32))); + return result + DatatypeConverter.printBase64Binary(engine.deriveKey(password, 32)); } @Override diff --git a/src/main/java/fr/xephi/authme/security/crypts/JOOMLA.java b/src/main/java/fr/xephi/authme/security/crypts/JOOMLA.java index ee7e49c7..ca72674b 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/JOOMLA.java +++ b/src/main/java/fr/xephi/authme/security/crypts/JOOMLA.java @@ -4,7 +4,7 @@ import fr.xephi.authme.security.HashUtils; import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Usage; -@Recommendation(Usage.RECOMMENDED) +@Recommendation(Usage.ACCEPTABLE) public class JOOMLA extends HexSaltedMethod { @Override diff --git a/src/main/java/fr/xephi/authme/security/pbkdf2/BinTools.java b/src/main/java/fr/xephi/authme/security/pbkdf2/BinTools.java deleted file mode 100644 index 34bf8aac..00000000 --- a/src/main/java/fr/xephi/authme/security/pbkdf2/BinTools.java +++ /dev/null @@ -1,114 +0,0 @@ -package fr.xephi.authme.security.pbkdf2; - -/* - * Free auxiliary functions. Copyright 2007, 2014, Matthias Gärtner - * - * This is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this software; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA, or see the FSF site: http://www.fsf.org. - */ - -/** - * Free auxiliary functions - * - * @author Matthias Gärtner - */ -public class BinTools { - public static final String hex = "0123456789ABCDEF"; - - /** - * Simple binary-to-hexadecimal conversion. - * - * @param b - * Input bytes. May be null. - * @return Hexadecimal representation of b. Uppercase A-F, two characters - * per byte. Empty string on null input. - */ - public static String bin2hex(final byte[] b) { - if (b == null) { - return ""; - } - StringBuffer sb = new StringBuffer(2 * b.length); - for (int i = 0; i < b.length; i++) { - int v = (256 + b[i]) % 256; - sb.append(hex.charAt((v / 16) & 15)); - sb.append(hex.charAt((v % 16) & 15)); - } - return sb.toString(); - } - - /** - * Convert hex string to array of bytes. - * - * @param s - * String containing hexadecimal digits. May be null - * . On odd length leading zero will be assumed. - * @return Array on bytes, non-null. - * @throws IllegalArgumentException - * when string contains non-hex character - */ - public static byte[] hex2bin(final String s) { - String m = s; - if (s == null) { - // Allow empty input string. - m = ""; - } else if (s.length() % 2 != 0) { - // Assume leading zero for odd string length - m = "0" + s; - } - byte r[] = new byte[m.length() / 2]; - for (int i = 0, n = 0; i < m.length(); n++) { - char h = m.charAt(i++); - char l = m.charAt(i++); - r[n] = (byte) (hex2bin(h) * 16 + hex2bin(l)); - } - return r; - } - - /** - * Convert hex digit to numerical value. - * - * @param c - * 0-9, a-f, A-F allowd. - * @return 0-15 - * @throws IllegalArgumentException - * on non-hex character - */ - public static int hex2bin(char c) { - if (c >= '0' && c <= '9') { - return (c - '0'); - } - if (c >= 'A' && c <= 'F') { - return (c - 'A' + 10); - } - if (c >= 'a' && c <= 'f') { - return (c - 'a' + 10); - } - throw new IllegalArgumentException("Input string may only contain hex digits, but found '" + c + "'"); - } - - public static void main(String[] args) { - byte b[] = new byte[256]; - byte bb = 0; - for (int i = 0; i < 256; i++) { - b[i] = bb++; - } - String s = bin2hex(b); - byte c[] = hex2bin(s); - String t = bin2hex(c); - if (!s.equals(t)) { - throw new AssertionError("Mismatch"); - } - } -} diff --git a/src/main/java/fr/xephi/authme/security/pbkdf2/MacBasedPRF.java b/src/main/java/fr/xephi/authme/security/pbkdf2/MacBasedPRF.java deleted file mode 100644 index 88ff11bf..00000000 --- a/src/main/java/fr/xephi/authme/security/pbkdf2/MacBasedPRF.java +++ /dev/null @@ -1,96 +0,0 @@ -package fr.xephi.authme.security.pbkdf2; - -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -/** - *

    - * Default PRF implementation based on standard javax.crypt.Mac mechanisms. - *

    - *

    - * A free Java implementation of Password Based Key Derivation Function 2 as - * defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner - *

    - *

    - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - *

    - *

    - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - *

    - *

    - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - *

    - *

    - * For Details, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. - *

    - * - * @author Matthias Gärtner - * @version 1.0 - */ -public class MacBasedPRF implements PRF { - - protected Mac mac; - - protected int hLen; - - protected final String macAlgorithm; - - /** - * Create Mac-based Pseudo Random Function. - * - * @param macAlgorithm Mac algorithm to use, i.e. HMacSHA1 or HMacMD5. - */ - public MacBasedPRF(String macAlgorithm) { - this.macAlgorithm = macAlgorithm; - try { - mac = Mac.getInstance(macAlgorithm); - hLen = mac.getMacLength(); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException(e); - } - } - - public MacBasedPRF(String macAlgorithm, String provider) { - this.macAlgorithm = macAlgorithm; - try { - mac = Mac.getInstance(macAlgorithm, provider); - hLen = mac.getMacLength(); - } catch (NoSuchAlgorithmException | NoSuchProviderException e) { - throw new RuntimeException(e); - } - } - - @Override - public byte[] doFinal(byte[] M) { - byte[] r = mac.doFinal(M); - return r; - } - - @Override - public int getHLen() { - return hLen; - } - - @Override - public void init(byte[] P) { - try { - mac.init(new SecretKeySpec(P, macAlgorithm)); - } catch (InvalidKeyException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2.java b/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2.java deleted file mode 100644 index 59bc96df..00000000 --- a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2.java +++ /dev/null @@ -1,97 +0,0 @@ -package fr.xephi.authme.security.pbkdf2; - -/** - *

    - * A free Java implementation of Password Based Key Derivation Function 2 as - * defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner - *

    - *

    - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - *

    - *

    - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - *

    - *

    - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - *

    - *

    - * For Details, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. - *

    - * - * @author Matthias Gärtner - * @version 1.0 - */ -public interface PBKDF2 { - - /** - * Convert String-based input to internal byte array, then invoke PBKDF2. - * Desired key length defaults to Pseudo Random Function block size. - * - * @param inputPassword Candidate password to compute the derived key for. - * - * @return internal byte array - */ - byte[] deriveKey(String inputPassword); - - /** - * Convert String-based input to internal byte array, then invoke PBKDF2. - * - * @param inputPassword Candidate password to compute the derived key for. - * @param dkLen Specify desired key length - * - * @return internal byte array - */ - byte[] deriveKey(String inputPassword, int dkLen); - - /** - * Convert String-based input to internal byte arrays, then invoke PBKDF2 - * and verify result against the reference data that is supplied in the - * PBKDF2Parameters. - * - * @param inputPassword Candidate password to compute the derived key for. - * - * @return true password match; false incorrect - * password - */ - boolean verifyKey(String inputPassword); - - /** - * Allow reading of configured parameters. - * - * @return Currently set parameters. - */ - PBKDF2Parameters getParameters(); - - /** - * Allow setting of configured parameters. - * - * @param parameters PBKDF2Parameters - */ - void setParameters(PBKDF2Parameters parameters); - - /** - * Get currently set Pseudo Random Function. - * - * @return Currently set Pseudo Random Function - */ - PRF getPseudoRandomFunction(); - - /** - * Set the Pseudo Random Function to use. Note that deriveKeys/getPRF does - * init this object using the supplied candidate password. If this is - * undesired, one has to override getPRF. - * - * @param prf Pseudo Random Function to set. - */ - void setPseudoRandomFunction(PRF prf); -} diff --git a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Engine.java b/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Engine.java deleted file mode 100644 index d32b8752..00000000 --- a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Engine.java +++ /dev/null @@ -1,346 +0,0 @@ -package fr.xephi.authme.security.pbkdf2; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; - -/** - *

    - * Request for Comments: 2898 PKCS #5: Password-Based Cryptography Specification - *

    - * Version 2.0 - *

    - *

    - * PBKDF2 (P, S, c, dkLen) - *

    - * Options: - *
      - *
    • PRF underlying pseudorandom function (hLen denotes the length in octets - * of the pseudorandom function output). PRF is pluggable.
    • - *
    - * Input: - *
      - *
    • P password, an octet string
    • - *
    • S salt, an octet string
    • - *
    • c iteration count, a positive integer
    • - *
    • dkLen intended length in octets of the derived key, a positive integer, - * at most (2^32 - 1) * hLen
    • - *
    - * Output: - *
      - *
    • DK derived key, a dkLen-octet string
    • - *
    - *

    - * A free Java implementation of Password Based Key Derivation Function 2 as - * defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner - *

    - *

    - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - *

    - *

    - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - *

    - *

    - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - *

    - *

    - * For Details, see - * http://www. - * gnu.org/licenses/old-licenses/lgpl-2.1.html. - *

    - * - * @author Matthias Gärtner - * @version 1.0 - * @see RFC 2898 - */ -public class PBKDF2Engine implements PBKDF2 { - - protected PBKDF2Parameters parameters; - - protected PRF prf; - - /** - * Constructor for PBKDF2 implementation object. PBKDF2 parameters must be - * passed later. - */ - public PBKDF2Engine() { - this.parameters = null; - prf = null; - } - - /** - * Constructor for PBKDF2 implementation object. PBKDF2 parameters are - * passed so that this implementation knows iteration count, method to use - * and String encoding. - * - * @param parameters Data holder for iteration count, method to use et cetera. - */ - public PBKDF2Engine(PBKDF2Parameters parameters) { - this.parameters = parameters; - prf = null; - } - - /** - * Constructor for PBKDF2 implementation object. PBKDF2 parameters are - * passed so that this implementation knows iteration count, method to use - * and String encoding. - * - * @param parameters Data holder for iteration count, method to use et cetera. - * @param prf Supply customer Pseudo Random Function. - */ - public PBKDF2Engine(PBKDF2Parameters parameters, PRF prf) { - this.parameters = parameters; - this.prf = prf; - } - - /** - * Convenience client function. Convert supplied password with random 8-byte - * salt and 1000 iterations using HMacSHA1. Assume that password is in - * ISO-8559-1 encoding. Output result as - * "Salt:iteration-count:PBKDF2" with binary data in hexadecimal - * encoding. - *

    - * Example: Password "password" (without the quotes) leads to - * 48290A0B96C426C3:1000:973899B1D4AFEB3ED371060D0797E0EE0142BD04 - *

    - * @param args Supply the password as argument. - * - * @throws IOException an ioexception occured - * @throws NoSuchAlgorithmException a NoSuchAlgorithmException occured - */ - public static void main(String[] args) - throws IOException, NoSuchAlgorithmException { - String password = "password"; - String candidate = null; - PBKDF2Formatter formatter = new PBKDF2HexFormatter(); - - if (args.length >= 1) { - password = args[0]; - } - if (args.length >= 2) { - candidate = args[1]; - } - if (candidate == null) { - // Creation mode - SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); - byte[] salt = new byte[8]; - sr.nextBytes(salt); - int iterations = 1000; - PBKDF2Parameters p = new PBKDF2Parameters("HmacSHA1", "ISO-8859-1", salt, iterations); - PBKDF2Engine e = new PBKDF2Engine(p); - p.setDerivedKey(e.deriveKey(password)); - candidate = formatter.toString(p); - } else { - // Verification mode - PBKDF2Parameters p = new PBKDF2Parameters(); - p.setHashAlgorithm("HmacSHA1"); - p.setHashCharset("ISO-8859-1"); - if (formatter.fromString(p, candidate)) { - throw new IllegalArgumentException("Candidate data does not have correct format (\"" + candidate + "\")"); - } - PBKDF2Engine e = new PBKDF2Engine(p); - boolean verifyOK = e.verifyKey(password); - System.exit(verifyOK ? 0 : 1); - } - } - - @Override - public byte[] deriveKey(String inputPassword) { - return deriveKey(inputPassword, 0); - } - - @Override - public byte[] deriveKey(String inputPassword, int dkLen) { - byte[] r = null; - byte[] P = null; - String charset = parameters.getHashCharset(); - if (inputPassword == null) { - inputPassword = ""; - } - try { - if (charset == null) { - P = inputPassword.getBytes(); - } else { - P = inputPassword.getBytes(charset); - } - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - assertPRF(P); - if (dkLen == 0) { - dkLen = prf.getHLen(); - } - r = PBKDF2(prf, parameters.getSalt(), parameters.getIterationCount(), dkLen); - return r; - } - - @Override - public boolean verifyKey(String inputPassword) { - byte[] referenceKey = getParameters().getDerivedKey(); - if (referenceKey == null || referenceKey.length == 0) { - return false; - } - byte[] inputKey = deriveKey(inputPassword, referenceKey.length); - - if (inputKey == null || inputKey.length != referenceKey.length) { - return false; - } - for (int i = 0; i < inputKey.length; i++) { - if (inputKey[i] != referenceKey[i]) { - return false; - } - } - return true; - } - - /** - * Factory method. Default implementation is (H)MAC-based. To be overridden - * in derived classes. - * - * @param P User-supplied candidate password as array of bytes. - */ - protected void assertPRF(byte[] P) { - if (prf == null) { - prf = new MacBasedPRF(parameters.getHashAlgorithm()); - } - prf.init(P); - } - - @Override - public PRF getPseudoRandomFunction() { - return prf; - } - - @Override - public void setPseudoRandomFunction(PRF prf) { - this.prf = prf; - } - - /** - * Core Password Based Key Derivation Function 2. - * - * @param prf Pseudo Random Function (i.e. HmacSHA1) - * @param S Salt as array of bytes. null means no salt. - * @param c Iteration count (see RFC 2898 4.2) - * @param dkLen desired length of derived key. - * - * @return internal byte array * @see RFC 2898 5.2 - */ - protected byte[] PBKDF2(PRF prf, byte[] S, int c, int dkLen) { - if (S == null) { - S = new byte[0]; - } - int hLen = prf.getHLen(); - int l = ceil(dkLen, hLen); - int r = dkLen - (l - 1) * hLen; - byte T[] = new byte[l * hLen]; - int ti_offset = 0; - for (int i = 1; i <= l; i++) { - _F(T, ti_offset, prf, S, c, i); - ti_offset += hLen; - } - if (r < hLen) { - // Incomplete last block - byte DK[] = new byte[dkLen]; - System.arraycopy(T, 0, DK, 0, dkLen); - return DK; - } - return T; - } - - /** - * Integer division with ceiling function. - * - * @param a Integer - * @param b Integer - * - * @return ceil(a/b) * @see RFC 2898 5.2 Step - * 2. - */ - protected int ceil(int a, int b) { - int m = 0; - if (a % b > 0) { - m = 1; - } - return a / b + m; - } - - /** - * Function F. - * - * @param dest Destination byte buffer - * @param offset Offset into destination byte buffer - * @param prf Pseudo Random Function - * @param S Salt as array of bytes - * @param c Iteration count - * @param blockIndex Integer - * - * @see RFC 2898 5.2 Step - * 3. - */ - protected void _F(byte[] dest, int offset, PRF prf, byte[] S, int c, - int blockIndex) { - int hLen = prf.getHLen(); - byte U_r[] = new byte[hLen]; - - // U0 = S || INT (i); - byte U_i[] = new byte[S.length + 4]; - System.arraycopy(S, 0, U_i, 0, S.length); - INT(U_i, S.length, blockIndex); - - for (int i = 0; i < c; i++) { - U_i = prf.doFinal(U_i); - xor(U_r, U_i); - } - System.arraycopy(U_r, 0, dest, offset, hLen); - } - - /** - * Block-Xor. Xor source bytes into destination byte buffer. Destination - * buffer must be same length or less than source buffer. - * - * @param dest byte array - * @param src byte array - */ - protected void xor(byte[] dest, byte[] src) { - for (int i = 0; i < dest.length; i++) { - dest[i] ^= src[i]; - } - } - - /** - * Four-octet encoding of the integer i, most significant octet first. - * - * @param dest byte array - * @param offset Integer - * @param i Integer - * - * @see RFC 2898 5.2 Step - * 3. - */ - protected void INT(byte[] dest, int offset, int i) { - dest[offset] = (byte) (i / (256 * 256 * 256)); - dest[offset + 1] = (byte) (i / (256 * 256)); - dest[offset + 2] = (byte) (i / (256)); - dest[offset + 3] = (byte) (i); - } - - @Override - public PBKDF2Parameters getParameters() { - return parameters; - } - - @Override - public void setParameters(PBKDF2Parameters parameters) { - this.parameters = parameters; - } -} diff --git a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Formatter.java b/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Formatter.java deleted file mode 100644 index 3916d1c0..00000000 --- a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Formatter.java +++ /dev/null @@ -1,56 +0,0 @@ -package fr.xephi.authme.security.pbkdf2; - -/** - *

    - * A free Java implementation of Password Based Key Derivation Function 2 as - * defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner - *

    - *

    - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - *

    - *

    - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - *

    - *

    - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - *

    - *

    - * For Details, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. - *

    - * - * @author Matthias Gärtner - * @version 1.0 - */ -public interface PBKDF2Formatter { - - /** - * Convert parameters to String. - * - * @param p Parameters object to output. - * - * @return String representation - */ - String toString(PBKDF2Parameters p); - - /** - * Convert String to parameters. Depending on actual implementation, it may - * be required to set further fields externally. - * - * @param s String representation of parameters to decode. - * @param p PBKDF2Parameters - * - * @return false syntax OK, true some syntax - * issue. - */ - boolean fromString(PBKDF2Parameters p, String s); -} diff --git a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2HexFormatter.java b/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2HexFormatter.java deleted file mode 100644 index 54544a4c..00000000 --- a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2HexFormatter.java +++ /dev/null @@ -1,62 +0,0 @@ -package fr.xephi.authme.security.pbkdf2; - -/** - *

    - * A free Java implementation of Password Based Key Derivation Function 2 as - * defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner - *

    - *

    - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - *

    - *

    - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - *

    - *

    - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - *

    - *

    - * For Details, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. - *

    - * - * @author Matthias Gärtner - * @version 1.0 - */ -public class PBKDF2HexFormatter implements PBKDF2Formatter { - - @Override - public boolean fromString(PBKDF2Parameters p, String s) { - if (p == null || s == null) { - return true; - } - - String[] p123 = s.split(":"); - if (p123.length != 3) { - return true; - } - - byte salt[] = BinTools.hex2bin(p123[0]); - int iterationCount = Integer.parseInt(p123[1]); - byte bDK[] = BinTools.hex2bin(p123[2]); - - p.setSalt(salt); - p.setIterationCount(iterationCount); - p.setDerivedKey(bDK); - return false; - } - - @Override - public String toString(PBKDF2Parameters p) { - String s = BinTools.bin2hex(p.getSalt()) + ":" + String.valueOf(p.getIterationCount()) + ":" + BinTools.bin2hex(p.getDerivedKey()); - return s; - } -} diff --git a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Parameters.java b/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Parameters.java deleted file mode 100644 index 04abaa9f..00000000 --- a/src/main/java/fr/xephi/authme/security/pbkdf2/PBKDF2Parameters.java +++ /dev/null @@ -1,139 +0,0 @@ -package fr.xephi.authme.security.pbkdf2; - -/** - *

    - * Parameter data holder for PBKDF2 configuration. - *

    - *

    - * A free Java implementation of Password Based Key Derivation Function 2 as - * defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner - *

    - *

    - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - *

    - *

    - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - *

    - *

    - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - *

    - *

    - * For Details, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. - *

    - * - * @author Matthias Gärtner - * @version 1.0 - */ -public class PBKDF2Parameters { - - protected byte[] salt; - - protected int iterationCount; - - protected String hashAlgorithm; - - protected String hashCharset; - - /** - * The derived key is actually only a convenience to store a reference - * derived key. It is not used during computation. - */ - protected byte[] derivedKey; - - /** - * Constructor. Defaults to null for byte arrays, UTF-8 as - * character set and 1000 for iteration count. - */ - public PBKDF2Parameters() { - this.hashAlgorithm = null; - this.hashCharset = "UTF-8"; - this.salt = null; - this.iterationCount = 1000; - this.derivedKey = null; - } - - /** - * Constructor. - * - * @param hashAlgorithm for example HMacSHA1 or HMacMD5 - * @param hashCharset for example UTF-8 - * @param salt Salt as byte array, may be null (not recommended) - * @param iterationCount Number of iterations to execute. Recommended value 1000. - */ - public PBKDF2Parameters(String hashAlgorithm, String hashCharset, - byte[] salt, int iterationCount) { - this.hashAlgorithm = hashAlgorithm; - this.hashCharset = hashCharset; - this.salt = salt; - this.iterationCount = iterationCount; - this.derivedKey = null; - } - - /** - * Constructor. - * - * @param hashAlgorithm for example HMacSHA1 or HMacMD5 - * @param hashCharset for example UTF-8 - * @param salt Salt as byte array, may be null (not recommended) - * @param iterationCount Number of iterations to execute. Recommended value 1000. - * @param derivedKey Convenience data holder, not used during computation. - */ - public PBKDF2Parameters(String hashAlgorithm, String hashCharset, - byte[] salt, int iterationCount, byte[] derivedKey) { - this.hashAlgorithm = hashAlgorithm; - this.hashCharset = hashCharset; - this.salt = salt; - this.iterationCount = iterationCount; - this.derivedKey = derivedKey; - } - - public int getIterationCount() { - return iterationCount; - } - - public void setIterationCount(int iterationCount) { - this.iterationCount = iterationCount; - } - - public byte[] getSalt() { - return salt; - } - - public void setSalt(byte[] salt) { - this.salt = salt; - } - - public byte[] getDerivedKey() { - return derivedKey; - } - - public void setDerivedKey(byte[] derivedKey) { - this.derivedKey = derivedKey; - } - - public String getHashAlgorithm() { - return hashAlgorithm; - } - - public void setHashAlgorithm(String hashAlgorithm) { - this.hashAlgorithm = hashAlgorithm; - } - - public String getHashCharset() { - return hashCharset; - } - - public void setHashCharset(String hashCharset) { - this.hashCharset = hashCharset; - } -} diff --git a/src/main/java/fr/xephi/authme/security/pbkdf2/PRF.java b/src/main/java/fr/xephi/authme/security/pbkdf2/PRF.java deleted file mode 100644 index af40e171..00000000 --- a/src/main/java/fr/xephi/authme/security/pbkdf2/PRF.java +++ /dev/null @@ -1,60 +0,0 @@ -package fr.xephi.authme.security.pbkdf2; - -/** - *

    - * A free Java implementation of Password Based Key Derivation Function 2 as - * defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner - *

    - *

    - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) - * any later version. - *

    - *

    - * This library is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - *

    - *

    - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - *

    - *

    - * For Details, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. - *

    - * - * @author Matthias Gärtner - * @version 1.0 - */ -public interface PRF { - - /** - * Initialize this instance with the user-supplied password. - * - * @param P The password supplied as array of bytes. It is the caller's - * task to convert String passwords to bytes as appropriate. - */ - void init(byte[] P); - - /** - * Pseudo Random Function - * - * @param M Input data/message etc. Together with any data supplied during - * initilization. - * - * @return Random bytes of hLen length. - */ - byte[] doFinal(byte[] M); - - /** - * Query block size of underlying algorithm/mechanism. - * - * @return block size - */ - int getHLen(); -} diff --git a/src/test/java/fr/xephi/authme/security/crypts/AbstractEncryptionMethodTest.java b/src/test/java/fr/xephi/authme/security/crypts/AbstractEncryptionMethodTest.java index 4c06a8cc..24093721 100644 --- a/src/test/java/fr/xephi/authme/security/crypts/AbstractEncryptionMethodTest.java +++ b/src/test/java/fr/xephi/authme/security/crypts/AbstractEncryptionMethodTest.java @@ -2,7 +2,9 @@ package fr.xephi.authme.security.crypts; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import fr.xephi.authme.TestHelper; import fr.xephi.authme.security.crypts.description.AsciiRestricted; +import org.junit.BeforeClass; import org.junit.Test; import java.util.List; @@ -100,6 +102,11 @@ public abstract class AbstractEncryptionMethodTest { GIVEN_PASSWORDS[3], result3); } + @BeforeClass + public static void setupLogger() { + TestHelper.setupLogger(); + } + @Test public void testGivenPasswords() { // Start with the 2nd to last password if we skip long tests diff --git a/src/test/java/fr/xephi/authme/security/crypts/BcryptTest.java b/src/test/java/fr/xephi/authme/security/crypts/BcryptTest.java index 3c0f1475..1fe9ed08 100644 --- a/src/test/java/fr/xephi/authme/security/crypts/BcryptTest.java +++ b/src/test/java/fr/xephi/authme/security/crypts/BcryptTest.java @@ -1,9 +1,7 @@ package fr.xephi.authme.security.crypts; -import fr.xephi.authme.TestHelper; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.HooksSettings; -import org.junit.BeforeClass; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; @@ -13,11 +11,6 @@ import static org.mockito.Mockito.mock; */ public class BcryptTest extends AbstractEncryptionMethodTest { - @BeforeClass - public static void initializeLogger() { - TestHelper.setupLogger(); - } - public BcryptTest() { super(new BCRYPT(mockSettings()), "$2a$10$6iATmYgwJVc3YONhVcZFve3Cfb5GnwvKhJ20r.hMjmcNkIT9.Uh9K", // password diff --git a/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2DjangoTest.java b/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2DjangoTest.java index 1da3c5b9..afff6bf8 100644 --- a/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2DjangoTest.java +++ b/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2DjangoTest.java @@ -1,18 +1,10 @@ package fr.xephi.authme.security.crypts; -import fr.xephi.authme.TestHelper; -import org.junit.BeforeClass; - /** * Test for {@link CryptPBKDF2Django}. */ public class CryptPBKDF2DjangoTest extends AbstractEncryptionMethodTest { - @BeforeClass - public static void setupLogger() { - TestHelper.setupLogger(); - } - public CryptPBKDF2DjangoTest() { super(new CryptPBKDF2Django(), "pbkdf2_sha256$15000$50a7ff2d7e00$t7Qx2CfzMhGEbyCa3Wk5nJvNjj3N+FdxhpwJDerl4Fs=", // password diff --git a/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2Test.java b/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2Test.java index 36ce7106..fcfd4d75 100644 --- a/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2Test.java +++ b/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2Test.java @@ -1,20 +1,16 @@ package fr.xephi.authme.security.crypts; -import org.junit.Ignore; - /** * Test for {@link CryptPBKDF2}. */ -@Ignore -// TODO #685: This algorithm seems broken public class CryptPBKDF2Test extends AbstractEncryptionMethodTest { public CryptPBKDF2Test() { super(new CryptPBKDF2(), - "pbkdf2_sha256$10000$dd9b1cd071f2$[82, -69, -58, -51, 101, 105, 61, -48, -49, 25, 50, -126, 115, 36, 16, -94, 4, 84, -94, 13, -115, -12, 94, -27, 94, -103, 115, -31, -56, -18, 8, 77, 36, 78, -61, 105, -7, -114, 41, 3, 48, 122, 27, 1, 56, 76, 126, 68, -120, 127, -95, 119, -7, 100, -87, -128, -77, 83, -118, 28, 43, 84, 73, 103]", // password - "pbkdf2_sha256$10000$4b3b650288cd$[99, 25, 45, 22, -66, -109, -109, 30, 117, 77, 22, 63, -36, -126, -116, -66, 35, 109, -33, -4, -112, 53, 48, 33, -20, 107, -100, -37, -89, 59, -29, -83, 57, -123, -40, 11, 98, 32, -74, 77, 107, -76, 95, -9, 110, -92, -31, -2, -18, 115, 43, -27, 16, 36, 75, -56, -11, 58, -62, 21, 0, 37, -59, -82]", // PassWord1 - "pbkdf2_sha256$10000$035205f5ab39$[-121, -15, 97, 35, -105, -57, -49, -60, -58, -106, 101, 78, -103, 2, -116, -120, 0, 106, -107, 10, 78, -97, 111, 98, -15, 40, -53, 84, 120, -86, 116, 12, -60, 19, 105, 1, 71, 99, 4, 43, -4, -36, 35, -110, 59, 73, -20, -8, 46, 102, 51, 84, 54, -92, -41, -84, 28, 36, 37, 26, 90, -6, -49, 70]", // &^%te$t?Pw@_ - "pbkdf2_sha256$10000$ca72ded579e9$[-81, 76, -103, 78, 68, -10, -58, -88, -57, 88, -38, 108, 115, -86, 13, -84, 80, 69, 48, 15, 105, 25, -2, 123, 9, 97, 23, -96, 95, -64, -56, 59, -124, 116, 36, 10, 96, -12, -76, -121, -51, 76, -96, -27, 84, 66, 85, 75, 95, -97, -60, -98, -41, -32, -58, 39, 82, -19, -25, 98, -15, -68, 59, -48]"); // âË_3(íù* + "pbkdf2_sha256$10000$b25801311edf$093E38B16DFF13FCE5CD64D5D888EE6E0376A3E572FE5DA6749515EA0F384413223A21C464B0BE899E64084D1FFEFD44F2AC768453C87F41B42CC6954C416900", // password + "pbkdf2_sha256$10000$fe705da06c57$A41527BD58FED9C9E6F452FC1BA8B0C4C4224ECC63E37F71EB1A0865D2AB81BBFEBCA9B7B6A6E8AEF4717B43F8EB6FB4EDEFFBB399D9D991EF7E23013595BAF0", // PassWord1 + "pbkdf2_sha256$10000$05603593cdda$1D30D1D90D826C866755969F06C312E21CC3E8DA0B777E2C764700E4E1FD890B731FAF44753D68F3FC025D3EAA709E800FBF2AF61DB23464311FCE7D35353A30", // &^%te$t?Pw@_ + "pbkdf2_sha256$10000$fb944d66d754$F7E3BF8CB07CE3B3C8C5C534F803252F7B4FD58832E33BA62BA46CA06F23BAE12BE03A9CB5874BCFD4469E42972406F920E59F002247B23C22A8CF3D0E7BFFE0"); // âË_3(íù* } } diff --git a/src/test/java/fr/xephi/authme/security/crypts/IPB4Test.java b/src/test/java/fr/xephi/authme/security/crypts/IPB4Test.java index 325d37d5..28c76a09 100644 --- a/src/test/java/fr/xephi/authme/security/crypts/IPB4Test.java +++ b/src/test/java/fr/xephi/authme/security/crypts/IPB4Test.java @@ -1,18 +1,10 @@ package fr.xephi.authme.security.crypts; -import fr.xephi.authme.TestHelper; -import org.junit.BeforeClass; - /** * Test for {@link IPB4}. */ public class IPB4Test extends AbstractEncryptionMethodTest { - @BeforeClass - public static void setUpSettings() { - TestHelper.setupLogger(); - } - public IPB4Test() { super(new IPB4(), new HashedPassword("$2a$13$leEvXu77OIwPwNvtZIJvaeAx8EItGHuR3nIlq8416g0gXeJaQdrr2", "leEvXu77OIwPwNvtZIJval"), //password diff --git a/src/test/java/fr/xephi/authme/security/crypts/XFBCRYPTTest.java b/src/test/java/fr/xephi/authme/security/crypts/XFBCRYPTTest.java index bda1c0f8..4edafbdd 100644 --- a/src/test/java/fr/xephi/authme/security/crypts/XFBCRYPTTest.java +++ b/src/test/java/fr/xephi/authme/security/crypts/XFBCRYPTTest.java @@ -1,18 +1,10 @@ package fr.xephi.authme.security.crypts; -import fr.xephi.authme.TestHelper; -import org.junit.BeforeClass; - /** * Test for {@link XFBCRYPT}. */ public class XFBCRYPTTest extends AbstractEncryptionMethodTest { - @BeforeClass - public static void setup() { - TestHelper.setupLogger(); - } - public XFBCRYPTTest() { super(new XFBCRYPT(), "$2a$10$UtuON/ZG.x8EWG/zQbryB.BHfQVrfxk3H7qykzP.UJQ8YiLjZyfqq", // password From 122c6586bcc17a06f4aeffa88adf8e399276927b Mon Sep 17 00:00:00 2001 From: ljacqu Date: Fri, 25 Nov 2016 16:41:55 +0100 Subject: [PATCH 55/67] #685 Add php implementation for PBKDF2 - Create php sample for PBKDF2 - Rename pbkdf2 java classes (remove Crypt prefix) - Remove options from hash setting comment that should not be used --- .../website_integration/AuthMeController.php | 1 - samples/website_integration/Pbkdf2.php | 53 +++++++++++++++++++ samples/website_integration/Sha256.php | 4 +- .../xephi/authme/security/HashAlgorithm.java | 9 ++-- .../crypts/{CryptPBKDF2.java => Pbkdf2.java} | 2 +- ...yptPBKDF2Django.java => Pbkdf2Django.java} | 4 +- .../settings/properties/SecuritySettings.java | 7 +-- ...2DjangoTest.java => Pbkdf2DjangoTest.java} | 8 +-- .../{CryptPBKDF2Test.java => Pbkdf2Test.java} | 8 +-- 9 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 samples/website_integration/Pbkdf2.php rename src/main/java/fr/xephi/authme/security/crypts/{CryptPBKDF2.java => Pbkdf2.java} (96%) rename src/main/java/fr/xephi/authme/security/crypts/{CryptPBKDF2Django.java => Pbkdf2Django.java} (95%) rename src/test/java/fr/xephi/authme/security/crypts/{CryptPBKDF2DjangoTest.java => Pbkdf2DjangoTest.java} (72%) rename src/test/java/fr/xephi/authme/security/crypts/{CryptPBKDF2Test.java => Pbkdf2Test.java} (83%) diff --git a/samples/website_integration/AuthMeController.php b/samples/website_integration/AuthMeController.php index 66fe03b4..f67cf060 100644 --- a/samples/website_integration/AuthMeController.php +++ b/samples/website_integration/AuthMeController.php @@ -109,7 +109,6 @@ abstract class AuthMeController { * @return string|null the hash, or null if unavailable (e.g. username doesn't exist) */ private function getHashFromDatabase($username) { - // Add here your database host, username, password and database name $mysqli = $this->getAuthmeMySqli(); if ($mysqli !== null) { $stmt = $mysqli->prepare('SELECT password FROM ' . self::AUTHME_TABLE . ' WHERE username = ?'); diff --git a/samples/website_integration/Pbkdf2.php b/samples/website_integration/Pbkdf2.php new file mode 100644 index 00000000..456c004f --- /dev/null +++ b/samples/website_integration/Pbkdf2.php @@ -0,0 +1,53 @@ +CHARS = self::initCharRange(); + } + + protected function isValidPassword($password, $hash) { + // hash := pbkdf2_sha256$iterations$salt$hash + $parts = explode('$', $hash); + return count($parts) === 4 && $hash === $this->computeHash($parts[1], $parts[2], $password); + } + + protected function hash($password) { + $salt = $this->generateSalt(); + return $this->computeHash(self::NUMBER_OF_ITERATIONS, $salt, $password); + } + + private function computeHash($iterations, $salt, $password) { + return 'pbkdf2_sha256$' . self::NUMBER_OF_ITERATIONS . '$' . $salt + . '$' . hash_pbkdf2('sha256', $password, $salt, self::NUMBER_OF_ITERATIONS, 64, false); + } + + /** + * @return string randomly generated salt + */ + private function generateSalt() { + $maxCharIndex = count($this->CHARS) - 1; + $salt = ''; + for ($i = 0; $i < self::SALT_LENGTH; ++$i) { + $salt .= $this->CHARS[mt_rand(0, $maxCharIndex)]; + } + return $salt; + } + + private static function initCharRange() { + return array_merge(range('0', '9'), range('a', 'f')); + } +} diff --git a/samples/website_integration/Sha256.php b/samples/website_integration/Sha256.php index 815abe59..80c0588f 100644 --- a/samples/website_integration/Sha256.php +++ b/samples/website_integration/Sha256.php @@ -15,7 +15,7 @@ class Sha256 extends AuthMeController { const SALT_LENGTH = 16; public function __construct() { - $this->CHARS = self::initRandomChars(); + $this->CHARS = self::initCharRange(); } protected function isValidPassword($password, $hash) { @@ -41,7 +41,7 @@ class Sha256 extends AuthMeController { return $salt; } - private static function initRandomChars() { + private static function initCharRange() { return array_merge(range('0', '9'), range('a', 'f')); } diff --git a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java index 7bb5681f..2cfc1b4b 100644 --- a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java +++ b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java @@ -1,10 +1,11 @@ package fr.xephi.authme.security; import fr.xephi.authme.security.crypts.EncryptionMethod; +import fr.xephi.authme.security.crypts.Pbkdf2; +import fr.xephi.authme.security.crypts.Pbkdf2Django; /** - * The list of hash algorithms supported by AuthMe. The linked {@link EncryptionMethod} implementation - * must be able to be instantiated with the default constructor. + * Hash algorithms supported by AuthMe. */ public enum HashAlgorithm { @@ -18,8 +19,8 @@ public enum HashAlgorithm { MD5(fr.xephi.authme.security.crypts.MD5.class), MD5VB(fr.xephi.authme.security.crypts.MD5VB.class), MYBB(fr.xephi.authme.security.crypts.MYBB.class), - PBKDF2(fr.xephi.authme.security.crypts.CryptPBKDF2.class), - PBKDF2DJANGO(fr.xephi.authme.security.crypts.CryptPBKDF2Django.class), + PBKDF2(Pbkdf2.class), + PBKDF2DJANGO(Pbkdf2Django.class), PHPBB(fr.xephi.authme.security.crypts.PHPBB.class), PHPFUSION(fr.xephi.authme.security.crypts.PHPFUSION.class), @Deprecated diff --git a/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2.java b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java similarity index 96% rename from src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2.java rename to src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java index 90cfd809..6b4dd625 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2.java +++ b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java @@ -7,7 +7,7 @@ import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Usage; @Recommendation(Usage.RECOMMENDED) -public class CryptPBKDF2 extends HexSaltedMethod { +public class Pbkdf2 extends HexSaltedMethod { private static final int NUMBER_OF_ITERATIONS = 10_000; diff --git a/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2Django.java b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java similarity index 95% rename from src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2Django.java rename to src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java index 6628ca91..528c1eb1 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/CryptPBKDF2Django.java +++ b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java @@ -9,7 +9,7 @@ import fr.xephi.authme.util.StringUtils; import javax.xml.bind.DatatypeConverter; @AsciiRestricted -public class CryptPBKDF2Django extends HexSaltedMethod { +public class Pbkdf2Django extends HexSaltedMethod { private static final int DEFAULT_ITERATIONS = 24000; @@ -32,7 +32,7 @@ public class CryptPBKDF2Django extends HexSaltedMethod { try { iterations = Integer.parseInt(line[1]); } catch (NumberFormatException e) { - ConsoleLogger.warning("Could not read number of rounds for CryptPBKDF2Django:" + ConsoleLogger.warning("Could not read number of rounds for Pbkdf2Django:" + StringUtils.formatException(e)); return false; } diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java index 3711715d..80b0fdf1 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java @@ -64,9 +64,10 @@ public class SecuritySettings implements SettingsHolder { newProperty("settings.security.unLoggedinGroup", "unLoggedinGroup"); @Comment({ - "Possible values: MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB,", - "MYBB, IPB3, PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512,", - "DOUBLEMD5, PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only)" + "Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512, WHIRLPOOL,", + "MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,", + "PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only). See full list at", + "https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md" }) public static final Property PASSWORD_HASH = newProperty(HashAlgorithm.class, "settings.security.passwordHash", HashAlgorithm.SHA256); diff --git a/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2DjangoTest.java b/src/test/java/fr/xephi/authme/security/crypts/Pbkdf2DjangoTest.java similarity index 72% rename from src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2DjangoTest.java rename to src/test/java/fr/xephi/authme/security/crypts/Pbkdf2DjangoTest.java index afff6bf8..a5a1af61 100644 --- a/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2DjangoTest.java +++ b/src/test/java/fr/xephi/authme/security/crypts/Pbkdf2DjangoTest.java @@ -1,12 +1,12 @@ package fr.xephi.authme.security.crypts; /** - * Test for {@link CryptPBKDF2Django}. + * Test for {@link Pbkdf2Django}. */ -public class CryptPBKDF2DjangoTest extends AbstractEncryptionMethodTest { +public class Pbkdf2DjangoTest extends AbstractEncryptionMethodTest { - public CryptPBKDF2DjangoTest() { - super(new CryptPBKDF2Django(), + public Pbkdf2DjangoTest() { + super(new Pbkdf2Django(), "pbkdf2_sha256$15000$50a7ff2d7e00$t7Qx2CfzMhGEbyCa3Wk5nJvNjj3N+FdxhpwJDerl4Fs=", // password "pbkdf2_sha256$15000$f9d8a58f3fe2$oMqmMGuJetdubW0cpubmT8CltQLjHT+L2GuwKsaWLx8=", // PassWord1 "pbkdf2_sha256$15000$1170bc7a31f5$Ex/2aQsXm4kogLIYARpUPn04ccK5LYYjyVPpl32ALjE=", // &^%te$t?Pw@_ diff --git a/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2Test.java b/src/test/java/fr/xephi/authme/security/crypts/Pbkdf2Test.java similarity index 83% rename from src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2Test.java rename to src/test/java/fr/xephi/authme/security/crypts/Pbkdf2Test.java index fcfd4d75..1d7b8de7 100644 --- a/src/test/java/fr/xephi/authme/security/crypts/CryptPBKDF2Test.java +++ b/src/test/java/fr/xephi/authme/security/crypts/Pbkdf2Test.java @@ -1,12 +1,12 @@ package fr.xephi.authme.security.crypts; /** - * Test for {@link CryptPBKDF2}. + * Test for {@link Pbkdf2}. */ -public class CryptPBKDF2Test extends AbstractEncryptionMethodTest { +public class Pbkdf2Test extends AbstractEncryptionMethodTest { - public CryptPBKDF2Test() { - super(new CryptPBKDF2(), + public Pbkdf2Test() { + super(new Pbkdf2(), "pbkdf2_sha256$10000$b25801311edf$093E38B16DFF13FCE5CD64D5D888EE6E0376A3E572FE5DA6749515EA0F384413223A21C464B0BE899E64084D1FFEFD44F2AC768453C87F41B42CC6954C416900", // password "pbkdf2_sha256$10000$fe705da06c57$A41527BD58FED9C9E6F452FC1BA8B0C4C4224ECC63E37F71EB1A0865D2AB81BBFEBCA9B7B6A6E8AEF4717B43F8EB6FB4EDEFFBB399D9D991EF7E23013595BAF0", // PassWord1 "pbkdf2_sha256$10000$05603593cdda$1D30D1D90D826C866755969F06C312E21CC3E8DA0B777E2C764700E4E1FD890B731FAF44753D68F3FC025D3EAA709E800FBF2AF61DB23464311FCE7D35353A30", // &^%te$t?Pw@_ From 5ec1c3fe24cfec1ec73492fdd82bd2f58854f6b7 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 26 Nov 2016 16:34:14 +0100 Subject: [PATCH 56/67] #1018 Load group names when AuthGroupHandler is constructed --- src/main/java/fr/xephi/authme/permission/AuthGroupHandler.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/fr/xephi/authme/permission/AuthGroupHandler.java b/src/main/java/fr/xephi/authme/permission/AuthGroupHandler.java index 492c6911..537c3ebc 100644 --- a/src/main/java/fr/xephi/authme/permission/AuthGroupHandler.java +++ b/src/main/java/fr/xephi/authme/permission/AuthGroupHandler.java @@ -10,6 +10,7 @@ import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.SecuritySettings; import org.bukkit.entity.Player; +import javax.annotation.PostConstruct; import javax.inject.Inject; import java.util.Arrays; @@ -115,6 +116,7 @@ public class AuthGroupHandler implements Reloadable { } @Override + @PostConstruct public void reload() { unloggedInGroup = settings.getProperty(SecuritySettings.UNLOGGEDIN_GROUP); unregisteredGroup = settings.getProperty(HooksSettings.UNREGISTERED_GROUP); From 79a3858b291801ae9b1f364049d71cd0afae6f6c Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 26 Nov 2016 18:41:04 +0100 Subject: [PATCH 57/67] #685 Allow to configure number of rounds for PBKDF2 --- .../xephi/authme/security/HashAlgorithm.java | 6 ++-- .../xephi/authme/security/crypts/Pbkdf2.java | 27 ++++++++++++++--- .../authme/security/crypts/Pbkdf2Django.java | 4 +-- .../settings/properties/SecuritySettings.java | 4 +++ .../HashAlgorithmIntegrationTest.java | 1 + .../authme/security/crypts/Pbkdf2Test.java | 30 ++++++++++++++++++- 6 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java index 2cfc1b4b..732582e0 100644 --- a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java +++ b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java @@ -1,8 +1,6 @@ package fr.xephi.authme.security; import fr.xephi.authme.security.crypts.EncryptionMethod; -import fr.xephi.authme.security.crypts.Pbkdf2; -import fr.xephi.authme.security.crypts.Pbkdf2Django; /** * Hash algorithms supported by AuthMe. @@ -19,8 +17,8 @@ public enum HashAlgorithm { MD5(fr.xephi.authme.security.crypts.MD5.class), MD5VB(fr.xephi.authme.security.crypts.MD5VB.class), MYBB(fr.xephi.authme.security.crypts.MYBB.class), - PBKDF2(Pbkdf2.class), - PBKDF2DJANGO(Pbkdf2Django.class), + PBKDF2(fr.xephi.authme.security.crypts.Pbkdf2.class), + PBKDF2DJANGO(fr.xephi.authme.security.crypts.Pbkdf2Django.class), PHPBB(fr.xephi.authme.security.crypts.PHPBB.class), PHPFUSION(fr.xephi.authme.security.crypts.PHPFUSION.class), @Deprecated diff --git a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java index 6b4dd625..5367a2a1 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java +++ b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2.java @@ -3,18 +3,30 @@ package fr.xephi.authme.security.crypts; import de.rtner.misc.BinTools; import de.rtner.security.auth.spi.PBKDF2Engine; import de.rtner.security.auth.spi.PBKDF2Parameters; +import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.security.crypts.description.Recommendation; import fr.xephi.authme.security.crypts.description.Usage; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.SecuritySettings; + +import javax.inject.Inject; @Recommendation(Usage.RECOMMENDED) public class Pbkdf2 extends HexSaltedMethod { - private static final int NUMBER_OF_ITERATIONS = 10_000; + private static final int DEFAULT_ROUNDS = 10_000; + private int numberOfRounds; + + @Inject + Pbkdf2(Settings settings) { + int configuredRounds = settings.getProperty(SecuritySettings.PBKDF2_NUMBER_OF_ROUNDS); + this.numberOfRounds = configuredRounds > 0 ? configuredRounds : DEFAULT_ROUNDS; + } @Override public String computeHash(String password, String salt, String name) { - String result = "pbkdf2_sha256$" + NUMBER_OF_ITERATIONS + "$" + salt + "$"; - PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), NUMBER_OF_ITERATIONS); + String result = "pbkdf2_sha256$" + numberOfRounds + "$" + salt + "$"; + PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), numberOfRounds); PBKDF2Engine engine = new PBKDF2Engine(params); return result + BinTools.bin2hex(engine.deriveKey(password, 64)); @@ -26,9 +38,16 @@ public class Pbkdf2 extends HexSaltedMethod { if (line.length != 4) { return false; } + int iterations; + try { + iterations = Integer.parseInt(line[1]); + } catch (NumberFormatException e) { + ConsoleLogger.logException("Cannot read number of rounds for Pbkdf2", e); + return false; + } String salt = line[2]; byte[] derivedKey = BinTools.hex2bin(line[3]); - PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), 10000, derivedKey); + PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), iterations, derivedKey); PBKDF2Engine engine = new PBKDF2Engine(params); return engine.verifyKey(password); } diff --git a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java index 528c1eb1..93988e0d 100644 --- a/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java +++ b/src/main/java/fr/xephi/authme/security/crypts/Pbkdf2Django.java @@ -4,7 +4,6 @@ import de.rtner.security.auth.spi.PBKDF2Engine; import de.rtner.security.auth.spi.PBKDF2Parameters; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.security.crypts.description.AsciiRestricted; -import fr.xephi.authme.util.StringUtils; import javax.xml.bind.DatatypeConverter; @@ -32,8 +31,7 @@ public class Pbkdf2Django extends HexSaltedMethod { try { iterations = Integer.parseInt(line[1]); } catch (NumberFormatException e) { - ConsoleLogger.warning("Could not read number of rounds for Pbkdf2Django:" - + StringUtils.formatException(e)); + ConsoleLogger.logException("Could not read number of rounds for Pbkdf2Django:", e); return false; } String salt = line[2]; diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java index 80b0fdf1..5bad44b0 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java @@ -86,6 +86,10 @@ public class SecuritySettings implements SettingsHolder { public static final Property> LEGACY_HASHES = new EnumSetProperty<>(HashAlgorithm.class, "settings.security.legacyHashes"); + @Comment("Number of rounds to use if passwordHash is set to PBKDF2. Default is 10000") + public static final Property PBKDF2_NUMBER_OF_ROUNDS = + newProperty("settings.security.pbkdf2Rounds", 10000); + @Comment({"Prevent unsafe passwords from being used; put them in lowercase!", "You should always set 'help' as unsafePassword due to possible conflicts.", "unsafePasswords:", diff --git a/src/test/java/fr/xephi/authme/security/HashAlgorithmIntegrationTest.java b/src/test/java/fr/xephi/authme/security/HashAlgorithmIntegrationTest.java index fcfa4fad..2d536819 100644 --- a/src/test/java/fr/xephi/authme/security/HashAlgorithmIntegrationTest.java +++ b/src/test/java/fr/xephi/authme/security/HashAlgorithmIntegrationTest.java @@ -32,6 +32,7 @@ public class HashAlgorithmIntegrationTest { Settings settings = mock(Settings.class); given(settings.getProperty(HooksSettings.BCRYPT_LOG2_ROUND)).willReturn(8); given(settings.getProperty(SecuritySettings.DOUBLE_MD5_SALT_LENGTH)).willReturn(16); + given(settings.getProperty(SecuritySettings.PBKDF2_NUMBER_OF_ROUNDS)).willReturn(10_000); injector = new InjectorBuilder().addDefaultHandlers("fr.xephi.authme").create(); injector.register(Settings.class, settings); } diff --git a/src/test/java/fr/xephi/authme/security/crypts/Pbkdf2Test.java b/src/test/java/fr/xephi/authme/security/crypts/Pbkdf2Test.java index 1d7b8de7..8296e56e 100644 --- a/src/test/java/fr/xephi/authme/security/crypts/Pbkdf2Test.java +++ b/src/test/java/fr/xephi/authme/security/crypts/Pbkdf2Test.java @@ -1,16 +1,44 @@ package fr.xephi.authme.security.crypts; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.SecuritySettings; +import org.junit.Test; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + /** * Test for {@link Pbkdf2}. */ public class Pbkdf2Test extends AbstractEncryptionMethodTest { public Pbkdf2Test() { - super(new Pbkdf2(), + super(new Pbkdf2(mockSettings()), "pbkdf2_sha256$10000$b25801311edf$093E38B16DFF13FCE5CD64D5D888EE6E0376A3E572FE5DA6749515EA0F384413223A21C464B0BE899E64084D1FFEFD44F2AC768453C87F41B42CC6954C416900", // password "pbkdf2_sha256$10000$fe705da06c57$A41527BD58FED9C9E6F452FC1BA8B0C4C4224ECC63E37F71EB1A0865D2AB81BBFEBCA9B7B6A6E8AEF4717B43F8EB6FB4EDEFFBB399D9D991EF7E23013595BAF0", // PassWord1 "pbkdf2_sha256$10000$05603593cdda$1D30D1D90D826C866755969F06C312E21CC3E8DA0B777E2C764700E4E1FD890B731FAF44753D68F3FC025D3EAA709E800FBF2AF61DB23464311FCE7D35353A30", // &^%te$t?Pw@_ "pbkdf2_sha256$10000$fb944d66d754$F7E3BF8CB07CE3B3C8C5C534F803252F7B4FD58832E33BA62BA46CA06F23BAE12BE03A9CB5874BCFD4469E42972406F920E59F002247B23C22A8CF3D0E7BFFE0"); // âË_3(íù* } + @Test + public void shouldDetectMatchForHashWithOtherRoundNumber() { + // given + Pbkdf2 pbkdf2 = new Pbkdf2(mockSettings()); + String hash = "pbkdf2_sha256$4128$3469b0d48b702046$DC8A54351008C6054E12FB19E0BF8A4EA6D4165E0EDC97A1ECD15231037C382DE5BF85D07D5BC9D1ADF9BBFE4CE257C6059FB1B9FF65DB69D8B205F064BE0DA9"; + String clearText = "PassWord1"; + + // when + boolean isMatch = pbkdf2.comparePassword(clearText, new HashedPassword(hash), ""); + + // then + assertThat(isMatch, equalTo(true)); + } + + private static Settings mockSettings() { + Settings settings = mock(Settings.class); + given(settings.getProperty(SecuritySettings.PBKDF2_NUMBER_OF_ROUNDS)).willReturn(4128); + return settings; + } } From 808ed84269f3f16b699fbbcb865ce7f9875e9ba7 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Mon, 28 Nov 2016 21:51:31 +0100 Subject: [PATCH 58/67] #411 Finalize forced commands implementation --- .../xephi/authme/listener/PlayerListener.java | 16 ++------ .../authme/process/join/AsynchronousJoin.java | 39 ++++++++++--------- .../commandconfig/CommandManager.java | 24 ++++++++++-- ...ater.java => CommandMigrationService.java} | 4 +- .../commandconfig/CommandSettingsHolder.java | 1 + .../commandconfig/CommandManagerTest.java | 4 +- ....java => CommandMigrationServiceTest.java} | 12 +++--- .../CommandYmlConsistencyTest.java | 4 +- 8 files changed, 56 insertions(+), 48 deletions(-) rename src/main/java/fr/xephi/authme/settings/commandconfig/{CommandsMigrater.java => CommandMigrationService.java} (98%) rename src/test/java/fr/xephi/authme/settings/commandconfig/{CommandsMigraterTest.java => CommandMigrationServiceTest.java} (93%) diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index 9b3eda8e..c380fbe1 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -157,9 +157,7 @@ public class PlayerListener implements Listener { if (spawn != null && spawn.getWorld() != null) { if (!player.getWorld().equals(spawn.getWorld())) { player.teleport(spawn); - return; - } - if (spawn.distance(player.getLocation()) > settings.getProperty(ALLOWED_MOVEMENT_RADIUS)) { + } else if (spawn.distance(player.getLocation()) > settings.getProperty(ALLOWED_MOVEMENT_RADIUS)) { player.teleport(spawn); } } @@ -313,17 +311,9 @@ public class PlayerListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerInventoryClick(InventoryClickEvent event) { - if (event.getWhoClicked() == null) { - return; + if (listenerService.shouldCancelEvent(event.getWhoClicked())) { + event.setCancelled(true); } - if (!(event.getWhoClicked() instanceof Player)) { - return; - } - Player player = (Player) event.getWhoClicked(); - if (!listenerService.shouldCancelEvent(player)) { - return; - } - event.setCancelled(true); } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index 490bc9ba..cf70c386 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -15,6 +15,7 @@ import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.process.AsynchronousProcess; import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.process.login.AsynchronousLogin; +import fr.xephi.authme.settings.commandconfig.CommandManager; import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; @@ -67,6 +68,9 @@ public class AsynchronousJoin implements AsynchronousProcess { @Inject private AsynchronousLogin asynchronousLogin; + @Inject + private CommandManager commandManager; + AsynchronousJoin() { } @@ -150,26 +154,23 @@ public class AsynchronousJoin implements AsynchronousProcess { final int registrationTimeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND; - bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(new Runnable() { - @Override - public void run() { - player.setOp(false); - if (!service.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT) - && service.getProperty(RestrictionSettings.REMOVE_SPEED)) { - player.setFlySpeed(0.0f); - player.setWalkSpeed(0.0f); - } - player.setNoDamageTicks(registrationTimeout); - if (pluginHookService.isEssentialsAvailable() && service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) { - player.performCommand("motd"); - } - if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) { - // Allow infinite blindness effect - int blindTimeOut = (registrationTimeout <= 0) ? 99999 : registrationTimeout; - player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blindTimeOut, 2)); - } + bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() -> { + player.setOp(false); + if (!service.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT) + && service.getProperty(RestrictionSettings.REMOVE_SPEED)) { + player.setFlySpeed(0.0f); + player.setWalkSpeed(0.0f); } - + player.setNoDamageTicks(registrationTimeout); + if (pluginHookService.isEssentialsAvailable() && service.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)) { + player.performCommand("motd"); + } + if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) { + // Allow infinite blindness effect + int blindTimeOut = (registrationTimeout <= 0) ? 99999 : registrationTimeout; + player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, blindTimeOut, 2)); + } + commandManager.runCommandsOnJoin(player); }); // Timeout and message task diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java index 2b476c4a..f21f7e5c 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandManager.java @@ -19,26 +19,42 @@ public class CommandManager implements Reloadable { private final File dataFolder; private final BukkitService bukkitService; - private final CommandsMigrater commandsMigrater; + private final CommandMigrationService commandMigrationService; private CommandConfig commandConfig; @Inject - CommandManager(@DataFolder File dataFolder, BukkitService bukkitService, CommandsMigrater commandsMigrater) { + CommandManager(@DataFolder File dataFolder, BukkitService bukkitService, + CommandMigrationService commandMigrationService) { this.dataFolder = dataFolder; this.bukkitService = bukkitService; - this.commandsMigrater = commandsMigrater; + this.commandMigrationService = commandMigrationService; reload(); } + /** + * Runs the configured commands for when a player has joined. + * + * @param player the joining player + */ public void runCommandsOnJoin(Player player) { executeCommands(player, commandConfig.getOnJoin()); } + /** + * Runs the configured commands for when a player has successfully registered. + * + * @param player the player who has registered + */ public void runCommandsOnRegister(Player player) { executeCommands(player, commandConfig.getOnRegister()); } + /** + * Runs the configured commands for when a player has logged in successfully. + * + * @param player the player that logged in + */ public void runCommandsOnLogin(Player player) { executeCommands(player, commandConfig.getOnLogin()); } @@ -60,7 +76,7 @@ public class CommandManager implements Reloadable { FileUtils.copyFileFromResource(file, "commands.yml"); SettingsManager settingsManager = new SettingsManager( - new YamlFileResource(file), commandsMigrater, CommandSettingsHolder.class); + new YamlFileResource(file), commandMigrationService, CommandSettingsHolder.class); commandConfig = settingsManager.getProperty(CommandSettingsHolder.COMMANDS); } diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java similarity index 98% rename from src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java rename to src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java index a64260e0..6b357615 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandsMigrater.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandMigrationService.java @@ -17,12 +17,12 @@ import java.util.stream.Collectors; /** * Migrates the commands from their old location, in config.yml, to the dedicated commands configuration file. */ -class CommandsMigrater implements MigrationService { +class CommandMigrationService implements MigrationService { @Inject private SettingsMigrationService settingsMigrationService; - CommandsMigrater() { + CommandMigrationService() { } @Override diff --git a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java index 75906a32..99a1c6e8 100644 --- a/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java +++ b/src/main/java/fr/xephi/authme/settings/commandconfig/CommandSettingsHolder.java @@ -46,6 +46,7 @@ public final class CommandSettingsHolder implements SettingsHolder { "Supported command events: onLogin, onJoin, onRegister" }; Map commentMap = new HashMap<>(); + // TODO ConfigMe/#25 cannot set comments on the root ("") commentMap.put("onLogin", comments); return commentMap; } diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java index ec03cb19..7b9d1bfc 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java @@ -42,7 +42,7 @@ public class CommandManagerTest { private CommandManager manager; @InjectMocks - private CommandsMigrater commandsMigrater; + private CommandMigrationService commandMigrationService; @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @@ -158,7 +158,7 @@ public class CommandManagerTest { } private void initManager() { - manager = new CommandManager(testFolder, bukkitService, commandsMigrater); + manager = new CommandManager(testFolder, bukkitService, commandMigrationService); } private void copyJarFileAsCommandsYml(String path) { diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java similarity index 93% rename from src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java rename to src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java index 0dae65fe..d04fc89e 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandsMigraterTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java @@ -33,13 +33,13 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verifyZeroInteractions; /** - * Test for {@link CommandsMigrater}. + * Test for {@link CommandMigrationService}. */ @RunWith(MockitoJUnitRunner.class) -public class CommandsMigraterTest { +public class CommandMigrationServiceTest { @InjectMocks - private CommandsMigrater commandsMigrater; + private CommandMigrationService commandMigrationService; @Mock private SettingsMigrationService settingsMigrationService; @@ -62,7 +62,7 @@ public class CommandsMigraterTest { CommandConfig configSpy = spy(commandConfig); // when - boolean result = commandsMigrater.transformOldCommands(configSpy); + boolean result = commandMigrationService.transformOldCommands(configSpy); // then assertThat(result, equalTo(false)); @@ -92,7 +92,7 @@ public class CommandsMigraterTest { commandConfig.setOnRegister(onRegisterCommands); // when - boolean result = commandsMigrater.transformOldCommands(commandConfig); + boolean result = commandMigrationService.transformOldCommands(commandConfig); // then assertThat(result, equalTo(true)); @@ -122,7 +122,7 @@ public class CommandsMigraterTest { PropertyResource resource = new YamlFileResource(commandFile); // when - boolean result = commandsMigrater.checkAndMigrate( + boolean result = commandMigrationService.checkAndMigrate( resource, ConfigurationDataBuilder.collectData(CommandSettingsHolder.class).getProperties()); // then diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java index ff9e51da..0cb17fbc 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java @@ -28,7 +28,7 @@ import static org.mockito.BDDMockito.given; public class CommandYmlConsistencyTest { @InjectMocks - private CommandsMigrater commandsMigrater; + private CommandMigrationService commandMigrationService; @Mock private SettingsMigrationService settingsMigrationService; @@ -51,7 +51,7 @@ public class CommandYmlConsistencyTest { PropertyResource resource = new YamlFileResource(commandFile); // when - boolean result = commandsMigrater.checkAndMigrate( + boolean result = commandMigrationService.checkAndMigrate( resource, ConfigurationDataBuilder.collectData(CommandSettingsHolder.class).getProperties()); // then From a38d3a25b85dddd7b9f709a55804b96d327c9e8b Mon Sep 17 00:00:00 2001 From: ljacqu Date: Thu, 1 Dec 2016 19:41:31 +0100 Subject: [PATCH 59/67] Update Mockito version --- pom.xml | 2 +- src/test/java/fr/xephi/authme/AuthMeInitializationTest.java | 2 +- src/test/java/fr/xephi/authme/ConsoleLoggerTest.java | 2 +- src/test/java/fr/xephi/authme/api/NewAPITest.java | 2 +- src/test/java/fr/xephi/authme/command/CommandHandlerTest.java | 2 +- src/test/java/fr/xephi/authme/command/CommandServiceTest.java | 2 +- .../fr/xephi/authme/command/executable/HelpCommandTest.java | 2 +- .../authme/command/executable/authme/AccountsCommandTest.java | 2 +- .../executable/authme/ChangePasswordAdminCommandTest.java | 2 +- .../authme/command/executable/authme/ConverterCommandTest.java | 2 +- .../authme/command/executable/authme/FirstSpawnCommandTest.java | 2 +- .../authme/command/executable/authme/ForceLoginCommandTest.java | 2 +- .../authme/command/executable/authme/GetEmailCommandTest.java | 2 +- .../authme/command/executable/authme/GetIpCommandTest.java | 2 +- .../authme/command/executable/authme/LastLoginCommandTest.java | 2 +- .../executable/authme/PurgeBannedPlayersCommandTest.java | 2 +- .../authme/command/executable/authme/PurgeCommandTest.java | 2 +- .../command/executable/authme/PurgeLastPositionCommandTest.java | 2 +- .../command/executable/authme/RegisterAdminCommandTest.java | 2 +- .../authme/command/executable/authme/ReloadCommandTest.java | 2 +- .../authme/command/executable/authme/SetEmailCommandTest.java | 2 +- .../command/executable/authme/SetFirstSpawnCommandTest.java | 2 +- .../authme/command/executable/authme/SetSpawnCommandTest.java | 2 +- .../authme/command/executable/authme/SpawnCommandTest.java | 2 +- .../command/executable/authme/SwitchAntiBotCommandTest.java | 2 +- .../command/executable/authme/UnregisterAdminCommandTest.java | 2 +- .../authme/command/executable/captcha/CaptchaCommandTest.java | 2 +- .../executable/changepassword/ChangePasswordCommandTest.java | 2 +- .../authme/command/executable/email/AddEmailCommandTest.java | 2 +- .../authme/command/executable/email/ChangeEmailCommandTest.java | 2 +- .../command/executable/email/RecoverEmailCommandTest.java | 2 +- .../authme/command/executable/email/ShowEmailCommandTest.java | 2 +- .../xephi/authme/command/executable/login/LoginCommandTest.java | 2 +- .../authme/command/executable/logout/LogoutCommandTest.java | 2 +- .../authme/command/executable/register/RegisterCommandTest.java | 2 +- .../command/executable/unregister/UnregisterCommandTest.java | 2 +- src/test/java/fr/xephi/authme/data/SessionManagerTest.java | 2 +- src/test/java/fr/xephi/authme/data/TempbanManagerTest.java | 2 +- src/test/java/fr/xephi/authme/data/limbo/LimboCacheTest.java | 2 +- .../java/fr/xephi/authme/initialization/TaskCloserTest.java | 2 +- src/test/java/fr/xephi/authme/listener/BlockListenerTest.java | 2 +- src/test/java/fr/xephi/authme/listener/EntityListenerTest.java | 2 +- src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java | 2 +- .../java/fr/xephi/authme/listener/PlayerListener111Test.java | 2 +- .../java/fr/xephi/authme/listener/PlayerListener16Test.java | 2 +- .../java/fr/xephi/authme/listener/PlayerListener18Test.java | 2 +- .../java/fr/xephi/authme/listener/PlayerListener19Test.java | 2 +- src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java | 2 +- src/test/java/fr/xephi/authme/listener/ServerListenerTest.java | 2 +- .../java/fr/xephi/authme/permission/PermissionsManagerTest.java | 2 +- src/test/java/fr/xephi/authme/process/ProcessServiceTest.java | 2 +- .../java/fr/xephi/authme/process/email/AsyncAddEmailTest.java | 2 +- .../fr/xephi/authme/process/email/AsyncChangeEmailTest.java | 2 +- .../fr/xephi/authme/process/login/AsynchronousLoginTest.java | 2 +- .../authme/process/unregister/AsynchronousUnregisterTest.java | 2 +- .../java/fr/xephi/authme/security/PasswordSecurityTest.java | 2 +- src/test/java/fr/xephi/authme/service/BukkitServiceTest.java | 2 +- src/test/java/fr/xephi/authme/service/GeoIpServiceTest.java | 2 +- src/test/java/fr/xephi/authme/service/MigrationServiceTest.java | 2 +- .../java/fr/xephi/authme/service/TeleportationServiceTest.java | 2 +- .../xephi/authme/settings/commandconfig/CommandManagerTest.java | 2 +- .../settings/commandconfig/CommandMigrationServiceTest.java | 2 +- .../settings/commandconfig/CommandYmlConsistencyTest.java | 2 +- src/test/java/fr/xephi/authme/task/CleanupTaskTest.java | 2 +- .../java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java | 2 +- src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java | 2 +- src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java | 2 +- 67 files changed, 67 insertions(+), 67 deletions(-) diff --git a/pom.xml b/pom.xml index 24a20245..52c17b68 100644 --- a/pom.xml +++ b/pom.xml @@ -919,7 +919,7 @@ org.mockito mockito-core test - 2.2.15 + 2.2.27 hamcrest-core diff --git a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java index 9e4ffd4e..3b5432bf 100644 --- a/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java +++ b/src/test/java/fr/xephi/authme/AuthMeInitializationTest.java @@ -28,7 +28,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.io.File; import java.io.IOException; diff --git a/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java b/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java index cb95bef6..8eae45ec 100644 --- a/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java +++ b/src/test/java/fr/xephi/authme/ConsoleLoggerTest.java @@ -12,7 +12,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.io.File; import java.io.IOException; diff --git a/src/test/java/fr/xephi/authme/api/NewAPITest.java b/src/test/java/fr/xephi/authme/api/NewAPITest.java index 02dfbec2..cc3dd188 100644 --- a/src/test/java/fr/xephi/authme/api/NewAPITest.java +++ b/src/test/java/fr/xephi/authme/api/NewAPITest.java @@ -18,7 +18,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.List; diff --git a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java index 8723e70c..4e0c43af 100644 --- a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java @@ -14,7 +14,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/CommandServiceTest.java b/src/test/java/fr/xephi/authme/command/CommandServiceTest.java index dabc8a09..e6b5fd11 100644 --- a/src/test/java/fr/xephi/authme/command/CommandServiceTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandServiceTest.java @@ -12,7 +12,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; diff --git a/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java index 37efa2e7..271f1174 100644 --- a/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/HelpCommandTest.java @@ -11,7 +11,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; import java.util.List; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java index 81e606a9..6f5cee4a 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java @@ -11,7 +11,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.Collections; 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 cdc3c978..93791fcb 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 @@ -17,7 +17,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java index dbbf3b71..1c8cdeda 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java @@ -13,7 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; import java.util.HashSet; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java index 84556cb9..3daaf7ad 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/FirstSpawnCommandTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java index 76a73033..46671d8a 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ForceLoginCommandTest.java @@ -10,7 +10,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java index 6f9d4d12..40a5fe8a 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java @@ -9,7 +9,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java index 4c681a14..28c945e3 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/GetIpCommandTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java index 8ff1baff..4b124de9 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java @@ -10,7 +10,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; import java.util.Date; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java index 05695a34..677ee1fe 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeBannedPlayersCommandTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; import java.util.HashSet; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java index 1464a2ca..08a1f634 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeCommandTest.java @@ -7,7 +7,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.Calendar; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java index 75d132ee..321881b6 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java @@ -9,7 +9,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java index 343515d9..4e528b07 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java @@ -19,7 +19,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java index 64915887..bb12b3dd 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java @@ -21,7 +21,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java index a0c6eea7..a98d4bbd 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java @@ -11,7 +11,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SetFirstSpawnCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SetFirstSpawnCommandTest.java index f9d466c1..f59dda89 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SetFirstSpawnCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SetFirstSpawnCommandTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SetSpawnCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SetSpawnCommandTest.java index 8eb9f785..17f77e31 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SetSpawnCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SetSpawnCommandTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SpawnCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SpawnCommandTest.java index 4605f495..c4c6abce 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SpawnCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SpawnCommandTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommandTest.java index 606e1ab6..03dd4077 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SwitchAntiBotCommandTest.java @@ -9,7 +9,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java index 4b2a0516..5c06fb16 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java @@ -11,7 +11,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java index cfdc51dc..b6271a0c 100644 --- a/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java @@ -9,7 +9,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java index 2329c233..dac17743 100644 --- a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java @@ -13,7 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java index 217d63c3..e935bbd0 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java @@ -10,7 +10,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java index 240ace31..8876abbf 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/ChangeEmailCommandTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java index 24c93c47..1c960405 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java @@ -18,7 +18,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java index 18513bf9..de2ba240 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java @@ -9,7 +9,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java index 1e6a4a47..2b6a5c19 100644 --- a/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/login/LoginCommandTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.ArrayList; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java index 35457c31..c5c66a16 100644 --- a/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/logout/LogoutCommandTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.ArrayList; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java index 7e7b23c9..1333c786 100644 --- a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java index 336b1742..c1dc8746 100644 --- a/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java @@ -9,7 +9,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/data/SessionManagerTest.java b/src/test/java/fr/xephi/authme/data/SessionManagerTest.java index f778dd16..f01311af 100644 --- a/src/test/java/fr/xephi/authme/data/SessionManagerTest.java +++ b/src/test/java/fr/xephi/authme/data/SessionManagerTest.java @@ -5,7 +5,7 @@ import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.PluginSettings; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Map; diff --git a/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java b/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java index 73d48ac3..28c2ab9e 100644 --- a/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java +++ b/src/test/java/fr/xephi/authme/data/TempbanManagerTest.java @@ -13,7 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Calendar; import java.util.Date; diff --git a/src/test/java/fr/xephi/authme/data/limbo/LimboCacheTest.java b/src/test/java/fr/xephi/authme/data/limbo/LimboCacheTest.java index 54f40865..8eb8e959 100644 --- a/src/test/java/fr/xephi/authme/data/limbo/LimboCacheTest.java +++ b/src/test/java/fr/xephi/authme/data/limbo/LimboCacheTest.java @@ -12,7 +12,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Map; diff --git a/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java b/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java index 7f677e0c..cb1e6cb4 100644 --- a/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java +++ b/src/test/java/fr/xephi/authme/initialization/TaskCloserTest.java @@ -14,7 +14,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.List; diff --git a/src/test/java/fr/xephi/authme/listener/BlockListenerTest.java b/src/test/java/fr/xephi/authme/listener/BlockListenerTest.java index e798c4df..6925343a 100644 --- a/src/test/java/fr/xephi/authme/listener/BlockListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/BlockListenerTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; diff --git a/src/test/java/fr/xephi/authme/listener/EntityListenerTest.java b/src/test/java/fr/xephi/authme/listener/EntityListenerTest.java index 4d678cf7..f55f59f8 100644 --- a/src/test/java/fr/xephi/authme/listener/EntityListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/EntityListenerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock; import static org.mockito.ArgumentMatchers.anyBoolean; diff --git a/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java b/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java index f27e9614..766fb06a 100644 --- a/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java +++ b/src/test/java/fr/xephi/authme/listener/OnJoinVerifierTest.java @@ -27,7 +27,7 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.Collection; diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListener111Test.java b/src/test/java/fr/xephi/authme/listener/PlayerListener111Test.java index 8f479a71..b7b2c605 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListener111Test.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListener111Test.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock; diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListener16Test.java b/src/test/java/fr/xephi/authme/listener/PlayerListener16Test.java index c60b8abf..5493a904 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListener16Test.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListener16Test.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock; diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListener18Test.java b/src/test/java/fr/xephi/authme/listener/PlayerListener18Test.java index 9b93a270..398e6f9e 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListener18Test.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListener18Test.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock; diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListener19Test.java b/src/test/java/fr/xephi/authme/listener/PlayerListener19Test.java index 50dd179d..b870ac06 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListener19Test.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListener19Test.java @@ -5,7 +5,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock; diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java index 437cb250..bc202cfb 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java @@ -36,7 +36,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.net.InetAddress; import java.util.ArrayList; diff --git a/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java b/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java index d40683c3..a2a326b6 100644 --- a/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/ServerListenerTest.java @@ -14,7 +14,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; diff --git a/src/test/java/fr/xephi/authme/permission/PermissionsManagerTest.java b/src/test/java/fr/xephi/authme/permission/PermissionsManagerTest.java index 8d562d9d..6c7efb45 100644 --- a/src/test/java/fr/xephi/authme/permission/PermissionsManagerTest.java +++ b/src/test/java/fr/xephi/authme/permission/PermissionsManagerTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; diff --git a/src/test/java/fr/xephi/authme/process/ProcessServiceTest.java b/src/test/java/fr/xephi/authme/process/ProcessServiceTest.java index 0c71cd51..e6df0b47 100644 --- a/src/test/java/fr/xephi/authme/process/ProcessServiceTest.java +++ b/src/test/java/fr/xephi/authme/process/ProcessServiceTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; diff --git a/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java b/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java index 10fdc0c5..46249d6d 100644 --- a/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java +++ b/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java @@ -13,7 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; diff --git a/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java b/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java index 330384cf..428a5003 100644 --- a/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java +++ b/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java @@ -11,7 +11,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; diff --git a/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java b/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java index 33e9b1aa..79f70131 100644 --- a/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java +++ b/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java @@ -23,7 +23,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java b/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java index 10978579..cfe141f3 100644 --- a/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java +++ b/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java @@ -23,7 +23,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; diff --git a/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java b/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java index e1c30f43..bca8b6d5 100644 --- a/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java +++ b/src/test/java/fr/xephi/authme/security/PasswordSecurityTest.java @@ -21,7 +21,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java b/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java index 923d73e6..597f89a7 100644 --- a/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/BukkitServiceTest.java @@ -13,7 +13,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Collection; diff --git a/src/test/java/fr/xephi/authme/service/GeoIpServiceTest.java b/src/test/java/fr/xephi/authme/service/GeoIpServiceTest.java index 62f00776..60e3aa68 100644 --- a/src/test/java/fr/xephi/authme/service/GeoIpServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/GeoIpServiceTest.java @@ -8,7 +8,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.io.File; import java.io.IOException; diff --git a/src/test/java/fr/xephi/authme/service/MigrationServiceTest.java b/src/test/java/fr/xephi/authme/service/MigrationServiceTest.java index cccefa00..fa82b97a 100644 --- a/src/test/java/fr/xephi/authme/service/MigrationServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/MigrationServiceTest.java @@ -13,7 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/service/TeleportationServiceTest.java b/src/test/java/fr/xephi/authme/service/TeleportationServiceTest.java index 318a5a33..3401738e 100644 --- a/src/test/java/fr/xephi/authme/service/TeleportationServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/TeleportationServiceTest.java @@ -18,7 +18,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java index 7b9d1bfc..fb8e4e40 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandManagerTest.java @@ -13,7 +13,7 @@ import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.io.File; import java.io.IOException; diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java index d04fc89e..1931ff2f 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandMigrationServiceTest.java @@ -11,7 +11,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.io.File; import java.util.Arrays; diff --git a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java index 0cb17fbc..1ea21489 100644 --- a/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java +++ b/src/test/java/fr/xephi/authme/settings/commandconfig/CommandYmlConsistencyTest.java @@ -12,7 +12,7 @@ import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.io.File; import java.util.Collections; diff --git a/src/test/java/fr/xephi/authme/task/CleanupTaskTest.java b/src/test/java/fr/xephi/authme/task/CleanupTaskTest.java index bb3bf37d..c58e8276 100644 --- a/src/test/java/fr/xephi/authme/task/CleanupTaskTest.java +++ b/src/test/java/fr/xephi/authme/task/CleanupTaskTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.List; diff --git a/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java b/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java index 98801153..633b0184 100644 --- a/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java +++ b/src/test/java/fr/xephi/authme/task/LimboPlayerTaskManagerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; diff --git a/src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java b/src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java index c0c952e9..4d3923e6 100644 --- a/src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java +++ b/src/test/java/fr/xephi/authme/task/purge/PurgeServiceTest.java @@ -16,7 +16,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import java.util.Arrays; import java.util.Calendar; diff --git a/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java b/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java index 286e0124..d371bad3 100644 --- a/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java +++ b/src/test/java/fr/xephi/authme/task/purge/PurgeTaskTest.java @@ -19,7 +19,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import java.util.ArrayList; From c325d0db41070b75bc697e684faeb220076ee919 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 3 Dec 2016 12:10:30 +0100 Subject: [PATCH 60/67] Merge CommandService and ProcessService to CommonService - Replace CommandService and ProcessService with CommonService: a service that offers our typical needs to work with settings, messages and permissions - Remove validation methods from CommonService: inject ValidationService directly. Validation methods are not used very frequently and therefore don't belong in CommonService. Their presence was a relict from our architecture before injection was used. --- .../xephi/authme/command/CommandService.java | 94 ------------- .../executable/authme/AccountsCommand.java | 10 +- .../authme/ChangePasswordAdminCommand.java | 14 +- .../executable/authme/ConverterCommand.java | 6 +- .../executable/authme/GetEmailCommand.java | 8 +- .../executable/authme/LastLoginCommand.java | 8 +- .../authme/PurgeLastPositionCommand.java | 8 +- .../authme/RegisterAdminCommand.java | 14 +- .../executable/authme/ReloadCommand.java | 6 +- .../executable/authme/SetEmailCommand.java | 24 ++-- .../authme/UnregisterAdminCommand.java | 6 +- .../executable/captcha/CaptchaCommand.java | 16 +-- .../changepassword/ChangePasswordCommand.java | 10 +- .../executable/email/AddEmailCommand.java | 6 +- .../executable/email/RecoverEmailCommand.java | 24 ++-- .../executable/email/ShowEmailCommand.java | 9 +- .../executable/register/RegisterCommand.java | 41 +++--- .../unregister/UnregisterCommand.java | 8 +- .../changepassword/AsyncChangePassword.java | 10 +- .../authme/process/email/AsyncAddEmail.java | 12 +- .../process/email/AsyncChangeEmail.java | 12 +- .../authme/process/join/AsynchronousJoin.java | 4 +- .../process/login/AsynchronousLogin.java | 4 +- .../process/login/ProcessSyncPlayerLogin.java | 24 ++-- .../process/logout/AsynchronousLogout.java | 4 +- .../ProcessSynchronousPlayerLogout.java | 4 +- .../authme/process/quit/AsynchronousQuit.java | 4 +- .../process/register/AsyncRegister.java | 4 +- .../register/ProcessSyncEmailRegister.java | 4 +- .../register/ProcessSyncPasswordRegister.java | 4 +- .../unregister/AsynchronousUnregister.java | 4 +- .../CommonService.java} | 54 ++++---- .../authme/command/CommandServiceTest.java | 130 ------------------ .../authme/AccountsCommandTest.java | 4 +- .../ChangePasswordAdminCommandTest.java | 4 +- .../authme/ConverterCommandTest.java | 4 +- .../authme/GetEmailCommandTest.java | 4 +- .../authme/LastLoginCommandTest.java | 4 +- .../authme/PurgeLastPositionCommandTest.java | 4 +- .../authme/RegisterAdminCommandTest.java | 6 +- .../executable/authme/ReloadCommandTest.java | 4 +- .../authme/SetEmailCommandTest.java | 48 ++++--- .../authme/UnregisterAdminCommandTest.java | 4 +- .../captcha/CaptchaCommandTest.java | 4 +- .../ChangePasswordCommandTest.java | 4 +- .../executable/email/AddEmailCommandTest.java | 4 +- .../email/RecoverEmailCommandTest.java | 4 +- .../email/ShowEmailCommandTest.java | 4 +- .../register/RegisterCommandTest.java | 25 ++-- .../unregister/UnregisterCommandTest.java | 4 +- .../process/email/AsyncAddEmailTest.java | 22 +-- .../process/email/AsyncChangeEmailTest.java | 24 ++-- .../process/login/AsynchronousLoginTest.java | 30 ++-- .../AsynchronousUnregisterTest.java | 4 +- .../CommonServiceTest.java} | 65 ++------- 55 files changed, 317 insertions(+), 553 deletions(-) delete mode 100644 src/main/java/fr/xephi/authme/command/CommandService.java rename src/main/java/fr/xephi/authme/{process/ProcessService.java => service/CommonService.java} (71%) delete mode 100644 src/test/java/fr/xephi/authme/command/CommandServiceTest.java rename src/test/java/fr/xephi/authme/{process/ProcessServiceTest.java => service/CommonServiceTest.java} (66%) diff --git a/src/main/java/fr/xephi/authme/command/CommandService.java b/src/main/java/fr/xephi/authme/command/CommandService.java deleted file mode 100644 index bb8bbeca..00000000 --- a/src/main/java/fr/xephi/authme/command/CommandService.java +++ /dev/null @@ -1,94 +0,0 @@ -package fr.xephi.authme.command; - -import com.github.authme.configme.properties.Property; -import fr.xephi.authme.message.MessageKey; -import fr.xephi.authme.message.Messages; -import fr.xephi.authme.settings.Settings; -import fr.xephi.authme.service.ValidationService; -import org.bukkit.command.CommandSender; - -import javax.inject.Inject; - -/** - * Service for implementations of {@link ExecutableCommand} to execute some common tasks. - * This service basically wraps calls, forwarding them to other classes. - */ -public class CommandService { - - @Inject - private Messages messages; - @Inject - private Settings settings; - @Inject - private ValidationService validationService; - - /** - * Send a message to a player. - * - * @param sender The command sender to send the message to - * @param messageKey The message key to send - */ - public void send(CommandSender sender, MessageKey messageKey) { - messages.send(sender, messageKey); - } - - /** - * Send a message to a player. - * - * @param sender The command sender to send the message to - * @param messageKey The message key to send - * @param replacements The replacement arguments for the message key's tags - */ - public void send(CommandSender sender, MessageKey messageKey, String... replacements) { - messages.send(sender, messageKey, replacements); - } - - /** - * Retrieve a message by its message key. - * - * @param key The message to retrieve - * @return The message - */ - public String[] retrieveMessage(MessageKey key) { - return messages.retrieve(key); - } - - /** - * Retrieve a message as a single String by its message key. - * - * @param key The message to retrieve - * @return The message - */ - public String retrieveSingle(MessageKey key) { - return messages.retrieveSingle(key); - } - - /** - * Retrieve the given property's value. - * - * @param property The property to retrieve - * @param The type of the property - * @return The property's value - */ - public T getProperty(Property property) { - return settings.getProperty(property); - } - - /** - * Return the settings manager. - * - * @return The settings manager - */ - public Settings getSettings() { - return settings; - } - - public boolean validateEmail(String email) { - return validationService.validateEmail(email); - } - - public boolean isEmailFreeForRegistration(String email, CommandSender sender) { - return validationService.isEmailFreeForRegistration(email, sender); - } - -} diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java index f3248b56..07365574 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/AccountsCommand.java @@ -1,11 +1,11 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; +import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import javax.inject.Inject; @@ -23,7 +23,7 @@ public class AccountsCommand implements ExecutableCommand { private BukkitService bukkitService; @Inject - private CommandService commandService; + private CommonService commonService; @Override public void executeCommand(final CommandSender sender, List arguments) { @@ -50,13 +50,13 @@ public class AccountsCommand implements ExecutableCommand { public void run() { PlayerAuth auth = dataSource.getAuth(playerName.toLowerCase()); if (auth == null) { - commandService.send(sender, MessageKey.UNKNOWN_USER); + commonService.send(sender, MessageKey.UNKNOWN_USER); return; } List accountList = dataSource.getAllAuthsByIp(auth.getIp()); if (accountList.isEmpty()) { - commandService.send(sender, MessageKey.USER_NOT_REGISTERED); + commonService.send(sender, MessageKey.USER_NOT_REGISTERED); } else if (accountList.size() == 1) { sender.sendMessage("[AuthMe] " + playerName + " is a single account player"); } else { 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 8f3a2b0a..d3d975b2 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,15 +1,15 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; -import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; 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; import fr.xephi.authme.service.ValidationService.ValidationResult; import org.bukkit.command.CommandSender; @@ -38,7 +38,7 @@ public class ChangePasswordAdminCommand implements ExecutableCommand { private ValidationService validationService; @Inject - private CommandService commandService; + private CommonService commonService; @Override public void executeCommand(final CommandSender sender, List arguments) { @@ -49,7 +49,7 @@ public class ChangePasswordAdminCommand implements ExecutableCommand { // Validate the password ValidationResult validationResult = validationService.validatePassword(playerPass, playerName); if (validationResult.hasError()) { - commandService.send(sender, validationResult.getMessageKey(), validationResult.getArgs()); + commonService.send(sender, validationResult.getMessageKey(), validationResult.getArgs()); return; } @@ -67,7 +67,7 @@ public class ChangePasswordAdminCommand implements ExecutableCommand { private void changePassword(String nameLowercase, String password, CommandSender sender) { PlayerAuth auth = getAuth(nameLowercase); if (auth == null) { - commandService.send(sender, MessageKey.UNKNOWN_USER); + commonService.send(sender, MessageKey.UNKNOWN_USER); return; } @@ -75,10 +75,10 @@ public class ChangePasswordAdminCommand implements ExecutableCommand { auth.setPassword(hashedPassword); if (dataSource.updatePassword(auth)) { - commandService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS); + commonService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS); ConsoleLogger.info(sender.getName() + " changed password of " + nameLowercase); } else { - commandService.send(sender, MessageKey.ERROR); + commonService.send(sender, MessageKey.ERROR); } } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java index 0cbadf2f..efa27ff0 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java @@ -4,7 +4,6 @@ import ch.jalu.injector.Injector; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.datasource.converter.Converter; import fr.xephi.authme.datasource.converter.CrazyLoginConverter; @@ -16,6 +15,7 @@ import fr.xephi.authme.datasource.converter.vAuthConverter; import fr.xephi.authme.datasource.converter.xAuthConverter; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import javax.inject.Inject; @@ -31,7 +31,7 @@ public class ConverterCommand implements ExecutableCommand { static final Map> CONVERTERS = getConverters(); @Inject - private CommandService commandService; + private CommonService commonService; @Inject private BukkitService bukkitService; @@ -61,7 +61,7 @@ public class ConverterCommand implements ExecutableCommand { try { converter.execute(sender); } catch (Exception e) { - commandService.send(sender, MessageKey.ERROR); + commonService.send(sender, MessageKey.ERROR); ConsoleLogger.logException("Error during conversion:", e); } } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/GetEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/GetEmailCommand.java index 57ff497a..efe9251e 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/GetEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/GetEmailCommand.java @@ -1,10 +1,10 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; +import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import javax.inject.Inject; @@ -19,7 +19,7 @@ public class GetEmailCommand implements ExecutableCommand { private DataSource dataSource; @Inject - private CommandService commandService; + private CommonService commonService; @Override public void executeCommand(CommandSender sender, List arguments) { @@ -27,7 +27,7 @@ public class GetEmailCommand implements ExecutableCommand { PlayerAuth auth = dataSource.getAuth(playerName); if (auth == null) { - commandService.send(sender, MessageKey.UNKNOWN_USER); + commonService.send(sender, MessageKey.UNKNOWN_USER); } else { sender.sendMessage("[AuthMe] " + playerName + "'s email: " + auth.getEmail()); } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java index 67fb2591..a7b622d3 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/LastLoginCommand.java @@ -1,10 +1,10 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; +import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import javax.inject.Inject; @@ -20,7 +20,7 @@ public class LastLoginCommand implements ExecutableCommand { private DataSource dataSource; @Inject - private CommandService commandService; + private CommonService commonService; @Override public void executeCommand(CommandSender sender, List arguments) { @@ -29,7 +29,7 @@ public class LastLoginCommand implements ExecutableCommand { PlayerAuth auth = dataSource.getAuth(playerName); if (auth == null) { - commandService.send(sender, MessageKey.USER_NOT_REGISTERED); + commonService.send(sender, MessageKey.USER_NOT_REGISTERED); return; } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommand.java index fa45367f..3a32c8ee 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommand.java @@ -1,10 +1,10 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; +import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import javax.inject.Inject; @@ -19,7 +19,7 @@ public class PurgeLastPositionCommand implements ExecutableCommand { private DataSource dataSource; @Inject - private CommandService commandService; + private CommonService commonService; @Override public void executeCommand(final CommandSender sender, List arguments) { @@ -35,7 +35,7 @@ public class PurgeLastPositionCommand implements ExecutableCommand { // Get the user auth and make sure the user exists PlayerAuth auth = dataSource.getAuth(playerName); if (auth == null) { - commandService.send(sender, MessageKey.UNKNOWN_USER); + commonService.send(sender, MessageKey.UNKNOWN_USER); return; } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommand.java index 784e9f4f..cba5edf0 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommand.java @@ -3,13 +3,13 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.limbo.LimboCache; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; 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; import fr.xephi.authme.service.ValidationService.ValidationResult; import org.bukkit.command.CommandSender; @@ -27,7 +27,7 @@ public class RegisterAdminCommand implements ExecutableCommand { private PasswordSecurity passwordSecurity; @Inject - private CommandService commandService; + private CommonService commonService; @Inject private DataSource dataSource; @@ -51,7 +51,7 @@ public class RegisterAdminCommand implements ExecutableCommand { // Command logic ValidationResult passwordValidation = validationService.validatePassword(playerPass, playerName); if (passwordValidation.hasError()) { - commandService.send(sender, passwordValidation.getMessageKey(), passwordValidation.getArgs()); + commonService.send(sender, passwordValidation.getMessageKey(), passwordValidation.getArgs()); return; } @@ -60,7 +60,7 @@ public class RegisterAdminCommand implements ExecutableCommand { @Override public void run() { if (dataSource.isAuthAvailable(playerNameLowerCase)) { - commandService.send(sender, MessageKey.NAME_ALREADY_REGISTERED); + commonService.send(sender, MessageKey.NAME_ALREADY_REGISTERED); return; } HashedPassword hashedPassword = passwordSecurity.computeHash(playerPass, playerNameLowerCase); @@ -71,12 +71,12 @@ public class RegisterAdminCommand implements ExecutableCommand { .build(); if (!dataSource.saveAuth(auth)) { - commandService.send(sender, MessageKey.ERROR); + commonService.send(sender, MessageKey.ERROR); return; } dataSource.setUnlogged(playerNameLowerCase); - commandService.send(sender, MessageKey.REGISTER_SUCCESS); + commonService.send(sender, MessageKey.REGISTER_SUCCESS); ConsoleLogger.info(sender.getName() + " registered " + playerName); final Player player = bukkitService.getPlayerExact(playerName); if (player != null) { @@ -84,7 +84,7 @@ public class RegisterAdminCommand implements ExecutableCommand { @Override public void run() { limboCache.restoreData(player); - player.kickPlayer(commandService.retrieveSingle(MessageKey.KICK_FOR_ADMIN_REGISTER)); + player.kickPlayer(commonService.retrieveSingleMessage(MessageKey.KICK_FOR_ADMIN_REGISTER)); } }); } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java index dc1ba638..037846aa 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/ReloadCommand.java @@ -3,12 +3,12 @@ package fr.xephi.authme.command.executable.authme; import ch.jalu.injector.Injector; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; import org.bukkit.command.CommandSender; @@ -35,7 +35,7 @@ public class ReloadCommand implements ExecutableCommand { private DataSource dataSource; @Inject - private CommandService commandService; + private CommonService commonService; @Override public void executeCommand(CommandSender sender, List arguments) { @@ -48,7 +48,7 @@ public class ReloadCommand implements ExecutableCommand { sender.sendMessage("Note: cannot change database type during /authme reload"); } performReloadOnServices(); - commandService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS); + commonService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS); } catch (Exception e) { sender.sendMessage("Error occurred during reload of AuthMe: aborting"); ConsoleLogger.logException("Aborting! Encountered exception during reload of AuthMe:", e); diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/SetEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/SetEmailCommand.java index 18eb29f5..987338fa 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/SetEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/SetEmailCommand.java @@ -1,12 +1,13 @@ package fr.xephi.authme.command.executable.authme; +import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; -import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.CommonService; +import fr.xephi.authme.service.ValidationService; import org.bukkit.command.CommandSender; import javax.inject.Inject; @@ -21,7 +22,7 @@ public class SetEmailCommand implements ExecutableCommand { private DataSource dataSource; @Inject - private CommandService commandService; + private CommonService commonService; @Inject private PlayerCache playerCache; @@ -29,6 +30,9 @@ public class SetEmailCommand implements ExecutableCommand { @Inject private BukkitService bukkitService; + @Inject + private ValidationService validationService; + @Override public void executeCommand(final CommandSender sender, List arguments) { // Get the player name and email address @@ -36,8 +40,8 @@ public class SetEmailCommand implements ExecutableCommand { final String playerEmail = arguments.get(1); // Validate the email address - if (!commandService.validateEmail(playerEmail)) { - commandService.send(sender, MessageKey.INVALID_EMAIL); + if (!validationService.validateEmail(playerEmail)) { + commonService.send(sender, MessageKey.INVALID_EMAIL); return; } @@ -47,17 +51,17 @@ public class SetEmailCommand implements ExecutableCommand { // Validate the user PlayerAuth auth = dataSource.getAuth(playerName); if (auth == null) { - commandService.send(sender, MessageKey.UNKNOWN_USER); + commonService.send(sender, MessageKey.UNKNOWN_USER); return; - } else if (!commandService.isEmailFreeForRegistration(playerEmail, sender)) { - commandService.send(sender, MessageKey.EMAIL_ALREADY_USED_ERROR); + } else if (!validationService.isEmailFreeForRegistration(playerEmail, sender)) { + commonService.send(sender, MessageKey.EMAIL_ALREADY_USED_ERROR); return; } // Set the email address auth.setEmail(playerEmail); if (!dataSource.updateEmail(auth)) { - commandService.send(sender, MessageKey.ERROR); + commonService.send(sender, MessageKey.ERROR); return; } @@ -67,7 +71,7 @@ public class SetEmailCommand implements ExecutableCommand { } // Show a status message - commandService.send(sender, MessageKey.EMAIL_CHANGED_SUCCESS); + commonService.send(sender, MessageKey.EMAIL_CHANGED_SUCCESS); } }); } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommand.java index 345351d9..d8901994 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommand.java @@ -1,11 +1,11 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.ExecutableCommand; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -21,7 +21,7 @@ public class UnregisterAdminCommand implements ExecutableCommand { private DataSource dataSource; @Inject - private CommandService commandService; + private CommonService commonService; @Inject private BukkitService bukkitService; @@ -38,7 +38,7 @@ public class UnregisterAdminCommand implements ExecutableCommand { // Make sure the user exists if (!dataSource.isAuthAvailable(playerName)) { - commandService.send(sender, MessageKey.UNKNOWN_USER); + commonService.send(sender, MessageKey.UNKNOWN_USER); return; } diff --git a/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java b/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java index 178c6f05..da7ed878 100644 --- a/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/captcha/CaptchaCommand.java @@ -1,10 +1,10 @@ package fr.xephi.authme.command.executable.captcha; +import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.data.CaptchaManager; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; -import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -19,16 +19,16 @@ public class CaptchaCommand extends PlayerCommand { private CaptchaManager captchaManager; @Inject - private CommandService commandService; + private CommonService commonService; @Override public void runCommand(Player player, List arguments) { final String playerName = player.getName().toLowerCase(); if (playerCache.isAuthenticated(playerName)) { - commandService.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); + commonService.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); } else if (!captchaManager.isCaptchaRequired(playerName)) { - commandService.send(player, MessageKey.USAGE_LOGIN); + commonService.send(player, MessageKey.USAGE_LOGIN); } else { checkCaptcha(player, arguments.get(0)); } @@ -37,11 +37,11 @@ public class CaptchaCommand extends PlayerCommand { private void checkCaptcha(Player player, String captchaCode) { final boolean isCorrectCode = captchaManager.checkCode(player.getName(), captchaCode); if (isCorrectCode) { - commandService.send(player, MessageKey.CAPTCHA_SUCCESS); - commandService.send(player, MessageKey.LOGIN_MESSAGE); + commonService.send(player, MessageKey.CAPTCHA_SUCCESS); + commonService.send(player, MessageKey.LOGIN_MESSAGE); } else { String newCode = captchaManager.generateCode(player.getName()); - commandService.send(player, MessageKey.CAPTCHA_WRONG_ERROR, newCode); + commonService.send(player, MessageKey.CAPTCHA_WRONG_ERROR, newCode); } } } diff --git a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java index bfcdbe77..4403c982 100644 --- a/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommand.java @@ -1,10 +1,10 @@ package fr.xephi.authme.command.executable.changepassword; -import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.PlayerCommand; +import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.service.ValidationService.ValidationResult; import org.bukkit.entity.Player; @@ -18,7 +18,7 @@ import java.util.List; public class ChangePasswordCommand extends PlayerCommand { @Inject - private CommandService commandService; + private CommonService commonService; @Inject private PlayerCache playerCache; @@ -36,14 +36,14 @@ public class ChangePasswordCommand extends PlayerCommand { String name = player.getName().toLowerCase(); if (!playerCache.isAuthenticated(name)) { - commandService.send(player, MessageKey.NOT_LOGGED_IN); + commonService.send(player, MessageKey.NOT_LOGGED_IN); return; } // Make sure the password is allowed ValidationResult passwordValidation = validationService.validatePassword(newPassword, name); if (passwordValidation.hasError()) { - commandService.send(player, passwordValidation.getMessageKey(), passwordValidation.getArgs()); + commonService.send(player, passwordValidation.getMessageKey(), passwordValidation.getArgs()); return; } diff --git a/src/main/java/fr/xephi/authme/command/executable/email/AddEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/AddEmailCommand.java index 85baa2d6..eae64fdb 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/AddEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/AddEmailCommand.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.email; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; +import fr.xephi.authme.service.CommonService; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -18,7 +18,7 @@ public class AddEmailCommand extends PlayerCommand { private Management management; @Inject - private CommandService commandService; + private CommonService commonService; @Override public void runCommand(Player player, List arguments) { @@ -29,7 +29,7 @@ public class AddEmailCommand extends PlayerCommand { // Closer inspection of the mail address handled by the async task management.performAddEmail(player, email); } else { - commandService.send(player, MessageKey.CONFIRM_EMAIL_MESSAGE); + commonService.send(player, MessageKey.CONFIRM_EMAIL_MESSAGE); } } } diff --git a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java index 89138b41..e77cd279 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java @@ -1,17 +1,17 @@ package fr.xephi.authme.command.executable.email; import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; -import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.security.PasswordSecurity; -import fr.xephi.authme.util.RandomStringUtils; import fr.xephi.authme.security.crypts.HashedPassword; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.RecoveryCodeService; +import fr.xephi.authme.util.RandomStringUtils; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -28,7 +28,7 @@ public class RecoverEmailCommand extends PlayerCommand { private PasswordSecurity passwordSecurity; @Inject - private CommandService commandService; + private CommonService commonService; @Inject private DataSource dataSource; @@ -49,23 +49,23 @@ public class RecoverEmailCommand extends PlayerCommand { if (!sendMailSsl.hasAllInformation()) { ConsoleLogger.warning("Mail API is not set"); - commandService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); + commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); return; } if (playerCache.isAuthenticated(playerName)) { - commandService.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); + commonService.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); return; } PlayerAuth auth = dataSource.getAuth(playerName); // TODO: Create method to get email only if (auth == null) { - commandService.send(player, MessageKey.REGISTER_EMAIL_MESSAGE); + commonService.send(player, MessageKey.REGISTER_EMAIL_MESSAGE); return; } final String email = auth.getEmail(); if (email == null || !email.equalsIgnoreCase(playerMail) || "your@email.com".equalsIgnoreCase(email)) { - commandService.send(player, MessageKey.INVALID_EMAIL); + commonService.send(player, MessageKey.INVALID_EMAIL); return; } @@ -85,13 +85,13 @@ public class RecoverEmailCommand extends PlayerCommand { private void createAndSendRecoveryCode(Player player, String email) { String recoveryCode = recoveryCodeService.generateCode(player.getName()); sendMailSsl.sendRecoveryCode(player.getName(), email, recoveryCode); - commandService.send(player, MessageKey.RECOVERY_CODE_SENT); + commonService.send(player, MessageKey.RECOVERY_CODE_SENT); } private void processRecoveryCode(Player player, String code, String email) { final String name = player.getName(); if (!recoveryCodeService.isCodeValid(name, code)) { - commandService.send(player, MessageKey.INCORRECT_RECOVERY_CODE); + commonService.send(player, MessageKey.INCORRECT_RECOVERY_CODE); return; } @@ -101,11 +101,11 @@ public class RecoverEmailCommand extends PlayerCommand { private void generateAndSendNewPassword(Player player, String email) { String name = player.getName(); - String thePass = RandomStringUtils.generate(commandService.getProperty(RECOVERY_PASSWORD_LENGTH)); + String thePass = RandomStringUtils.generate(commonService.getProperty(RECOVERY_PASSWORD_LENGTH)); HashedPassword hashNew = passwordSecurity.computeHash(thePass, name); dataSource.updatePassword(name, hashNew); sendMailSsl.sendPasswordMail(name, email, thePass); - commandService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); + commonService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); } } diff --git a/src/main/java/fr/xephi/authme/command/executable/email/ShowEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/ShowEmailCommand.java index 68bc06dd..151236e1 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/ShowEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/ShowEmailCommand.java @@ -1,10 +1,10 @@ package fr.xephi.authme.command.executable.email; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -14,8 +14,9 @@ import java.util.List; * Show email command. */ public class ShowEmailCommand extends PlayerCommand { + @Inject - private CommandService commandService; + private CommonService commonService; @Inject private PlayerCache playerCache; @@ -24,9 +25,9 @@ public class ShowEmailCommand extends PlayerCommand { public void runCommand(Player player, List arguments) { PlayerAuth auth = playerCache.getAuth(player.getName()); if (auth.getEmail() != null && !"your@email.com".equalsIgnoreCase(auth.getEmail())) { - commandService.send(player, MessageKey.EMAIL_SHOW, auth.getEmail()); + commonService.send(player, MessageKey.EMAIL_SHOW, auth.getEmail()); } else { - commandService.send(player, MessageKey.SHOW_NO_EMAIL); + commonService.send(player, MessageKey.SHOW_NO_EMAIL); } } } diff --git a/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java index f49ec2db..cc18adbf 100644 --- a/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/register/RegisterCommand.java @@ -1,15 +1,16 @@ package fr.xephi.authme.command.executable.register; import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.PlayerCommand; import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; import fr.xephi.authme.security.HashAlgorithm; -import fr.xephi.authme.util.RandomStringUtils; +import fr.xephi.authme.service.CommonService; +import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.SecuritySettings; +import fr.xephi.authme.util.RandomStringUtils; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -20,20 +21,26 @@ import static fr.xephi.authme.settings.properties.RegistrationSettings.ENABLE_CO import static fr.xephi.authme.settings.properties.RegistrationSettings.USE_EMAIL_REGISTRATION; import static fr.xephi.authme.settings.properties.RestrictionSettings.ENABLE_PASSWORD_CONFIRMATION; +/** + * Command for /register. + */ public class RegisterCommand extends PlayerCommand { @Inject private Management management; @Inject - private CommandService commandService; + private CommonService commonService; @Inject private SendMailSSL sendMailSsl; + @Inject + private ValidationService validationService; + @Override public void runCommand(Player player, List arguments) { - if (commandService.getProperty(SecuritySettings.PASSWORD_HASH) == HashAlgorithm.TWO_FACTOR) { + if (commonService.getProperty(SecuritySettings.PASSWORD_HASH) == HashAlgorithm.TWO_FACTOR) { //for two factor auth we don't need to check the usage management.performRegister(player, "", "", true); return; @@ -42,11 +49,11 @@ public class RegisterCommand extends PlayerCommand { // Ensure that there is 1 argument, or 2 if confirmation is required final boolean useConfirmation = isConfirmationRequired(); if (arguments.isEmpty() || useConfirmation && arguments.size() < 2) { - commandService.send(player, MessageKey.USAGE_REGISTER); + commonService.send(player, MessageKey.USAGE_REGISTER); return; } - if (commandService.getProperty(USE_EMAIL_REGISTRATION)) { + if (commonService.getProperty(USE_EMAIL_REGISTRATION)) { handleEmailRegistration(player, arguments); } else { handlePasswordRegistration(player, arguments); @@ -59,8 +66,8 @@ public class RegisterCommand extends PlayerCommand { } private void handlePasswordRegistration(Player player, List arguments) { - if (commandService.getProperty(ENABLE_PASSWORD_CONFIRMATION) && !arguments.get(0).equals(arguments.get(1))) { - commandService.send(player, MessageKey.PASSWORD_MATCH_ERROR); + if (commonService.getProperty(ENABLE_PASSWORD_CONFIRMATION) && !arguments.get(0).equals(arguments.get(1))) { + commonService.send(player, MessageKey.PASSWORD_MATCH_ERROR); } else { management.performRegister(player, arguments.get(0), "", true); } @@ -68,19 +75,19 @@ public class RegisterCommand extends PlayerCommand { private void handleEmailRegistration(Player player, List arguments) { if (!sendMailSsl.hasAllInformation()) { - commandService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); + commonService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS); ConsoleLogger.warning("Cannot register player '" + player.getName() + "': no email or password is set " + "to send emails from. Please adjust your config at " + EmailSettings.MAIL_ACCOUNT.getPath()); return; } final String email = arguments.get(0); - if (!commandService.validateEmail(email)) { - commandService.send(player, MessageKey.INVALID_EMAIL); - } else if (commandService.getProperty(ENABLE_CONFIRM_EMAIL) && !email.equals(arguments.get(1))) { - commandService.send(player, MessageKey.USAGE_REGISTER); + if (!validationService.validateEmail(email)) { + commonService.send(player, MessageKey.INVALID_EMAIL); + } else if (commonService.getProperty(ENABLE_CONFIRM_EMAIL) && !email.equals(arguments.get(1))) { + commonService.send(player, MessageKey.USAGE_REGISTER); } else { - String thePass = RandomStringUtils.generate(commandService.getProperty(RECOVERY_PASSWORD_LENGTH)); + String thePass = RandomStringUtils.generate(commonService.getProperty(RECOVERY_PASSWORD_LENGTH)); management.performRegister(player, thePass, email, true); } } @@ -91,8 +98,8 @@ public class RegisterCommand extends PlayerCommand { * @return True if the confirmation is needed, false otherwise */ private boolean isConfirmationRequired() { - return commandService.getProperty(USE_EMAIL_REGISTRATION) - ? commandService.getProperty(ENABLE_CONFIRM_EMAIL) - : commandService.getProperty(ENABLE_PASSWORD_CONFIRMATION); + return commonService.getProperty(USE_EMAIL_REGISTRATION) + ? commonService.getProperty(ENABLE_CONFIRM_EMAIL) + : commonService.getProperty(ENABLE_PASSWORD_CONFIRMATION); } } diff --git a/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java b/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java index c3aaf58a..09b996a2 100644 --- a/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/unregister/UnregisterCommand.java @@ -1,10 +1,10 @@ package fr.xephi.authme.command.executable.unregister; -import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.command.PlayerCommand; +import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; +import fr.xephi.authme.service.CommonService; import org.bukkit.entity.Player; import javax.inject.Inject; @@ -19,7 +19,7 @@ public class UnregisterCommand extends PlayerCommand { private Management management; @Inject - private CommandService commandService; + private CommonService commonService; @Inject private PlayerCache playerCache; @@ -31,7 +31,7 @@ public class UnregisterCommand extends PlayerCommand { // Make sure the player is authenticated if (!playerCache.isAuthenticated(playerName)) { - commandService.send(player, MessageKey.NOT_LOGGED_IN); + commonService.send(player, MessageKey.NOT_LOGGED_IN); return; } 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 80d304dd..2a3fa175 100644 --- a/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java +++ b/src/main/java/fr/xephi/authme/process/changepassword/AsyncChangePassword.java @@ -6,7 +6,7 @@ import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.AsynchronousProcess; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.HashedPassword; import org.bukkit.entity.Player; @@ -19,7 +19,7 @@ public class AsyncChangePassword implements AsynchronousProcess { private DataSource dataSource; @Inject - private ProcessService processService; + private CommonService commonService; @Inject private PasswordSecurity passwordSecurity; @@ -39,15 +39,15 @@ public class AsyncChangePassword implements AsynchronousProcess { auth.setPassword(hashedPassword); if (!dataSource.updatePassword(auth)) { - processService.send(player, MessageKey.ERROR); + commonService.send(player, MessageKey.ERROR); return; } playerCache.updatePlayer(auth); - processService.send(player, MessageKey.PASSWORD_CHANGED_SUCCESS); + commonService.send(player, MessageKey.PASSWORD_CHANGED_SUCCESS); ConsoleLogger.info(player.getName() + " changed his password"); } else { - processService.send(player, MessageKey.WRONG_PASSWORD); + commonService.send(player, MessageKey.WRONG_PASSWORD); } } } diff --git a/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java b/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java index 5a8a8e90..fb5c6c9c 100644 --- a/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java +++ b/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java @@ -6,7 +6,8 @@ import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.AsynchronousProcess; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; +import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.properties.RegistrationSettings; import org.bukkit.entity.Player; @@ -18,7 +19,7 @@ import javax.inject.Inject; public class AsyncAddEmail implements AsynchronousProcess { @Inject - private ProcessService service; + private CommonService service; @Inject private DataSource dataSource; @@ -26,6 +27,9 @@ public class AsyncAddEmail implements AsynchronousProcess { @Inject private PlayerCache playerCache; + @Inject + private ValidationService validationService; + AsyncAddEmail() { } public void addEmail(Player player, String email) { @@ -37,9 +41,9 @@ public class AsyncAddEmail implements AsynchronousProcess { if (currentEmail != null && !"your@email.com".equals(currentEmail)) { service.send(player, MessageKey.USAGE_CHANGE_EMAIL); - } else if (!service.validateEmail(email)) { + } else if (!validationService.validateEmail(email)) { service.send(player, MessageKey.INVALID_EMAIL); - } else if (!service.isEmailFreeForRegistration(email, player)) { + } else if (!validationService.isEmailFreeForRegistration(email, player)) { service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR); } else { auth.setEmail(email); diff --git a/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java b/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java index 6bc83106..d876ab58 100644 --- a/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java +++ b/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java @@ -5,7 +5,8 @@ import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.AsynchronousProcess; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; +import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.properties.RegistrationSettings; import org.bukkit.entity.Player; @@ -17,7 +18,7 @@ import javax.inject.Inject; public class AsyncChangeEmail implements AsynchronousProcess { @Inject - private ProcessService service; + private CommonService service; @Inject private PlayerCache playerCache; @@ -25,6 +26,9 @@ public class AsyncChangeEmail implements AsynchronousProcess { @Inject private DataSource dataSource; + @Inject + private ValidationService validationService; + AsyncChangeEmail() { } public void changeEmail(Player player, String oldEmail, String newEmail) { @@ -35,11 +39,11 @@ public class AsyncChangeEmail implements AsynchronousProcess { if (currentEmail == null) { service.send(player, MessageKey.USAGE_ADD_EMAIL); - } else if (newEmail == null || !service.validateEmail(newEmail)) { + } else if (newEmail == null || !validationService.validateEmail(newEmail)) { service.send(player, MessageKey.INVALID_NEW_EMAIL); } else if (!oldEmail.equals(currentEmail)) { service.send(player, MessageKey.INVALID_OLD_EMAIL); - } else if (!service.isEmailFreeForRegistration(newEmail, player)) { + } else if (!validationService.isEmailFreeForRegistration(newEmail, player)) { service.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR); } else { saveNewEmail(auth, player, newEmail); diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java index cf70c386..dab9cdc2 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java @@ -13,7 +13,7 @@ import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.permission.AuthGroupType; import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.process.AsynchronousProcess; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.process.login.AsynchronousLogin; import fr.xephi.authme.settings.commandconfig.CommandManager; import fr.xephi.authme.settings.properties.HooksSettings; @@ -45,7 +45,7 @@ public class AsynchronousJoin implements AsynchronousProcess { private DataSource database; @Inject - private ProcessService service; + private CommonService service; @Inject private PlayerCache playerCache; diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java index 318b1b30..dac60ad1 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -16,7 +16,7 @@ import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.permission.PlayerStatePermission; import fr.xephi.authme.process.AsynchronousProcess; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.process.SyncProcessManager; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.settings.properties.DatabaseSettings; @@ -44,7 +44,7 @@ public class AsynchronousLogin implements AsynchronousProcess { private DataSource dataSource; @Inject - private ProcessService service; + private CommonService service; @Inject private PermissionsManager permissionsManager; diff --git a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java index f9263759..d64bda77 100644 --- a/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java @@ -8,13 +8,13 @@ import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.events.LoginEvent; import fr.xephi.authme.events.RestoreInventoryEvent; import fr.xephi.authme.listener.PlayerListener; -import fr.xephi.authme.process.ProcessService; import fr.xephi.authme.process.SynchronousProcess; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.service.BungeeService; +import fr.xephi.authme.service.TeleportationService; +import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.commandconfig.CommandManager; import fr.xephi.authme.settings.properties.RegistrationSettings; -import fr.xephi.authme.service.BukkitService; -import fr.xephi.authme.service.TeleportationService; import fr.xephi.authme.util.StringUtils; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -33,9 +33,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { @Inject private BungeeService bungeeService; - @Inject - private ProcessService service; - @Inject private LimboCache limboCache; @@ -54,6 +51,9 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { @Inject private CommandManager commandManager; + @Inject + private Settings settings; + ProcessSyncPlayerLogin() { } @@ -77,7 +77,7 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { // because LimboCache#restoreData teleport player to last location. } - if (service.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) { + if (settings.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) { restoreInventory(player); } @@ -94,7 +94,7 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { } } - if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) { + if (settings.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) { player.removePotionEffect(PotionEffectType.BLINDNESS); } @@ -103,13 +103,13 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess { player.saveData(); // Login is done, display welcome message - if (service.getProperty(RegistrationSettings.USE_WELCOME_MESSAGE)) { - if (service.getProperty(RegistrationSettings.BROADCAST_WELCOME_MESSAGE)) { - for (String s : service.getSettings().getWelcomeMessage()) { + if (settings.getProperty(RegistrationSettings.USE_WELCOME_MESSAGE)) { + if (settings.getProperty(RegistrationSettings.BROADCAST_WELCOME_MESSAGE)) { + for (String s : settings.getWelcomeMessage()) { Bukkit.getServer().broadcastMessage(plugin.replaceAllInfo(s, player)); } } else { - for (String s : service.getSettings().getWelcomeMessage()) { + for (String s : settings.getWelcomeMessage()) { player.sendMessage(plugin.replaceAllInfo(s, player)); } } diff --git a/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java b/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java index 7374d738..efd3066a 100644 --- a/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java @@ -6,7 +6,7 @@ import fr.xephi.authme.data.limbo.LimboCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.AsynchronousProcess; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.process.SyncProcessManager; import fr.xephi.authme.settings.properties.RestrictionSettings; import org.bukkit.entity.Player; @@ -19,7 +19,7 @@ public class AsynchronousLogout implements AsynchronousProcess { private DataSource database; @Inject - private ProcessService service; + private CommonService service; @Inject private PlayerCache playerCache; diff --git a/src/main/java/fr/xephi/authme/process/logout/ProcessSynchronousPlayerLogout.java b/src/main/java/fr/xephi/authme/process/logout/ProcessSynchronousPlayerLogout.java index 72ff935e..17710df4 100644 --- a/src/main/java/fr/xephi/authme/process/logout/ProcessSynchronousPlayerLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/ProcessSynchronousPlayerLogout.java @@ -6,7 +6,7 @@ import fr.xephi.authme.events.LogoutEvent; import fr.xephi.authme.listener.protocollib.ProtocolLibService; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.permission.AuthGroupType; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; @@ -25,7 +25,7 @@ import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND; public class ProcessSynchronousPlayerLogout implements SynchronousProcess { @Inject - private ProcessService service; + private CommonService service; @Inject private BukkitService bukkitService; diff --git a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java b/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java index c8f63bbd..d34cbde0 100644 --- a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java +++ b/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java @@ -7,7 +7,7 @@ import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.CacheDataSource; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.process.AsynchronousProcess; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.process.SyncProcessManager; import fr.xephi.authme.settings.SpawnLoader; import fr.xephi.authme.settings.properties.RestrictionSettings; @@ -27,7 +27,7 @@ public class AsynchronousQuit implements AsynchronousProcess { private DataSource database; @Inject - private ProcessService service; + private CommonService service; @Inject private PlayerCache playerCache; diff --git a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java index 627a993b..40e6806c 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -7,7 +7,7 @@ import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.process.AsynchronousProcess; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.process.SyncProcessManager; import fr.xephi.authme.process.login.AsynchronousLogin; import fr.xephi.authme.security.HashAlgorithm; @@ -51,7 +51,7 @@ public class AsyncRegister implements AsynchronousProcess { @Inject private PasswordSecurity passwordSecurity; @Inject - private ProcessService service; + private CommonService service; @Inject private SyncProcessManager syncProcessManager; @Inject diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java index 3347b382..aea1b4be 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncEmailRegister.java @@ -3,7 +3,7 @@ package fr.xephi.authme.process.register; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.permission.AuthGroupType; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.task.LimboPlayerTaskManager; @@ -16,7 +16,7 @@ import javax.inject.Inject; public class ProcessSyncEmailRegister implements SynchronousProcess { @Inject - private ProcessService service; + private CommonService service; @Inject private LimboPlayerTaskManager limboPlayerTaskManager; diff --git a/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java b/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java index efc4f1b1..fae428d0 100644 --- a/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/ProcessSyncPasswordRegister.java @@ -4,7 +4,7 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.data.limbo.LimboCache; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.permission.AuthGroupType; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.process.SynchronousProcess; import fr.xephi.authme.service.BungeeService; import fr.xephi.authme.settings.commandconfig.CommandManager; @@ -25,7 +25,7 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess { private BungeeService bungeeService; @Inject - private ProcessService service; + private CommonService service; @Inject private LimboCache limboCache; diff --git a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java b/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java index 7d63d055..764e5676 100644 --- a/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java +++ b/src/main/java/fr/xephi/authme/process/unregister/AsynchronousUnregister.java @@ -9,7 +9,7 @@ import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.permission.AuthGroupHandler; import fr.xephi.authme.permission.AuthGroupType; import fr.xephi.authme.process.AsynchronousProcess; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; @@ -31,7 +31,7 @@ public class AsynchronousUnregister implements AsynchronousProcess { private DataSource dataSource; @Inject - private ProcessService service; + private CommonService service; @Inject private PasswordSecurity passwordSecurity; diff --git a/src/main/java/fr/xephi/authme/process/ProcessService.java b/src/main/java/fr/xephi/authme/service/CommonService.java similarity index 71% rename from src/main/java/fr/xephi/authme/process/ProcessService.java rename to src/main/java/fr/xephi/authme/service/CommonService.java index 575b8053..1b1d9593 100644 --- a/src/main/java/fr/xephi/authme/process/ProcessService.java +++ b/src/main/java/fr/xephi/authme/service/CommonService.java @@ -1,4 +1,4 @@ -package fr.xephi.authme.process; +package fr.xephi.authme.service; import com.github.authme.configme.properties.Property; import fr.xephi.authme.message.MessageKey; @@ -8,16 +8,15 @@ import fr.xephi.authme.permission.AuthGroupType; import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.settings.Settings; -import fr.xephi.authme.service.ValidationService; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import javax.inject.Inject; /** - * Service for asynchronous and synchronous processes. + * Service for the most common operations regarding settings, messages and permissions. */ -public class ProcessService { +public class CommonService { @Inject private Settings settings; @@ -25,17 +24,17 @@ public class ProcessService { @Inject private Messages messages; - @Inject - private ValidationService validationService; - @Inject private PermissionsManager permissionsManager; @Inject private AuthGroupHandler authGroupHandler; + CommonService() { + } + /** - * Retrieve a property's value. + * Retrieves a property's value. * * @param property the property to retrieve * @param the property type @@ -46,16 +45,7 @@ public class ProcessService { } /** - * Return the settings manager. - * - * @return settings manager - */ - public Settings getSettings() { - return settings; - } - - /** - * Send a message to the command sender. + * Sends a message to the command sender. * * @param sender the command sender * @param key the message key @@ -65,7 +55,7 @@ public class ProcessService { } /** - * Send a message to the command sender with the given replacements. + * Sends a message to the command sender with the given replacements. * * @param sender the command sender * @param key the message key @@ -76,7 +66,7 @@ public class ProcessService { } /** - * Retrieve a message. + * Retrieves a message. * * @param key the key of the message * @return the message, split by line @@ -86,7 +76,7 @@ public class ProcessService { } /** - * Retrieve a message as one piece. + * Retrieves a message in one piece. * * @param key the key of the message * @return the message @@ -95,18 +85,24 @@ public class ProcessService { return messages.retrieveSingle(key); } - public boolean validateEmail(String email) { - return validationService.validateEmail(email); - } - - public boolean isEmailFreeForRegistration(String email, CommandSender sender) { - return validationService.isEmailFreeForRegistration(email, sender); - } - + /** + * Checks whether the player has the given permission. + * + * @param player the player + * @param node the permission node to check + * @return true if player has permission, false otherwise + */ public boolean hasPermission(Player player, PermissionNode node) { return permissionsManager.hasPermission(player, node); } + /** + * Sets the permission group of the given player. + * + * @param player the player to process + * @param group the group to add the player to + * @return true on success, false otherwise + */ public boolean setGroup(Player player, AuthGroupType group) { return authGroupHandler.setGroup(player, group); } diff --git a/src/test/java/fr/xephi/authme/command/CommandServiceTest.java b/src/test/java/fr/xephi/authme/command/CommandServiceTest.java deleted file mode 100644 index e6b5fd11..00000000 --- a/src/test/java/fr/xephi/authme/command/CommandServiceTest.java +++ /dev/null @@ -1,130 +0,0 @@ -package fr.xephi.authme.command; - -import com.github.authme.configme.properties.Property; -import fr.xephi.authme.message.MessageKey; -import fr.xephi.authme.message.Messages; -import fr.xephi.authme.settings.Settings; -import fr.xephi.authme.settings.properties.SecuritySettings; -import fr.xephi.authme.service.ValidationService; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * Test for {@link CommandService}. - */ -@RunWith(MockitoJUnitRunner.class) -public class CommandServiceTest { - - @InjectMocks - private CommandService commandService; - @Mock - private Messages messages; - @Mock - private Settings settings; - @Mock - private ValidationService validationService; - - @Test - public void shouldSendMessage() { - // given - CommandSender sender = mock(CommandSender.class); - - // when - commandService.send(sender, MessageKey.INVALID_EMAIL); - - // then - verify(messages).send(sender, MessageKey.INVALID_EMAIL); - } - - @Test - public void shouldSendMessageWithReplacements() { - // given - CommandSender sender = mock(Player.class); - - // when - commandService.send(sender, MessageKey.ANTIBOT_AUTO_ENABLED_MESSAGE, "10"); - - // then - verify(messages).send(sender, MessageKey.ANTIBOT_AUTO_ENABLED_MESSAGE, "10"); - } - - @Test - public void shouldRetrieveMessage() { - // given - MessageKey key = MessageKey.USAGE_CAPTCHA; - String[] givenMessages = new String[]{"Lorem ipsum...", "Test line test"}; - given(messages.retrieve(key)).willReturn(givenMessages); - - // when - String[] result = commandService.retrieveMessage(key); - - // then - assertThat(result, equalTo(givenMessages)); - verify(messages).retrieve(key); - } - - @Test - public void shouldRetrieveProperty() { - // given - Property property = SecuritySettings.CAPTCHA_LENGTH; - given(settings.getProperty(property)).willReturn(7); - - // when - int result = commandService.getProperty(property); - - // then - assertThat(result, equalTo(7)); - verify(settings).getProperty(property); - } - - @Test - public void shouldReturnSettings() { - // given/when - Settings result = commandService.getSettings(); - - // then - assertThat(result, equalTo(settings)); - } - - @Test - public void shouldValidateEmail() { - // given - String email = "test@example.tld"; - given(validationService.validateEmail(email)).willReturn(true); - - // when - boolean result = commandService.validateEmail(email); - - // then - assertThat(result, equalTo(true)); - verify(validationService).validateEmail(email); - } - - @Test - public void shouldCheckIfEmailCanBeUsed() { - // given - String email = "mail@example.com"; - CommandSender sender = mock(CommandSender.class); - given(validationService.isEmailFreeForRegistration(email, sender)) - .willReturn(true); - - // when - boolean result = commandService.isEmailFreeForRegistration(email, sender); - - // then - assertThat(result, equalTo(true)); - verify(validationService).isEmailFreeForRegistration(email, sender); - } - -} diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java index 6f5cee4a..29a07be8 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/AccountsCommandTest.java @@ -1,10 +1,10 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,7 +36,7 @@ public class AccountsCommandTest { @InjectMocks private AccountsCommand command; @Mock - private CommandService service; + private CommonService service; @Mock private DataSource dataSource; @Mock 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 93791fcb..a4c80228 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 @@ -1,7 +1,6 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.TestHelper; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; @@ -9,6 +8,7 @@ import fr.xephi.authme.message.MessageKey; 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; import fr.xephi.authme.service.ValidationService.ValidationResult; import org.bukkit.command.CommandSender; @@ -39,7 +39,7 @@ public class ChangePasswordAdminCommandTest { private ChangePasswordAdminCommand command; @Mock - private CommandService service; + private CommonService service; @Mock private PasswordSecurity passwordSecurity; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java index 1c8cdeda..cf306599 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java @@ -2,10 +2,10 @@ package fr.xephi.authme.command.executable.authme; import ch.jalu.injector.Injector; import fr.xephi.authme.TestHelper; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.datasource.converter.Converter; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.util.StringUtils; import org.bukkit.command.CommandSender; import org.junit.BeforeClass; @@ -42,7 +42,7 @@ public class ConverterCommandTest { private ConverterCommand command; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private BukkitService bukkitService; diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java index 40a5fe8a..1e3fe391 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/GetEmailCommandTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,7 +32,7 @@ public class GetEmailCommandTest { private DataSource dataSource; @Mock - private CommandService service; + private CommonService service; @Test public void shouldReportUnknownUser() { diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java index 4b124de9..494de2cc 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/LastLoginCommandTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.data.auth.PlayerAuth; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import org.junit.Test; import org.junit.runner.RunWith; @@ -39,7 +39,7 @@ public class LastLoginCommandTest { private DataSource dataSource; @Mock - private CommandService service; + private CommonService service; @Test diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java index 321881b6..5f3aa6f1 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/PurgeLastPositionCommandTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import org.junit.Test; import org.junit.runner.RunWith; @@ -33,7 +33,7 @@ public class PurgeLastPositionCommandTest { private DataSource dataSource; @Mock - private CommandService service; + private CommonService service; @Test diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java index 4e528b07..91419912 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/RegisterAdminCommandTest.java @@ -1,7 +1,6 @@ package fr.xephi.authme.command.executable.authme; import fr.xephi.authme.TestHelper; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.limbo.LimboCache; import fr.xephi.authme.datasource.DataSource; @@ -9,6 +8,7 @@ import fr.xephi.authme.message.MessageKey; 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; import fr.xephi.authme.service.ValidationService.ValidationResult; import org.bukkit.command.CommandSender; @@ -51,7 +51,7 @@ public class RegisterAdminCommandTest { private BukkitService bukkitService; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private ValidationService validationService; @@ -164,7 +164,7 @@ public class RegisterAdminCommandTest { Player player = mock(Player.class); given(bukkitService.getPlayerExact(user)).willReturn(player); String kickForAdminRegister = "Admin registered you -- log in again"; - given(commandService.retrieveSingle(MessageKey.KICK_FOR_ADMIN_REGISTER)).willReturn(kickForAdminRegister); + given(commandService.retrieveSingleMessage(MessageKey.KICK_FOR_ADMIN_REGISTER)).willReturn(kickForAdminRegister); CommandSender sender = mock(CommandSender.class); // when diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java index bb12b3dd..3d9cf354 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/ReloadCommandTest.java @@ -3,13 +3,13 @@ package fr.xephi.authme.command.executable.authme; import ch.jalu.injector.Injector; import fr.xephi.authme.AuthMe; import fr.xephi.authme.TestHelper; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSourceType; import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.initialization.SettingsDependent; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.output.LogLevel; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.PluginSettings; @@ -59,7 +59,7 @@ public class ReloadCommandTest { private DataSource dataSource; @Mock - private CommandService commandService; + private CommonService commandService; @BeforeClass public static void setUpLogger() { diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java index a98d4bbd..30c97c89 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/SetEmailCommandTest.java @@ -1,11 +1,12 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.command.CommandService; 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.service.BukkitService; +import fr.xephi.authme.service.CommonService; +import fr.xephi.authme.service.ValidationService; import org.bukkit.command.CommandSender; import org.junit.Test; import org.junit.runner.RunWith; @@ -37,27 +38,30 @@ public class SetEmailCommandTest { private DataSource dataSource; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private PlayerCache playerCache; @Mock private BukkitService bukkitService; + + @Mock + private ValidationService validationService; @Test public void shouldRejectInvalidMail() { // given String user = "somebody"; String email = "some.test@example.org"; - given(commandService.validateEmail(email)).willReturn(false); + given(validationService.validateEmail(email)).willReturn(false); CommandSender sender = mock(CommandSender.class); // when command.executeCommand(sender, Arrays.asList(user, email)); // then - verify(commandService).validateEmail(email); + verify(validationService).validateEmail(email); verify(commandService).send(sender, MessageKey.INVALID_EMAIL); verifyZeroInteractions(dataSource); } @@ -67,7 +71,7 @@ public class SetEmailCommandTest { // given String user = "nonexistent"; String email = "mail@example.com"; - given(commandService.validateEmail(email)).willReturn(true); + given(validationService.validateEmail(email)).willReturn(true); given(dataSource.getAuth(user)).willReturn(null); CommandSender sender = mock(CommandSender.class); @@ -76,7 +80,7 @@ public class SetEmailCommandTest { runOptionallyAsyncTask(bukkitService); // then - verify(commandService).validateEmail(email); + verify(validationService).validateEmail(email); verify(dataSource).getAuth(user); verify(commandService).send(sender, MessageKey.UNKNOWN_USER); verifyNoMoreInteractions(dataSource); @@ -87,20 +91,20 @@ public class SetEmailCommandTest { // given String user = "someone"; String email = "mail@example.com"; - given(commandService.validateEmail(email)).willReturn(true); + given(validationService.validateEmail(email)).willReturn(true); PlayerAuth auth = mock(PlayerAuth.class); given(dataSource.getAuth(user)).willReturn(auth); CommandSender sender = mock(CommandSender.class); - given(commandService.isEmailFreeForRegistration(email, sender)).willReturn(false); + given(validationService.isEmailFreeForRegistration(email, sender)).willReturn(false); // when command.executeCommand(sender, Arrays.asList(user, email)); runOptionallyAsyncTask(bukkitService); // then - verify(commandService).validateEmail(email); + verify(validationService).validateEmail(email); verify(dataSource).getAuth(user); - verify(commandService).isEmailFreeForRegistration(email, sender); + verify(validationService).isEmailFreeForRegistration(email, sender); verify(commandService).send(sender, MessageKey.EMAIL_ALREADY_USED_ERROR); verifyNoMoreInteractions(dataSource); verifyZeroInteractions(auth); @@ -111,11 +115,11 @@ public class SetEmailCommandTest { // given String user = "Bobby"; String email = "new-addr@example.org"; - given(commandService.validateEmail(email)).willReturn(true); + given(validationService.validateEmail(email)).willReturn(true); PlayerAuth auth = mock(PlayerAuth.class); given(dataSource.getAuth(user)).willReturn(auth); CommandSender sender = mock(CommandSender.class); - given(commandService.isEmailFreeForRegistration(email, sender)).willReturn(true); + given(validationService.isEmailFreeForRegistration(email, sender)).willReturn(true); given(dataSource.updateEmail(auth)).willReturn(false); // when @@ -123,9 +127,9 @@ public class SetEmailCommandTest { runOptionallyAsyncTask(bukkitService); // then - verify(commandService).validateEmail(email); + verify(validationService).validateEmail(email); verify(dataSource).getAuth(user); - verify(commandService).isEmailFreeForRegistration(email, sender); + verify(validationService).isEmailFreeForRegistration(email, sender); verify(commandService).send(sender, MessageKey.ERROR); verify(dataSource).updateEmail(auth); verifyNoMoreInteractions(dataSource); @@ -136,11 +140,11 @@ public class SetEmailCommandTest { // given String user = "Bobby"; String email = "new-addr@example.org"; - given(commandService.validateEmail(email)).willReturn(true); + given(validationService.validateEmail(email)).willReturn(true); PlayerAuth auth = mock(PlayerAuth.class); given(dataSource.getAuth(user)).willReturn(auth); CommandSender sender = mock(CommandSender.class); - given(commandService.isEmailFreeForRegistration(email, sender)).willReturn(true); + given(validationService.isEmailFreeForRegistration(email, sender)).willReturn(true); given(dataSource.updateEmail(auth)).willReturn(true); given(playerCache.getAuth(user)).willReturn(null); @@ -149,9 +153,9 @@ public class SetEmailCommandTest { runOptionallyAsyncTask(bukkitService); // then - verify(commandService).validateEmail(email); + verify(validationService).validateEmail(email); verify(dataSource).getAuth(user); - verify(commandService).isEmailFreeForRegistration(email, sender); + verify(validationService).isEmailFreeForRegistration(email, sender); verify(commandService).send(sender, MessageKey.EMAIL_CHANGED_SUCCESS); verify(dataSource).updateEmail(auth); verify(playerCache, never()).updatePlayer(any(PlayerAuth.class)); @@ -163,11 +167,11 @@ public class SetEmailCommandTest { // given String user = "Bobby"; String email = "new-addr@example.org"; - given(commandService.validateEmail(email)).willReturn(true); + given(validationService.validateEmail(email)).willReturn(true); PlayerAuth auth = mock(PlayerAuth.class); given(dataSource.getAuth(user)).willReturn(auth); CommandSender sender = mock(CommandSender.class); - given(commandService.isEmailFreeForRegistration(email, sender)).willReturn(true); + given(validationService.isEmailFreeForRegistration(email, sender)).willReturn(true); given(dataSource.updateEmail(auth)).willReturn(true); given(playerCache.getAuth(user)).willReturn(mock(PlayerAuth.class)); @@ -176,9 +180,9 @@ public class SetEmailCommandTest { runOptionallyAsyncTask(bukkitService); // then - verify(commandService).validateEmail(email); + verify(validationService).validateEmail(email); verify(dataSource).getAuth(user); - verify(commandService).isEmailFreeForRegistration(email, sender); + verify(validationService).isEmailFreeForRegistration(email, sender); verify(commandService).send(sender, MessageKey.EMAIL_CHANGED_SUCCESS); verify(dataSource).updateEmail(auth); verify(playerCache).updatePlayer(auth); diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java index 5c06fb16..4651b2be 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/UnregisterAdminCommandTest.java @@ -1,10 +1,10 @@ package fr.xephi.authme.command.executable.authme; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.junit.Test; @@ -33,7 +33,7 @@ public class UnregisterAdminCommandTest { private DataSource dataSource; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private BukkitService bukkitService; diff --git a/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java index b6271a0c..45783270 100644 --- a/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/captcha/CaptchaCommandTest.java @@ -2,8 +2,8 @@ package fr.xephi.authme.command.executable.captcha; import fr.xephi.authme.data.CaptchaManager; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.entity.Player; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,7 +34,7 @@ public class CaptchaCommandTest { private PlayerCache playerCache; @Mock - private CommandService commandService; + private CommonService commandService; @Test public void shouldDetectIfPlayerIsLoggedIn() { diff --git a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java index dac17743..d306ff06 100644 --- a/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/changepassword/ChangePasswordCommandTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.changepassword; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.service.ValidationService.ValidationResult; import org.bukkit.command.BlockCommandSender; @@ -38,7 +38,7 @@ public class ChangePasswordCommandTest { private ChangePasswordCommand command; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private PlayerCache playerCache; diff --git a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java index e935bbd0..75c10e7a 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/AddEmailCommandTest.java @@ -1,8 +1,8 @@ package fr.xephi.authme.command.executable.email; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; +import fr.xephi.authme.service.CommonService; import org.bukkit.command.BlockCommandSender; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -29,7 +29,7 @@ public class AddEmailCommandTest { private AddEmailCommand command; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private Management management; diff --git a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java index 1c960405..6d11412d 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java @@ -1,7 +1,6 @@ package fr.xephi.authme.command.executable.email; import fr.xephi.authme.TestHelper; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.datasource.DataSource; @@ -9,6 +8,7 @@ import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.HashedPassword; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.RecoveryCodeService; import fr.xephi.authme.settings.properties.EmailSettings; import org.bukkit.entity.Player; @@ -50,7 +50,7 @@ public class RecoverEmailCommandTest { private PasswordSecurity passwordSecurity; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private DataSource dataSource; diff --git a/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java index de2ba240..2825728a 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/ShowEmailCommandTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.email; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; import fr.xephi.authme.message.MessageKey; +import fr.xephi.authme.service.CommonService; import org.bukkit.entity.Player; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,7 +30,7 @@ public class ShowEmailCommandTest { private ShowEmailCommand command; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private PlayerCache playerCache; diff --git a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java index 1333c786..c63c8c96 100644 --- a/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/register/RegisterCommandTest.java @@ -1,11 +1,12 @@ package fr.xephi.authme.command.executable.register; import fr.xephi.authme.TestHelper; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.mail.SendMailSSL; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; import fr.xephi.authme.security.HashAlgorithm; +import fr.xephi.authme.service.CommonService; +import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.RegistrationSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; @@ -21,7 +22,6 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -44,7 +44,7 @@ public class RegisterCommandTest { private RegisterCommand command; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private Management management; @@ -52,6 +52,9 @@ public class RegisterCommandTest { @Mock private SendMailSSL sendMailSsl; + @Mock + private ValidationService validationService; + @BeforeClass public static void setup() { TestHelper.setupLogger(); @@ -70,7 +73,7 @@ public class RegisterCommandTest { CommandSender sender = mock(BlockCommandSender.class); // when - command.executeCommand(sender, new ArrayList()); + command.executeCommand(sender, Collections.emptyList()); // then verify(sender).sendMessage(argThat(containsString("Player only!"))); @@ -84,7 +87,7 @@ public class RegisterCommandTest { Player player = mock(Player.class); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(management).performRegister(player, "", "", true); @@ -97,7 +100,7 @@ public class RegisterCommandTest { Player player = mock(Player.class); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(commandService).send(player, MessageKey.USAGE_REGISTER); @@ -154,7 +157,7 @@ public class RegisterCommandTest { public void shouldRejectInvalidEmail() { // given String playerMail = "player@example.org"; - given(commandService.validateEmail(playerMail)).willReturn(false); + given(validationService.validateEmail(playerMail)).willReturn(false); given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true); given(commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL)).willReturn(true); @@ -165,7 +168,7 @@ public class RegisterCommandTest { command.executeCommand(player, Arrays.asList(playerMail, playerMail)); // then - verify(commandService).validateEmail(playerMail); + verify(validationService).validateEmail(playerMail); verify(commandService).send(player, MessageKey.INVALID_EMAIL); verifyZeroInteractions(management); } @@ -174,7 +177,7 @@ public class RegisterCommandTest { public void shouldRejectInvalidEmailConfirmation() { // given String playerMail = "bobber@bobby.org"; - given(commandService.validateEmail(playerMail)).willReturn(true); + given(validationService.validateEmail(playerMail)).willReturn(true); given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true); given(commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL)).willReturn(true); @@ -194,7 +197,7 @@ public class RegisterCommandTest { public void shouldPerformEmailRegistration() { // given String playerMail = "asfd@lakjgre.lds"; - given(commandService.validateEmail(playerMail)).willReturn(true); + given(validationService.validateEmail(playerMail)).willReturn(true); int passLength = 7; given(commandService.getProperty(EmailSettings.RECOVERY_PASSWORD_LENGTH)).willReturn(passLength); @@ -207,7 +210,7 @@ public class RegisterCommandTest { command.executeCommand(player, Arrays.asList(playerMail, playerMail)); // then - verify(commandService).validateEmail(playerMail); + verify(validationService).validateEmail(playerMail); verify(sendMailSsl).hasAllInformation(); verify(management).performRegister(eq(player), argThat(stringWithLength(passLength)), eq(playerMail), eq(true)); } diff --git a/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java index c1dc8746..e646031f 100644 --- a/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/unregister/UnregisterCommandTest.java @@ -1,9 +1,9 @@ package fr.xephi.authme.command.executable.unregister; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.command.CommandService; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.process.Management; +import fr.xephi.authme.service.CommonService; import org.bukkit.entity.Player; import org.junit.Test; import org.junit.runner.RunWith; @@ -31,7 +31,7 @@ public class UnregisterCommandTest { private Management management; @Mock - private CommandService commandService; + private CommonService commandService; @Mock private PlayerCache playerCache; diff --git a/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java b/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java index 46249d6d..c8c82962 100644 --- a/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java +++ b/src/test/java/fr/xephi/authme/process/email/AsyncAddEmailTest.java @@ -5,7 +5,8 @@ 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.ProcessService; +import fr.xephi.authme.service.CommonService; +import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.properties.RegistrationSettings; import org.bukkit.entity.Player; import org.junit.BeforeClass; @@ -40,7 +41,10 @@ public class AsyncAddEmailTest { private PlayerCache playerCache; @Mock - private ProcessService service; + private CommonService service; + + @Mock + private ValidationService validationService; @BeforeClass public static void setUp() { @@ -57,8 +61,8 @@ public class AsyncAddEmailTest { given(auth.getEmail()).willReturn(null); given(playerCache.getAuth("tester")).willReturn(auth); given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(true); - given(service.validateEmail(email)).willReturn(true); - given(service.isEmailFreeForRegistration(email, player)).willReturn(true); + given(validationService.validateEmail(email)).willReturn(true); + given(validationService.isEmailFreeForRegistration(email, player)).willReturn(true); // when asyncAddEmail.addEmail(player, email); @@ -80,8 +84,8 @@ public class AsyncAddEmailTest { given(auth.getEmail()).willReturn(null); given(playerCache.getAuth("tester")).willReturn(auth); given(dataSource.updateEmail(any(PlayerAuth.class))).willReturn(false); - given(service.validateEmail(email)).willReturn(true); - given(service.isEmailFreeForRegistration(email, player)).willReturn(true); + given(validationService.validateEmail(email)).willReturn(true); + given(validationService.isEmailFreeForRegistration(email, player)).willReturn(true); // when asyncAddEmail.addEmail(player, email); @@ -117,7 +121,7 @@ public class AsyncAddEmailTest { PlayerAuth auth = mock(PlayerAuth.class); given(auth.getEmail()).willReturn(null); given(playerCache.getAuth("my_player")).willReturn(auth); - given(service.validateEmail(email)).willReturn(false); + given(validationService.validateEmail(email)).willReturn(false); // when asyncAddEmail.addEmail(player, email); @@ -136,8 +140,8 @@ public class AsyncAddEmailTest { PlayerAuth auth = mock(PlayerAuth.class); given(auth.getEmail()).willReturn(null); given(playerCache.getAuth("testname")).willReturn(auth); - given(service.validateEmail(email)).willReturn(true); - given(service.isEmailFreeForRegistration(email, player)).willReturn(false); + given(validationService.validateEmail(email)).willReturn(true); + given(validationService.isEmailFreeForRegistration(email, player)).willReturn(false); // when asyncAddEmail.addEmail(player, email); diff --git a/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java b/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java index 428a5003..145de51c 100644 --- a/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java +++ b/src/test/java/fr/xephi/authme/process/email/AsyncChangeEmailTest.java @@ -4,7 +4,8 @@ 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.ProcessService; +import fr.xephi.authme.service.CommonService; +import fr.xephi.authme.service.ValidationService; import fr.xephi.authme.settings.properties.RegistrationSettings; import org.bukkit.entity.Player; import org.junit.Test; @@ -39,7 +40,10 @@ public class AsyncChangeEmailTest { private DataSource dataSource; @Mock - private ProcessService service; + private CommonService service; + + @Mock + private ValidationService validationService; @Test public void shouldAddEmail() { @@ -50,8 +54,8 @@ public class AsyncChangeEmailTest { PlayerAuth auth = authWithMail("old@mail.tld"); given(playerCache.getAuth("bobby")).willReturn(auth); given(dataSource.updateEmail(auth)).willReturn(true); - given(service.validateEmail(newEmail)).willReturn(true); - given(service.isEmailFreeForRegistration(newEmail, player)).willReturn(true); + given(validationService.validateEmail(newEmail)).willReturn(true); + given(validationService.isEmailFreeForRegistration(newEmail, player)).willReturn(true); // when process.changeEmail(player, "old@mail.tld", newEmail); @@ -71,8 +75,8 @@ public class AsyncChangeEmailTest { PlayerAuth auth = authWithMail("old@mail.tld"); given(playerCache.getAuth("bobby")).willReturn(auth); given(dataSource.updateEmail(auth)).willReturn(false); - given(service.validateEmail(newEmail)).willReturn(true); - given(service.isEmailFreeForRegistration(newEmail, player)).willReturn(true); + given(validationService.validateEmail(newEmail)).willReturn(true); + given(validationService.isEmailFreeForRegistration(newEmail, player)).willReturn(true); // when process.changeEmail(player, "old@mail.tld", newEmail); @@ -108,7 +112,7 @@ public class AsyncChangeEmailTest { given(playerCache.isAuthenticated("bobby")).willReturn(true); PlayerAuth auth = authWithMail("old@mail.tld"); given(playerCache.getAuth("bobby")).willReturn(auth); - given(service.validateEmail(newEmail)).willReturn(false); + given(validationService.validateEmail(newEmail)).willReturn(false); // when process.changeEmail(player, "old@mail.tld", newEmail); @@ -127,7 +131,7 @@ public class AsyncChangeEmailTest { given(playerCache.isAuthenticated("bobby")).willReturn(true); PlayerAuth auth = authWithMail("other@address.email"); given(playerCache.getAuth("bobby")).willReturn(auth); - given(service.validateEmail(newEmail)).willReturn(true); + given(validationService.validateEmail(newEmail)).willReturn(true); // when process.changeEmail(player, "old@mail.tld", newEmail); @@ -146,8 +150,8 @@ public class AsyncChangeEmailTest { given(playerCache.isAuthenticated("username")).willReturn(true); PlayerAuth auth = authWithMail("old@example.com"); given(playerCache.getAuth("username")).willReturn(auth); - given(service.validateEmail(newEmail)).willReturn(true); - given(service.isEmailFreeForRegistration(newEmail, player)).willReturn(false); + given(validationService.validateEmail(newEmail)).willReturn(true); + given(validationService.isEmailFreeForRegistration(newEmail, player)).willReturn(false); // when process.changeEmail(player, "old@example.com", newEmail); diff --git a/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java b/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java index 79f70131..d2a60529 100644 --- a/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java +++ b/src/test/java/fr/xephi/authme/process/login/AsynchronousLoginTest.java @@ -8,7 +8,7 @@ import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerStatePermission; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.properties.DatabaseSettings; import fr.xephi.authme.settings.properties.HooksSettings; @@ -56,7 +56,7 @@ public class AsynchronousLoginTest { @Mock private PlayerCache playerCache; @Mock - private ProcessService processService; + private CommonService commonService; @Mock private LimboPlayerTaskManager limboPlayerTaskManager; @Mock @@ -81,7 +81,7 @@ public class AsynchronousLoginTest { // then verify(playerCache, only()).isAuthenticated(name); - verify(processService).send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); + verify(commonService).send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); verifyZeroInteractions(dataSource); } @@ -98,7 +98,7 @@ public class AsynchronousLoginTest { // then verify(playerCache, only()).isAuthenticated(name); - verify(processService).send(player, MessageKey.USER_NOT_REGISTERED); + verify(commonService).send(player, MessageKey.USER_NOT_REGISTERED); verify(dataSource, only()).getAuth(name); } @@ -111,15 +111,15 @@ public class AsynchronousLoginTest { int groupId = 13; PlayerAuth auth = PlayerAuth.builder().name(name).groupId(groupId).build(); given(dataSource.getAuth(name)).willReturn(auth); - given(processService.getProperty(DatabaseSettings.MYSQL_COL_GROUP)).willReturn("group"); - given(processService.getProperty(HooksSettings.NON_ACTIVATED_USERS_GROUP)).willReturn(groupId); + given(commonService.getProperty(DatabaseSettings.MYSQL_COL_GROUP)).willReturn("group"); + given(commonService.getProperty(HooksSettings.NON_ACTIVATED_USERS_GROUP)).willReturn(groupId); // when asynchronousLogin.forceLogin(player); // then verify(playerCache, only()).isAuthenticated(name); - verify(processService).send(player, MessageKey.ACCOUNT_NOT_ACTIVATED); + verify(commonService).send(player, MessageKey.ACCOUNT_NOT_ACTIVATED); verify(dataSource, only()).getAuth(name); } @@ -133,7 +133,7 @@ public class AsynchronousLoginTest { given(playerCache.isAuthenticated(name)).willReturn(false); PlayerAuth auth = PlayerAuth.builder().name(name).build(); given(dataSource.getAuth(name)).willReturn(auth); - given(processService.getProperty(DatabaseSettings.MYSQL_COL_GROUP)).willReturn(""); + given(commonService.getProperty(DatabaseSettings.MYSQL_COL_GROUP)).willReturn(""); doReturn(true).when(asynchronousLogin).hasReachedMaxLoggedInPlayersForIp(any(Player.class), anyString()); // when @@ -141,7 +141,7 @@ public class AsynchronousLoginTest { // then verify(playerCache, only()).isAuthenticated(name); - verify(processService).send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); + verify(commonService).send(player, MessageKey.ALREADY_LOGGED_IN_ERROR); verify(dataSource, only()).getAuth(name); verify(asynchronousLogin).hasReachedMaxLoggedInPlayersForIp(player, ip); } @@ -156,8 +156,8 @@ public class AsynchronousLoginTest { given(playerCache.isAuthenticated(name)).willReturn(false); PlayerAuth auth = PlayerAuth.builder().name(name).build(); given(dataSource.getAuth(name)).willReturn(auth); - given(processService.getProperty(DatabaseSettings.MYSQL_COL_GROUP)).willReturn(""); - given(processService.getProperty(PluginSettings.USE_ASYNC_TASKS)).willReturn(true); + given(commonService.getProperty(DatabaseSettings.MYSQL_COL_GROUP)).willReturn(""); + given(commonService.getProperty(PluginSettings.USE_ASYNC_TASKS)).willReturn(true); doReturn(false).when(asynchronousLogin).hasReachedMaxLoggedInPlayersForIp(any(Player.class), anyString()); doAnswer(new Answer() { @Override @@ -181,7 +181,7 @@ public class AsynchronousLoginTest { public void shouldPassMaxLoginPerIpCheck() { // given Player player = mockPlayer("Carl"); - given(processService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(2); + given(commonService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(2); given(permissionsManager.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)).willReturn(false); mockOnlinePlayersInBukkitService(); @@ -198,7 +198,7 @@ public class AsynchronousLoginTest { public void shouldSkipIpCheckForZeroThreshold() { // given Player player = mockPlayer("Fiona"); - given(processService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(0); + given(commonService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(0); // when boolean result = asynchronousLogin.hasReachedMaxLoggedInPlayersForIp(player, "192.168.0.1"); @@ -212,7 +212,7 @@ public class AsynchronousLoginTest { public void shouldSkipIpCheckForPlayerWithMultipleAccountsPermission() { // given Player player = mockPlayer("Frank"); - given(processService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(1); + given(commonService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(1); given(permissionsManager.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)).willReturn(true); // when @@ -228,7 +228,7 @@ public class AsynchronousLoginTest { public void shouldFailIpCheckForIpWithTooManyPlayersOnline() { // given Player player = mockPlayer("Ian"); - given(processService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(2); + given(commonService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(2); given(permissionsManager.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)).willReturn(false); mockOnlinePlayersInBukkitService(); diff --git a/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java b/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java index cfe141f3..d586b425 100644 --- a/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java +++ b/src/test/java/fr/xephi/authme/process/unregister/AsynchronousUnregisterTest.java @@ -8,7 +8,7 @@ import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.permission.AuthGroupHandler; import fr.xephi.authme.permission.AuthGroupType; -import fr.xephi.authme.process.ProcessService; +import fr.xephi.authme.service.CommonService; import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.crypts.HashedPassword; import fr.xephi.authme.service.BukkitService; @@ -45,7 +45,7 @@ public class AsynchronousUnregisterTest { @Mock private DataSource dataSource; @Mock - private ProcessService service; + private CommonService service; @Mock private PasswordSecurity passwordSecurity; @Mock diff --git a/src/test/java/fr/xephi/authme/process/ProcessServiceTest.java b/src/test/java/fr/xephi/authme/service/CommonServiceTest.java similarity index 66% rename from src/test/java/fr/xephi/authme/process/ProcessServiceTest.java rename to src/test/java/fr/xephi/authme/service/CommonServiceTest.java index e6df0b47..ff992bfe 100644 --- a/src/test/java/fr/xephi/authme/process/ProcessServiceTest.java +++ b/src/test/java/fr/xephi/authme/service/CommonServiceTest.java @@ -1,4 +1,4 @@ -package fr.xephi.authme.process; +package fr.xephi.authme.service; import fr.xephi.authme.message.MessageKey; import fr.xephi.authme.message.Messages; @@ -9,7 +9,6 @@ import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.SecuritySettings; -import fr.xephi.authme.service.ValidationService; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.junit.Test; @@ -25,16 +24,13 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; /** - * Test for {@link ProcessService}. + * Test for {@link CommonService}. */ @RunWith(MockitoJUnitRunner.class) -public class ProcessServiceTest { +public class CommonServiceTest { @InjectMocks - private ProcessService processService; - - @Mock - private ValidationService validationService; + private CommonService commonService; @Mock private Settings settings; @@ -54,22 +50,13 @@ public class ProcessServiceTest { given(settings.getProperty(SecuritySettings.CAPTCHA_LENGTH)).willReturn(8); // when - int result = processService.getProperty(SecuritySettings.CAPTCHA_LENGTH); + int result = commonService.getProperty(SecuritySettings.CAPTCHA_LENGTH); // then verify(settings).getProperty(SecuritySettings.CAPTCHA_LENGTH); assertThat(result, equalTo(8)); } - @Test - public void shouldReturnSettings() { - // given/when - Settings result = processService.getSettings(); - - // then - assertThat(result, equalTo(settings)); - } - @Test public void shouldSendMessageToPlayer() { // given @@ -77,7 +64,7 @@ public class ProcessServiceTest { MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED; // when - processService.send(sender, key); + commonService.send(sender, key); // then verify(messages).send(sender, key); @@ -91,7 +78,7 @@ public class ProcessServiceTest { String[] replacements = new String[]{"test", "toast"}; // when - processService.send(sender, key, replacements); + commonService.send(sender, key, replacements); // then verify(messages).send(sender, key, replacements); @@ -105,7 +92,7 @@ public class ProcessServiceTest { given(messages.retrieve(key)).willReturn(lines); // when - String[] result = processService.retrieveMessage(key); + String[] result = commonService.retrieveMessage(key); // then assertThat(result, equalTo(lines)); @@ -120,43 +107,13 @@ public class ProcessServiceTest { given(messages.retrieveSingle(key)).willReturn(text); // when - String result = processService.retrieveSingleMessage(key); + String result = commonService.retrieveSingleMessage(key); // then assertThat(result, equalTo(text)); verify(messages).retrieveSingle(key); } - @Test - public void shouldValidateEmail() { - // given - String email = "test@example.tld"; - given(validationService.validateEmail(email)).willReturn(true); - - // when - boolean result = processService.validateEmail(email); - - // then - assertThat(result, equalTo(true)); - verify(validationService).validateEmail(email); - } - - @Test - public void shouldCheckIfEmailCanBeUsed() { - // given - String email = "mail@example.com"; - CommandSender sender = mock(CommandSender.class); - given(validationService.isEmailFreeForRegistration(email, sender)) - .willReturn(true); - - // when - boolean result = processService.isEmailFreeForRegistration(email, sender); - - // then - assertThat(result, equalTo(true)); - verify(validationService).isEmailFreeForRegistration(email, sender); - } - @Test public void shouldCheckPermission() { // given @@ -165,7 +122,7 @@ public class ProcessServiceTest { given(permissionsManager.hasPermission(player, permission)).willReturn(true); // when - boolean result = processService.hasPermission(player, permission); + boolean result = commonService.hasPermission(player, permission); // then verify(permissionsManager).hasPermission(player, permission); @@ -180,7 +137,7 @@ public class ProcessServiceTest { given(authGroupHandler.setGroup(player, type)).willReturn(true); // when - boolean result = processService.setGroup(player, type); + boolean result = commonService.setGroup(player, type); // then verify(authGroupHandler).setGroup(player, type); From 2d27c0cbb6c95f60b25b5410bc6361ad288d8947 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 4 Dec 2016 16:26:13 +0100 Subject: [PATCH 61/67] Add Romanian translation --- docs/translations.md | 9 ++- src/main/resources/messages/messages_ro.yml | 76 +++++++++++++++++++ .../TranslationPageGenerator.java | 1 + 3 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/messages/messages_ro.yml diff --git a/docs/translations.md b/docs/translations.md index 42170005..905a5eaf 100644 --- a/docs/translations.md +++ b/docs/translations.md @@ -1,5 +1,5 @@ - + # AuthMe Translations The following translations are available in AuthMe. Set `messagesLanguage` to the language code @@ -12,7 +12,7 @@ Code | Language | Translated |   [br](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_br.yml) | Brazilian | 100% | bar [cz](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_cz.yml) | Czech | 88% | bar [de](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_de.yml) | German | 95% | bar -[es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 97% | bar +[es](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_es.yml) | Spanish | 100% | bar [eu](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_eu.yml) | Basque | 64% | bar [fi](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fi.yml) | Finnish | 68% | bar [fr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_fr.yml) | French | 95% | bar @@ -23,8 +23,9 @@ Code | Language | Translated |   [ko](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ko.yml) | Korean | 74% | bar [lt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_lt.yml) | Latvian | 55% | bar [nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 78% | bar -[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 99% | bar +[pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 100% | bar [pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 88% | bar +[ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 83% | bar [ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 100% | bar [sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 49% | bar [tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 83% | bar @@ -37,4 +38,4 @@ Code | Language | Translated |   --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sat Nov 19 11:44:25 CET 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Dec 04 16:24:35 CET 2016 diff --git a/src/main/resources/messages/messages_ro.yml b/src/main/resources/messages/messages_ro.yml new file mode 100644 index 00000000..cc75b987 --- /dev/null +++ b/src/main/resources/messages/messages_ro.yml @@ -0,0 +1,76 @@ +kick_antibot: 'Protectia AntiBot-ului este activata! Trebuie sa astepti cateva minute pentru a intra pe server.' +unknown_user: '&cNu putem gasi jucator-ul in baza de date!' +unsafe_spawn: '&cLocatia asta care esti acum nu esti in siguranta, ai fost teleportat la spaun.' +not_logged_in: '&cNu te-ai logat!' +reg_voluntarily: 'Te poti regista pe server folosind comanda "/register "' +usage_log: '&cFoloseste: /login pentru a te loga.' +wrong_pwd: '&cParola gresiat!' +unregistered: '&cTeai unregistart cu succes!' +reg_disabled: '&cRegistrarea in joc nu este activata!' +valid_session: '&2Teai logat cu reconectarea sesiuni.' +login: '&2Teai logat cu succes!' +vb_nonActiv: '&cContul tau nu este activat, te rugan verificati email-ul!' +user_regged: '&cCineva este registrat cu acest nume!' +no_perm: '&4Nu ai permisiune sa faci aceasta actiune!' +error: '&4A aparut o eroare, te rugam contacteaza un membru din staff!' +login_msg: '&cTe rugam sa te logezi folosind comana "/login "' +reg_msg: '&3Te rugam sa te inregistrezi folosind comanda "/register "' +reg_email_msg: '&3Te rugam sa te inregistrezi folosind comanda "/register "' +max_reg: '&cTeai inregistrat cu prea multe counturi (%reg_count/%max_acc %reg_names) pentru conexiunea ta!' +usage_reg: '&cFoloseste comanda: /register ' +usage_unreg: '&cFoloseste comanda: /unregister ' +pwd_changed: '&2Parola a fost inregistrata cu succes!' +user_unknown: '&cAcest jucator nu este inregistrat!' +password_error: '&cParolele nu au corespuns, verificale di nou!' +password_error_nick: '&cNu poti folosi numele ca si parola, te rugam incearca alta...' +password_error_unsafe: '&cParola aleasa nu este in siguranta, te rugam alege alta...' +invalid_session: '&cIP-ul tau a fost schimbat si sesiunea ta a expirat!' +reg_only: '&4Doar jucatori inregistrati pot intra pwe server! Te rugam foloseste http://example.ro pentru a te inregistra!' +logged_in: '&cIesti deja logat!' +logout: '&2Teai delogat cu succes!' +same_nick: '&4Acelas nume se joaca deja pe server!' +registered: '&2Teai inregistrat cu succes!' +pass_len: '&cParola ta este prea scurta pentru a te inregistra! Te rugam incearca alta!' +reload: '&2Configuratiile si baza de date sau reloadat corect!' +timeout: '&4A expirat timp-ul de logare, ai fost dat afara de server, te rugam incearca di nou!' +usage_changepassword: '&cFoloseste comanda: /changepassword ' +name_len: '&4Numele tau este prea scur pentru a te inregistra!' +regex: '&4Numele tau contine caractere ilegale. Caractere permise: REG_EX' +add_email: '&3Te rugam adaugati email-ul la contul tau folosind comanda "/email add "' +recovery_email: '&3Tiai uitat parola? Te rugam foloseste comanda "/email recovery "' +usage_captcha: '&3Pentru a te loga trebuie sa folosesti codul de la captcha, te rugam foloseste comanda "/captcha "' +wrong_captcha: '&cCod-ul captcha este gresit, te rugam foloseste comanda "/captcha THE_CAPTCHA" in chat!' +valid_captcha: '&2Cod-ul captcha a fost scris corect!' +kick_forvip: '&3Un V.I.P a intrat pe server cand era plin!' +kick_fullserver: '&4Server-ul este plin, te rugam incearca di nou mai tarziu!' +usage_email_add: '&cFoloseste comanda: /email add ' +usage_email_change: '&cFoloseste comanda: /email change ' +usage_email_recovery: '&cFoloseste comanda: /email recovery ' +new_email_invalid: '&cNoul email este invalid, incearca di nou!' +old_email_invalid: '&cEmail-ul vechi este invalid, incearca di nou!' +email_invalid: '&cEmail-ul este invalid, incearca di nou!' +email_added: '&2Email-ul a fost adaugat cu succes la cont-ul tau!' +email_confirm: '&cTe rugam confirma adresa de email!' +email_changed: '&2Email-ul a fost schimbat corect!' +email_send: ' &2Recuperarea email-ul a fost trimis cu succes! Te rugam verificati email-ul in inbox!' +email_exists: '&cRecuperarea email-ului a fost deja setata ! Puteti sa-l aruncati si sa trimiteti unul nou folosind comanda de mai jos:' +country_banned: '&4Tara ta este banata pe acest server!' +antibot_auto_enabled: '&4[AntiBotService] AntiBot-ul a fost activat din cauza numărului mare de conexiuni!' +antibot_auto_disabled: '&2[AntiBotService] AntiBot-ul a fost desactivat dupa %m de minute!' +email_already_used: '&4Email-ul a fost deja folosit' +two_factor_create: '&2Cod-ul tau secret este %code. Il poti scana de aici %url' +not_owner_error: 'Tu nu esti owner-ul acestui cont. Te rugam alege alt nume!' +invalid_name_case: 'Ar trebui sa intri cu un nume %valid nu %invalid' +# TODO denied_command: '&cIn order to use this command you must be authenticated!' +# TODO same_ip_online: 'A player with the same IP is already in game!' +# TODO denied_chat: '&cIn order to chat you must be authenticated!' +# TODO password_error_chars: '&4Your password contains illegal characters. Allowed chars: REG_EX' +# TODO email_show: '&2Your current email address is: &f%email' +# TODO show_no_email: '&2You currently don''t have email address associated with this account.' +# TODO tempban_max_logins: '&cYou have been temporarily banned for failing to log in too many times.' +# TODO accounts_owned_self: 'You own %count accounts:' +# TODO accounts_owned_other: 'The player %name has %count accounts:' +# TODO kicked_admin_registered: 'An admin just registered you; please log in again' +# TODO incomplete_email_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.' +# TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' +# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' \ No newline at end of file diff --git a/src/test/java/tools/docs/translations/TranslationPageGenerator.java b/src/test/java/tools/docs/translations/TranslationPageGenerator.java index 83277927..f24321f8 100644 --- a/src/test/java/tools/docs/translations/TranslationPageGenerator.java +++ b/src/test/java/tools/docs/translations/TranslationPageGenerator.java @@ -124,6 +124,7 @@ public class TranslationPageGenerator implements AutoToolTask { .put("nl", "Dutch") .put("pl", "Polish") .put("pt", "Portuguese") + .put("ro", "Romanian") .put("ru", "Russian") .put("sk", "Slovakian") .put("tr", "Turkish") From 2586963780d235a96c03145067e389117bd7a694 Mon Sep 17 00:00:00 2001 From: DNx5 Date: Tue, 6 Dec 2016 01:24:36 +0700 Subject: [PATCH 62/67] Remove redundant Optional usages --- .../authme/datasource/CacheDataSource.java | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java index ebd9299e..fc4e88a4 100644 --- a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java @@ -1,6 +1,5 @@ package fr.xephi.authme.datasource; -import com.google.common.base.Optional; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -11,22 +10,19 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.data.auth.PlayerCache; -import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.datasource.DataSourceType; import fr.xephi.authme.security.crypts.HashedPassword; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; -import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class CacheDataSource implements DataSource { private final DataSource source; - private final LoadingCache> cachedAuths; + private final LoadingCache cachedAuths; private final ListeningExecutorService executorService; /** @@ -45,25 +41,20 @@ public class CacheDataSource implements DataSource { cachedAuths = CacheBuilder.newBuilder() .refreshAfterWrite(5, TimeUnit.MINUTES) .expireAfterAccess(15, TimeUnit.MINUTES) - .build(new CacheLoader>() { + .build(new CacheLoader() { @Override - public Optional load(String key) { - return Optional.fromNullable(source.getAuth(key)); + public PlayerAuth load(String key) { + return source.getAuth(key); } @Override - public ListenableFuture> reload(final String key, Optional oldValue) { - return executorService.submit(new Callable>() { - @Override - public Optional call() { - return load(key); - } - }); + public ListenableFuture reload(final String key, PlayerAuth oldValue) { + return executorService.submit(() -> load(key)); } }); } - public LoadingCache> getCachedAuths() { + public LoadingCache getCachedAuths() { return cachedAuths; } @@ -80,9 +71,9 @@ public class CacheDataSource implements DataSource { @Override public HashedPassword getPassword(String user) { user = user.toLowerCase(); - Optional pAuthOpt = cachedAuths.getIfPresent(user); - if (pAuthOpt != null && pAuthOpt.isPresent()) { - return pAuthOpt.get().getPassword(); + PlayerAuth auth = cachedAuths.getIfPresent(user); + if (auth != null) { + return auth.getPassword(); } return source.getPassword(user); } @@ -90,7 +81,7 @@ public class CacheDataSource implements DataSource { @Override public PlayerAuth getAuth(String user) { user = user.toLowerCase(); - return cachedAuths.getUnchecked(user).orNull(); + return cachedAuths.getUnchecked(user); } @Override From 7054c087f167cbc6de1159eab873e957acdbcb1c Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 11 Dec 2016 08:18:03 +0100 Subject: [PATCH 63/67] Integrate Romanian corrections and additions by @nicuch --- docs/translations.md | 6 +- src/main/resources/messages/messages_ro.yml | 116 ++++++++++---------- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/docs/translations.md b/docs/translations.md index 905a5eaf..a96f2cf6 100644 --- a/docs/translations.md +++ b/docs/translations.md @@ -1,5 +1,5 @@ - + # AuthMe Translations The following translations are available in AuthMe. Set `messagesLanguage` to the language code @@ -25,7 +25,7 @@ Code | Language | Translated |   [nl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_nl.yml) | Dutch | 78% | bar [pl](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pl.yml) | Polish | 100% | bar [pt](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_pt.yml) | Portuguese | 88% | bar -[ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 83% | bar +[ro](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ro.yml) | Romanian | 100% | bar [ru](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_ru.yml) | Russian | 100% | bar [sk](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_sk.yml) | Slovakian | 49% | bar [tr](https://github.com/AuthMe/AuthMeReloaded/blob/master/src/main/resources/messages/messages_tr.yml) | Turkish | 83% | bar @@ -38,4 +38,4 @@ Code | Language | Translated |   --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Dec 04 16:24:35 CET 2016 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Dec 11 08:16:38 CET 2016 diff --git a/src/main/resources/messages/messages_ro.yml b/src/main/resources/messages/messages_ro.yml index cc75b987..f6233c76 100644 --- a/src/main/resources/messages/messages_ro.yml +++ b/src/main/resources/messages/messages_ro.yml @@ -1,76 +1,76 @@ kick_antibot: 'Protectia AntiBot-ului este activata! Trebuie sa astepti cateva minute pentru a intra pe server.' -unknown_user: '&cNu putem gasi jucator-ul in baza de date!' -unsafe_spawn: '&cLocatia asta care esti acum nu esti in siguranta, ai fost teleportat la spaun.' +unknown_user: '&cNu putem gasi jucatorul in baza de date!' +unsafe_spawn: '&cLocatia in care esti acum nu este sigura, ai fost teleportat la spawn.' not_logged_in: '&cNu te-ai logat!' -reg_voluntarily: 'Te poti regista pe server folosind comanda "/register "' +reg_voluntarily: 'Te poti inregista pe server folosind comanda "/register "' usage_log: '&cFoloseste: /login pentru a te loga.' -wrong_pwd: '&cParola gresiat!' -unregistered: '&cTeai unregistart cu succes!' -reg_disabled: '&cRegistrarea in joc nu este activata!' -valid_session: '&2Teai logat cu reconectarea sesiuni.' -login: '&2Teai logat cu succes!' -vb_nonActiv: '&cContul tau nu este activat, te rugan verificati email-ul!' -user_regged: '&cCineva este registrat cu acest nume!' -no_perm: '&4Nu ai permisiune sa faci aceasta actiune!' +wrong_pwd: '&cParola gresita!' +unregistered: '&cTe-ai unregistart cu succes!' +reg_disabled: '&cInegistrarea in joc nu este activata!' +valid_session: '&2Te-ai logat cu reconectarea sesiuni.' +login: '&2Te-ai logat cu succes!' +vb_nonActiv: '&cContul tau nu este activat, te rugam verifica-ti email-ul!' +user_regged: '&cCineva este inregistrat cu acest nume!' +no_perm: '&4Nu ai permisiunea!' error: '&4A aparut o eroare, te rugam contacteaza un membru din staff!' -login_msg: '&cTe rugam sa te logezi folosind comana "/login "' +login_msg: '&cTe rugam sa te autentifici folosind comanda "/login "' reg_msg: '&3Te rugam sa te inregistrezi folosind comanda "/register "' -reg_email_msg: '&3Te rugam sa te inregistrezi folosind comanda "/register "' -max_reg: '&cTeai inregistrat cu prea multe counturi (%reg_count/%max_acc %reg_names) pentru conexiunea ta!' +reg_email_msg: '&3Te rugam sa te inregistrezi folosind comanda "/register "' +max_reg: '&cTe-ai inregistrat cu prea multe counturi (%reg_count/%max_acc %reg_names) pentru conexiunea ta!' usage_reg: '&cFoloseste comanda: /register ' usage_unreg: '&cFoloseste comanda: /unregister ' pwd_changed: '&2Parola a fost inregistrata cu succes!' user_unknown: '&cAcest jucator nu este inregistrat!' -password_error: '&cParolele nu au corespuns, verificale di nou!' +password_error: '&cParolele nu corespund, verifica-le din nou!' password_error_nick: '&cNu poti folosi numele ca si parola, te rugam incearca alta...' -password_error_unsafe: '&cParola aleasa nu este in siguranta, te rugam alege alta...' +password_error_unsafe: '&cParola aleasa nu este sigura, te rugam alege alta...' invalid_session: '&cIP-ul tau a fost schimbat si sesiunea ta a expirat!' -reg_only: '&4Doar jucatori inregistrati pot intra pwe server! Te rugam foloseste http://example.ro pentru a te inregistra!' -logged_in: '&cIesti deja logat!' -logout: '&2Teai delogat cu succes!' -same_nick: '&4Acelas nume se joaca deja pe server!' -registered: '&2Teai inregistrat cu succes!' +reg_only: '&4Doar jucatori inregistrati pot intra pe server! Te rugam foloseste http://example.ro pentru a te inregistra!' +logged_in: '&cEsti deja autentificat!' +logout: '&2Te-ai dezautentificat cu succes!' +same_nick: '&4Acelasi nume se joaca deja pe server!' +registered: '&2Te-ai inregistrat cu succes!' pass_len: '&cParola ta este prea scurta pentru a te inregistra! Te rugam incearca alta!' -reload: '&2Configuratiile si baza de date sau reloadat corect!' -timeout: '&4A expirat timp-ul de logare, ai fost dat afara de server, te rugam incearca di nou!' -usage_changepassword: '&cFoloseste comanda: /changepassword ' -name_len: '&4Numele tau este prea scur pentru a te inregistra!' +reload: '&2Configuratiile si baza de date sau reincarcat corect!' +timeout: '&4A expirat timpul de autentificare si ai fost dat afara de server, te rugam incearca din nou!' +usage_changepassword: '&cFoloseste comanda: /changepassword ' +name_len: '&4Numele tau este prea scurt pentru a te inregistra!' regex: '&4Numele tau contine caractere ilegale. Caractere permise: REG_EX' -add_email: '&3Te rugam adaugati email-ul la contul tau folosind comanda "/email add "' -recovery_email: '&3Tiai uitat parola? Te rugam foloseste comanda "/email recovery "' -usage_captcha: '&3Pentru a te loga trebuie sa folosesti codul de la captcha, te rugam foloseste comanda "/captcha "' -wrong_captcha: '&cCod-ul captcha este gresit, te rugam foloseste comanda "/captcha THE_CAPTCHA" in chat!' +add_email: '&3Te rugam adaugati email-ul la contul tau folosind comanda "/email add "' +recovery_email: '&3Ti-ai uitat parola? Te rugam foloseste comanda "/email recovery "' +usage_captcha: '&3Pentru a te autentifica trebuie sa folosesti codul de la captcha, te rugam foloseste comanda "/captcha "' +wrong_captcha: '&cCod-ul captcha este gresit, te rugam foloseste comanda "/captcha "!' valid_captcha: '&2Cod-ul captcha a fost scris corect!' kick_forvip: '&3Un V.I.P a intrat pe server cand era plin!' -kick_fullserver: '&4Server-ul este plin, te rugam incearca di nou mai tarziu!' -usage_email_add: '&cFoloseste comanda: /email add ' -usage_email_change: '&cFoloseste comanda: /email change ' -usage_email_recovery: '&cFoloseste comanda: /email recovery ' -new_email_invalid: '&cNoul email este invalid, incearca di nou!' -old_email_invalid: '&cEmail-ul vechi este invalid, incearca di nou!' -email_invalid: '&cEmail-ul este invalid, incearca di nou!' -email_added: '&2Email-ul a fost adaugat cu succes la cont-ul tau!' +kick_fullserver: '&4Server-ul este plin, te rugam incearca din nou mai tarziu!' +usage_email_add: '&cFoloseste comanda: /email add ' +usage_email_change: '&cFoloseste comanda: /email change ' +usage_email_recovery: '&cFoloseste comanda: /email recovery ' +new_email_invalid: '&cNoul email este invalid, incearca din nou!' +old_email_invalid: '&cEmail-ul vechi este invalid, incearca din nou!' +email_invalid: '&cEmail-ul este invalid, incearca din nou!' +email_added: '&2Email-ul a fost adaugat cu succes la contul tau!' email_confirm: '&cTe rugam confirma adresa de email!' email_changed: '&2Email-ul a fost schimbat corect!' -email_send: ' &2Recuperarea email-ul a fost trimis cu succes! Te rugam verificati email-ul in inbox!' -email_exists: '&cRecuperarea email-ului a fost deja setata ! Puteti sa-l aruncati si sa trimiteti unul nou folosind comanda de mai jos:' -country_banned: '&4Tara ta este banata pe acest server!' -antibot_auto_enabled: '&4[AntiBotService] AntiBot-ul a fost activat din cauza numărului mare de conexiuni!' -antibot_auto_disabled: '&2[AntiBotService] AntiBot-ul a fost desactivat dupa %m de minute!' +email_send: ' &2Recuperarea email-ul a fost trimis cu succes! Te rugam sa verificati email-ul in inbox!' +email_exists: '&cRecuperarea email-ului a fost deja trimisa! Puteti sa-l anulati si sa trimiteti unul nou folosind comanda de mai jos:' +country_banned: '&4Tara ta este interzisa pe acest server!' +antibot_auto_enabled: '&4[AntiBotService] AntiBot-ul a fost activat din cauza numărului mare de conexiuni!' +antibot_auto_disabled: '&2[AntiBotService] AntiBot-ul a fost dezactivat dupa %m de minute!' email_already_used: '&4Email-ul a fost deja folosit' -two_factor_create: '&2Cod-ul tau secret este %code. Il poti scana de aici %url' -not_owner_error: 'Tu nu esti owner-ul acestui cont. Te rugam alege alt nume!' -invalid_name_case: 'Ar trebui sa intri cu un nume %valid nu %invalid' -# TODO denied_command: '&cIn order to use this command you must be authenticated!' -# TODO same_ip_online: 'A player with the same IP is already in game!' -# TODO denied_chat: '&cIn order to chat you must be authenticated!' -# TODO password_error_chars: '&4Your password contains illegal characters. Allowed chars: REG_EX' -# TODO email_show: '&2Your current email address is: &f%email' -# TODO show_no_email: '&2You currently don''t have email address associated with this account.' -# TODO tempban_max_logins: '&cYou have been temporarily banned for failing to log in too many times.' -# TODO accounts_owned_self: 'You own %count accounts:' -# TODO accounts_owned_other: 'The player %name has %count accounts:' -# TODO kicked_admin_registered: 'An admin just registered you; please log in again' -# TODO incomplete_email_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.' -# TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' -# TODO recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' \ No newline at end of file +two_factor_create: '&2Codul tau secret este %code. Il poti scana de aici %url' +not_owner_error: 'Tu nu esti detinatorul acestui cont. Te rugam alege alt nume!' +invalid_name_case: 'Ar trebui sa intri cu numele %valid nu %invalid' +denied_command: '&cPentru a folosi comanda trebuie sa te autentifici!' +same_ip_online: 'Un jucator cu acelasi IP joaca deja!' +denied_chat: 'Pentru a folosi chat-ul trebuie sa te autentifici!' +password_error_chars: '&4Parola ta contine caractere ilegale. Caractere permise: REG_EX' +email_show: '&2Adresa ta curenta de email este: &f%email' +show_no_email: '&2Nu ai nici-o adresa de email asociat cu acest cont.' +tempban_max_logins: '&cAi fost interzis temporar deoarece ai incercat sa te autentifici de prea multe ori.' +accounts_owned_self: 'Detii %count conturi:' +accounts_owned_other: 'Jucatorul %name are %count conturi:' +kicked_admin_registered: 'Un administrator tocmai te-a inregistrat, te rog autentifica-te din nou.' +incomplete_email_settings: 'Eroare: nu toate setarile necesare pentru trimiterea email-ului sunt facute! Te rugam contacteaza un administrator.' +recovery_code_sent: 'Un cod de recuperare a parolei a fost trimis catre email-ul tau.' +recovery_code_incorrect: 'Codul de recuperare nu este corect! Foloseste /email recovery [email] pentru a genera unul nou.' From 5a4e827893dfb81085aef78310ccf305365e1818 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 11 Dec 2016 09:47:48 +0100 Subject: [PATCH 64/67] #960 Send message to player if email could not be sent --- .../executable/email/RecoverEmailCommand.java | 25 +- .../fr/xephi/authme/mail/SendMailSSL.java | 103 ++++---- .../authme/message/MessageFileHandler.java | 2 +- .../fr/xephi/authme/message/MessageKey.java | 2 + .../process/register/AsyncRegister.java | 8 +- src/main/resources/messages/messages_en.yml | 1 + src/main/resources/messages/messages_ro.yml | 4 +- .../email/RecoverEmailCommandTest.java | 3 + .../fr/xephi/authme/mail/SendMailSSLTest.java | 248 ++++++++++++++++++ 9 files changed, 330 insertions(+), 66 deletions(-) create mode 100644 src/test/java/fr/xephi/authme/mail/SendMailSSLTest.java diff --git a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java index e77cd279..c3acb475 100644 --- a/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/email/RecoverEmailCommand.java @@ -84,19 +84,22 @@ public class RecoverEmailCommand extends PlayerCommand { private void createAndSendRecoveryCode(Player player, String email) { String recoveryCode = recoveryCodeService.generateCode(player.getName()); - sendMailSsl.sendRecoveryCode(player.getName(), email, recoveryCode); - commonService.send(player, MessageKey.RECOVERY_CODE_SENT); + boolean couldSendMail = sendMailSsl.sendRecoveryCode(player.getName(), email, recoveryCode); + if (couldSendMail) { + commonService.send(player, MessageKey.RECOVERY_CODE_SENT); + } else { + commonService.send(player, MessageKey.EMAIL_SEND_FAILURE); + } } private void processRecoveryCode(Player player, String code, String email) { final String name = player.getName(); - if (!recoveryCodeService.isCodeValid(name, code)) { + if (recoveryCodeService.isCodeValid(name, code)) { + generateAndSendNewPassword(player, email); + recoveryCodeService.removeCode(name); + } else { commonService.send(player, MessageKey.INCORRECT_RECOVERY_CODE); - return; } - - generateAndSendNewPassword(player, email); - recoveryCodeService.removeCode(name); } private void generateAndSendNewPassword(Player player, String email) { @@ -105,7 +108,11 @@ public class RecoverEmailCommand extends PlayerCommand { HashedPassword hashNew = passwordSecurity.computeHash(thePass, name); dataSource.updatePassword(name, hashNew); - sendMailSsl.sendPasswordMail(name, email, thePass); - commonService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); + boolean couldSendMail = sendMailSsl.sendPasswordMail(name, email, thePass); + if (couldSendMail) { + commonService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE); + } else { + commonService.send(player, MessageKey.EMAIL_SEND_FAILURE); + } } } diff --git a/src/main/java/fr/xephi/authme/mail/SendMailSSL.java b/src/main/java/fr/xephi/authme/mail/SendMailSSL.java index 2076c1d1..c90d9422 100644 --- a/src/main/java/fr/xephi/authme/mail/SendMailSSL.java +++ b/src/main/java/fr/xephi/authme/mail/SendMailSSL.java @@ -1,8 +1,8 @@ package fr.xephi.authme.mail; -import fr.xephi.authme.AuthMe; +import com.google.common.annotations.VisibleForTesting; import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.initialization.DataFolder; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.SecuritySettings; @@ -11,6 +11,7 @@ import fr.xephi.authme.util.StringUtils; import org.apache.commons.mail.EmailConstants; import org.apache.commons.mail.EmailException; import org.apache.commons.mail.HtmlEmail; +import org.bukkit.Server; import javax.activation.CommandMap; import javax.activation.DataSource; @@ -29,18 +30,19 @@ import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD; /** - * @author Xephi59 + * Sends emails to players on behalf of the server. */ public class SendMailSSL { - @Inject - private AuthMe plugin; - @Inject - private Settings settings; - @Inject - private BukkitService bukkitService; + private final File dataFolder; + private final String serverName; + private final Settings settings; - SendMailSSL() { + @Inject + SendMailSSL(@DataFolder File dataFolder, Server server, Settings settings) { + this.dataFolder = dataFolder; + this.serverName = server.getServerName(); + this.settings = settings; } /** @@ -59,62 +61,57 @@ public class SendMailSSL { * @param name the name of the player * @param mailAddress the player's email * @param newPass the new password + * @return true if email could be sent, false otherwise */ - public void sendPasswordMail(String name, String mailAddress, String newPass) { + public boolean sendPasswordMail(String name, String mailAddress, String newPass) { if (!hasAllInformation()) { ConsoleLogger.warning("Cannot perform email registration: not all email settings are complete"); - return; + return false; } - final String mailText = replaceTagsForPasswordMail(settings.getPasswordEmailMessage(), name, newPass); - bukkitService.runTaskAsynchronously(new Runnable() { + HtmlEmail email; + try { + email = initializeMail(mailAddress); + } catch (EmailException e) { + ConsoleLogger.logException("Failed to create email with the given settings:", e); + return false; + } - @Override - public void run() { - HtmlEmail email; - try { - email = initializeMail(mailAddress); - } catch (EmailException e) { - ConsoleLogger.logException("Failed to create email with the given settings:", e); - return; - } - - String content = mailText; - // Generate an image? - File file = null; - if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) { - try { - file = generateImage(name, plugin, newPass); - content = embedImageIntoEmailContent(file, email, content); - } catch (IOException | EmailException e) { - ConsoleLogger.logException( - "Unable to send new password as image for email " + mailAddress + ":", e); - } - } - - sendEmail(content, email); - FileUtils.delete(file); + String mailText = replaceTagsForPasswordMail(settings.getPasswordEmailMessage(), name, newPass); + // Generate an image? + File file = null; + if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) { + try { + file = generateImage(name, newPass); + mailText = embedImageIntoEmailContent(file, email, mailText); + } catch (IOException | EmailException e) { + ConsoleLogger.logException( + "Unable to send new password as image for email " + mailAddress + ":", e); } - }); + } + + boolean couldSendEmail = sendEmail(mailText, email); + FileUtils.delete(file); + return couldSendEmail; } - public void sendRecoveryCode(String name, String email, String code) { - String message = replaceTagsForRecoveryCodeMail(settings.getRecoveryCodeEmailMessage(), - name, code, settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)); - + public boolean sendRecoveryCode(String name, String email, String code) { HtmlEmail htmlEmail; try { htmlEmail = initializeMail(email); } catch (EmailException e) { ConsoleLogger.logException("Failed to create email for recovery code:", e); - return; + return false; } - sendEmail(message, htmlEmail); + + String message = replaceTagsForRecoveryCodeMail(settings.getRecoveryCodeEmailMessage(), + name, code, settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)); + return sendEmail(message, htmlEmail); } - private static File generateImage(String name, AuthMe plugin, String newPass) throws IOException { + private File generateImage(String name, String newPass) throws IOException { ImageGenerator gen = new ImageGenerator(newPass); - File file = new File(plugin.getDataFolder(), name + "_new_pass.jpg"); + File file = new File(dataFolder, name + "_new_pass.jpg"); ImageIO.write(gen.generateImage(), "jpg", file); return file; } @@ -126,7 +123,8 @@ public class SendMailSSL { return content.replace("", ""); } - private HtmlEmail initializeMail(String emailAddress) throws EmailException { + @VisibleForTesting + HtmlEmail initializeMail(String emailAddress) throws EmailException { String senderMail = settings.getProperty(EmailSettings.MAIL_ACCOUNT); String senderName = StringUtils.isEmpty(settings.getProperty(EmailSettings.MAIL_SENDER_NAME)) ? senderMail @@ -147,7 +145,8 @@ public class SendMailSSL { return email; } - private static boolean sendEmail(String content, HtmlEmail email) { + @VisibleForTesting + boolean sendEmail(String content, HtmlEmail email) { Thread.currentThread().setContextClassLoader(SendMailSSL.class.getClassLoader()); // Issue #999: Prevent UnsupportedDataTypeException: no object DCH for MIME type multipart/alternative // cf. http://stackoverflow.com/questions/21856211/unsupporteddatatypeexception-no-object-dch-for-mime-type @@ -177,14 +176,14 @@ public class SendMailSSL { private String replaceTagsForPasswordMail(String mailText, String name, String newPass) { return mailText .replace("", name) - .replace("", plugin.getServer().getServerName()) + .replace("", serverName) .replace("", newPass); } private String replaceTagsForRecoveryCodeMail(String mailText, String name, String code, int hoursValid) { return mailText .replace("", name) - .replace("", plugin.getServer().getServerName()) + .replace("", serverName) .replace("", code) .replace("", String.valueOf(hoursValid)); } diff --git a/src/main/java/fr/xephi/authme/message/MessageFileHandler.java b/src/main/java/fr/xephi/authme/message/MessageFileHandler.java index e870bdf3..a0d4e947 100644 --- a/src/main/java/fr/xephi/authme/message/MessageFileHandler.java +++ b/src/main/java/fr/xephi/authme/message/MessageFileHandler.java @@ -53,7 +53,7 @@ public class MessageFileHandler { if (message == null) { ConsoleLogger.warning("Error getting message with key '" + key + "'. " - + "Please verify your config file at '" + filename + "'"); + + "Please update your config file '" + filename + "' (or run /authme messages)"); return getDefault(key); } return message; diff --git a/src/main/java/fr/xephi/authme/message/MessageKey.java b/src/main/java/fr/xephi/authme/message/MessageKey.java index ed3df4b3..f4bbd2fe 100644 --- a/src/main/java/fr/xephi/authme/message/MessageKey.java +++ b/src/main/java/fr/xephi/authme/message/MessageKey.java @@ -153,6 +153,8 @@ public enum MessageKey { INCOMPLETE_EMAIL_SETTINGS("incomplete_email_settings"), + EMAIL_SEND_FAILURE("email_send_failure"), + RECOVERY_CODE_SENT("recovery_code_sent"), INCORRECT_RECOVERY_CODE("recovery_code_incorrect"); diff --git a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java index 40e6806c..02ef0ce1 100644 --- a/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java +++ b/src/main/java/fr/xephi/authme/process/register/AsyncRegister.java @@ -148,8 +148,12 @@ public class AsyncRegister implements AsynchronousProcess { } database.updateEmail(auth); database.updateSession(auth); - sendMailSsl.sendPasswordMail(name, email, password); - syncProcessManager.processSyncEmailRegister(player); + boolean couldSendMail = sendMailSsl.sendPasswordMail(name, email, password); + if (couldSendMail) { + syncProcessManager.processSyncEmailRegister(player); + } else { + service.send(player, MessageKey.EMAIL_SEND_FAILURE); + } } private void passwordRegister(final Player player, String password, boolean autoLogin) { diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml index 0463d17c..d04e38cd 100644 --- a/src/main/resources/messages/messages_en.yml +++ b/src/main/resources/messages/messages_en.yml @@ -72,5 +72,6 @@ accounts_owned_self: 'You own %count accounts:' accounts_owned_other: 'The player %name has %count accounts:' kicked_admin_registered: 'An admin just registered you; please log in again' incomplete_email_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.' +email_send_failure: 'The email could not be sent. Please contact an administrator.' recovery_code_sent: 'A recovery code to reset your password has been sent to your email.' recovery_code_incorrect: 'The recovery code is not correct! Use /email recovery [email] to generate a new one' diff --git a/src/main/resources/messages/messages_ro.yml b/src/main/resources/messages/messages_ro.yml index f6233c76..c872fe28 100644 --- a/src/main/resources/messages/messages_ro.yml +++ b/src/main/resources/messages/messages_ro.yml @@ -38,8 +38,8 @@ name_len: '&4Numele tau este prea scurt pentru a te inregistra!' regex: '&4Numele tau contine caractere ilegale. Caractere permise: REG_EX' add_email: '&3Te rugam adaugati email-ul la contul tau folosind comanda "/email add "' recovery_email: '&3Ti-ai uitat parola? Te rugam foloseste comanda "/email recovery "' -usage_captcha: '&3Pentru a te autentifica trebuie sa folosesti codul de la captcha, te rugam foloseste comanda "/captcha "' -wrong_captcha: '&cCod-ul captcha este gresit, te rugam foloseste comanda "/captcha "!' +usage_captcha: '&3Pentru a te autentifica trebuie sa folosesti codul de la captcha, te rugam foloseste comanda "/captcha "' +wrong_captcha: '&cCod-ul captcha este gresit, te rugam foloseste comanda "/captcha THE_CAPTCHA"!' valid_captcha: '&2Cod-ul captcha a fost scris corect!' kick_forvip: '&3Un V.I.P a intrat pe server cand era plin!' kick_fullserver: '&4Server-ul este plin, te rugam incearca din nou mai tarziu!' diff --git a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java index 6d11412d..978a2bef 100644 --- a/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/email/RecoverEmailCommandTest.java @@ -168,6 +168,7 @@ public class RecoverEmailCommandTest { Player sender = mock(Player.class); given(sender.getName()).willReturn(name); given(sendMailSsl.hasAllInformation()).willReturn(true); + given(sendMailSsl.sendRecoveryCode(anyString(), anyString(), anyString())).willReturn(true); given(playerCache.isAuthenticated(name)).willReturn(false); String email = "v@example.com"; given(dataSource.getAuth(name)).willReturn(newAuthWithEmail(email)); @@ -217,6 +218,7 @@ public class RecoverEmailCommandTest { Player sender = mock(Player.class); given(sender.getName()).willReturn(name); given(sendMailSsl.hasAllInformation()).willReturn(true); + given(sendMailSsl.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true); given(playerCache.isAuthenticated(name)).willReturn(false); String email = "vulture@example.com"; String code = "A6EF3AC8"; @@ -251,6 +253,7 @@ public class RecoverEmailCommandTest { Player sender = mock(Player.class); given(sender.getName()).willReturn(name); given(sendMailSsl.hasAllInformation()).willReturn(true); + given(sendMailSsl.sendPasswordMail(anyString(), anyString(), anyString())).willReturn(true); given(playerCache.isAuthenticated(name)).willReturn(false); String email = "shark@example.org"; PlayerAuth auth = newAuthWithEmail(email); diff --git a/src/test/java/fr/xephi/authme/mail/SendMailSSLTest.java b/src/test/java/fr/xephi/authme/mail/SendMailSSLTest.java new file mode 100644 index 00000000..7d3746ea --- /dev/null +++ b/src/test/java/fr/xephi/authme/mail/SendMailSSLTest.java @@ -0,0 +1,248 @@ +package fr.xephi.authme.mail; + +import ch.jalu.injector.testing.BeforeInjecting; +import ch.jalu.injector.testing.DelayedInjectionRunner; +import ch.jalu.injector.testing.InjectDelayed; +import fr.xephi.authme.TestHelper; +import fr.xephi.authme.initialization.DataFolder; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.EmailSettings; +import fr.xephi.authme.settings.properties.SecuritySettings; +import org.apache.commons.mail.EmailException; +import org.apache.commons.mail.HtmlEmail; +import org.bukkit.Server; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; + +import java.io.File; +import java.io.IOException; +import java.util.Properties; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +/** + * Test for {@link SendMailSSL}. + */ +@RunWith(DelayedInjectionRunner.class) +public class SendMailSSLTest { + + @InjectDelayed + private SendMailSSL sendMailSSL; + + @Mock + private Settings settings; + @Mock + private Server server; + @DataFolder + private File dataFolder; + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @BeforeClass + public static void initLogger() { + TestHelper.setupLogger(); + } + + @BeforeInjecting + public void initFields() throws IOException { + dataFolder = temporaryFolder.newFolder(); + given(server.getServerName()).willReturn("serverName"); + given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("mail@example.org"); + given(settings.getProperty(EmailSettings.MAIL_PASSWORD)).willReturn("pass1234"); + } + + @Test + public void shouldHaveAllInformation() { + // given / when / then + assertThat(sendMailSSL.hasAllInformation(), equalTo(true)); + } + + @Test + public void shouldSendPasswordMail() throws EmailException { + // given + given(settings.getPasswordEmailMessage()) + .willReturn("Hi , your new password for is "); + given(settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)).willReturn(false); + SendMailSSL sendMailSpy = spy(sendMailSSL); + HtmlEmail email = mock(HtmlEmail.class); + doReturn(email).when(sendMailSpy).initializeMail(anyString()); + doReturn(true).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class)); + + // when + boolean result = sendMailSpy.sendPasswordMail("Player", "user@example.com", "new_password"); + + // then + assertThat(result, equalTo(true)); + verify(sendMailSpy).initializeMail("user@example.com"); + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email)); + assertThat(messageCaptor.getValue(), + equalTo("Hi Player, your new password for serverName is new_password")); + } + + @Test + public void shouldHandleMailCreationError() throws EmailException { + // given + SendMailSSL sendMailSpy = spy(sendMailSSL); + doThrow(EmailException.class).when(sendMailSpy).initializeMail(anyString()); + + // when + boolean result = sendMailSpy.sendPasswordMail("Player", "user@example.com", "new_password"); + + // then + assertThat(result, equalTo(false)); + verify(sendMailSpy).initializeMail("user@example.com"); + verify(sendMailSpy, never()).sendEmail(anyString(), any(HtmlEmail.class)); + } + + @Test + public void shouldHandleMailSendingFailure() throws EmailException { + // given + given(settings.getPasswordEmailMessage()).willReturn("Hi , your new pass is "); + given(settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)).willReturn(false); + SendMailSSL sendMailSpy = spy(sendMailSSL); + HtmlEmail email = mock(HtmlEmail.class); + doReturn(email).when(sendMailSpy).initializeMail(anyString()); + doReturn(false).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class)); + + // when + boolean result = sendMailSpy.sendPasswordMail("bobby", "user@example.com", "myPassw0rd"); + + // then + assertThat(result, equalTo(false)); + verify(sendMailSpy).initializeMail("user@example.com"); + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email)); + assertThat(messageCaptor.getValue(), equalTo("Hi bobby, your new pass is myPassw0rd")); + } + + @Test + public void shouldSendRecoveryCode() throws EmailException { + // given + given(settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)).willReturn(7); + given(settings.getRecoveryCodeEmailMessage()) + .willReturn("Hi , your code on is (valid hours)"); + SendMailSSL sendMailSpy = spy(sendMailSSL); + HtmlEmail email = mock(HtmlEmail.class); + doReturn(email).when(sendMailSpy).initializeMail(anyString()); + doReturn(true).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class)); + + // when + boolean result = sendMailSpy.sendRecoveryCode("Timmy", "tim@example.com", "12C56A"); + + // then + assertThat(result, equalTo(true)); + verify(sendMailSpy).initializeMail("tim@example.com"); + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email)); + assertThat(messageCaptor.getValue(), equalTo("Hi Timmy, your code on serverName is 12C56A (valid 7 hours)")); + } + + @Test + public void shouldHandleMailCreationErrorForRecoveryCode() throws EmailException { + // given + SendMailSSL sendMailSpy = spy(sendMailSSL); + doThrow(EmailException.class).when(sendMailSpy).initializeMail(anyString()); + + // when + boolean result = sendMailSpy.sendRecoveryCode("Player", "player@example.org", "ABC1234"); + + // then + assertThat(result, equalTo(false)); + verify(sendMailSpy).initializeMail("player@example.org"); + verify(sendMailSpy, never()).sendEmail(anyString(), any(HtmlEmail.class)); + } + + @Test + public void shouldHandleFailureToSendRecoveryCode() throws EmailException { + // given + given(settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID)).willReturn(7); + given(settings.getRecoveryCodeEmailMessage()).willReturn("Hi , your code is "); + SendMailSSL sendMailSpy = spy(sendMailSSL); + HtmlEmail email = mock(HtmlEmail.class); + doReturn(email).when(sendMailSpy).initializeMail(anyString()); + doReturn(false).when(sendMailSpy).sendEmail(anyString(), any(HtmlEmail.class)); + + // when + boolean result = sendMailSpy.sendRecoveryCode("John", "user@example.com", "1DEF77"); + + // then + assertThat(result, equalTo(false)); + verify(sendMailSpy).initializeMail("user@example.com"); + ArgumentCaptor messageCaptor = ArgumentCaptor.forClass(String.class); + verify(sendMailSpy).sendEmail(messageCaptor.capture(), eq(email)); + assertThat(messageCaptor.getValue(), equalTo("Hi John, your code is 1DEF77")); + } + + @Test + public void shouldCreateEmailObject() throws EmailException { + // given + given(settings.getProperty(EmailSettings.SMTP_PORT)).willReturn(465); + String smtpHost = "mail.example.com"; + given(settings.getProperty(EmailSettings.SMTP_HOST)).willReturn(smtpHost); + String senderMail = "sender@example.org"; + given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn(senderMail); + String senderName = "Server administration"; + given(settings.getProperty(EmailSettings.MAIL_SENDER_NAME)).willReturn(senderName); + + // when + HtmlEmail email = sendMailSSL.initializeMail("recipient@example.com"); + + // then + assertThat(email, not(nullValue())); + assertThat(email.getToAddresses(), hasSize(1)); + assertThat(email.getToAddresses().get(0).getAddress(), equalTo("recipient@example.com")); + assertThat(email.getFromAddress().getAddress(), equalTo(senderMail)); + assertThat(email.getFromAddress().getPersonal(), equalTo(senderName)); + assertThat(email.getHostName(), equalTo(smtpHost)); + assertThat(email.getSmtpPort(), equalTo("465")); + } + + @Test + public void shouldCreateEmailObjectWithOAuth2() throws EmailException { + // given + given(settings.getProperty(EmailSettings.SMTP_PORT)).willReturn(587); + given(settings.getProperty(EmailSettings.OAUTH2_TOKEN)).willReturn("oAuth2 token"); + String smtpHost = "mail.example.com"; + given(settings.getProperty(EmailSettings.SMTP_HOST)).willReturn(smtpHost); + String senderMail = "sender@example.org"; + given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn(senderMail); + + // when + HtmlEmail email = sendMailSSL.initializeMail("recipient@example.com"); + + // then + assertThat(email, not(nullValue())); + assertThat(email.getToAddresses(), hasSize(1)); + assertThat(email.getToAddresses().get(0).getAddress(), equalTo("recipient@example.com")); + assertThat(email.getFromAddress().getAddress(), equalTo(senderMail)); + assertThat(email.getHostName(), equalTo(smtpHost)); + assertThat(email.getSmtpPort(), equalTo("587")); + + Properties mailProperties = email.getMailSession().getProperties(); + assertThat(mailProperties.getProperty("mail.smtp.auth.mechanisms"), equalTo("XOAUTH2")); + assertThat(mailProperties.getProperty("mail.smtp.auth.plain.disable"), equalTo("true")); + assertThat(mailProperties.getProperty(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP), equalTo("oAuth2 token")); + } + +} From b3a8c726cf0a251e5bf431bfbe65176d470fb1ee Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 11 Dec 2016 09:55:47 +0100 Subject: [PATCH 65/67] Use Optional in CacheDataSource again - An exception is thrown e.g. when running '/authme email player' where 'player' does not exist because CacheLoader#load may not ever return null (see Javadoc). Therefore, we are forced to wrap the PlayerAuth in an Optional. - Use Java 8 Optional instead of Google's --- .../authme/datasource/CacheDataSource.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java index fc4e88a4..fbbaa507 100644 --- a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java +++ b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java @@ -15,6 +15,7 @@ import fr.xephi.authme.security.crypts.HashedPassword; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -22,7 +23,7 @@ import java.util.concurrent.TimeUnit; public class CacheDataSource implements DataSource { private final DataSource source; - private final LoadingCache cachedAuths; + private final LoadingCache> cachedAuths; private final ListeningExecutorService executorService; /** @@ -41,20 +42,20 @@ public class CacheDataSource implements DataSource { cachedAuths = CacheBuilder.newBuilder() .refreshAfterWrite(5, TimeUnit.MINUTES) .expireAfterAccess(15, TimeUnit.MINUTES) - .build(new CacheLoader() { + .build(new CacheLoader>() { @Override - public PlayerAuth load(String key) { - return source.getAuth(key); + public Optional load(String key) { + return Optional.ofNullable(source.getAuth(key)); } @Override - public ListenableFuture reload(final String key, PlayerAuth oldValue) { + public ListenableFuture> reload(final String key, Optional oldValue) { return executorService.submit(() -> load(key)); } }); } - public LoadingCache getCachedAuths() { + public LoadingCache> getCachedAuths() { return cachedAuths; } @@ -71,9 +72,9 @@ public class CacheDataSource implements DataSource { @Override public HashedPassword getPassword(String user) { user = user.toLowerCase(); - PlayerAuth auth = cachedAuths.getIfPresent(user); - if (auth != null) { - return auth.getPassword(); + Optional pAuthOpt = cachedAuths.getIfPresent(user); + if (pAuthOpt != null && pAuthOpt.isPresent()) { + return pAuthOpt.get().getPassword(); } return source.getPassword(user); } @@ -81,7 +82,7 @@ public class CacheDataSource implements DataSource { @Override public PlayerAuth getAuth(String user) { user = user.toLowerCase(); - return cachedAuths.getUnchecked(user); + return cachedAuths.getUnchecked(user).orElse(null); } @Override From 5b6d0f5d97da18c28c8c4b64576af01ed5d36d62 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 11 Dec 2016 10:17:26 +0100 Subject: [PATCH 66/67] Create tool task that adds javadoc to the MessageKey entries --- .../fr/xephi/authme/message/MessageKey.java | 77 +++++++++++++++++++ .../messages/AddJavaDocToMessageEnumTask.java | 50 ++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/test/java/tools/messages/AddJavaDocToMessageEnumTask.java diff --git a/src/main/java/fr/xephi/authme/message/MessageKey.java b/src/main/java/fr/xephi/authme/message/MessageKey.java index f4bbd2fe..c9fd5fec 100644 --- a/src/main/java/fr/xephi/authme/message/MessageKey.java +++ b/src/main/java/fr/xephi/authme/message/MessageKey.java @@ -5,158 +5,235 @@ package fr.xephi.authme.message; */ public enum MessageKey { + /** In order to use this command you must be authenticated! */ DENIED_COMMAND("denied_command"), + /** A player with the same IP is already in game! */ SAME_IP_ONLINE("same_ip_online"), + /** In order to chat you must be authenticated! */ DENIED_CHAT("denied_chat"), + /** AntiBot protection mode is enabled! You have to wait some minutes before joining the server. */ KICK_ANTIBOT("kick_antibot"), + /** Can't find the requested user in the database! */ UNKNOWN_USER("unknown_user"), + /** Your quit location was unsafe, you have been teleported to the world's spawnpoint. */ UNSAFE_QUIT_LOCATION("unsafe_spawn"), + /** You're not logged in! */ NOT_LOGGED_IN("not_logged_in"), + /** You can register yourself to the server with the command "/register >password> >ConfirmPassword>" */ REGISTER_VOLUNTARILY("reg_voluntarily"), + /** Usage: /login >password> */ USAGE_LOGIN("usage_log"), + /** Wrong password! */ WRONG_PASSWORD("wrong_pwd"), + /** Successfully unregistered! */ UNREGISTERED_SUCCESS("unregistered"), + /** In-game registration is disabled! */ REGISTRATION_DISABLED("reg_disabled"), + /** Logged-in due to Session Reconnection. */ SESSION_RECONNECTION("valid_session"), + /** Successful login! */ LOGIN_SUCCESS("login"), + /** Your account isn't activated yet, please check your emails! */ ACCOUNT_NOT_ACTIVATED("vb_nonActiv"), + /** You already have registered this username! */ NAME_ALREADY_REGISTERED("user_regged"), + /** You don't have the permission to perform this action! */ NO_PERMISSION("no_perm"), + /** An unexpected error occurred, please contact an administrator! */ ERROR("error"), + /** Please, login with the command "/login >password>" */ LOGIN_MESSAGE("login_msg"), + /** Please, register to the server with the command "/register >password> >ConfirmPassword>" */ REGISTER_MESSAGE("reg_msg"), + /** Please, register to the server with the command "/register >email> >confirmEmail>" */ REGISTER_EMAIL_MESSAGE("reg_email_msg"), + /** You have exceeded the maximum number of registrations (%reg_count/%max_acc %reg_names) for your connection! */ MAX_REGISTER_EXCEEDED("max_reg", "%max_acc", "%reg_count", "%reg_names"), + /** Usage: /register >password> >ConfirmPassword> */ USAGE_REGISTER("usage_reg"), + /** Usage: /unregister >password> */ USAGE_UNREGISTER("usage_unreg"), + /** Password changed successfully! */ PASSWORD_CHANGED_SUCCESS("pwd_changed"), + /** This user isn't registered! */ USER_NOT_REGISTERED("user_unknown"), + /** Passwords didn't match, check them again! */ PASSWORD_MATCH_ERROR("password_error"), + /** You can't use your name as password, please choose another one... */ PASSWORD_IS_USERNAME_ERROR("password_error_nick"), + /** The chosen password isn't safe, please choose another one... */ PASSWORD_UNSAFE_ERROR("password_error_unsafe"), + /** Your password contains illegal characters. Allowed chars: REG_EX */ PASSWORD_CHARACTERS_ERROR("password_error_chars", "REG_EX"), + /** Your IP has been changed and your session data has expired! */ SESSION_EXPIRED("invalid_session"), + /** Only registered users can join the server! Please visit http://example.com to register yourself! */ MUST_REGISTER_MESSAGE("reg_only"), + /** You're already logged in! */ ALREADY_LOGGED_IN_ERROR("logged_in"), + /** Logged-out successfully! */ LOGOUT_SUCCESS("logout"), + /** The same username is already playing on the server! */ USERNAME_ALREADY_ONLINE_ERROR("same_nick"), + /** Successfully registered! */ REGISTER_SUCCESS("registered"), + /** Your password is too short or too long! Please try with another one! */ INVALID_PASSWORD_LENGTH("pass_len"), + /** Configuration and database have been reloaded correctly! */ CONFIG_RELOAD_SUCCESS("reload"), + /** Login timeout exceeded, you have been kicked from the server, please try again! */ LOGIN_TIMEOUT_ERROR("timeout"), + /** Usage: /changepassword >oldPassword> >newPassword> */ USAGE_CHANGE_PASSWORD("usage_changepassword"), + /** Your username is either too short or too long! */ INVALID_NAME_LENGTH("name_len"), + /** Your username contains illegal characters. Allowed chars: REG_EX */ INVALID_NAME_CHARACTERS("regex", "REG_EX"), + /** Please add your email to your account with the command "/email add >yourEmail> >confirmEmail>" */ ADD_EMAIL_MESSAGE("add_email"), + /** Forgot your password? Please use the command "/email recovery >yourEmail>" */ FORGOT_PASSWORD_MESSAGE("recovery_email"), + /** To login you have to solve a captcha code, please use the command "/captcha >theCaptcha>" */ USAGE_CAPTCHA("usage_captcha", ""), + /** Wrong captcha, please type "/captcha THE_CAPTCHA" into the chat! */ CAPTCHA_WRONG_ERROR("wrong_captcha", "THE_CAPTCHA"), + /** Captcha code solved correctly! */ CAPTCHA_SUCCESS("valid_captcha"), + /** A VIP player has joined the server when it was full! */ KICK_FOR_VIP("kick_forvip"), + /** The server is full, try again later! */ KICK_FULL_SERVER("kick_fullserver"), + /** Usage: /email add >email> >confirmEmail> */ USAGE_ADD_EMAIL("usage_email_add"), + /** Usage: /email change >oldEmail> >newEmail> */ USAGE_CHANGE_EMAIL("usage_email_change"), + /** Usage: /email recovery >Email> */ USAGE_RECOVER_EMAIL("usage_email_recovery"), + /** Invalid new email, try again! */ INVALID_NEW_EMAIL("new_email_invalid"), + /** Invalid old email, try again! */ INVALID_OLD_EMAIL("old_email_invalid"), + /** Invalid email address, try again! */ INVALID_EMAIL("email_invalid"), + /** Email address successfully added to your account! */ EMAIL_ADDED_SUCCESS("email_added"), + /** Please confirm your email address! */ CONFIRM_EMAIL_MESSAGE("email_confirm"), + /** Email address changed correctly! */ EMAIL_CHANGED_SUCCESS("email_changed"), + /** Your current email address is: %email */ EMAIL_SHOW("email_show", "%email"), + /** You currently don't have email address associated with this account. */ SHOW_NO_EMAIL("show_no_email"), + /** Recovery email sent successfully! Please check your email inbox! */ RECOVERY_EMAIL_SENT_MESSAGE("email_send"), + /** A recovery email was already sent! You can discard it and send a new one using the command below: */ RECOVERY_EMAIL_ALREADY_SENT_MESSAGE("email_exists"), + /** Your country is banned from this server! */ COUNTRY_BANNED_ERROR("country_banned"), + /** [AntiBotService] AntiBot enabled due to the huge number of connections! */ ANTIBOT_AUTO_ENABLED_MESSAGE("antibot_auto_enabled"), + /** [AntiBotService] AntiBot disabled after %m minutes! */ ANTIBOT_AUTO_DISABLED_MESSAGE("antibot_auto_disabled", "%m"), + /** The email address is already being used */ EMAIL_ALREADY_USED_ERROR("email_already_used"), + /** Your secret code is %code. You can scan it from here %url */ TWO_FACTOR_CREATE("two_factor_create", "%code", "%url"), + /** You are not the owner of this account. Please choose another name! */ NOT_OWNER_ERROR("not_owner_error"), + /** You should join using username %valid, not %invalid. */ INVALID_NAME_CASE("invalid_name_case", "%valid", "%invalid"), + /** You have been temporarily banned for failing to log in too many times. */ TEMPBAN_MAX_LOGINS("tempban_max_logins"), + /** You own %count accounts: */ ACCOUNTS_OWNED_SELF("accounts_owned_self", "%count"), + /** The player %name has %count accounts: */ ACCOUNTS_OWNED_OTHER("accounts_owned_other", "%name", "%count"), + /** An admin just registered you; please log in again */ KICK_FOR_ADMIN_REGISTER("kicked_admin_registered"), + /** Error: not all required settings are set for sending emails. Please contact an admin. */ INCOMPLETE_EMAIL_SETTINGS("incomplete_email_settings"), + /** The email could not be sent. Please contact an administrator. */ EMAIL_SEND_FAILURE("email_send_failure"), + /** A recovery code to reset your password has been sent to your email. */ RECOVERY_CODE_SENT("recovery_code_sent"), + /** The recovery code is not correct! Use /email recovery [email] to generate a new one */ INCORRECT_RECOVERY_CODE("recovery_code_incorrect"); private String key; diff --git a/src/test/java/tools/messages/AddJavaDocToMessageEnumTask.java b/src/test/java/tools/messages/AddJavaDocToMessageEnumTask.java new file mode 100644 index 00000000..24e99a4f --- /dev/null +++ b/src/test/java/tools/messages/AddJavaDocToMessageEnumTask.java @@ -0,0 +1,50 @@ +package tools.messages; + +import fr.xephi.authme.message.MessageKey; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import tools.utils.AutoToolTask; +import tools.utils.ToolsConstants; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * Task to add English messages as javadoc comment to each MessageKey enum entry. + */ +public class AddJavaDocToMessageEnumTask implements AutoToolTask { + + private static final String MESSAGES_FILE = ToolsConstants.MAIN_RESOURCES_ROOT + "messages/messages_en.yml"; + + private FileConfiguration configuration; + + @Override + public void executeDefault() { + configuration = YamlConfiguration.loadConfiguration(new File(MESSAGES_FILE)); + + List entries = new ArrayList<>(); + for (MessageKey entry : MessageKey.values()) { + String tags = entry.getTags().length == 0 + ? "" + : ", \"" + String.join("\", \"", entry.getTags()) + "\""; + + entries.add("/** " + getMessageForJavaDoc(entry) + " */" + + "\n\t" + entry.name() + "(\"" + entry.getKey() + "\"" + tags + ")"); + } + + System.out.println("\t" + String.join(",\n\n\t", entries) + ";"); + } + + @Override + public String getTaskName() { + return "addJavaDocToMessageEnum"; + } + + private String getMessageForJavaDoc(MessageKey key) { + return configuration.getString(key.getKey()) + .replaceAll("&[0-9a-f]", "") + .replace("&", "&") + .replace("<", ">"); + } +} From e8692160c53b545b6bcbc2d6127b071a43b5caf6 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 11 Dec 2016 10:31:49 +0100 Subject: [PATCH 67/67] Remove unused import/export messages tool tasks --- .../translation/AuthMeYamlConfiguration.java | 58 --------- .../translation/ExportMessagesTask.java | 106 ---------------- .../translation/ImportMessagesTask.java | 116 ------------------ .../messages/translation/LanguageExport.java | 19 --- .../messages/translation/MessageExport.java | 20 --- .../translation/WriteAllExportsTask.java | 35 ------ .../translation/export/export-is-written-here | 0 7 files changed, 354 deletions(-) delete mode 100644 src/test/java/tools/messages/translation/AuthMeYamlConfiguration.java delete mode 100644 src/test/java/tools/messages/translation/ExportMessagesTask.java delete mode 100644 src/test/java/tools/messages/translation/ImportMessagesTask.java delete mode 100644 src/test/java/tools/messages/translation/LanguageExport.java delete mode 100644 src/test/java/tools/messages/translation/MessageExport.java delete mode 100644 src/test/java/tools/messages/translation/WriteAllExportsTask.java delete mode 100644 src/test/java/tools/messages/translation/export/export-is-written-here diff --git a/src/test/java/tools/messages/translation/AuthMeYamlConfiguration.java b/src/test/java/tools/messages/translation/AuthMeYamlConfiguration.java deleted file mode 100644 index 21564b57..00000000 --- a/src/test/java/tools/messages/translation/AuthMeYamlConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -package tools.messages.translation; - -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; - -import java.io.File; -import java.io.IOException; -import java.util.regex.Pattern; - -/** - * Extension of {@link YamlConfiguration} to customize the writing style. - */ -public class AuthMeYamlConfiguration extends YamlConfiguration { - - // Differences to YamlConfiguration: Texts are always in single quotes - // and line breaks are only applied after 200 chars - @Override - public String saveToString() { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - options.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED); - options.setPrettyFlow(true); - options.setWidth(200); - Yaml yaml = new Yaml(options); - - String header = buildHeader(); - String dump = yaml.dump(getValues(false)); - - if (dump.equals(BLANK_CONFIG)) { - dump = ""; - } - // By setting the scalar style to SINGLE_QUOTED both keys and values will be enclosed in single quotes. - // We want all texts wrapped in single quotes, but not the keys. Seems like this is not possible in SnakeYAML - dump = Pattern.compile("^'([a-zA-Z0-9-_]+)': ", Pattern.MULTILINE) - .matcher(dump).replaceAll("$1: "); - - return header + dump; - } - - /** - * Behaves similarly to {@link YamlConfiguration#loadConfiguration(File)} but returns an object - * of this class instead. - * - * @param file the file to load - * @return the constructed AuthMeYamlConfiguration instance - */ - public static AuthMeYamlConfiguration loadConfiguration(File file) { - AuthMeYamlConfiguration config = new AuthMeYamlConfiguration(); - try { - config.load(file); - } catch (IOException | InvalidConfigurationException ex) { - throw new IllegalStateException(ex); - } - return config; - } -} diff --git a/src/test/java/tools/messages/translation/ExportMessagesTask.java b/src/test/java/tools/messages/translation/ExportMessagesTask.java deleted file mode 100644 index 7ea2a419..00000000 --- a/src/test/java/tools/messages/translation/ExportMessagesTask.java +++ /dev/null @@ -1,106 +0,0 @@ -package tools.messages.translation; - -import com.google.common.io.CharStreams; -import com.google.gson.Gson; -import fr.xephi.authme.message.MessageKey; -import fr.xephi.authme.util.StringUtils; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import tools.utils.ToolTask; -import tools.utils.ToolsConstants; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; - -/** - * Task to export a language's messages to the remote translation service. - */ -public class ExportMessagesTask implements ToolTask { - - /** The folder containing the messages files. */ - protected static final String MESSAGES_FOLDER = ToolsConstants.MAIN_RESOURCES_ROOT + "messages/"; - /** The remote URL to send an updated file to. */ - private static final String UPDATE_URL = "http://jalu.ch/ext/authme/update.php"; - private final Gson gson = new Gson(); - - @Override - public String getTaskName() { - return "exportMessages"; - } - - @Override - public void execute(Scanner scanner) { - System.out.println("Enter language code of messages to export:"); - String languageCode = scanner.nextLine().trim(); - - File file = new File(MESSAGES_FOLDER + "messages_" + languageCode + ".yml"); - if (!file.exists()) { - throw new IllegalStateException("File '" + file.getAbsolutePath() + "' does not exist"); - } - - FileConfiguration configuration = YamlConfiguration.loadConfiguration(file); - String json = convertToJson(languageCode, loadDefaultMessages(), configuration); - - String result = sendJsonToRemote(languageCode, json); - System.out.println("Answer: " + result); - } - - protected String convertToJson(String code, FileConfiguration defaultMessages, FileConfiguration messageFile) { - List list = new ArrayList<>(); - for (MessageKey key : MessageKey.values()) { - list.add(new MessageExport(key.getKey(), key.getTags(), getString(key, defaultMessages), - getString(key, messageFile))); - } - - return gson.toJson(new LanguageExport(code, list)); - } - - protected FileConfiguration loadDefaultMessages() { - return YamlConfiguration.loadConfiguration(new File(MESSAGES_FOLDER + "messages_en.yml")); - } - - private static String getString(MessageKey key, FileConfiguration configuration) { - return configuration.getString(key.getKey(), ""); - } - - private static String sendJsonToRemote(String language, String json) { - try { - String encodedData = "file=" + URLEncoder.encode(json, "UTF-8") - + "&language=" + URLEncoder.encode(language, "UTF-8"); - - URL url = new URL(UPDATE_URL); - HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - conn.setDoOutput(true); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - conn.setRequestProperty("Content-Length", String.valueOf(encodedData.length())); - OutputStream os = conn.getOutputStream(); - os.write(encodedData.getBytes()); - os.flush(); - os.close(); - - return "Response code: " + conn.getResponseCode() - + "\n" + inputStreamToString(conn.getInputStream()); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - - private static String inputStreamToString(InputStream is) { - try (InputStreamReader isr = new InputStreamReader(is)) { - return CharStreams.toString(isr); - } catch (IOException e) { - return "Failed to read output - " + StringUtils.formatException(e); - } - } - -} diff --git a/src/test/java/tools/messages/translation/ImportMessagesTask.java b/src/test/java/tools/messages/translation/ImportMessagesTask.java deleted file mode 100644 index 765c49f1..00000000 --- a/src/test/java/tools/messages/translation/ImportMessagesTask.java +++ /dev/null @@ -1,116 +0,0 @@ -package tools.messages.translation; - -import com.google.common.io.Resources; -import com.google.gson.Gson; -import fr.xephi.authme.message.MessageKey; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import tools.messages.MessageFileVerifier; -import tools.messages.VerifyMessagesTask; -import tools.utils.FileIoUtils; -import tools.utils.ToolTask; -import tools.utils.ToolsConstants; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.HashSet; -import java.util.Scanner; -import java.util.Set; -import java.util.regex.Pattern; - -/** - * Imports a message file from a remote JSON export and validates the resulting file. - *

    - * Comments at the top of an existing file should remain after the import, but it is important - * to verify that no unwanted changes have been applied to the file. Note that YAML comments - * tend to disappear if there is no space between the # and the first character. - */ -public class ImportMessagesTask implements ToolTask { - - private static final String MESSAGES_FOLDER = ToolsConstants.MAIN_RESOURCES_ROOT + "messages/"; - private Gson gson = new Gson(); - private Set messageCodes; - - @Override - public String getTaskName() { - return "importMessages"; - } - - @Override - public void execute(Scanner scanner) { - System.out.println("Enter URL to import from"); - // Dirty trick: replace https:// with http:// so we don't have to worry about installing certificates... - String url = scanner.nextLine().replace("https://", "http://"); - - LanguageExport languageExport = getLanguageExportFromUrl(url); - if (languageExport == null) { - throw new IllegalStateException("An error occurred: constructed language export is null"); - } - - mergeExportIntoFile(languageExport); - System.out.println("Saved to messages file for code '" + languageExport.code + "'"); - } - - private LanguageExport getLanguageExportFromUrl(String location) { - try { - URL url = new URL(location); - String json = Resources.toString(url, StandardCharsets.UTF_8); - return gson.fromJson(json, LanguageExport.class); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - - private void mergeExportIntoFile(LanguageExport export) { - String languageCode = export.code; - String fileName = MESSAGES_FOLDER + "messages_" + languageCode + ".yml"; - File file = new File(fileName); - FileConfiguration fileConfiguration; - if (file.exists()) { - removeAllTodoComments(fileName); - fileConfiguration = AuthMeYamlConfiguration.loadConfiguration(file); - } else { - fileConfiguration = new AuthMeYamlConfiguration(); - } - - buildMessageCodeList(); - for (MessageExport messageExport : export.messages) { - if (!messageCodes.contains(messageExport.key)) { - throw new IllegalStateException("Message key '" + messageExport.key + "' does not exist"); - } else if (!messageExport.translatedMessage.isEmpty()) { - fileConfiguration.set(messageExport.key, messageExport.translatedMessage); - } - } - try { - fileConfiguration.save(file); - } catch (IOException e) { - throw new IllegalStateException(e); - } - - MessageFileVerifier verifier = new MessageFileVerifier(file); - VerifyMessagesTask.verifyFileAndAddKeys(verifier, YamlConfiguration.loadConfiguration( - new File(MESSAGES_FOLDER + "messages_en.yml"))); - } - - private void buildMessageCodeList() { - messageCodes = new HashSet<>(MessageKey.values().length); - for (MessageKey messageKey : MessageKey.values()) { - messageCodes.add(messageKey.getKey()); - } - } - - /** - * Removes all to-do comments written by {@link VerifyMessagesTask}. This is helpful as the YamlConfiguration - * moves those comments otherwise upon saving. - * - * @param file The file whose to-do comments should be removed - */ - private static void removeAllTodoComments(String file) { - String contents = FileIoUtils.readFromFile(file); - String regex = "^# TODO .*$"; - contents = Pattern.compile(regex, Pattern.MULTILINE).matcher(contents).replaceAll(""); - FileIoUtils.writeToFile(file, contents); - } -} diff --git a/src/test/java/tools/messages/translation/LanguageExport.java b/src/test/java/tools/messages/translation/LanguageExport.java deleted file mode 100644 index c15a54bd..00000000 --- a/src/test/java/tools/messages/translation/LanguageExport.java +++ /dev/null @@ -1,19 +0,0 @@ -package tools.messages.translation; - -import java.util.Collections; -import java.util.List; - -/** - * Export of a language's messages. - */ -public class LanguageExport { - - public final String code; - public final List messages; - - public LanguageExport(String code, List messages) { - this.code = code; - this.messages = Collections.unmodifiableList(messages); - } - -} diff --git a/src/test/java/tools/messages/translation/MessageExport.java b/src/test/java/tools/messages/translation/MessageExport.java deleted file mode 100644 index 1b37347c..00000000 --- a/src/test/java/tools/messages/translation/MessageExport.java +++ /dev/null @@ -1,20 +0,0 @@ -package tools.messages.translation; - -/** - * Container class for one translatable message. - */ -public class MessageExport { - - public final String key; - public final String tags; - public final String defaultMessage; - public final String translatedMessage; - - public MessageExport(String key, String[] tags, String defaultMessage, String translatedMessage) { - this.key = key; - this.tags = String.join(",", tags); - this.defaultMessage = defaultMessage; - this.translatedMessage = translatedMessage; - } - -} diff --git a/src/test/java/tools/messages/translation/WriteAllExportsTask.java b/src/test/java/tools/messages/translation/WriteAllExportsTask.java deleted file mode 100644 index f59d31ef..00000000 --- a/src/test/java/tools/messages/translation/WriteAllExportsTask.java +++ /dev/null @@ -1,35 +0,0 @@ -package tools.messages.translation; - -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import tools.utils.FileIoUtils; -import tools.utils.ToolsConstants; - -import java.io.File; -import java.util.Scanner; - -import static tools.utils.FileIoUtils.listFilesOrThrow; - -/** - * Task which exports all messages to a local folder. - */ -public class WriteAllExportsTask extends ExportMessagesTask { - - private static final String OUTPUT_FOLDER = ToolsConstants.TOOLS_SOURCE_ROOT + "messages/translation/export/"; - - @Override - public String getTaskName() { - return "writeAllExports"; - } - - @Override - public void execute(Scanner scanner) { - final File[] messageFiles = listFilesOrThrow(new File(MESSAGES_FOLDER)); - final FileConfiguration defaultMessages = loadDefaultMessages(); - for (File file : messageFiles) { - String code = file.getName().substring("messages_".length(), file.getName().length() - ".yml".length()); - String json = convertToJson(code, defaultMessages, YamlConfiguration.loadConfiguration(file)); - FileIoUtils.writeToFile(OUTPUT_FOLDER + "messages_" + code + ".json", json); - } - } -} diff --git a/src/test/java/tools/messages/translation/export/export-is-written-here b/src/test/java/tools/messages/translation/export/export-is-written-here deleted file mode 100644 index e69de29b..00000000