diff --git a/samples/website_integration/Pbkdf2.php b/samples/website_integration/Pbkdf2.php index 456c004f..9b804af9 100644 --- a/samples/website_integration/Pbkdf2.php +++ b/samples/website_integration/Pbkdf2.php @@ -5,7 +5,7 @@ * ------------------------------------------------------- * * See AuthMeController for details. * * * - * Source: https://github.com/AuthMe-Team/AuthMeReloaded/ * + * Source: https://github.com/AuthMe/AuthMeReloaded/ * ***********************************************************/ class Pbkdf2 extends AuthMeController { diff --git a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java index caa7968a..2e5ad98c 100644 --- a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java +++ b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java @@ -21,7 +21,7 @@ import java.util.ArrayList; import java.util.List; /** - * The current AuthMeApi of AuthMe. + * The current API of AuthMe. * * Recommended method of retrieving the AuthMeApi object: * @@ -44,8 +44,9 @@ public class AuthMeApi { * Constructor for AuthMeApi. */ @Inject - AuthMeApi(AuthMe plugin, PluginHookService pluginHookService, DataSource dataSource, PasswordSecurity passwordSecurity, - Management management, ValidationService validationService, PlayerCache playerCache, GeoIpService geoIpService) { + AuthMeApi(AuthMe plugin, PluginHookService pluginHookService, DataSource dataSource, PlayerCache playerCache, + PasswordSecurity passwordSecurity, Management management, ValidationService validationService, + GeoIpService geoIpService) { this.plugin = plugin; this.pluginHookService = pluginHookService; this.dataSource = dataSource; diff --git a/src/main/java/fr/xephi/authme/command/CommandMapper.java b/src/main/java/fr/xephi/authme/command/CommandMapper.java index 33003c3a..b7ed2170 100644 --- a/src/main/java/fr/xephi/authme/command/CommandMapper.java +++ b/src/main/java/fr/xephi/authme/command/CommandMapper.java @@ -44,7 +44,7 @@ public class CommandMapper { * @param parts The parts to map to commands and arguments * @return The generated {@link FoundCommandResult} */ - public FoundCommandResult mapPartsToCommand(CommandSender sender, final List parts) { + public FoundCommandResult mapPartsToCommand(CommandSender sender, List parts) { if (Utils.isCollectionEmpty(parts)) { return new FoundCommandResult(null, parts, null, 0.0, MISSING_BASE_COMMAND); } @@ -87,6 +87,14 @@ public class CommandMapper { return classes; } + /** + * Return the command whose label matches the given parts the best. This method is called when + * a successful mapping could not be performed. + * + * @param base the base command + * @param parts the command parts + * @return the closest result + */ 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) { @@ -189,14 +197,10 @@ public class CommandMapper { } private static double getLabelDifference(CommandDescription command, String givenLabel) { - double minDifference = Double.POSITIVE_INFINITY; - for (String commandLabel : command.getLabels()) { - double difference = StringUtils.getDifference(commandLabel, givenLabel); - if (difference < minDifference) { - minDifference = difference; - } - } - return minDifference; + return command.getLabels().stream() + .map(label -> StringUtils.getDifference(label, givenLabel)) + .min(Double::compareTo) + .orElseThrow(() -> new IllegalStateException("Command does not have any labels set")); } } diff --git a/src/main/java/fr/xephi/authme/command/CommandUtils.java b/src/main/java/fr/xephi/authme/command/CommandUtils.java index 699e4f37..90d0138a 100644 --- a/src/main/java/fr/xephi/authme/command/CommandUtils.java +++ b/src/main/java/fr/xephi/authme/command/CommandUtils.java @@ -7,11 +7,20 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; +/** + * Utility functions for {@link CommandDescription} objects. + */ public final class CommandUtils { private CommandUtils() { } + /** + * Returns the minimum number of arguments required for running the command (= number of mandatory arguments). + * + * @param command the command to process + * @return min number of arguments required by the command + */ public static int getMinNumberOfArguments(CommandDescription command) { int mandatoryArguments = 0; for (CommandArgumentDescription argument : command.getArguments()) { @@ -22,20 +31,16 @@ public final class CommandUtils { return mandatoryArguments; } + /** + * Returns the maximum number of arguments the command accepts. + * + * @param command the command to process + * @return max number of arguments that may be passed to the command + */ public static int getMaxNumberOfArguments(CommandDescription command) { return command.getArguments().size(); } - public static String constructCommandPath(CommandDescription command) { - StringBuilder sb = new StringBuilder(); - String prefix = "/"; - for (CommandDescription ancestor : constructParentList(command)) { - sb.append(prefix).append(ancestor.getLabels().get(0)); - prefix = " "; - } - return sb.toString(); - } - /** * Constructs a hierarchical list of commands for the given command. The commands are in order: * the parents of the given command precede the provided command. For example, given the command @@ -54,6 +59,29 @@ public final class CommandUtils { return Lists.reverse(commands); } + /** + * Returns a textual representation of the command, e.g. {@code /authme register}. + * + * @param command the command to create the path for + * @return the command string + */ + public static String constructCommandPath(CommandDescription command) { + StringBuilder sb = new StringBuilder(); + String prefix = "/"; + for (CommandDescription ancestor : constructParentList(command)) { + sb.append(prefix).append(ancestor.getLabels().get(0)); + prefix = " "; + } + return sb.toString(); + } + + /** + * Returns a textual representation of the command, including its arguments. + * For example: {@code /authme purge [includeZero]}. + * + * @param command the command to create a usage string for + * @return the command's path and arguments + */ public static String buildSyntax(CommandDescription command) { String arguments = command.getArguments().stream() .map(arg -> formatArgument(arg)) @@ -73,12 +101,12 @@ public final class CommandUtils { } /** - * Format a command argument with the proper type of brackets. + * Formats a command argument with the proper type of brackets. * * @param argument the argument to format * @return the formatted argument */ - public static String formatArgument(CommandArgumentDescription argument) { + private static String formatArgument(CommandArgumentDescription argument) { if (argument.isOptional()) { return "[" + argument.getName() + "]"; } diff --git a/src/main/java/fr/xephi/authme/command/executable/HelpCommand.java b/src/main/java/fr/xephi/authme/command/executable/HelpCommand.java index 0f7d90d2..118994f0 100644 --- a/src/main/java/fr/xephi/authme/command/executable/HelpCommand.java +++ b/src/main/java/fr/xephi/authme/command/executable/HelpCommand.java @@ -20,6 +20,9 @@ import static fr.xephi.authme.command.help.HelpProvider.SHOW_CHILDREN; import static fr.xephi.authme.command.help.HelpProvider.SHOW_COMMAND; import static fr.xephi.authme.command.help.HelpProvider.SHOW_DESCRIPTION; +/** + * Displays help information to a user. + */ public class HelpCommand implements ExecutableCommand { @Inject @@ -51,7 +54,8 @@ public class HelpCommand implements ExecutableCommand { int mappedCommandLevel = result.getCommandDescription().getLabelCount(); if (mappedCommandLevel == 1) { - helpProvider.outputHelp(sender, result, SHOW_COMMAND | SHOW_DESCRIPTION | SHOW_CHILDREN | SHOW_ALTERNATIVES); + helpProvider.outputHelp(sender, result, + SHOW_COMMAND | SHOW_DESCRIPTION | SHOW_CHILDREN | SHOW_ALTERNATIVES); } else { helpProvider.outputHelp(sender, result, ALL_OPTIONS); } diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/TestEmailSender.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/TestEmailSender.java index 4d3cfc07..b57a5d6a 100644 --- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/TestEmailSender.java +++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/TestEmailSender.java @@ -68,6 +68,17 @@ class TestEmailSender implements DebugSection { return DebugSectionPermissions.TEST_EMAIL; } + /** + * Gets the email address to use based on the sender and the arguments. If the arguments are empty, + * we attempt to retrieve the email from the sender. If there is an argument, we verify that it is + * an email address. + * {@code null} is returned if no email address could be found. This method informs the sender of + * the specific error in such cases. + * + * @param sender the command sender + * @param arguments the provided arguments + * @return the email to use, or null if none found + */ private String getEmail(CommandSender sender, List arguments) { if (arguments.isEmpty()) { DataSourceResult emailResult = dataSource.getEmail(sender.getName()); 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 5b9d75ab..1ae1efca 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 @@ -97,6 +97,15 @@ public class RegisterCommand extends PlayerCommand { return null; } + /** + * Verifies that the second argument is valid (based on the configuration) + * to perform a password registration. The player is informed if the check + * is unsuccessful. + * + * @param player the player to register + * @param arguments the provided arguments + * @return true if valid, false otherwise + */ private boolean isSecondArgValidForPasswordRegistration(Player player, List arguments) { RegisterSecondaryArgument secondArgType = commonService.getProperty(REGISTER_SECOND_ARGUMENT); // cases where args.size < 2 @@ -143,6 +152,15 @@ public class RegisterCommand extends PlayerCommand { } } + /** + * Verifies that the second argument is valid (based on the configuration) + * to perform an email registration. The player is informed if the check + * is unsuccessful. + * + * @param player the player to register + * @param arguments the provided arguments + * @return true if valid, false otherwise + */ private boolean isSecondArgValidForEmailRegistration(Player player, List arguments) { RegisterSecondaryArgument secondArgType = commonService.getProperty(REGISTER_SECOND_ARGUMENT); // cases where args.size < 2 diff --git a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java index 23e87cab..4327b827 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpProvider.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpProvider.java @@ -58,7 +58,15 @@ public class HelpProvider implements Reloadable { this.helpMessagesService = helpMessagesService; } - private List printHelp(CommandSender sender, FoundCommandResult result, int options) { + /** + * Builds the help messages based on the provided arguments. + * + * @param sender the sender to evaluate permissions with + * @param result the command result to create help for + * @param options output options + * @return the generated help messages + */ + private List buildHelpOutput(CommandSender sender, FoundCommandResult result, int options) { if (result.getCommandDescription() == null) { return singletonList(ChatColor.DARK_RED + "Failed to retrieve any help information!"); } @@ -75,8 +83,7 @@ public class HelpProvider implements Reloadable { } CommandDescription command = helpMessagesService.buildLocalizedDescription(result.getCommandDescription()); - List labels = ImmutableList.copyOf(result.getLabels()); - List correctLabels = ImmutableList.copyOf(filterCorrectLabels(command, labels)); + List correctLabels = ImmutableList.copyOf(filterCorrectLabels(command, result.getLabels())); if (hasFlag(SHOW_COMMAND, options)) { lines.add(ChatColor.GOLD + helpMessagesService.getMessage(HelpSection.COMMAND) + ": " @@ -91,30 +98,30 @@ public class HelpProvider implements Reloadable { lines.add(ChatColor.WHITE + " " + command.getDetailedDescription()); } if (hasFlag(SHOW_ARGUMENTS, options)) { - printArguments(command, lines); + addArgumentsInfo(command, lines); } if (hasFlag(SHOW_PERMISSIONS, options) && sender != null) { - printPermissions(command, sender, lines); + addPermissionsInfo(command, sender, lines); } if (hasFlag(SHOW_ALTERNATIVES, options)) { - printAlternatives(command, correctLabels, lines); + addAlternativesInfo(command, correctLabels, lines); } if (hasFlag(SHOW_CHILDREN, options)) { - printChildren(command, labels, lines); + addChildrenInfo(command, correctLabels, lines); } return lines; } /** - * Output the help for a given command. + * Outputs the help for a given command. * - * @param sender The sender to output the help to - * @param result The result to output information about - * @param options Output options, see {@link HelpProvider} + * @param sender the sender to output the help to + * @param result the result to output information about + * @param options output options */ public void outputHelp(CommandSender sender, FoundCommandResult result, int options) { - List lines = printHelp(sender, result, options); + List lines = buildHelpOutput(sender, result, options); for (String line : lines) { sender.sendMessage(line); } @@ -134,6 +141,7 @@ public class HelpProvider implements Reloadable { * @param options the options to process * @return the options without any disabled sections */ + @SuppressWarnings("checkstyle:BooleanExpressionComplexity") private int filterDisabledSections(int options) { if (enabledSections == null) { enabledSections = flagFor(HelpSection.COMMAND, SHOW_COMMAND) @@ -151,7 +159,13 @@ public class HelpProvider implements Reloadable { return helpMessagesService.getMessage(section).isEmpty() ? 0 : flag; } - private void printArguments(CommandDescription command, List lines) { + /** + * Adds help info about the given command's arguments into the provided list. + * + * @param command the command to generate arguments info for + * @param lines the output collection to add the info to + */ + private void addArgumentsInfo(CommandDescription command, List lines) { if (command.getArguments().isEmpty()) { return; } @@ -171,7 +185,14 @@ public class HelpProvider implements Reloadable { } } - private void printAlternatives(CommandDescription command, List correctLabels, List lines) { + /** + * Adds help info about the given command's alternative labels into the provided list. + * + * @param command the command for which to generate info about its labels + * @param correctLabels labels used to access the command (sanitized) + * @param lines the output collection to add the info to + */ + private void addAlternativesInfo(CommandDescription command, List correctLabels, List lines) { if (command.getLabels().size() <= 1) { return; } @@ -199,7 +220,14 @@ public class HelpProvider implements Reloadable { } } - private void printPermissions(CommandDescription command, CommandSender sender, List lines) { + /** + * Adds help info about the given command's permissions into the provided list. + * + * @param command the command to generate permissions info for + * @param sender the command sender, used to evaluate permissions + * @param lines the output collection to add the info to + */ + private void addPermissionsInfo(CommandDescription command, CommandSender sender, List lines) { PermissionNode permission = command.getPermission(); if (permission == null) { return; @@ -240,13 +268,20 @@ public class HelpProvider implements Reloadable { return helpMessagesService.getMessage(HelpMessage.NO_PERMISSION); } - private void printChildren(CommandDescription command, List parentLabels, List lines) { + /** + * Adds help info about the given command's child command into the provided list. + * + * @param command the command for which to generate info about its child commands + * @param correctLabels the labels used to access the given command (sanitized) + * @param lines the output collection to add the info to + */ + private void addChildrenInfo(CommandDescription command, List correctLabels, List lines) { if (command.getChildren().isEmpty()) { return; } lines.add(ChatColor.GOLD + helpMessagesService.getMessage(HelpSection.CHILDREN) + ":"); - String parentCommandPath = String.join(" ", parentLabels); + String parentCommandPath = String.join(" ", correctLabels); for (CommandDescription child : command.getChildren()) { lines.add(" /" + parentCommandPath + " " + child.getLabels().get(0) + ChatColor.GRAY + ChatColor.ITALIC + ": " + helpMessagesService.getDescription(child)); @@ -257,6 +292,23 @@ public class HelpProvider implements Reloadable { return (flag & options) != 0; } + /** + * Returns a list of labels for the given command, using the labels from the provided labels list + * as long as they are correct. + *

