diff --git a/docs/commands.md b/docs/commands.md
index 344b643d..b9e127f8 100644
--- a/docs/commands.md
+++ b/docs/commands.md
@@ -1,5 +1,5 @@
-
+
## AuthMe Commands
You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >`
@@ -47,8 +47,8 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
Requires `authme.admin.converter`
- **/authme messages**: Adds missing messages to the current messages file.
Requires `authme.admin.updatemessages`
-- **/authme debug** [child] [params]: Allows various operations for debugging.
-
Requires `authme.debug`
+- **/authme debug** [child] [arg] [arg]: Allows various operations for debugging.
+
Requires `authme.debug.command`
- **/authme help** [query]: View detailed help for /authme commands.
- **/login** <password>: Command to log in using AuthMeReloaded.
Requires `authme.player.login`
@@ -82,6 +82,7 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
Requires `authme.player.captcha`
- **/captcha help** [query]: View detailed help for /captcha commands.
+
---
-This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Wed Mar 22 23:10:32 CET 2017
+This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Fri Apr 14 18:52:29 CEST 2017
diff --git a/docs/permission_nodes.md b/docs/permission_nodes.md
index fb640820..ef9df8d8 100644
--- a/docs/permission_nodes.md
+++ b/docs/permission_nodes.md
@@ -1,5 +1,5 @@
-
+
## AuthMe Permission Nodes
The following are the permission nodes that are currently supported by the latest dev builds.
@@ -31,6 +31,16 @@ The following are the permission nodes that are currently supported by the lates
- **authme.bypassantibot** – Permission node to bypass AntiBot protection.
- **authme.bypassforcesurvival** – Permission for users to bypass force-survival mode.
- **authme.bypasspurge** – Permission to bypass the purging process.
+- **authme.debug.command** – General permission to use the /authme debug command.
+- **authme.debug.country** – Permission to use the country lookup section.
+- **authme.debug.db** – Permission to view data from the database.
+- **authme.debug.group** – Permission to view permission groups.
+- **authme.debug.limbo** – Permission to use the limbo data viewer.
+- **authme.debug.mail** – Permission to use the test email sender.
+- **authme.debug.perm** – Permission to use the permission checker.
+- **authme.debug.spawn** – Permission to view spawn information.
+- **authme.debug.stats** – Permission to use the stats section.
+- **authme.debug.valid** – Permission to use sample validation.
- **authme.player.*** – Permission to use all player (non-admin) commands.
- **authme.player.canbeforced** – Permission for users a login can be forced to.
- **authme.player.captcha** – Command permission to use captcha.
@@ -49,4 +59,4 @@ The following are the permission nodes that are currently supported by the lates
---
-This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sun Oct 23 15:38:58 CEST 2016
+This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Fri Apr 14 18:52:32 CEST 2017
diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java
index dd27c279..841cdf4d 100644
--- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java
+++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java
@@ -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();
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/CountryLookup.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/CountryLookup.java
index 05de8ab1..781b8392 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/CountryLookup.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/CountryLookup.java
@@ -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) + ")");
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/DataStatistics.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/DataStatistics.java
index 3bf28e05..4afba2de 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/DataStatistics.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/DataStatistics.java
@@ -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());
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
index fc7cd429..e8976287 100644
--- 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
@@ -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 debugSectionFactory;
+ @Inject
+ private PermissionsManager permissionsManager;
+
private Map sections;
@Override
public void executeCommand(CommandSender sender, List 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 arguments) {
+ private DebugSection findDebugSection(List 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 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 getSections() {
if (sections == null) {
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
index 1f038983..155520c4 100644
--- 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
@@ -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 arguments);
+ /**
+ * @return permission required to run this section
+ */
+ PermissionNode getRequiredPermission();
+
}
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionChecker.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionChecker.java
index 436ef180..4d2bacf1 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionChecker.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionChecker.java
@@ -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> PERMISSION_NODE_CLASSES =
- ImmutableList.of(AdminPermission.class, PlayerPermission.class, PlayerStatePermission.class);
+ static final List> 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 + "'");
}
-
}
/**
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/InputValidator.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/InputValidator.java
index 47202506..d1131e0a 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/InputValidator.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/InputValidator.java
@@ -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:");
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/LimboPlayerViewer.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/LimboPlayerViewer.java
index a8c62e68..b017d193 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/LimboPlayerViewer.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/LimboPlayerViewer.java
@@ -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.
*/
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
index a7bf19eb..0fd62d8d 100644
--- 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
@@ -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;
+ }
}
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewer.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewer.java
index a985c827..f4a26ec8 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewer.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/PlayerAuthViewer.java
@@ -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.
*
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/SpawnLocationViewer.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/SpawnLocationViewer.java
index 0262055e..cfb6e0cd 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/SpawnLocationViewer.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/SpawnLocationViewer.java
@@ -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)));
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/debug/TestEmailSender.java b/src/main/java/fr/xephi/authme/command/executable/authme/debug/TestEmailSender.java
index 04ba276a..e83dfee5 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/debug/TestEmailSender.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/debug/TestEmailSender.java
@@ -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 arguments) {
if (arguments.isEmpty()) {
PlayerAuth auth = dataSource.getAuth(sender.getName());
diff --git a/src/main/java/fr/xephi/authme/permission/DebugSectionPermissions.java b/src/main/java/fr/xephi/authme/permission/DebugSectionPermissions.java
new file mode 100644
index 00000000..ee2d0d7f
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/permission/DebugSectionPermissions.java
@@ -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;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java b/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java
index 2160eea5..aaeb0eea 100644
--- a/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java
+++ b/src/main/java/fr/xephi/authme/permission/PlayerStatePermission.java
@@ -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.
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index f04829d4..3ca000fd 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -45,7 +45,7 @@ commands:
- cp
email:
description: Add email or recover password
- usage: /email show|add|change|recover
+ usage: /email show|add|change|recover|code|setpassword
captcha:
description: Captcha Command
usage: /captcha
@@ -154,7 +154,47 @@ permissions:
description: Permission to bypass the purging process.
default: false
authme.debug:
- description: Permission to use the /authme debug command.
+ description: Gives access to /authme debug and all its sections
+ children:
+ authme.debug.command: true
+ authme.debug.country: true
+ authme.debug.db: true
+ authme.debug.group: true
+ authme.debug.limbo: true
+ authme.debug.mail: true
+ authme.debug.perm: true
+ authme.debug.spawn: true
+ authme.debug.stats: true
+ authme.debug.valid: true
+ authme.debug.command:
+ description: General permission to use the /authme debug command.
+ default: op
+ authme.debug.country:
+ description: Permission to use the country lookup section.
+ default: op
+ authme.debug.db:
+ description: Permission to view data from the database.
+ default: op
+ authme.debug.group:
+ description: Permission to view permission groups.
+ default: op
+ authme.debug.limbo:
+ description: Permission to use the limbo data viewer.
+ default: op
+ authme.debug.mail:
+ description: Permission to use the test email sender.
+ default: op
+ authme.debug.perm:
+ description: Permission to use the permission checker.
+ default: op
+ authme.debug.spawn:
+ description: Permission to view spawn information.
+ default: op
+ authme.debug.stats:
+ description: Permission to use the stats section.
+ default: op
+ authme.debug.valid:
+ description: Permission to use sample validation.
default: op
authme.player.*:
description: Gives access to all player commands
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugCommandTest.java
new file mode 100644
index 00000000..a8703444
--- /dev/null
+++ b/src/test/java/fr/xephi/authme/command/executable/authme/debug/DebugCommandTest.java
@@ -0,0 +1,154 @@
+package fr.xephi.authme.command.executable.authme.debug;
+
+import fr.xephi.authme.initialization.factory.Factory;
+import fr.xephi.authme.permission.DebugSectionPermissions;
+import fr.xephi.authme.permission.PermissionNode;
+import fr.xephi.authme.permission.PermissionsManager;
+import org.bukkit.command.CommandSender;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Collections.emptyList;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;
+
+/**
+ * Test for {@link DebugCommand}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class DebugCommandTest {
+
+ /**
+ * Number we test against if we expect an action to have been performed for each debug section.
+ * This is a minimum number so tests don't fail each time a new debug section is added; however,
+ * it should be close to the total.
+ */
+ private static final int MIN_DEBUG_SECTIONS = 9;
+
+ @InjectMocks
+ private DebugCommand command;
+
+ @Mock
+ private Factory debugSectionFactory;
+
+ @Mock
+ private PermissionsManager permissionsManager;
+
+ @Before
+ @SuppressWarnings("unchecked")
+ public void initFactory() {
+ given(debugSectionFactory.newInstance(any(Class.class))).willAnswer(
+ invocation -> {
+ Class> classArgument = invocation.getArgument(0);
+ checkArgument(DebugSection.class.isAssignableFrom(classArgument));
+ return spy(classArgument);
+ });
+ }
+
+ @Test
+ public void shouldListAllAvailableDebugSections() {
+ // given
+ CommandSender sender = mock(CommandSender.class);
+ given(permissionsManager.hasPermission(eq(sender), any(PermissionNode.class))).willReturn(false);
+ given(permissionsManager.hasPermission(sender, DebugSectionPermissions.INPUT_VALIDATOR)).willReturn(true);
+ given(permissionsManager.hasPermission(sender, DebugSectionPermissions.DATA_STATISTICS)).willReturn(true);
+
+ // when
+ command.executeCommand(sender, emptyList());
+
+ // then
+ verify(debugSectionFactory, atLeast(MIN_DEBUG_SECTIONS)).newInstance(any(Class.class));
+ verify(permissionsManager, atLeast(MIN_DEBUG_SECTIONS)).hasPermission(eq(sender), any(DebugSectionPermissions.class));
+
+ ArgumentCaptor strCaptor = ArgumentCaptor.forClass(String.class);
+ verify(sender, times(3)).sendMessage(strCaptor.capture());
+ assertThat(strCaptor.getAllValues(), contains(
+ containsString("Sections available to you"),
+ containsString("stats: Outputs general data statistics"),
+ containsString("valid: Check if email / password is valid")));
+ }
+
+ @Test
+ public void shouldNotListAnyDebugSection() {
+ // given
+ CommandSender sender = mock(CommandSender.class);
+ given(permissionsManager.hasPermission(eq(sender), any(PermissionNode.class))).willReturn(false);
+
+ // when
+ command.executeCommand(sender, emptyList());
+
+ // then
+ verify(debugSectionFactory, atLeast(MIN_DEBUG_SECTIONS)).newInstance(any(Class.class));
+ verify(permissionsManager, atLeast(MIN_DEBUG_SECTIONS)).hasPermission(eq(sender), any(DebugSectionPermissions.class));
+
+ ArgumentCaptor strCaptor = ArgumentCaptor.forClass(String.class);
+ verify(sender, times(2)).sendMessage(strCaptor.capture());
+ assertThat(strCaptor.getAllValues(), contains(
+ equalTo("Sections available to you:"),
+ containsString("You don't have permission to view any debug section")));
+ }
+
+ @Test
+ public void shouldRunSection() {
+ // given
+ DebugSection section = spy(InputValidator.class);
+ doNothing().when(section).execute(any(CommandSender.class), anyList());
+ // Mockito throws a runtime error if below we use the usual "given(factory.newInstance(...)).willReturn(...)"
+ doReturn(section).when(debugSectionFactory).newInstance(InputValidator.class);
+
+ CommandSender sender = mock(CommandSender.class);
+ given(permissionsManager.hasPermission(sender, section.getRequiredPermission())).willReturn(true);
+ List arguments = Arrays.asList(section.getName().toUpperCase(), "test", "toast");
+
+ // when
+ command.executeCommand(sender, arguments);
+
+ // then
+ verify(permissionsManager).hasPermission(sender, section.getRequiredPermission());
+ verify(section).execute(sender, Arrays.asList("test", "toast"));
+ }
+
+ @Test
+ public void shouldNotRunSectionForMissingPermission() {
+ // given
+ DebugSection section = spy(InputValidator.class);
+ // Mockito throws a runtime error if below we use the usual "given(factory.newInstance(...)).willReturn(...)"
+ doReturn(section).when(debugSectionFactory).newInstance(InputValidator.class);
+
+ CommandSender sender = mock(CommandSender.class);
+ given(permissionsManager.hasPermission(sender, section.getRequiredPermission())).willReturn(false);
+ List arguments = Arrays.asList(section.getName().toUpperCase(), "test");
+
+ // when
+ command.executeCommand(sender, arguments);
+
+ // then
+ verify(permissionsManager).hasPermission(sender, section.getRequiredPermission());
+ verify(section, never()).execute(any(CommandSender.class), anyList());
+ verify(sender).sendMessage(argThat(containsString("You don't have permission")));
+ }
+}
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java
index 9f7c6a92..4bd8eab1 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java
+++ b/src/test/java/fr/xephi/authme/command/executable/authme/debug/HasPermissionCheckerTest.java
@@ -20,9 +20,9 @@ import java.util.stream.Collectors;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
+import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.atLeast;
@@ -55,8 +55,7 @@ public class HasPermissionCheckerTest {
.collect(Collectors.toList());
// when / then
- assertThat(HasPermissionChecker.PERMISSION_NODE_CLASSES.containsAll(permissionClasses), equalTo(true));
- assertThat(HasPermissionChecker.PERMISSION_NODE_CLASSES, hasSize(permissionClasses.size()));
+ assertThat(HasPermissionChecker.PERMISSION_NODE_CLASSES, containsInAnyOrder(permissionClasses.toArray()));
}
@Test
diff --git a/src/test/java/fr/xephi/authme/permission/AbstractPermissionsEnumTest.java b/src/test/java/fr/xephi/authme/permission/AbstractPermissionsEnumTest.java
new file mode 100644
index 00000000..4b327ec4
--- /dev/null
+++ b/src/test/java/fr/xephi/authme/permission/AbstractPermissionsEnumTest.java
@@ -0,0 +1,52 @@
+package fr.xephi.authme.permission;
+
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.fail;
+
+/**
+ * Has common tests for enums implementing {@link PermissionNode}.
+ */
+public abstract class AbstractPermissionsEnumTest {
+
+ @Test
+ public void shouldAllStartWitRequiredPrefix() {
+ // given
+ String requiredPrefix = getRequiredPrefix();
+
+ // when/then
+ for (PermissionNode permission : getPermissionNodes()) {
+ if (!permission.getNode().startsWith(requiredPrefix)) {
+ fail("The permission '" + permission + "' does not start with the required prefix '"
+ + requiredPrefix + "'");
+ }
+ }
+ }
+
+ @Test
+ public void shouldHaveUniqueNodes() {
+ // given
+ Set nodes = new HashSet<>();
+
+ // when/then
+ for (PermissionNode permission : getPermissionNodes()) {
+ if (!nodes.add(permission.getNode())) {
+ fail("More than one enum value defines the node '" + permission.getNode() + "'");
+ }
+ }
+ }
+
+ /**
+ * @return the permission nodes to test
+ */
+ protected abstract PermissionNode[] getPermissionNodes();
+
+ /**
+ * @return text with which all permission nodes must start with
+ */
+ protected abstract String getRequiredPrefix();
+
+}
diff --git a/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java b/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java
index 3cfa0e27..f3e4f1fd 100644
--- a/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java
+++ b/src/test/java/fr/xephi/authme/permission/AdminPermissionTest.java
@@ -1,42 +1,18 @@
package fr.xephi.authme.permission;
-import org.junit.Test;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import static org.junit.Assert.fail;
-
/**
* Test for {@link AdminPermission}.
*/
-public class AdminPermissionTest {
+public class AdminPermissionTest extends AbstractPermissionsEnumTest {
- @Test
- public void shouldStartWithAuthMeAdminPrefix() {
- // given
- String requiredPrefix = "authme.admin.";
-
- // when/then
- for (AdminPermission permission : AdminPermission.values()) {
- if (!permission.getNode().startsWith(requiredPrefix)) {
- fail("The permission '" + permission + "' does not start with the required prefix '"
- + requiredPrefix + "'");
- }
- }
+ @Override
+ protected PermissionNode[] getPermissionNodes() {
+ return AdminPermission.values();
}
- @Test
- public void shouldHaveUniqueNodes() {
- // given
- Set nodes = new HashSet<>();
-
- // when/then
- for (AdminPermission permission : AdminPermission.values()) {
- if (!nodes.add(permission.getNode())) {
- fail("More than one enum value defines the node '" + permission.getNode() + "'");
- }
- }
+ @Override
+ protected String getRequiredPrefix() {
+ return "authme.admin.";
}
}
diff --git a/src/test/java/fr/xephi/authme/permission/DebugSectionPermissionsTest.java b/src/test/java/fr/xephi/authme/permission/DebugSectionPermissionsTest.java
new file mode 100644
index 00000000..3e0a9f01
--- /dev/null
+++ b/src/test/java/fr/xephi/authme/permission/DebugSectionPermissionsTest.java
@@ -0,0 +1,17 @@
+package fr.xephi.authme.permission;
+
+/**
+ * Test for {@link DebugSectionPermissions}.
+ */
+public class DebugSectionPermissionsTest extends AbstractPermissionsEnumTest {
+
+ @Override
+ protected PermissionNode[] getPermissionNodes() {
+ return DebugSectionPermissions.values();
+ }
+
+ @Override
+ protected String getRequiredPrefix() {
+ return "authme.debug.";
+ }
+}
diff --git a/src/test/java/fr/xephi/authme/permission/PermissionConsistencyTest.java b/src/test/java/fr/xephi/authme/permission/PermissionConsistencyTest.java
index 757319d5..6d7a37e2 100644
--- a/src/test/java/fr/xephi/authme/permission/PermissionConsistencyTest.java
+++ b/src/test/java/fr/xephi/authme/permission/PermissionConsistencyTest.java
@@ -31,7 +31,7 @@ public class PermissionConsistencyTest {
/** Wildcard permissions (present in plugin.yml but not in the codebase). */
private static final Set PLUGIN_YML_PERMISSIONS_WILDCARDS =
- ImmutableSet.of("authme.admin.*", "authme.player.*", "authme.player.email");
+ ImmutableSet.of("authme.admin.*", "authme.player.*", "authme.player.email", "authme.debug");
/** Name of the fields that make up a permission entry in plugin.yml. */
private static final Set PERMISSION_FIELDS = ImmutableSet.of("description", "default", "children");
diff --git a/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java b/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java
index ad8f6fe9..32a45b98 100644
--- a/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java
+++ b/src/test/java/fr/xephi/authme/permission/PlayerPermissionTest.java
@@ -1,41 +1,17 @@
package fr.xephi.authme.permission;
-import org.junit.Test;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import static org.junit.Assert.fail;
-
/**
* Test for {@link PlayerPermission}.
*/
-public class PlayerPermissionTest {
+public class PlayerPermissionTest extends AbstractPermissionsEnumTest {
- @Test
- public void shouldStartWithPlayerPrefix() {
- // given
- String playerBranch = "authme.player.";
-
- // when/then
- for (PlayerPermission permission : PlayerPermission.values()) {
- if (!permission.getNode().startsWith(playerBranch)) {
- fail("The permission '" + permission + "' should use a node with the player-specific branch '"
- + playerBranch + "'");
- }
- }
+ @Override
+ protected PermissionNode[] getPermissionNodes() {
+ return PlayerPermission.values();
}
- @Test
- public void shouldHaveUniqueNodes() {
- // given
- Set nodes = new HashSet<>();
-
- // when/then
- for (PlayerPermission permission : PlayerPermission.values()) {
- if (!nodes.add(permission.getNode())) {
- fail("More than one enum value defines the node '" + permission.getNode() + "'");
- }
- }
+ @Override
+ protected String getRequiredPrefix() {
+ return "authme.player.";
}
}
diff --git a/src/test/java/fr/xephi/authme/permission/PlayerStatePermissionTest.java b/src/test/java/fr/xephi/authme/permission/PlayerStatePermissionTest.java
index 6c3e3d16..56e5e1ce 100644
--- a/src/test/java/fr/xephi/authme/permission/PlayerStatePermissionTest.java
+++ b/src/test/java/fr/xephi/authme/permission/PlayerStatePermissionTest.java
@@ -2,7 +2,7 @@ package fr.xephi.authme.permission;
import org.junit.Test;
-import java.util.HashSet;
+import java.util.Collection;
import java.util.Set;
import static com.google.common.collect.Sets.newHashSet;
@@ -11,39 +11,32 @@ import static org.junit.Assert.fail;
/**
* Test for {@link PlayerStatePermission}.
*/
-public class PlayerStatePermissionTest {
+public class PlayerStatePermissionTest extends AbstractPermissionsEnumTest {
@Test
- public void shouldStartWithAuthMeAdminPrefix() {
+ public void shouldNotStartWithOtherPrefixes() {
// given
- String requiredPrefix = "authme.";
- Set forbiddenPrefixes = newHashSet("authme.player", "authme.admin");
+ Set forbiddenPrefixes = newHashSet("authme.player", "authme.admin", "authme.debug");
// when/then
for (PlayerStatePermission permission : PlayerStatePermission.values()) {
- if (!permission.getNode().startsWith(requiredPrefix)) {
- fail("The permission '" + permission + "' does not start with the required prefix '"
- + requiredPrefix + "'");
- } else if (hasAnyPrefix(permission.getNode(), forbiddenPrefixes)) {
+ if (startsWithAny(permission.getNode(), forbiddenPrefixes)) {
fail("The permission '" + permission + "' should not start with any of " + forbiddenPrefixes);
}
}
}
- @Test
- public void shouldHaveUniqueNodes() {
- // given
- Set nodes = new HashSet<>();
-
- // when/then
- for (PlayerStatePermission permission : PlayerStatePermission.values()) {
- if (!nodes.add(permission.getNode())) {
- fail("More than one enum value defines the node '" + permission.getNode() + "'");
- }
- }
+ @Override
+ protected PermissionNode[] getPermissionNodes() {
+ return PlayerStatePermission.values();
}
- private static boolean hasAnyPrefix(String node, Set prefixes) {
+ @Override
+ protected String getRequiredPrefix() {
+ return "authme.";
+ }
+
+ private static boolean startsWithAny(String node, Collection prefixes) {
for (String prefix : prefixes) {
if (node.startsWith(prefix)) {
return true;
@@ -51,5 +44,4 @@ public class PlayerStatePermissionTest {
}
return false;
}
-
}
diff --git a/src/test/java/tools/docs/permissions/PermissionNodesGatherer.java b/src/test/java/tools/docs/permissions/PermissionNodesGatherer.java
index e3635512..f177cbc6 100644
--- a/src/test/java/tools/docs/permissions/PermissionNodesGatherer.java
+++ b/src/test/java/tools/docs/permissions/PermissionNodesGatherer.java
@@ -25,7 +25,7 @@ public class PermissionNodesGatherer {
* the second group should contain the enum value.
*/
private static final Pattern JAVADOC_WITH_ENUM_PATTERN = Pattern.compile(
- "/\\*\\*\\s+\\*" // Match starting '/**' and the '*' on the next line
+ "/\\*\\*(\\s+\\*)?" // Match starting '/**' and optional whitespace with a '*'
+ "(.*?)\\s+\\*/" // Capture everything until we encounter '*/'
+ "\\s+([A-Z_]+)\\("); // Match the enum name (e.g. 'LOGIN'), until before the first '('
@@ -87,8 +87,8 @@ public class PermissionNodesGatherer {
Map allMatches = new HashMap<>();
Matcher matcher = JAVADOC_WITH_ENUM_PATTERN.matcher(source);
while (matcher.find()) {
- String description = matcher.group(1);
- String enumValue = matcher.group(2);
+ String description = matcher.group(2);
+ String enumValue = matcher.group(3);
allMatches.put(enumValue, description);
}
return allMatches;
diff --git a/src/test/java/tools/filegeneration/GeneratePluginYml.java b/src/test/java/tools/filegeneration/GeneratePluginYml.java
index b4a017c6..8fdc779d 100644
--- a/src/test/java/tools/filegeneration/GeneratePluginYml.java
+++ b/src/test/java/tools/filegeneration/GeneratePluginYml.java
@@ -32,8 +32,9 @@ public class GeneratePluginYml implements AutoToolTask {
private static final Map WILDCARD_PERMISSIONS = ImmutableMap.of(
"authme.player.*", "Gives access to all player commands",
+ "authme.player.email", "Gives access to all email commands",
"authme.admin.*", "Gives access to all admin commands",
- "authme.player.email", "Gives access to all email commands");
+ "authme.debug", "Gives access to /authme debug and all its sections");
private List permissionNodes;