#1034 Create permissions for debug sections

- Add an individual permission for each debug section (including wildcard perm)
- Create test for DebugCommand
- Refactor tests for the enum permission nodes to use the same abstract class
- Update related project files (plugin.yml, permission docs, command docs)
This commit is contained in:
ljacqu
2017-04-14 19:54:17 +02:00
parent cbec5427f2
commit 2a747c7d01
27 changed files with 480 additions and 120 deletions
@@ -39,8 +39,8 @@ import fr.xephi.authme.command.executable.logout.LogoutCommand;
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.DebugSectionPermissions;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.permission.PlayerStatePermission;
import java.util.Arrays;
import java.util.Collection;
@@ -312,10 +312,9 @@ public class CommandInitializer {
.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)
.withArgument("arg", "argument (depends on debug section)", true)
.withArgument("arg", "argument (depends on debug section)", true)
.permission(DebugSectionPermissions.DEBUG_COMMAND)
.executableCommand(DebugCommand.class)
.register();
@@ -2,6 +2,8 @@ package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.service.GeoIpService;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.settings.properties.ProtectionSettings;
@@ -54,6 +56,11 @@ class CountryLookup implements DebugSection {
}
}
@Override
public PermissionNode getRequiredPermission() {
return DebugSectionPermissions.COUNTRY_LOOKUP;
}
private void outputInfoForIpAddr(CommandSender sender, String ipAddr) {
sender.sendMessage("IP '" + ipAddr + "' maps to country '" + geoIpService.getCountryCode(ipAddr)
+ "' (" + geoIpService.getCountryName(ipAddr) + ")");
@@ -8,6 +8,8 @@ import fr.xephi.authme.initialization.HasCleanup;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.initialization.factory.SingletonStore;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
@@ -52,6 +54,11 @@ class DataStatistics implements DebugSection {
outputInjectorStats(sender);
}
@Override
public PermissionNode getRequiredPermission() {
return DebugSectionPermissions.DATA_STATISTICS;
}
private void outputDatabaseStats(CommandSender sender) {
sender.sendMessage("Total players in DB: " + dataSource.getAccountsRegistered());
sender.sendMessage("Total marked as logged in in DB: " + dataSource.getLoggedPlayers().size());
@@ -3,6 +3,8 @@ package fr.xephi.authme.command.executable.authme.debug;
import com.google.common.collect.ImmutableSet;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.initialization.factory.Factory;
import fr.xephi.authme.permission.PermissionsManager;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
@@ -24,27 +26,48 @@ public class DebugCommand implements ExecutableCommand {
@Inject
private Factory<DebugSection> debugSectionFactory;
@Inject
private PermissionsManager permissionsManager;
private Map<String, DebugSection> sections;
@Override
public void executeCommand(CommandSender sender, List<String> arguments) {
DebugSection debugSection = getDebugSection(arguments);
DebugSection debugSection = findDebugSection(arguments);
if (debugSection == null) {
sender.sendMessage("Available sections:");
getSections().values()
.forEach(e -> sender.sendMessage("- " + e.getName() + ": " + e.getDescription()));
sendAvailableSections(sender);
} else {
debugSection.execute(sender, arguments.subList(1, arguments.size()));
executeSection(debugSection, sender, arguments);
}
}
private DebugSection getDebugSection(List<String> arguments) {
private DebugSection findDebugSection(List<String> arguments) {
if (arguments.isEmpty()) {
return null;
}
return getSections().get(arguments.get(0).toLowerCase());
}
private void sendAvailableSections(CommandSender sender) {
sender.sendMessage("Sections available to you:");
long availableSections = getSections().values().stream()
.filter(section -> permissionsManager.hasPermission(sender, section.getRequiredPermission()))
.peek(e -> sender.sendMessage("- " + e.getName() + ": " + e.getDescription()))
.count();
if (availableSections == 0) {
sender.sendMessage(ChatColor.RED + "You don't have permission to view any debug section");
}
}
private void executeSection(DebugSection section, CommandSender sender, List<String> arguments) {
if (permissionsManager.hasPermission(sender, section.getRequiredPermission())) {
section.execute(sender, arguments.subList(1, arguments.size()));
} else {
sender.sendMessage(ChatColor.RED + "You don't have permission for this section. See /authme debug");
}
}
// Lazy getter
private Map<String, DebugSection> getSections() {
if (sections == null) {
@@ -1,5 +1,6 @@
package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.permission.PermissionNode;
import org.bukkit.command.CommandSender;
import java.util.List;
@@ -27,4 +28,9 @@ interface DebugSection {
*/
void execute(CommandSender sender, List<String> arguments);
/**
* @return permission required to run this section
*/
PermissionNode getRequiredPermission();
}
@@ -2,6 +2,7 @@ package fr.xephi.authme.command.executable.authme.debug;
import com.google.common.collect.ImmutableList;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.DefaultPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
@@ -25,8 +26,8 @@ import java.util.function.BiFunction;
*/
class HasPermissionChecker implements DebugSection {
static final List<Class<? extends PermissionNode>> PERMISSION_NODE_CLASSES =
ImmutableList.of(AdminPermission.class, PlayerPermission.class, PlayerStatePermission.class);
static final List<Class<? extends PermissionNode>> PERMISSION_NODE_CLASSES = ImmutableList.of(
AdminPermission.class, PlayerPermission.class, PlayerStatePermission.class, DebugSectionPermissions.class);
@Inject
private PermissionsManager permissionsManager;
@@ -69,6 +70,11 @@ class HasPermissionChecker implements DebugSection {
}
}
@Override
public PermissionNode getRequiredPermission() {
return DebugSectionPermissions.HAS_PERMISSION_CHECK;
}
/**
* Performs a permission check and informs the given sender of the result. {@code permissionChecker} is the
* permission check to perform with the given {@code node} and the {@code player}.
@@ -90,7 +96,6 @@ class HasPermissionChecker implements DebugSection {
sender.sendMessage(ChatColor.DARK_RED + "Check failed: player '" + player.getName()
+ "' does NOT have permission '" + node + "'");
}
}
/**
@@ -3,6 +3,8 @@ 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.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.service.ValidationService.ValidationResult;
import org.bukkit.ChatColor;
@@ -60,6 +62,11 @@ class InputValidator implements DebugSection {
}
}
@Override
public PermissionNode getRequiredPermission() {
return DebugSectionPermissions.INPUT_VALIDATOR;
}
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:");
@@ -3,6 +3,8 @@ 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.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.service.BukkitService;
import org.bukkit.ChatColor;
@@ -71,6 +73,11 @@ class LimboPlayerViewer implements DebugSection {
.sendEntry("Group", LimboPlayer::getGroup, permissionsManager::getPrimaryGroup);
}
@Override
public PermissionNode getRequiredPermission() {
return DebugSectionPermissions.LIMBO_PLAYER_VIEWER;
}
/**
* Displays the info for the given LimboPlayer and Player to the provided CommandSender.
*/
@@ -1,5 +1,7 @@
package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@@ -38,4 +40,9 @@ class PermissionGroups implements DebugSection {
sender.sendMessage("Primary group is: " + permissionsManager.getGroups(player));
}
}
@Override
public PermissionNode getRequiredPermission() {
return DebugSectionPermissions.PERM_GROUPS;
}
}
@@ -2,6 +2,8 @@ package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.ChatColor;
@@ -50,6 +52,11 @@ class PlayerAuthViewer implements DebugSection {
}
}
@Override
public PermissionNode getRequiredPermission() {
return DebugSectionPermissions.PLAYER_AUTH_VIEWER;
}
/**
* Outputs the PlayerAuth information to the given sender.
*
@@ -1,5 +1,7 @@
package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.SpawnLoader;
@@ -49,6 +51,11 @@ class SpawnLocationViewer implements DebugSection {
}
}
@Override
public PermissionNode getRequiredPermission() {
return DebugSectionPermissions.SPAWN_LOCATION;
}
private void showGeneralInfo(CommandSender sender) {
sender.sendMessage("Spawn priority: "
+ String.join(", ", settings.getProperty(RestrictionSettings.SPAWN_PRIORITY)));
@@ -4,6 +4,8 @@ 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.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.util.StringUtils;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
@@ -60,6 +62,11 @@ class TestEmailSender implements DebugSection {
}
}
@Override
public PermissionNode getRequiredPermission() {
return DebugSectionPermissions.TEST_EMAIL;
}
private String getEmail(CommandSender sender, List<String> arguments) {
if (arguments.isEmpty()) {
PlayerAuth auth = dataSource.getAuth(sender.getName());
@@ -0,0 +1,58 @@
package fr.xephi.authme.permission;
/**
* Permissions for the debug sections (/authme debug).
*/
public enum DebugSectionPermissions implements PermissionNode {
/** General permission to use the /authme debug command. */
DEBUG_COMMAND("authme.debug.command"),
/** Permission to use the country lookup section. */
COUNTRY_LOOKUP("authme.debug.country"),
/** Permission to use the stats section. */
DATA_STATISTICS("authme.debug.stats"),
/** Permission to use the permission checker. */
HAS_PERMISSION_CHECK("authme.debug.perm"),
/** Permission to use sample validation. */
INPUT_VALIDATOR("authme.debug.valid"),
/** Permission to use the limbo data viewer. */
LIMBO_PLAYER_VIEWER("authme.debug.limbo"),
/** Permission to view permission groups. */
PERM_GROUPS("authme.debug.group"),
/** Permission to view data from the database. */
PLAYER_AUTH_VIEWER("authme.debug.db"),
/** Permission to view spawn information. */
SPAWN_LOCATION("authme.debug.spawn"),
/** Permission to use the test email sender. */
TEST_EMAIL("authme.debug.mail");
private final String node;
/**
* Constructor.
*
* @param node the permission node
*/
DebugSectionPermissions(String node) {
this.node = node;
}
@Override
public String getNode() {
return node;
}
@Override
public DefaultPermission getDefaultPermission() {
return DefaultPermission.OP_ONLY;
}
}
@@ -29,12 +29,7 @@ public enum PlayerStatePermission implements PermissionNode {
/**
* Permission to bypass the purging process.
*/
BYPASS_PURGE("authme.bypasspurge", DefaultPermission.NOT_ALLOWED),
/**
* Permission to use the /authme debug command.
*/
DEBUG_COMMAND("authme.debug", DefaultPermission.OP_ONLY);
BYPASS_PURGE("authme.bypasspurge", DefaultPermission.NOT_ALLOWED);
/**
* The permission node.