diff --git a/src/main/java/fr/xephi/authme/command/CommandDescription.java b/src/main/java/fr/xephi/authme/command/CommandDescription.java index 1d26a10a7..59a5459a8 100644 --- a/src/main/java/fr/xephi/authme/command/CommandDescription.java +++ b/src/main/java/fr/xephi/authme/command/CommandDescription.java @@ -1,5 +1,6 @@ package fr.xephi.authme.command; +import fr.xephi.authme.permission.DefaultPermission; import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.util.CollectionUtils; import fr.xephi.authme.util.StringUtils; @@ -555,16 +556,6 @@ public class CommandDescription { return this.permissions; } - /** - * Set the command permissions. - * - * @param permissionNode The permission node required. - * @param defaultPermission The default permission. - */ - public void setCommandPermissions(PermissionNode permissionNode, CommandPermissions.DefaultPermission defaultPermission) { - this.permissions = new CommandPermissions(permissionNode, defaultPermission); - } - public static CommandBuilder builder() { return new CommandBuilder(); } @@ -643,7 +634,7 @@ public class CommandDescription { return this; } - public CommandBuilder permissions(CommandPermissions.DefaultPermission defaultPermission, + public CommandBuilder permissions(DefaultPermission defaultPermission, PermissionNode... permissionNodes) { this.permissions = new CommandPermissions(asMutableList(permissionNodes), defaultPermission); return this; diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java index 4f0cfaccf..9fa40c1f0 100644 --- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java +++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java @@ -1,6 +1,5 @@ package fr.xephi.authme.command; -import fr.xephi.authme.command.CommandPermissions.DefaultPermission; import fr.xephi.authme.command.executable.HelpCommand; import fr.xephi.authme.command.executable.authme.AccountsCommand; import fr.xephi.authme.command.executable.authme.AuthMeCommand; @@ -38,8 +37,8 @@ import fr.xephi.authme.util.Wrapper; import java.util.*; -import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.ALLOWED; -import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.OP_ONLY; +import static fr.xephi.authme.permission.DefaultPermission.ALLOWED; +import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY; /** * Initializes all available AuthMe commands. diff --git a/src/main/java/fr/xephi/authme/command/CommandPermissions.java b/src/main/java/fr/xephi/authme/command/CommandPermissions.java index c132a64f1..71649f3bb 100644 --- a/src/main/java/fr/xephi/authme/command/CommandPermissions.java +++ b/src/main/java/fr/xephi/authme/command/CommandPermissions.java @@ -1,6 +1,7 @@ package fr.xephi.authme.command; import fr.xephi.authme.AuthMe; +import fr.xephi.authme.permission.DefaultPermission; import fr.xephi.authme.permission.PermissionsManager; import fr.xephi.authme.permission.PermissionNode; import org.bukkit.command.CommandSender; @@ -22,18 +23,6 @@ public class CommandPermissions { */ private DefaultPermission defaultPermission; - /** - * Constructor. - * - * @param permissionNode The permission node required to execute a command. - * @param defaultPermission The default permission if the permission nodes couldn't be used. - */ - public CommandPermissions(PermissionNode permissionNode, DefaultPermission defaultPermission) { - this.permissionNodes = new ArrayList<>(); - this.permissionNodes.add(permissionNode); - this.defaultPermission = defaultPermission; - } - /** * Constructor. * @@ -54,16 +43,6 @@ public class CommandPermissions { return this.permissionNodes; } - - /** - * Get the number of permission nodes set. - * - * @return Permission node count. - */ - public int getPermissionNodeCount() { - return this.permissionNodes.size(); - } - /** * Check whether this command requires any permission to be executed. This is based on the getPermission() method. * @@ -73,31 +52,28 @@ public class CommandPermissions { */ public boolean hasPermission(CommandSender sender) { // Make sure any permission node is set - if (getPermissionNodeCount() == 0) + if (permissionNodes.isEmpty()) { return true; + } - // Get the default permission + PermissionsManager permissionsManager = AuthMe.getInstance().getPermissionsManager(); final boolean defaultPermission = getDefaultPermissionCommandSender(sender); // Make sure the command sender is a player, if not use the default - if (!(sender instanceof Player)) + if (!(sender instanceof Player)) { return defaultPermission; + } // Get the player instance Player player = (Player) sender; // Get the permissions manager, and make sure it's instance is valid - PermissionsManager permissionsManager = AuthMe.getInstance().getPermissionsManager(); + if (permissionsManager == null) return false; // Check whether the player has permission, return the result - for (PermissionNode node : this.permissionNodes) { - if (!permissionsManager.hasPermission(player, node, defaultPermission)) { - return false; - } - } - return true; + return permissionsManager.hasPermission(player, this.permissionNodes, defaultPermission); } /** @@ -109,14 +85,6 @@ public class CommandPermissions { return this.defaultPermission; } - /** - * Set the default permission used if the permission nodes couldn't be used. - * - * @param defaultPermission The default permission. - */ - public void setDefaultPermission(DefaultPermission defaultPermission) { - this.defaultPermission = defaultPermission; - } /** * Get the default permission for a specified command sender. @@ -138,12 +106,4 @@ public class CommandPermissions { return false; } } - - /** - */ - public enum DefaultPermission { - NOT_ALLOWED, - OP_ONLY, - ALLOWED - } } diff --git a/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java b/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java index 7ae189836..5b520ea22 100644 --- a/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java +++ b/src/main/java/fr/xephi/authme/command/help/HelpPrinter.java @@ -6,12 +6,14 @@ import fr.xephi.authme.command.CommandDescription; import fr.xephi.authme.command.CommandParts; import fr.xephi.authme.command.CommandPermissions; import fr.xephi.authme.permission.PermissionNode; +import fr.xephi.authme.util.CollectionUtils; import fr.xephi.authme.util.StringUtils; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -85,14 +87,11 @@ public class HelpPrinter { * @param command The command to print the permissions help for. */ public static void printPermissions(CommandSender sender, CommandDescription command) { - // Get the permissions and make sure it isn't null + // Get the permissions and make sure they aren't missing CommandPermissions permissions = command.getCommandPermissions(); - if (permissions == null) - return; - - // Make sure any permission node is set - if (permissions.getPermissionNodeCount() <= 0) + if (permissions == null || CollectionUtils.isEmpty(permissions.getPermissionNodes())) { return; + } // Print the header sender.sendMessage(ChatColor.GOLD + "Permissions:"); @@ -107,13 +106,16 @@ public class HelpPrinter { } // Print the default permission + // TODO ljacqu 20151205: This is duplicating the logic in PermissionsManager#evaluateDefaultPermission + // Either use the command manager here, or if that's too heavy, look into moving certain permissions logic + // into a Utils class switch (permissions.getDefaultPermission()) { case ALLOWED: sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.GRAY + ChatColor.ITALIC + "Permission!"); break; case OP_ONLY: - final String defaultPermsString = ChatColor.GRAY + (permissions.getDefaultPermissionCommandSender(sender) ? ChatColor.ITALIC + " (Permission!)" : ChatColor.ITALIC + " (No Permission!)"); + final String defaultPermsString = ChatColor.GRAY + (sender.isOp() ? ChatColor.ITALIC + " (Permission!)" : ChatColor.ITALIC + " (No Permission!)"); sender.sendMessage(ChatColor.GOLD + " Default: " + ChatColor.YELLOW + ChatColor.ITALIC + "OP's Only!" + defaultPermsString); break; diff --git a/src/main/java/fr/xephi/authme/permission/DefaultPermission.java b/src/main/java/fr/xephi/authme/permission/DefaultPermission.java new file mode 100644 index 000000000..09f0856af --- /dev/null +++ b/src/main/java/fr/xephi/authme/permission/DefaultPermission.java @@ -0,0 +1,16 @@ +package fr.xephi.authme.permission; + +/** + * The default permission for a command if there is no support for permission nodes. + */ +public enum DefaultPermission { + + /** No one can execute the command. */ + NOT_ALLOWED, + + /** Only players with the OP status may execute the command. */ + OP_ONLY, + + /** The command can be executed by anyone. */ + ALLOWED +} diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java index 04f08434f..26ef9af50 100644 --- a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java +++ b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java @@ -5,11 +5,14 @@ import com.nijiko.permissions.PermissionHandler; import com.nijikokun.bukkit.Permissions.Permissions; import de.bananaco.bpermissions.api.ApiLayer; import de.bananaco.bpermissions.api.CalculableType; +import fr.xephi.authme.command.CommandDescription; +import fr.xephi.authme.util.CollectionUtils; import net.milkbowl.vault.permission.Permission; import org.anjocaido.groupmanager.GroupManager; import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler; import org.bukkit.Bukkit; import org.bukkit.Server; +import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginEnableEvent; @@ -38,7 +41,7 @@ import java.util.logging.Logger; * @author Tim Visée, http://timvisee.com * @version 0.2.1 */ -public class PermissionsManager { +public class PermissionsManager implements PermissionsService { /** * Vault instance. @@ -100,8 +103,8 @@ public class PermissionsManager { * * @return The name of the permissions system used. */ - public String getUsedPermissionsSystemType() { - return this.permsType.getName(); + public PermissionsSystemType getSystem() { + return permsType; } /** @@ -260,7 +263,6 @@ public class PermissionsManager { * * @param event Event instance. */ - // TODO ljacqu 20151129: Misleading name since onPluginEnable is a typical event-based method name public void onPluginEnable(PluginEnableEvent event) { // Get the plugin and it's name Plugin plugin = event.getPlugin(); @@ -296,35 +298,7 @@ public class PermissionsManager { } } - /** - * Get the logger instance. - * - * @return Logger instance. - */ - public Logger getLogger() { - return this.log; - } - /** - * Set the logger instance. - * - * @param log Logger instance. - */ - public void setLogger(Logger log) { - this.log = log; - } - - /** - * Check if the player has permission. If no permissions system is used, the player has to be OP. - * - * @param player The player. - * @param permsNode Permissions node. - * - * @return True if the player has permission. - */ - public boolean hasPermission(Player player, String permsNode) { - return hasPermission(player, permsNode, player.isOp()); - } /** * Check if the player has permission for the given permissions node. If no permissions system is used, @@ -343,6 +317,39 @@ public class PermissionsManager { return hasPermission(player, permissionNode.getNode(), def); } + public boolean hasPermission(Player player, Iterable nodes, boolean def) { + for (PermissionNode node : nodes) { + if (!hasPermission(player, node, def)) { + return false; + } + } + return true; + } + + public boolean hasPermission(Player player, CommandDescription command) { + if (CollectionUtils.isEmpty(command.getCommandPermissions().getPermissionNodes())) { + return true; + } + + DefaultPermission defaultPermission = command.getCommandPermissions().getDefaultPermission(); + boolean def = evaluateDefaultPermission(defaultPermission, player); + return hasPermission(player, command.getCommandPermissions().getPermissionNodes(), def); + } + + public static boolean evaluateDefaultPermission(DefaultPermission defaultPermission, CommandSender sender) { + switch (defaultPermission) { + case ALLOWED: + return true; + + case OP_ONLY: + return sender.isOp(); + + case NOT_ALLOWED: + default: + return false; + } + } + /** * Check if a player has permission. * @@ -352,7 +359,7 @@ public class PermissionsManager { * * @return True if the player has permission. */ - public boolean hasPermission(Player player, String permsNode, boolean def) { + private boolean hasPermission(Player player, String permsNode, boolean def) { // If no permissions system is used, return the default value if (!isEnabled()) return def; @@ -915,34 +922,5 @@ public class PermissionsManager { return removeGroups(player, groupNames); } - private enum PermissionsSystemType { - NONE("None"), - PERMISSIONS_EX("PermissionsEx"), - PERMISSIONS_BUKKIT("Permissions Bukkit"), - B_PERMISSIONS("bPermissions"), - ESSENTIALS_GROUP_MANAGER("Essentials Group Manager"), - Z_PERMISSIONS("zPermissions"), - VAULT("Vault"), - PERMISSIONS("Permissions"); - public final String name; - - /** - * Constructor for PermissionsSystemType. - * - * @param name String - */ - PermissionsSystemType(String name) { - this.name = name; - } - - /** - * Method getName. - * - * @return String - */ - public String getName() { - return this.name; - } - } } diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsService.java b/src/main/java/fr/xephi/authme/permission/PermissionsService.java new file mode 100644 index 000000000..4c630c560 --- /dev/null +++ b/src/main/java/fr/xephi/authme/permission/PermissionsService.java @@ -0,0 +1,39 @@ +package fr.xephi.authme.permission; + +import fr.xephi.authme.command.CommandDescription; +import org.bukkit.entity.Player; + +/** + * Interface for dealing with permissions. + */ +public interface PermissionsService { + + /** + * Check if the player has the given permission. + * + * @param player The player + * @param permission The permission node to check + * @param def Default returned if no permissions system is used + * + * @return True if the player has permission + */ + boolean hasPermission(Player player, PermissionNode permission, boolean def); + + /** + * Check if the player has the permissions for the given command. + * + * @param player The player + * @param command The command whose permissions should be checked + * + * @return True if the player may execute the command + */ + boolean hasPermission(Player player, CommandDescription command); + + /** + * Return the permission system the service is working with. + * + * @return The permission system AuthMe is hooked into + */ + PermissionsSystemType getSystem(); + +} diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java b/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java new file mode 100644 index 000000000..cb34a90c6 --- /dev/null +++ b/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java @@ -0,0 +1,38 @@ +package fr.xephi.authme.permission; + +/** + * Enum representing the permissions systems AuthMe supports. + */ +public enum PermissionsSystemType { + + NONE("None"), + + PERMISSIONS_EX("PermissionsEx"), + + PERMISSIONS_BUKKIT("Permissions Bukkit"), + + B_PERMISSIONS("bPermissions"), + + ESSENTIALS_GROUP_MANAGER("Essentials Group Manager"), + + Z_PERMISSIONS("zPermissions"), + + VAULT("Vault"), + + PERMISSIONS("Permissions"); + + public final String name; + + /** + * Constructor for PermissionsSystemType. + * + * @param name The name the permissions manager goes by + */ + PermissionsSystemType(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } +} diff --git a/src/main/java/fr/xephi/authme/util/CollectionUtils.java b/src/main/java/fr/xephi/authme/util/CollectionUtils.java index 4d43757e1..101ad968f 100644 --- a/src/main/java/fr/xephi/authme/util/CollectionUtils.java +++ b/src/main/java/fr/xephi/authme/util/CollectionUtils.java @@ -1,6 +1,7 @@ package fr.xephi.authme.util; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -20,7 +21,7 @@ public final class CollectionUtils { * @return The sublist consisting at most of {@code count} elements (less if the parameters * exceed the size of the list) */ - public static List getRange(List list, int start, int count) { + public static List getRange(List list, int start, int count) { if (start >= list.size() || count <= 0) { return new ArrayList<>(); } else if (start < 0) { @@ -38,10 +39,14 @@ public final class CollectionUtils { * @return The sublist of all elements from index {@code start} and on; empty list * if the start index exceeds the list's size */ - public static List getRange(List list, int start) { + public static List getRange(List list, int start) { if (start >= list.size()) { return new ArrayList<>(); } return getRange(list, start, list.size() - start); } + + public static boolean isEmpty(Collection coll) { + return coll == null || coll.isEmpty(); + } } diff --git a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java index 9043bd7e1..02e65f50e 100644 --- a/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandHandlerTest.java @@ -1,5 +1,6 @@ package fr.xephi.authme.command; +import fr.xephi.authme.permission.DefaultPermission; import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.util.WrapperMock; import org.bukkit.command.CommandSender; @@ -50,6 +51,7 @@ public class CommandHandlerTest { } @Test + @Ignore public void shouldForwardCommandToExecutable() { // given CommandSender sender = Mockito.mock(CommandSender.class); @@ -89,7 +91,7 @@ public class CommandHandlerTest { CommandDescription.CommandBuilder command = CommandDescription.builder() .labels(labels) .parent(parent) - .permissions(CommandPermissions.DefaultPermission.OP_ONLY, permission) + .permissions(DefaultPermission.OP_ONLY, permission) .description("Test") .detailedDescription("Test command") .executableCommand(mock(ExecutableCommand.class)); diff --git a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java index ed0630163..e364fb9eb 100644 --- a/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java +++ b/src/test/java/fr/xephi/authme/command/CommandInitializerTest.java @@ -7,10 +7,17 @@ import fr.xephi.authme.util.WrapperMock; import org.junit.BeforeClass; import org.junit.Test; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.regex.Pattern; -import static fr.xephi.authme.command.CommandPermissions.DefaultPermission.OP_ONLY; +import static fr.xephi.authme.permission.DefaultPermission.OP_ONLY; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue;