#1034 Add debug sections for spawn and input validation

This commit is contained in:
ljacqu 2017-03-26 12:10:51 +02:00
parent c54231b255
commit 8cf7983027
9 changed files with 210 additions and 11 deletions

View File

@ -177,6 +177,7 @@
</module>
<module name="MissingOverride"/>
<module name="EqualsHashCode"/>
<module name="EqualsAvoidNull"/>
</module>
<module name="FileTabCharacter"/>
</module>

View File

@ -288,8 +288,7 @@ public class AuthMe extends JavaPlugin {
ConsoleLogger.warning("Note: You have set Email.useTls to false but this only affects mail over port 25");
}
// Unsalted hashes will be deprecated in 5.4 (see Github issue #1016). Exclude RoyalAuth from this check because
// it is needed to hook into an existing system.
// Unsalted hashes will be deprecated in 5.4 (see Github issue #1016)
HashAlgorithm hash = settings.getProperty(SecuritySettings.PASSWORD_HASH);
if (OnStartupTasks.isHashDeprecatedIn54(hash)) {
ConsoleLogger.warning("You are using an unsalted hash (" + hash + "). Support for this will be removed "

View File

@ -16,13 +16,14 @@ import java.util.TreeMap;
*/
public class DebugCommand implements ExecutableCommand {
private static final Set<Class<? extends DebugSection>> SECTION_CLASSES = ImmutableSet.of(
PermissionGroups.class, DataStatistics.class, CountryLookup.class, PlayerAuthViewer.class, InputValidator.class,
LimboPlayerViewer.class, CountryLookup.class, HasPermissionChecker.class, TestEmailSender.class,
SpawnLocationViewer.class);
@Inject
private Factory<DebugSection> debugSectionFactory;
private Set<Class<? extends DebugSection>> sectionClasses = ImmutableSet.of(PermissionGroups.class,
DataStatistics.class, CountryLookup.class, PlayerAuthViewer.class, LimboPlayerViewer.class, CountryLookup.class,
HasPermissionChecker.class, TestEmailSender.class);
private Map<String, DebugSection> sections;
@Override
@ -48,7 +49,7 @@ public class DebugCommand implements ExecutableCommand {
private Map<String, DebugSection> getSections() {
if (sections == null) {
Map<String, DebugSection> sections = new TreeMap<>();
for (Class<? extends DebugSection> sectionClass : sectionClasses) {
for (Class<? extends DebugSection> sectionClass : SECTION_CLASSES) {
DebugSection section = debugSectionFactory.newInstance(sectionClass);
sections.put(section.getName(), section);
}

View File

@ -0,0 +1,115 @@
package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.listener.FailedVerificationException;
import fr.xephi.authme.listener.OnJoinVerifier;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.service.ValidationService.ValidationResult;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.Arrays;
import java.util.List;
import static fr.xephi.authme.command.executable.authme.debug.InputValidator.ValidationObject.MAIL;
import static fr.xephi.authme.command.executable.authme.debug.InputValidator.ValidationObject.NAME;
import static fr.xephi.authme.command.executable.authme.debug.InputValidator.ValidationObject.PASS;
/**
* Checks if a sample username, email or password is valid according to the AuthMe settings.
*/
class InputValidator implements DebugSection {
@Inject
private ValidationService validationService;
@Inject
private Messages messages;
@Inject
private OnJoinVerifier onJoinVerifier;
@Override
public String getName() {
return "valid";
}
@Override
public String getDescription() {
return "Check if email / password is valid according to your settings";
}
@Override
public void execute(CommandSender sender, List<String> arguments) {
if (arguments.size() < 2 || !ValidationObject.matchesAny(arguments.get(0))) {
displayUsageHint(sender);
} else if (PASS.matches(arguments.get(0))) {
validatePassword(sender, arguments.get(1));
} else if (MAIL.matches(arguments.get(0))) {
validateEmail(sender, arguments.get(1));
} else if (NAME.matches(arguments.get(0))) {
validateUsername(sender, arguments.get(1));
} else {
throw new IllegalStateException("Unexpected validation object with arg[0] = '" + arguments.get(0) + "'");
}
}
private void displayUsageHint(CommandSender sender) {
sender.sendMessage("You can define forbidden emails and passwords in your config.yml");
sender.sendMessage("This command allows you to test some of the values:");
sender.sendMessage("/authme debug valid pass test1234 -- test if 'test1234' is allowed password");
sender.sendMessage("/authme debug valid mail t@t.tld -- test if 't@t.tld' is allowed email");
sender.sendMessage("/authme debug valid name bobby1 -- test if 'bobby1' is allowed username");
}
private void validatePassword(CommandSender sender, String password) {
ValidationResult validationResult = validationService.validatePassword(password, "");
sender.sendMessage("Validation of password '" + password + "' returned:");
if (validationResult.hasError()) {
messages.send(sender, validationResult.getMessageKey(), validationResult.getArgs());
} else {
sender.sendMessage(ChatColor.DARK_GREEN + "Valid password!");
}
}
private void validateEmail(CommandSender sender, String email) {
boolean isValidEmail = validationService.validateEmail(email);
sender.sendMessage("Validation of email '" + email + "' returned:");
if (isValidEmail) {
sender.sendMessage(ChatColor.DARK_GREEN + "Valid email!");
} else {
sender.sendMessage(ChatColor.DARK_RED + "Email is not valid!");
}
}
private void validateUsername(CommandSender sender, String username) {
sender.sendMessage("Validation of username '" + username + "' returned:");
try {
onJoinVerifier.checkIsValidName(username);
sender.sendMessage("Valid username!");
} catch (FailedVerificationException failedVerificationEx) {
messages.send(sender, failedVerificationEx.getReason(), failedVerificationEx.getArgs());
}
}
enum ValidationObject {
PASS, MAIL, NAME;
static boolean matchesAny(String arg) {
return Arrays.stream(values()).anyMatch(vo -> vo.matches(arg));
}
boolean matches(String arg) {
return name().equalsIgnoreCase(arg);
}
}
}

View File

@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.data.limbo.persistence.LimboPersistence;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.service.BukkitService;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@ -31,6 +32,9 @@ class LimboPlayerViewer implements DebugSection {
@Inject
private BukkitService bukkitService;
@Inject
private PermissionsManager permissionsManager;
@Override
public String getName() {
return "limbo";
@ -64,8 +68,7 @@ class LimboPlayerViewer implements DebugSection {
.sendEntry("Can fly", LimboPlayer::isCanFly, Player::getAllowFlight)
.sendEntry("Fly speed", LimboPlayer::getFlySpeed, Player::getFlySpeed)
.sendEntry("Location", l -> formatLocation(l.getLocation()), p -> formatLocation(p.getLocation()))
.sendEntry("Group", LimboPlayer::getGroup, p -> "");
sender.sendMessage("Note: group is not shown for Player. Use /authme debug groups");
.sendEntry("Group", LimboPlayer::getGroup, permissionsManager::getPrimaryGroup);
}
/**

View File

@ -35,6 +35,7 @@ class PermissionGroups implements DebugSection {
} else {
sender.sendMessage("Player " + name + " has permission groups: "
+ String.join(", ", permissionsManager.getGroups(player)));
sender.sendMessage("Primary group is: " + permissionsManager.getGroups(player));
}
}
}

View File

@ -0,0 +1,78 @@
package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.List;
import static fr.xephi.authme.command.executable.authme.debug.DebugSectionUtils.formatLocation;
/**
* Shows the spawn location that AuthMe is configured to use.
*/
class SpawnLocationViewer implements DebugSection {
@Inject
private SpawnLoader spawnLoader;
@Inject
private Settings settings;
@Inject
private BukkitService bukkitService;
@Override
public String getName() {
return "spawn";
}
@Override
public String getDescription() {
return "Shows the spawn location that AuthMe will use";
}
@Override
public void execute(CommandSender sender, List<String> arguments) {
if (arguments.isEmpty()) {
showGeneralInfo(sender);
} else if ("?".equals(arguments.get(0))) {
showHelp(sender);
} else {
showPlayerSpawn(sender, arguments.get(0));
}
}
private void showGeneralInfo(CommandSender sender) {
sender.sendMessage("Spawn priority: "
+ String.join(", ", settings.getProperty(RestrictionSettings.SPAWN_PRIORITY)));
sender.sendMessage("AuthMe spawn location: " + formatLocation(spawnLoader.getSpawn()));
sender.sendMessage("AuthMe first spawn location: " + formatLocation(spawnLoader.getFirstSpawn()));
sender.sendMessage("AuthMe (first)spawn are only used depending on the configured priority!");
sender.sendMessage("Use '/authme debug spawn ?' for further help");
}
private void showHelp(CommandSender sender) {
sender.sendMessage("Use /authme spawn and /authme firstspawn to teleport to the spawns.");
sender.sendMessage("/authme set(first)spawn sets the (first) spawn to your current location.");
sender.sendMessage("Use /authme debug spawn <player> to view where a player would be teleported to.");
sender.sendMessage("Read more at https://github.com/AuthMe/AuthMeReloaded/wiki/Spawn-Handling");
}
private void showPlayerSpawn(CommandSender sender, String playerName) {
Player player = bukkitService.getPlayerExact(playerName);
if (player == null) {
sender.sendMessage("Player '" + playerName + "' is not online!");
} else {
Location spawn = spawnLoader.getSpawnLocation(player);
sender.sendMessage("Player '" + playerName + "' has spawn location: " + formatLocation(spawn));
sender.sendMessage("Note: this check excludes the AuthMe firstspawn.");
}
}
}

View File

@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.mail.SendMailSsl;
import fr.xephi.authme.util.StringUtils;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.bukkit.ChatColor;
@ -76,7 +77,7 @@ class TestEmailSender implements DebugSection {
return email;
} else {
String email = arguments.get(0);
if (email.contains("@")) {
if (StringUtils.isInsideString('@', email)) {
return email;
}
sender.sendMessage(ChatColor.RED + "Invalid email! Usage: /authme debug mail test@example.com");

View File

@ -29,7 +29,7 @@ import java.util.regex.Pattern;
/**
* Service for performing various verifications when a player joins.
*/
class OnJoinVerifier implements Reloadable {
public class OnJoinVerifier implements Reloadable {
@Inject
private Settings settings;