From 24162ad94b1f79562775baa99ec3eaf76f221866 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sun, 29 Jan 2017 19:47:14 +0100 Subject: [PATCH] #1034 Create debug command structure + utility to see permission groups - Relevant to current work... :) --- .../authme/command/CommandInitializer.java | 15 ++++++ .../executable/authme/debug/DebugCommand.java | 46 +++++++++++++++++++ .../executable/authme/debug/DebugSection.java | 30 ++++++++++++ .../authme/debug/PermissionGroups.java | 40 ++++++++++++++++ .../permission/PlayerStatePermission.java | 7 ++- src/main/resources/plugin.yml | 7 ++- .../command/CommandInitializerTest.java | 29 ------------ 7 files changed, 142 insertions(+), 32 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/command/executable/authme/debug/DebugCommand.java create mode 100644 src/main/java/fr/xephi/authme/command/executable/authme/debug/DebugSection.java create mode 100644 src/main/java/fr/xephi/authme/command/executable/authme/debug/PermissionGroups.java diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java index 7e01e0e3..98030c96 100644 --- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java +++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java @@ -24,6 +24,7 @@ import fr.xephi.authme.command.executable.authme.SpawnCommand; import fr.xephi.authme.command.executable.authme.SwitchAntiBotCommand; import fr.xephi.authme.command.executable.authme.UnregisterAdminCommand; import fr.xephi.authme.command.executable.authme.VersionCommand; +import fr.xephi.authme.command.executable.authme.debug.DebugCommand; import fr.xephi.authme.command.executable.captcha.CaptchaCommand; import fr.xephi.authme.command.executable.changepassword.ChangePasswordCommand; import fr.xephi.authme.command.executable.email.AddEmailCommand; @@ -37,6 +38,7 @@ import fr.xephi.authme.command.executable.register.RegisterCommand; import fr.xephi.authme.command.executable.unregister.UnregisterCommand; import fr.xephi.authme.permission.AdminPermission; import fr.xephi.authme.permission.PlayerPermission; +import fr.xephi.authme.permission.PlayerStatePermission; import java.util.Arrays; import java.util.Collection; @@ -298,6 +300,19 @@ public class CommandInitializer { .executableCommand(MessagesCommand.class) .register(); + CommandDescription.builder() + .parent(AUTHME_BASE) + .labels("debug", "dbg") + .description("Debug features") + .detailedDescription("Allows various operations for debugging.") + .withArgument("child", "The child to execute", true) + .withArgument(".", "meaning varies", true) + .withArgument(".", "meaning varies", true) + .withArgument(".", "meaning varies", true) + .permission(PlayerStatePermission.DEBUG_COMMAND) + .executableCommand(DebugCommand.class) + .register(); + // Register the base login command final CommandDescription LOGIN_BASE = CommandDescription.builder() .parent(null) diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/DebugCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/DebugCommand.java new file mode 100644 index 00000000..f9541deb --- /dev/null +++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/DebugCommand.java @@ -0,0 +1,46 @@ +package fr.xephi.authme.command.executable.authme.debug; + +import fr.xephi.authme.command.ExecutableCommand; +import org.bukkit.command.CommandSender; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Debug command main. + */ +public class DebugCommand implements ExecutableCommand { + + @Inject + private PermissionGroups permissionGroups; + + private Map sections; + + @PostConstruct + private void collectSections() { + Map sections = Stream.of(permissionGroups) + .collect(Collectors.toMap(DebugSection::getName, Function.identity())); + this.sections = sections; + } + + @Override + public void executeCommand(CommandSender sender, List arguments) { + if (arguments.isEmpty()) { + sender.sendMessage("Available sections:"); + sections.values() + .forEach(e -> sender.sendMessage("- " + e.getName() + ": " + e.getDescription())); + } else { + DebugSection debugSection = sections.get(arguments.get(0).toLowerCase()); + if (debugSection == null) { + sender.sendMessage("Unknown subcommand"); + } else { + debugSection.execute(sender, arguments.subList(1, arguments.size())); + } + } + } +} diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/DebugSection.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/DebugSection.java new file mode 100644 index 00000000..1f038983 --- /dev/null +++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/DebugSection.java @@ -0,0 +1,30 @@ +package fr.xephi.authme.command.executable.authme.debug; + +import org.bukkit.command.CommandSender; + +import java.util.List; + +/** + * A debug section: "child" command of the debug command. + */ +interface DebugSection { + + /** + * @return the name to get to this child command + */ + String getName(); + + /** + * @return short description of the child command + */ + String getDescription(); + + /** + * Executes the debug child command. + * + * @param sender the sender executing the command + * @param arguments the arguments, without the label of the child command + */ + void execute(CommandSender sender, List arguments); + +} diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/PermissionGroups.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/PermissionGroups.java new file mode 100644 index 00000000..e3876ff0 --- /dev/null +++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/PermissionGroups.java @@ -0,0 +1,40 @@ +package fr.xephi.authme.command.executable.authme.debug; + +import fr.xephi.authme.permission.PermissionsManager; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import javax.inject.Inject; +import java.util.List; + +/** + * Outputs the permission groups of a player. + */ +class PermissionGroups implements DebugSection { + + @Inject + private PermissionsManager permissionsManager; + + @Override + public String getName() { + return "groups"; + } + + @Override + public String getDescription() { + return "Show permission groups a player belongs to"; + } + + @Override + public void execute(CommandSender sender, List arguments) { + String name = arguments.isEmpty() ? sender.getName() : arguments.get(0); + Player player = Bukkit.getPlayer(name); + if (player == null) { + sender.sendMessage("Player " + name + " could not be found"); + } else { + sender.sendMessage("Player " + name + " has permission groups: " + + String.join(", ", permissionsManager.getGroups(player))); + } + } +} diff --git a/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java b/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java index aaeb0eea..2160eea5 100644 --- a/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java @@ -29,7 +29,12 @@ public enum PlayerStatePermission implements PermissionNode { /** * Permission to bypass the purging process. */ - BYPASS_PURGE("authme.bypasspurge", DefaultPermission.NOT_ALLOWED); + BYPASS_PURGE("authme.bypasspurge", DefaultPermission.NOT_ALLOWED), + + /** + * Permission to use the /authme debug command. + */ + DEBUG_COMMAND("authme.debug", DefaultPermission.OP_ONLY); /** * The permission node. diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9ca68c31..f04829d4 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -17,7 +17,7 @@ softdepend: commands: authme: description: AuthMe op commands - usage: /authme register|unregister|forcelogin|password|lastlogin|accounts|email|setemail|getip|spawn|setspawn|firstspawn|setfirstspawn|purge|resetpos|purgebannedplayers|switchantibot|reload|version|converter|messages + usage: /authme register|unregister|forcelogin|password|lastlogin|accounts|email|setemail|getip|spawn|setspawn|firstspawn|setfirstspawn|purge|resetpos|purgebannedplayers|switchantibot|reload|version|converter|messages|debug login: description: Login command usage: /login @@ -153,6 +153,9 @@ permissions: authme.bypasspurge: description: Permission to bypass the purging process. default: false + authme.debug: + description: Permission to use the /authme debug command. + default: op authme.player.*: description: Gives access to all player commands children: @@ -207,5 +210,5 @@ permissions: description: Command permission to unregister. default: true authme.vip: - description: Permission node to identify VIP users. + description: When the server is full and someone with this permission joins the server, someone will be kicked. default: op diff --git a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java index a4e51e28..23bb2458 100644 --- a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java @@ -1,7 +1,5 @@ package fr.xephi.authme.command; -import fr.xephi.authme.permission.AdminPermission; -import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.util.StringUtils; import org.junit.BeforeClass; import org.junit.Test; @@ -16,7 +14,6 @@ import java.util.Set; import java.util.function.BiConsumer; import java.util.regex.Pattern; -import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertThat; @@ -199,32 +196,6 @@ public class CommandInitializerTest { walkThroughCommands(commands, noArgumentForParentChecker); } - /** - * Test that commands defined with the OP_ONLY default permission have at least one admin permission node. - */ - @Test - public void shouldNotHavePlayerPermissionIfDefaultsToOpOnly() { - // given - BiConsumer adminPermissionChecker = new BiConsumer() { - @Override - public void accept(CommandDescription command, Integer depth) { - PermissionNode permission = command.getPermission(); - if (permission != null && OP_ONLY.equals(permission.getDefaultPermission()) - && !hasAdminNode(permission)) { - fail("The command with labels " + command.getLabels() + " has OP_ONLY default " - + "permission but no permission node on admin level"); - } - } - - private boolean hasAdminNode(PermissionNode permission) { - return permission instanceof AdminPermission; - } - }; - - // when/then - walkThroughCommands(commands, adminPermissionChecker); - } - /** * Tests that multiple CommandDescription instances pointing to the same ExecutableCommand use the same * count of arguments.