#1034 Add debug sections for spawn and input validation
This commit is contained in:
parent
c54231b255
commit
8cf7983027
@ -177,6 +177,7 @@
|
|||||||
</module>
|
</module>
|
||||||
<module name="MissingOverride"/>
|
<module name="MissingOverride"/>
|
||||||
<module name="EqualsHashCode"/>
|
<module name="EqualsHashCode"/>
|
||||||
|
<module name="EqualsAvoidNull"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="FileTabCharacter"/>
|
<module name="FileTabCharacter"/>
|
||||||
</module>
|
</module>
|
||||||
|
|||||||
@ -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");
|
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
|
// Unsalted hashes will be deprecated in 5.4 (see Github issue #1016)
|
||||||
// it is needed to hook into an existing system.
|
|
||||||
HashAlgorithm hash = settings.getProperty(SecuritySettings.PASSWORD_HASH);
|
HashAlgorithm hash = settings.getProperty(SecuritySettings.PASSWORD_HASH);
|
||||||
if (OnStartupTasks.isHashDeprecatedIn54(hash)) {
|
if (OnStartupTasks.isHashDeprecatedIn54(hash)) {
|
||||||
ConsoleLogger.warning("You are using an unsalted hash (" + hash + "). Support for this will be removed "
|
ConsoleLogger.warning("You are using an unsalted hash (" + hash + "). Support for this will be removed "
|
||||||
|
|||||||
@ -16,13 +16,14 @@ import java.util.TreeMap;
|
|||||||
*/
|
*/
|
||||||
public class DebugCommand implements ExecutableCommand {
|
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
|
@Inject
|
||||||
private Factory<DebugSection> debugSectionFactory;
|
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;
|
private Map<String, DebugSection> sections;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -48,7 +49,7 @@ public class DebugCommand implements ExecutableCommand {
|
|||||||
private Map<String, DebugSection> getSections() {
|
private Map<String, DebugSection> getSections() {
|
||||||
if (sections == null) {
|
if (sections == null) {
|
||||||
Map<String, DebugSection> sections = new TreeMap<>();
|
Map<String, DebugSection> sections = new TreeMap<>();
|
||||||
for (Class<? extends DebugSection> sectionClass : sectionClasses) {
|
for (Class<? extends DebugSection> sectionClass : SECTION_CLASSES) {
|
||||||
DebugSection section = debugSectionFactory.newInstance(sectionClass);
|
DebugSection section = debugSectionFactory.newInstance(sectionClass);
|
||||||
sections.put(section.getName(), section);
|
sections.put(section.getName(), section);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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.LimboPlayer;
|
||||||
import fr.xephi.authme.data.limbo.LimboService;
|
import fr.xephi.authme.data.limbo.LimboService;
|
||||||
import fr.xephi.authme.data.limbo.persistence.LimboPersistence;
|
import fr.xephi.authme.data.limbo.persistence.LimboPersistence;
|
||||||
|
import fr.xephi.authme.permission.PermissionsManager;
|
||||||
import fr.xephi.authme.service.BukkitService;
|
import fr.xephi.authme.service.BukkitService;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -31,6 +32,9 @@ class LimboPlayerViewer implements DebugSection {
|
|||||||
@Inject
|
@Inject
|
||||||
private BukkitService bukkitService;
|
private BukkitService bukkitService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PermissionsManager permissionsManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "limbo";
|
return "limbo";
|
||||||
@ -64,8 +68,7 @@ class LimboPlayerViewer implements DebugSection {
|
|||||||
.sendEntry("Can fly", LimboPlayer::isCanFly, Player::getAllowFlight)
|
.sendEntry("Can fly", LimboPlayer::isCanFly, Player::getAllowFlight)
|
||||||
.sendEntry("Fly speed", LimboPlayer::getFlySpeed, Player::getFlySpeed)
|
.sendEntry("Fly speed", LimboPlayer::getFlySpeed, Player::getFlySpeed)
|
||||||
.sendEntry("Location", l -> formatLocation(l.getLocation()), p -> formatLocation(p.getLocation()))
|
.sendEntry("Location", l -> formatLocation(l.getLocation()), p -> formatLocation(p.getLocation()))
|
||||||
.sendEntry("Group", LimboPlayer::getGroup, p -> "");
|
.sendEntry("Group", LimboPlayer::getGroup, permissionsManager::getPrimaryGroup);
|
||||||
sender.sendMessage("Note: group is not shown for Player. Use /authme debug groups");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -35,6 +35,7 @@ class PermissionGroups implements DebugSection {
|
|||||||
} else {
|
} else {
|
||||||
sender.sendMessage("Player " + name + " has permission groups: "
|
sender.sendMessage("Player " + name + " has permission groups: "
|
||||||
+ String.join(", ", permissionsManager.getGroups(player)));
|
+ String.join(", ", permissionsManager.getGroups(player)));
|
||||||
|
sender.sendMessage("Primary group is: " + permissionsManager.getGroups(player));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@ import fr.xephi.authme.ConsoleLogger;
|
|||||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.mail.SendMailSsl;
|
import fr.xephi.authme.mail.SendMailSsl;
|
||||||
|
import fr.xephi.authme.util.StringUtils;
|
||||||
import org.apache.commons.mail.EmailException;
|
import org.apache.commons.mail.EmailException;
|
||||||
import org.apache.commons.mail.HtmlEmail;
|
import org.apache.commons.mail.HtmlEmail;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
@ -76,7 +77,7 @@ class TestEmailSender implements DebugSection {
|
|||||||
return email;
|
return email;
|
||||||
} else {
|
} else {
|
||||||
String email = arguments.get(0);
|
String email = arguments.get(0);
|
||||||
if (email.contains("@")) {
|
if (StringUtils.isInsideString('@', email)) {
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
sender.sendMessage(ChatColor.RED + "Invalid email! Usage: /authme debug mail test@example.com");
|
sender.sendMessage(ChatColor.RED + "Invalid email! Usage: /authme debug mail test@example.com");
|
||||||
|
|||||||
@ -29,7 +29,7 @@ import java.util.regex.Pattern;
|
|||||||
/**
|
/**
|
||||||
* Service for performing various verifications when a player joins.
|
* Service for performing various verifications when a player joins.
|
||||||
*/
|
*/
|
||||||
class OnJoinVerifier implements Reloadable {
|
public class OnJoinVerifier implements Reloadable {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Settings settings;
|
private Settings settings;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user