+ * Background: commands may have multiple labels (e.g. /authme register vs. /authme reg). It is interesting + * for us to keep with which label the user requested the command. At the same time, when a user inputs a + * non-existent label, we try to find the most similar one. This method keeps all labels that exists and will + * default to the command's first label when an invalid label is encountered. + *

+ * Examples: + * command = "authme register", labels = {authme, egister}. Output: {authme, register} + * command = "authme register", labels = {authme, reg}. Output: {authme, reg} + * + * @param command the command to compare the labels against + * @param labels the labels as input by the user + * @return list of correct labels, keeping the user's input where possible + */ @VisibleForTesting static List filterCorrectLabels(CommandDescription command, List labels) { List commands = CommandUtils.constructParentList(command); 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 b08b965a..ec8fc47e 100644 --- a/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java +++ b/src/main/java/fr/xephi/authme/data/auth/PlayerAuth.java @@ -234,6 +234,11 @@ public class PlayerAuth { private float yaw; private float pitch; + /** + * Creates a PlayerAuth object. + * + * @return the generated PlayerAuth + */ public PlayerAuth build() { PlayerAuth auth = new PlayerAuth(); auth.nickname = checkNotNull(name).toLowerCase(); @@ -277,6 +282,12 @@ public class PlayerAuth { return this; } + /** + * Sets the location info based on the argument. + * + * @param location the location info to set + * @return this builder instance + */ public Builder location(Location location) { this.x = location.getX(); this.y = location.getY(); diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java b/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java index 64a93551..b3c0cc90 100644 --- a/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java +++ b/src/main/java/fr/xephi/authme/data/limbo/persistence/DistributedFilesPersistenceHandler.java @@ -57,7 +57,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler { @Override public LimboPlayer getLimboPlayer(Player player) { - String uuid = PlayerUtils.getUUIDorName(player); + String uuid = PlayerUtils.getUuidOrName(player); File file = getPlayerSegmentFile(uuid); Map entries = readLimboPlayers(file); return entries == null ? null : entries.get(uuid); @@ -65,7 +65,7 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler { @Override public void saveLimboPlayer(Player player, LimboPlayer limbo) { - String uuid = PlayerUtils.getUUIDorName(player); + String uuid = PlayerUtils.getUuidOrName(player); File file = getPlayerSegmentFile(uuid); Map entries = null; @@ -79,17 +79,17 @@ class DistributedFilesPersistenceHandler implements LimboPersistenceHandler { entries = new HashMap<>(); } - entries.put(PlayerUtils.getUUIDorName(player), limbo); + entries.put(PlayerUtils.getUuidOrName(player), limbo); saveEntries(entries, file); } @Override public void removeLimboPlayer(Player player) { - String uuid = PlayerUtils.getUUIDorName(player); + String uuid = PlayerUtils.getUuidOrName(player); File file = getPlayerSegmentFile(uuid); if (file.exists()) { Map entries = readLimboPlayers(file); - if (entries != null && entries.remove(PlayerUtils.getUUIDorName(player)) != null) { + if (entries != null && entries.remove(PlayerUtils.getUuidOrName(player)) != null) { saveEntries(entries, file); } } diff --git a/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java b/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java index 8408ee55..880c463e 100644 --- a/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java +++ b/src/main/java/fr/xephi/authme/data/limbo/persistence/IndividualFilesPersistenceHandler.java @@ -39,7 +39,7 @@ class IndividualFilesPersistenceHandler implements LimboPersistenceHandler { @Override public LimboPlayer getLimboPlayer(Player player) { - String id = PlayerUtils.getUUIDorName(player); + String id = PlayerUtils.getUuidOrName(player); File file = new File(cacheDir, id + File.separator + "data.json"); if (!file.exists()) { return null; @@ -56,7 +56,7 @@ class IndividualFilesPersistenceHandler implements LimboPersistenceHandler { @Override public void saveLimboPlayer(Player player, LimboPlayer limboPlayer) { - String id = PlayerUtils.getUUIDorName(player); + String id = PlayerUtils.getUuidOrName(player); try { File file = new File(cacheDir, id + File.separator + "data.json"); Files.createParentDirs(file); @@ -75,7 +75,7 @@ class IndividualFilesPersistenceHandler implements LimboPersistenceHandler { */ @Override public void removeLimboPlayer(Player player) { - String id = PlayerUtils.getUUIDorName(player); + String id = PlayerUtils.getUuidOrName(player); File file = new File(cacheDir, id); if (file.exists()) { FileUtils.purgeDirectory(file); diff --git a/src/main/java/fr/xephi/authme/datasource/DataSourceResult.java b/src/main/java/fr/xephi/authme/datasource/DataSourceResult.java index f556f853..c005874e 100644 --- a/src/main/java/fr/xephi/authme/datasource/DataSourceResult.java +++ b/src/main/java/fr/xephi/authme/datasource/DataSourceResult.java @@ -3,7 +3,7 @@ package fr.xephi.authme.datasource; /** * Wraps a value and allows to specify whether a value is missing or the player is not registered. */ -public class DataSourceResult { +public final class DataSourceResult { /** Instance used when a player does not exist. */ private static final DataSourceResult UNKNOWN_PLAYER = new DataSourceResult<>(null); diff --git a/src/main/java/fr/xephi/authme/datasource/MySQL.java b/src/main/java/fr/xephi/authme/datasource/MySQL.java index d04c7c3b..3da644d6 100644 --- a/src/main/java/fr/xephi/authme/datasource/MySQL.java +++ b/src/main/java/fr/xephi/authme/datasource/MySQL.java @@ -89,6 +89,11 @@ public class MySQL implements DataSource { setParameters(settings); } + /** + * Retrieves various settings. + * + * @param settings the settings to read properties from + */ private void setParameters(Settings settings) { this.host = settings.getProperty(DatabaseSettings.MYSQL_HOST); this.port = settings.getProperty(DatabaseSettings.MYSQL_PORT); @@ -112,6 +117,9 @@ public class MySQL implements DataSource { this.useSsl = settings.getProperty(DatabaseSettings.MYSQL_USE_SSL); } + /** + * Sets up the connection arguments to the database. + */ private void setConnectionArguments() { ds = new HikariDataSource(); ds.setPoolName("AuthMeMYSQLPool"); @@ -159,6 +167,9 @@ public class MySQL implements DataSource { return ds.getConnection(); } + /** + * Creates the table or any of its required columns if they don't exist. + */ private void checkTablesAndColumns() throws SQLException { try (Connection con = getConnection(); Statement st = con.createStatement()) { // Create table with ID column if it doesn't exist diff --git a/src/main/java/fr/xephi/authme/datasource/converter/VAuthConverter.java b/src/main/java/fr/xephi/authme/datasource/converter/VAuthConverter.java index ff88db2d..c21be137 100644 --- a/src/main/java/fr/xephi/authme/datasource/converter/VAuthConverter.java +++ b/src/main/java/fr/xephi/authme/datasource/converter/VAuthConverter.java @@ -42,8 +42,9 @@ public class VAuthConverter implements Converter { } catch (Exception | NoSuchMethodError e) { pname = getName(UUID.fromString(name)); } - if (pname == null) + if (pname == null) { continue; + } auth = PlayerAuth.builder() .name(pname.toLowerCase()) .realName(pname) diff --git a/src/main/java/fr/xephi/authme/mail/EmailService.java b/src/main/java/fr/xephi/authme/mail/EmailService.java index 5eb588d1..cfa2f927 100644 --- a/src/main/java/fr/xephi/authme/mail/EmailService.java +++ b/src/main/java/fr/xephi/authme/mail/EmailService.java @@ -80,6 +80,14 @@ public class EmailService { return couldSendEmail; } + /** + * Sends an email to the user with a recovery code for the password recovery process. + * + * @param name the name of the player + * @param email the player's email address + * @param code the recovery code + * @return true if email could be sent, false otherwise + */ public boolean sendRecoveryCode(String name, String email, String code) { HtmlEmail htmlEmail; try { diff --git a/src/main/java/fr/xephi/authme/mail/SendMailSsl.java b/src/main/java/fr/xephi/authme/mail/SendMailSsl.java index 34011595..885f8198 100644 --- a/src/main/java/fr/xephi/authme/mail/SendMailSsl.java +++ b/src/main/java/fr/xephi/authme/mail/SendMailSsl.java @@ -39,6 +39,13 @@ public class SendMailSsl { && !settings.getProperty(MAIL_PASSWORD).isEmpty(); } + /** + * Creates a {@link HtmlEmail} object configured as per the AuthMe config + * with the given email address as recipient. + * + * @param emailAddress the email address the email is destined for + * @return the created HtmlEmail object + */ public HtmlEmail initializeMail(String emailAddress) throws EmailException { String senderMail = StringUtils.isEmpty(settings.getProperty(EmailSettings.MAIL_ADDRESS)) ? settings.getProperty(EmailSettings.MAIL_ACCOUNT) @@ -66,6 +73,13 @@ public class SendMailSsl { return email; } + /** + * Sets the given content to the HtmlEmail object and sends it. + * + * @param content the content to set + * @param email the email object to send + * @return true upon success, false otherwise + */ public boolean sendEmail(String content, HtmlEmail email) { Thread.currentThread().setContextClassLoader(SendMailSsl.class.getClassLoader()); // Issue #999: Prevent UnsupportedDataTypeException: no object DCH for MIME type multipart/alternative @@ -93,6 +107,12 @@ public class SendMailSsl { } } + /** + * Sets properties to the given HtmlEmail object based on the port from which it will be sent. + * + * @param email the email object to configure + * @param port the configured outgoing port + */ private void setPropertiesForPort(HtmlEmail email, int port) throws EmailException { switch (port) { case 587: diff --git a/src/main/java/fr/xephi/authme/output/LogFilterHelper.java b/src/main/java/fr/xephi/authme/output/LogFilterHelper.java index 7d46daf8..22553830 100644 --- a/src/main/java/fr/xephi/authme/output/LogFilterHelper.java +++ b/src/main/java/fr/xephi/authme/output/LogFilterHelper.java @@ -12,14 +12,14 @@ import java.util.List; */ final class LogFilterHelper { - private static final String ISSUED_COMMAND_TEXT = "issued server command:"; - @VisibleForTesting static final List COMMANDS_TO_SKIP = withAndWithoutAuthMePrefix( "/login ", "/l ", "/log ", "/register ", "/reg ", "/unregister ", "/unreg ", "/changepassword ", "/cp ", "/changepass ", "/authme register ", "/authme reg ", "/authme r ", "/authme changepassword ", "/authme password ", "/authme changepass ", "/authme cp "); + private static final String ISSUED_COMMAND_TEXT = "issued server command:"; + private LogFilterHelper() { // Util class } diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java index 139179ea..3bdfdfb9 100644 --- a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java +++ b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java @@ -23,14 +23,13 @@ import java.util.Collection; import java.util.Collections; /** - *

* PermissionsManager. - *

+ *

* A permissions manager, to manage and use various permissions systems. * This manager supports dynamic plugin hooking and various other features. - *

+ *

* Written by Tim Visée. - *

+ * * @author Tim Visée, http://timvisee.com * @version 0.3 */ @@ -211,8 +210,8 @@ public class PermissionsManager implements Reloadable { } /** - * Check if a player has permission for the given permission node. This is for offline player checks. If no permissions - * system is used, then the player will not have permission. + * Check if a player has permission for the given permission node. This is for offline player checks. + * If no permissions system is used, then the player will not have permission. * * @param player The offline player * @param permissionNode The permission node to verify @@ -250,11 +249,7 @@ public class PermissionsManager implements Reloadable { * @return True if the current permissions system supports groups, false otherwise. */ public boolean hasGroupSupport() { - // If no permissions system is used, return false - if (!isEnabled()) - return false; - - return handler.hasGroupSupport(); + return isEnabled() && handler.hasGroupSupport(); } /** @@ -265,11 +260,7 @@ public class PermissionsManager implements Reloadable { * @return Permission groups, or an empty collection if this feature is not supported. */ public Collection getGroups(Player player) { - // If no permissions system is used, return an empty list - if (!isEnabled()) - return Collections.emptyList(); - - return handler.getGroups(player); + return isEnabled() ? handler.getGroups(player) : Collections.emptyList(); } /** @@ -280,11 +271,7 @@ public class PermissionsManager implements Reloadable { * @return The name of the primary permission group. Or null. */ public String getPrimaryGroup(Player player) { - // If no permissions system is used, return an empty list - if (!isEnabled()) - return null; - - return handler.getPrimaryGroup(player); + return isEnabled() ? handler.getPrimaryGroup(player) : null; } /** @@ -294,14 +281,10 @@ public class PermissionsManager implements Reloadable { * @param groupName The group name. * * @return True if the player is in the specified group, false otherwise. - * False is also returned if groups aren't supported by the used permissions system. + * False is also returned if groups aren't supported by the used permissions system. */ public boolean isInGroup(Player player, String groupName) { - // If no permissions system is used, return false - if (!isEnabled()) - return false; - - return handler.isInGroup(player, groupName); + return isEnabled() && handler.isInGroup(player, groupName); } /** @@ -311,7 +294,7 @@ public class PermissionsManager implements Reloadable { * @param groupName The name of the group. * * @return True if succeed, false otherwise. - * False is also returned if this feature isn't supported for the current permissions system. + * False is also returned if this feature isn't supported for the current permissions system. */ public boolean addGroup(Player player, String groupName) { if (!isEnabled() || StringUtils.isEmpty(groupName)) { @@ -327,13 +310,10 @@ public class PermissionsManager implements Reloadable { * @param groupName The name of the group. * * @return True if succeed, false otherwise. - * False is also returned if this feature isn't supported for the current permissions system. + * False is also returned if this feature isn't supported for the current permissions system. */ public boolean removeGroups(Player player, String groupName) { - if (!isEnabled()) - return false; - - return handler.removeFromGroup(player, groupName); + return isEnabled() && handler.removeFromGroup(player, groupName); } /** @@ -371,14 +351,10 @@ public class PermissionsManager implements Reloadable { * @param groupName The name of the group. * * @return True if succeed, false otherwise. - * False is also returned if this feature isn't supported for the current permissions system. + * False is also returned if this feature isn't supported for the current permissions system. */ public boolean setGroup(Player player, String groupName) { - // If no permissions system is used, return false - if (!isEnabled()) - return false; - - return handler.setGroup(player, groupName); + return isEnabled() && handler.setGroup(player, groupName); } /** @@ -389,12 +365,13 @@ public class PermissionsManager implements Reloadable { * @param player The player to remove all groups from. * * @return True if succeed, false otherwise. - * False will also be returned if this feature isn't supported for the used permissions system. + * False will also be returned if this feature isn't supported for the used permissions system. */ public boolean removeAllGroups(Player player) { // If no permissions system is used, return false - if (!isEnabled()) + if (!isEnabled()) { return false; + } // Get a list of current groups Collection groupNames = getGroups(player); 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 cb5a2c66..d2d68ceb 100644 --- a/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java +++ b/src/main/java/fr/xephi/authme/process/email/AsyncAddEmail.java @@ -32,6 +32,12 @@ public class AsyncAddEmail implements AsynchronousProcess { AsyncAddEmail() { } + /** + * Handles the request to add the given email to the player's account. + * + * @param player the player to add the email to + * @param email the email to add + */ public void addEmail(Player player, String email) { String playerName = player.getName().toLowerCase(); 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 5a054416..6b7e2b63 100644 --- a/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java +++ b/src/main/java/fr/xephi/authme/process/email/AsyncChangeEmail.java @@ -30,6 +30,13 @@ public class AsyncChangeEmail implements AsynchronousProcess { AsyncChangeEmail() { } + /** + * Handles the request to change the player's email address. + * + * @param player the player to change the email for + * @param oldEmail provided old email + * @param newEmail provided new email + */ public void changeEmail(Player player, String oldEmail, String newEmail) { String playerName = player.getName().toLowerCase(); if (playerCache.isAuthenticated(playerName)) { 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 acec4180..b96efdfa 100644 --- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java @@ -269,6 +269,12 @@ public class AsynchronousLogin implements AsynchronousProcess { ); } + /** + * Sends info about the other accounts owned by the given player to the configured users. + * + * @param auths the names of the accounts also owned by the player + * @param player the player + */ private void displayOtherAccounts(List auths, Player player) { if (!service.getProperty(RestrictionSettings.DISPLAY_OTHER_ACCOUNTS) || auths.size() <= 1) { return; 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 1f59d965..fb1ae36c 100644 --- a/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/AsynchronousLogout.java @@ -12,6 +12,9 @@ import org.bukkit.entity.Player; import javax.inject.Inject; +/** + * Async task when a player wants to log out. + */ public class AsynchronousLogout implements AsynchronousProcess { @Inject @@ -29,7 +32,12 @@ public class AsynchronousLogout implements AsynchronousProcess { AsynchronousLogout() { } - public void logout(final Player player) { + /** + * Handles a player's request to log out. + * + * @param player the player wanting to log out + */ + public void logout(Player player) { final String name = player.getName().toLowerCase(); if (!playerCache.isAuthenticated(name)) { service.send(player, MessageKey.NOT_LOGGED_IN); diff --git a/src/main/java/fr/xephi/authme/service/GeoIpService.java b/src/main/java/fr/xephi/authme/service/GeoIpService.java index 22e9af2c..f7aeaedc 100644 --- a/src/main/java/fr/xephi/authme/service/GeoIpService.java +++ b/src/main/java/fr/xephi/authme/service/GeoIpService.java @@ -76,6 +76,11 @@ public class GeoIpService { return false; } + /** + * Create a thread which will attempt to download new data from the GeoLite website. + * + * @return the generated download thread + */ private Thread createDownloadTask() { return new Thread(new Runnable() { @Override diff --git a/src/main/java/fr/xephi/authme/service/PluginHookService.java b/src/main/java/fr/xephi/authme/service/PluginHookService.java index 9ebcd712..26d0e6f8 100644 --- a/src/main/java/fr/xephi/authme/service/PluginHookService.java +++ b/src/main/java/fr/xephi/authme/service/PluginHookService.java @@ -90,7 +90,7 @@ public class PluginHookService { } /** - * Query the CombatTagPlus plugin whether the given player is an NPC. + * Queries the CombatTagPlus plugin whether the given player is an NPC. * * @param player The player to verify * @return True if the player is an NPC according to CombatTagPlus, false if not or if the plugin is unavailable @@ -103,14 +103,23 @@ public class PluginHookService { // ------ // "Is plugin available" methods // ------ + /** + * @return true if we have a hook to Essentials, false otherwise + */ public boolean isEssentialsAvailable() { return essentials != null; } + /** + * @return true if we have a hook to Multiverse, false otherwise + */ public boolean isMultiverseAvailable() { return multiverse != null; } + /** + * @return true if we have a hook to CombatTagPlus, false otherwise + */ public boolean isCombatTagPlusAvailable() { return combatTagPlus != null; } @@ -118,6 +127,10 @@ public class PluginHookService { // ------ // Hook methods // ------ + + /** + * Attempts to create a hook into Essentials. + */ public void tryHookToEssentials() { try { essentials = getPlugin(pluginManager, "Essentials", Essentials.class); @@ -126,6 +139,9 @@ public class PluginHookService { } } + /** + * Attempts to create a hook into CombatTagPlus. + */ public void tryHookToCombatPlus() { try { combatTagPlus = getPlugin(pluginManager, "CombatTagPlus", CombatTagPlus.class); @@ -134,6 +150,9 @@ public class PluginHookService { } } + /** + * Attempts to create a hook into Multiverse. + */ public void tryHookToMultiverse() { try { multiverse = getPlugin(pluginManager, "Multiverse-Core", MultiverseCore.class); @@ -145,12 +164,23 @@ public class PluginHookService { // ------ // Unhook methods // ------ + /** + * Unhooks from Essentials. + */ public void unhookEssentials() { essentials = null; } + + /** + * Unhooks from CombatTagPlus. + */ public void unhookCombatPlus() { combatTagPlus = null; } + + /** + * Unhooks from Multiverse. + */ public void unhookMultiverse() { multiverse = null; } diff --git a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java index ade6833d..7e41196f 100644 --- a/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java +++ b/src/main/java/fr/xephi/authme/settings/SettingsMigrationService.java @@ -52,6 +52,7 @@ public class SettingsMigrationService extends PlainMigrationService { } @Override + @SuppressWarnings("checkstyle:BooleanExpressionComplexity") protected boolean performMigrations(PropertyResource resource, List> properties) { boolean changes = false; if ("[a-zA-Z0-9_?]*".equals(resource.getString(ALLOWED_NICKNAME_CHARACTERS.getPath()))) { @@ -229,13 +230,19 @@ public class SettingsMigrationService extends PlainMigrationService { return false; } + /** + * Converts old boolean configurations for registration to the new enum properties, if applicable. + * + * @param resource The property resource + * @return True if the configuration has changed, false otherwise + */ private static boolean convertToRegistrationType(PropertyResource resource) { - String oldEmailRegistrationPath = "settings.registration.enableEmailRegistrationSystem"; - if (RegistrationSettings.REGISTRATION_TYPE.isPresent(resource) || !resource.contains(oldEmailRegistrationPath)) { + String oldEmailRegisterPath = "settings.registration.enableEmailRegistrationSystem"; + if (RegistrationSettings.REGISTRATION_TYPE.isPresent(resource) || !resource.contains(oldEmailRegisterPath)) { return false; } - boolean useEmail = newProperty(oldEmailRegistrationPath, false).getValue(resource); + boolean useEmail = newProperty(oldEmailRegisterPath, false).getValue(resource); RegistrationType registrationType = useEmail ? RegistrationType.EMAIL : RegistrationType.PASSWORD; String useConfirmationPath = useEmail @@ -253,6 +260,12 @@ public class SettingsMigrationService extends PlainMigrationService { return true; } + /** + * Migrates old permission group settings to the new configurations. + * + * @param resource The property resource + * @return True if the configuration has changed, false otherwise + */ private static boolean mergeAndMovePermissionGroupSettings(PropertyResource resource) { boolean performedChanges; @@ -274,7 +287,7 @@ public class SettingsMigrationService extends PlainMigrationService { } /** - * Checks for an old property path and moves it to a new path if present. + * Checks for an old property path and moves it to a new path if it is present and the new path is not yet set. * * @param oldProperty The old property (create a temporary {@link Property} object with the path) * @param newProperty The new property to move the value to diff --git a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java index 13f28004..09442ed4 100644 --- a/src/main/java/fr/xephi/authme/settings/SpawnLoader.java +++ b/src/main/java/fr/xephi/authme/settings/SpawnLoader.java @@ -165,6 +165,8 @@ public class SpawnLoader implements Reloadable { case "authme": spawnLoc = getSpawn(); break; + default: + // ignore } if (spawnLoc != null) { return spawnLoc; diff --git a/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java b/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java index 6e6e5836..13bd2923 100644 --- a/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java +++ b/src/main/java/fr/xephi/authme/task/purge/PurgeExecutor.java @@ -2,11 +2,11 @@ package fr.xephi.authme.task.purge; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.datasource.DataSource; -import fr.xephi.authme.service.PluginHookService; import fr.xephi.authme.permission.PermissionsManager; +import fr.xephi.authme.service.BukkitService; +import fr.xephi.authme.service.PluginHookService; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.PurgeSettings; -import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.util.PlayerUtils; import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; @@ -67,8 +67,7 @@ public class PurgeExecutor { } int i = 0; - File dataFolder = new File("." + File.separator + "plugins" + File.separator + "AntiXRayData" - + File.separator + "PlayerData"); + File dataFolder = new File(makePath(".", "plugins", "AntiXRayData", "PlayerData")); if (!dataFolder.exists() || !dataFolder.isDirectory()) { return; } @@ -102,8 +101,7 @@ public class PurgeExecutor { } int i = 0; - File dataFolder = new File("." + File.separator + "plugins" + File.separator + "LimitedCreative" - + File.separator + "inventories"); + File dataFolder = new File(makePath(".", "plugins", "LimitedCreative", "inventories")); if (!dataFolder.exists() || !dataFolder.isDirectory()) { return; } @@ -148,11 +146,11 @@ public class PurgeExecutor { } int i = 0; - File dataFolder = new File(server.getWorldContainer() - , makePath(settings.getProperty(PurgeSettings.DEFAULT_WORLD), "players")); + File dataFolder = new File(server.getWorldContainer(), + makePath(settings.getProperty(PurgeSettings.DEFAULT_WORLD), "players")); for (OfflinePlayer offlinePlayer : cleared) { - File playerFile = new File(dataFolder, PlayerUtils.getUUIDorName(offlinePlayer) + ".dat"); + File playerFile = new File(dataFolder, PlayerUtils.getUuidOrName(offlinePlayer) + ".dat"); if (playerFile.delete()) { i++; } @@ -184,7 +182,7 @@ public class PurgeExecutor { } for (OfflinePlayer offlinePlayer : cleared) { - File playerFile = new File(userDataFolder, PlayerUtils.getUUIDorName(offlinePlayer) + ".yml"); + File playerFile = new File(userDataFolder, PlayerUtils.getUuidOrName(offlinePlayer) + ".yml"); if (playerFile.exists() && playerFile.delete()) { i++; } @@ -193,7 +191,7 @@ public class PurgeExecutor { ConsoleLogger.info("AutoPurge: Removed " + i + " EssentialsFiles"); } - // TODO: What is this method for? Is it correct? + // TODO #676: What is this method for? Is it correct? synchronized void purgePermissions(Collection cleared) { if (!settings.getProperty(PurgeSettings.REMOVE_PERMISSIONS)) { return; diff --git a/src/main/java/fr/xephi/authme/util/PlayerUtils.java b/src/main/java/fr/xephi/authme/util/PlayerUtils.java index 3c4e067b..7eba43d3 100644 --- a/src/main/java/fr/xephi/authme/util/PlayerUtils.java +++ b/src/main/java/fr/xephi/authme/util/PlayerUtils.java @@ -19,7 +19,7 @@ public final class PlayerUtils { * * @return player's UUID or Name in String. */ - public static String getUUIDorName(OfflinePlayer player) { + public static String getUuidOrName(OfflinePlayer player) { // We may made this configurable in future // so we can have uuid support. try { diff --git a/src/test/java/fr/xephi/authme/ClassesConsistencyTest.java b/src/test/java/fr/xephi/authme/ClassesConsistencyTest.java index ac050488..7f26cef5 100644 --- a/src/test/java/fr/xephi/authme/ClassesConsistencyTest.java +++ b/src/test/java/fr/xephi/authme/ClassesConsistencyTest.java @@ -6,7 +6,6 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import fr.xephi.authme.datasource.Columns; import fr.xephi.authme.initialization.HasCleanup; -import fr.xephi.authme.listener.PlayerListener; import fr.xephi.authme.process.register.executors.RegistrationMethod; import fr.xephi.authme.security.crypts.Whirlpool; import fr.xephi.authme.util.expiring.ExpiringMap; diff --git a/src/test/java/fr/xephi/authme/api/NewAPITest.java b/src/test/java/fr/xephi/authme/api/NewAPITest.java new file mode 100644 index 00000000..5cf89742 --- /dev/null +++ b/src/test/java/fr/xephi/authme/api/NewAPITest.java @@ -0,0 +1,250 @@ +package fr.xephi.authme.api; + +import fr.xephi.authme.ReflectionTestUtils; +import fr.xephi.authme.api.v3.AuthMeApi; +import fr.xephi.authme.data.auth.PlayerAuth; +import fr.xephi.authme.data.auth.PlayerCache; +import fr.xephi.authme.datasource.DataSource; +import fr.xephi.authme.process.Management; +import fr.xephi.authme.security.PasswordSecurity; +import fr.xephi.authme.service.PluginHookService; +import fr.xephi.authme.service.ValidationService; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; +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 java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.sameInstance; +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 fr.xephi.authme.api.NewAPI}. + */ +@RunWith(MockitoJUnitRunner.class) +public class NewAPITest { + + @InjectMocks + private NewAPI api; + + @Mock + private PluginHookService pluginHookService; + @Mock + private ValidationService validationService; + @Mock + private DataSource dataSource; + @Mock + private Management management; + @Mock + private PasswordSecurity passwordSecurity; + @Mock + private PlayerCache playerCache; + + @Test + public void shouldReturnInstanceOrNull() { + NewAPI result = NewAPI.getInstance(); + assertThat(result, sameInstance(api)); + + ReflectionTestUtils.setField(AuthMeApi.class, null, "singleton", null); + assertThat(AuthMeApi.getInstance(), nullValue()); + } + + @Test + public void shouldReturnIfPlayerIsAuthenticated() { + // given + String name = "Bobby"; + Player player = mockPlayerWithName(name); + given(playerCache.isAuthenticated(name)).willReturn(true); + + // when + boolean result = api.isAuthenticated(player); + + // then + verify(playerCache).isAuthenticated(name); + assertThat(result, equalTo(true)); + } + + @Test + public void shouldReturnIfPlayerIsNpc() { + // given + Player player = mock(Player.class); + given(pluginHookService.isNpc(player)).willReturn(true); + + // when + boolean result = api.isNPC(player); + + // then + assertThat(result, equalTo(true)); + } + + @Test + public void shouldReturnIfPlayerIsUnrestricted() { + // given + String name = "Tester"; + Player player = mockPlayerWithName(name); + given(validationService.isUnrestricted(name)).willReturn(true); + + // when + boolean result = api.isUnrestricted(player); + + // then + verify(validationService).isUnrestricted(name); + assertThat(result, equalTo(true)); + } + + @Test + public void shouldGetLastLocation() { + // given + String name = "Gary"; + Player player = mockPlayerWithName(name); + PlayerAuth auth = PlayerAuth.builder().name(name) + .locWorld("world") + .locX(12.4) + .locY(24.6) + .locZ(-438.2) + .locYaw(3.41f) + .locPitch(0.29f) + .build(); + given(playerCache.getAuth(name)).willReturn(auth); + Server server = mock(Server.class); + ReflectionTestUtils.setField(Bukkit.class, null, "server", server); + World world = mock(World.class); + given(server.getWorld(auth.getWorld())).willReturn(world); + + // when + Location result = api.getLastLocation(player); + + // then + assertThat(result, not(nullValue())); + assertThat(result.getX(), equalTo(auth.getQuitLocX())); + assertThat(result.getY(), equalTo(auth.getQuitLocY())); + assertThat(result.getZ(), equalTo(auth.getQuitLocZ())); + assertThat(result.getWorld(), equalTo(world)); + } + + @Test + public void shouldReturnNullForUnavailablePlayer() { + // given + String name = "Numan"; + Player player = mockPlayerWithName(name); + given(playerCache.getAuth(name)).willReturn(null); + + // when + Location result = api.getLastLocation(player); + + // then + assertThat(result, nullValue()); + } + + @Test + public void shouldCheckForRegisteredName() { + // given + String name = "toaster"; + given(dataSource.isAuthAvailable(name)).willReturn(true); + + // when + boolean result = api.isRegistered(name); + + // then + assertThat(result, equalTo(true)); + } + + @Test + public void shouldCheckPassword() { + // given + String playerName = "Robert"; + String password = "someSecretPhrase2983"; + given(passwordSecurity.comparePassword(password, playerName)).willReturn(true); + + // when + boolean result = api.checkPassword(playerName, password); + + // then + verify(passwordSecurity).comparePassword(password, playerName); + assertThat(result, equalTo(true)); + } + + @Test + public void shouldReturnAuthNames() { + // given + String[] names = {"bobby", "peter", "elisabeth", "craig"}; + List auths = Arrays.stream(names) + .map(name -> PlayerAuth.builder().name(name).build()) + .collect(Collectors.toList()); + given(dataSource.getAllAuths()).willReturn(auths); + + // when + List result = api.getRegisteredNames(); + + // then + assertThat(result, contains(names)); + } + + @Test + public void shouldReturnAuthRealNames() { + // given + String[] names = {"Bobby", "peter", "Elisabeth", "CRAIG"}; + List auths = Arrays.stream(names) + .map(name -> PlayerAuth.builder().name(name).realName(name).build()) + .collect(Collectors.toList()); + given(dataSource.getAllAuths()).willReturn(auths); + + // when + List result = api.getRegisteredRealNames(); + + // then + assertThat(result, contains(names)); + } + + @Test + public void shouldUnregisterPlayer() { + // given + Player player = mock(Player.class); + String name = "Donald"; + given(player.getName()).willReturn(name); + + // when + api.forceUnregister(player); + + // then + verify(management).performUnregisterByAdmin(null, name, player); + } + + @Test + public void shouldUnregisterPlayerByName() { + // given + Server server = mock(Server.class); + ReflectionTestUtils.setField(Bukkit.class, null, "server", server); + String name = "tristan"; + Player player = mock(Player.class); + given(server.getPlayer(name)).willReturn(player); + + // when + api.forceUnregister(name); + + // then + verify(management).performUnregisterByAdmin(null, name, player); + } + + private static Player mockPlayerWithName(String name) { + Player player = mock(Player.class); + given(player.getName()).willReturn(name); + return player; + } +} diff --git a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java index 23bb2458..8fb2dcad 100644 --- a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java @@ -212,6 +212,7 @@ public class CommandInitializerTest { testCollectionForCommand(command, CommandUtils.getMinNumberOfArguments(command), mandatoryArguments); testCollectionForCommand(command, CommandUtils.getMaxNumberOfArguments(command), totalArguments); } + private void testCollectionForCommand(CommandDescription command, int argCount, Map, Integer> collection) { final Class clazz = command.getExecutableCommand(); diff --git a/src/test/java/fr/xephi/authme/command/TestCommandsUtil.java b/src/test/java/fr/xephi/authme/command/TestCommandsUtil.java index 9f9b02ca..111eb088 100644 --- a/src/test/java/fr/xephi/authme/command/TestCommandsUtil.java +++ b/src/test/java/fr/xephi/authme/command/TestCommandsUtil.java @@ -82,7 +82,7 @@ public final class TestCommandsUtil { throw new IllegalStateException("Could not find command with label '" + label + "'"); } - /** Shortcut command to initialize a new test command. */ + /* Shortcut command to initialize a new test command. */ private static CommandDescription createCommand(PermissionNode permission, CommandDescription parent, List labels, Class commandClass, CommandArgumentDescription... arguments) { @@ -103,7 +103,7 @@ public final class TestCommandsUtil { return command.register(); } - /** Shortcut command to initialize a new argument description. */ + /* Shortcut command to initialize a new argument description. */ private static CommandArgumentDescription newArgument(String label, boolean isOptional) { return new CommandArgumentDescription(label, "'" + label + "' argument description", isOptional); } 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 7e341723..c5a7301a 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 @@ -118,7 +118,7 @@ public class AccountsCommandTest { // given CommandSender sender = mock(CommandSender.class); List arguments = Collections.singletonList("123.45.67.89"); - given(dataSource.getAllAuthsByIp("123.45.67.89")).willReturn(Collections.emptyList()); + given(dataSource.getAllAuthsByIp("123.45.67.89")).willReturn(Collections.emptyList()); // when command.executeCommand(sender, arguments); diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java index f17f75fe..84ce1a9c 100644 --- a/src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java +++ b/src/test/java/fr/xephi/authme/command/executable/authme/AuthMeCommandTest.java @@ -25,7 +25,7 @@ public class AuthMeCommandTest { CommandSender sender = mock(CommandSender.class); // when - command.executeCommand(sender, Collections.emptyList()); + command.executeCommand(sender, Collections.emptyList()); // then ArgumentCaptor messagesCaptor = ArgumentCaptor.forClass(String.class); 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 3daaf7ad..4b1af2b9 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 @@ -40,7 +40,7 @@ public class FirstSpawnCommandTest { Player player = mock(Player.class); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(player).teleport(firstSpawn); @@ -54,7 +54,7 @@ public class FirstSpawnCommandTest { Player player = mock(Player.class); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(player).sendMessage(argThat(containsString("spawn has failed"))); 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 43099db6..f0891ffe 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 @@ -90,15 +90,15 @@ public class LastLoginCommandTest { CommandSender sender = mock(CommandSender.class); given(sender.getName()).willReturn(name); - long lastLogin = System.currentTimeMillis() - - (412 * DAY_IN_MSEC + 10 * HOUR_IN_MSEC - 9000); + long lastLogin = System.currentTimeMillis() + - (412 * DAY_IN_MSEC + 10 * HOUR_IN_MSEC - 9000); PlayerAuth auth = mock(PlayerAuth.class); given(auth.getLastLogin()).willReturn(lastLogin); given(auth.getIp()).willReturn("123.45.66.77"); given(dataSource.getAuth(name)).willReturn(auth); // when - command.executeCommand(sender, Collections.emptyList()); + command.executeCommand(sender, Collections.emptyList()); // then verify(dataSource).getAuth(name); 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 677ee1fe..199044cb 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 @@ -46,7 +46,7 @@ public class PurgeBannedPlayersCommandTest { CommandSender sender = mock(CommandSender.class); // when - command.executeCommand(sender, Collections.emptyList()); + command.executeCommand(sender, Collections.emptyList()); // then verify(bukkitService).getBannedPlayers(); 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 5f3aa6f1..a4880512 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 @@ -63,7 +63,7 @@ public class PurgeLastPositionCommandTest { given(dataSource.getAuth(player)).willReturn(auth); // when - command.executeCommand(sender, Collections.emptyList()); + command.executeCommand(sender, Collections.emptyList()); // then verify(dataSource).getAuth(player); 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 f59dda89..67cb3d91 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 @@ -39,7 +39,7 @@ public class SetFirstSpawnCommandTest { given(spawnLoader.setFirstSpawn(location)).willReturn(true); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(spawnLoader).setFirstSpawn(location); @@ -55,7 +55,7 @@ public class SetFirstSpawnCommandTest { given(spawnLoader.setFirstSpawn(location)).willReturn(false); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(spawnLoader).setFirstSpawn(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 c4c6abce..b9566c98 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 @@ -41,7 +41,7 @@ public class SpawnCommandTest { Player player = mock(Player.class); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(player).teleport(spawn); @@ -55,7 +55,7 @@ public class SpawnCommandTest { Player player = mock(Player.class); // when - command.executeCommand(player, Collections.emptyList()); + command.executeCommand(player, Collections.emptyList()); // then verify(player).sendMessage(argThat(containsString("Spawn has failed"))); 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 03dd4077..f3c2e99c 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 @@ -47,7 +47,7 @@ public class SwitchAntiBotCommandTest { CommandSender sender = mock(CommandSender.class); // when - command.executeCommand(sender, Collections.emptyList()); + command.executeCommand(sender, Collections.emptyList()); // then verify(sender).sendMessage(argThat(containsString("status: ACTIVE"))); diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java index b6b04f74..312482d7 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java @@ -212,7 +212,7 @@ public class PlayerListenerTest { public void shouldNotCancelEventForAuthenticatedPlayer() { // given given(settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)).willReturn(false); - given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(Collections.emptyList()); + given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(Collections.emptyList()); Player player = playerWithMockedServer(); // PlayerCommandPreprocessEvent#getPlayer is final, so create a spy instead of a mock PlayerCommandPreprocessEvent event = spy(new PlayerCommandPreprocessEvent(player, "/hub")); diff --git a/src/test/java/fr/xephi/authme/util/PlayerUtilsTest.java b/src/test/java/fr/xephi/authme/util/PlayerUtilsTest.java index d16a8547..cfeecdcf 100644 --- a/src/test/java/fr/xephi/authme/util/PlayerUtilsTest.java +++ b/src/test/java/fr/xephi/authme/util/PlayerUtilsTest.java @@ -44,7 +44,7 @@ public class PlayerUtilsTest { given(player.getUniqueId()).willReturn(uuid); // when - String result = PlayerUtils.getUUIDorName(player); + String result = PlayerUtils.getUuidOrName(player); // then assertThat(result, equalTo(uuid.toString())); @@ -59,7 +59,7 @@ public class PlayerUtilsTest { given(player.getName()).willReturn(name); // when - String result = PlayerUtils.getUUIDorName(player); + String result = PlayerUtils.getUuidOrName(player); // then assertThat(result, equalTo(name));