#1034 Create debug command structure + utility to see permission groups

- Relevant to current work... :)
This commit is contained in:
ljacqu 2017-01-29 19:47:14 +01:00
parent 350ef9b5e6
commit 24162ad94b
7 changed files with 142 additions and 32 deletions

View File

@ -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)

View File

@ -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<String, DebugSection> sections;
@PostConstruct
private void collectSections() {
Map<String, DebugSection> sections = Stream.of(permissionGroups)
.collect(Collectors.toMap(DebugSection::getName, Function.identity()));
this.sections = sections;
}
@Override
public void executeCommand(CommandSender sender, List<String> 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()));
}
}
}
}

View File

@ -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<String> arguments);
}

View File

@ -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<String> 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)));
}
}
}

View File

@ -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.

View File

@ -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 <password>
@ -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

View File

@ -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<CommandDescription, Integer> adminPermissionChecker = new BiConsumer<CommandDescription, Integer>() {
@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.