From fbfb8decd018edc0338707f93f54c2c0381d6a18 Mon Sep 17 00:00:00 2001 From: simpleauthority Date: Sat, 2 Jun 2018 21:28:19 -0700 Subject: [PATCH] Implement CommandPermissionResolver (#135) This pull request is an initial attempt at implementing permission for commands for the JDA module. It includes one added file, **JDACommandPermissionResolver** which implements CommandPermissionResolver. I created a map to store the Discord permission offsets stored mapped by their kebab-cased name (i.e. "ADMINISTRATOR" becomes "administrator", "MANAGE_SERVER" becomes "manage-server". The implementation of `hasPermission(JDACommandEvent, String)` is fairly simple: - Get the issuer's Member object - Check if it's null; if so, return false. - Get the permission offset from the aforementioned map - Check if it's null; if so, return false. - Return whether or not the member has the permission. --------------------------------------- This PR allows new commands to use the `@CommandPermission` annotation like so: ```java @CommandAlias("test|t") public class Command extends BaseCommand { @Subcommand("admin|a") @CommandPermission("manage-server") public void adminCommand(MessageReceivedEvent event) { //... } } ``` --- .../commands/CommandPermissionResolver.java | 2 +- .../co/aikar/commands/JDACommandEvent.java | 2 +- .../co/aikar/commands/JDACommandManager.java | 2 +- .../JDACommandPermissionResolver.java | 34 +++++++++++++++++++ .../java/co/aikar/commands/JDAOptions.java | 2 +- 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 jda/src/main/java/co/aikar/commands/JDACommandPermissionResolver.java diff --git a/jda/src/main/java/co/aikar/commands/CommandPermissionResolver.java b/jda/src/main/java/co/aikar/commands/CommandPermissionResolver.java index c4917db0..ba439965 100644 --- a/jda/src/main/java/co/aikar/commands/CommandPermissionResolver.java +++ b/jda/src/main/java/co/aikar/commands/CommandPermissionResolver.java @@ -2,5 +2,5 @@ package co.aikar.commands; public interface CommandPermissionResolver { - boolean hasPermission(JDACommandEvent event, String permission); + boolean hasPermission(JDACommandManager manager, JDACommandEvent event, String permission); } diff --git a/jda/src/main/java/co/aikar/commands/JDACommandEvent.java b/jda/src/main/java/co/aikar/commands/JDACommandEvent.java index a495a0b2..dfe9548f 100644 --- a/jda/src/main/java/co/aikar/commands/JDACommandEvent.java +++ b/jda/src/main/java/co/aikar/commands/JDACommandEvent.java @@ -48,7 +48,7 @@ public class JDACommandEvent implements CommandIssuer { @Override public boolean hasPermission(String permission) { CommandPermissionResolver permissionResolver = this.manager.getPermissionResolver(); - return permissionResolver == null || permissionResolver.hasPermission(this, permission); + return permissionResolver == null || permissionResolver.hasPermission(manager, this, permission); } @Override diff --git a/jda/src/main/java/co/aikar/commands/JDACommandManager.java b/jda/src/main/java/co/aikar/commands/JDACommandManager.java index 6b366de5..b10ad522 100644 --- a/jda/src/main/java/co/aikar/commands/JDACommandManager.java +++ b/jda/src/main/java/co/aikar/commands/JDACommandManager.java @@ -91,7 +91,7 @@ public class JDACommandManager extends CommandManager< } } - private long getBotOwnerId() { + public long getBotOwnerId() { // Just in case initialization on ReadyEvent fails. initializeBotOwner(); return botOwner; diff --git a/jda/src/main/java/co/aikar/commands/JDACommandPermissionResolver.java b/jda/src/main/java/co/aikar/commands/JDACommandPermissionResolver.java new file mode 100644 index 00000000..4aa52849 --- /dev/null +++ b/jda/src/main/java/co/aikar/commands/JDACommandPermissionResolver.java @@ -0,0 +1,34 @@ +package co.aikar.commands; + +import net.dv8tion.jda.core.Permission; + +import java.util.HashMap; +import java.util.Map; + +public class JDACommandPermissionResolver implements CommandPermissionResolver { + private Map discordPermissionOffsets; + + public JDACommandPermissionResolver() { + discordPermissionOffsets = new HashMap<>(); + for (Permission permission : Permission.values()) { + discordPermissionOffsets.put(permission.name().toLowerCase().replaceAll("_", "-"), permission.getOffset()); + } + } + + @Override + public boolean hasPermission(JDACommandManager manager, JDACommandEvent event, String permission) { + // Explicitly return true if the issuer is the bot's owner. They are always allowed. + if (manager.getBotOwnerId() == event.getIssuer().getAuthor().getIdLong()) { + return true; + } + + Integer permissionOffset = discordPermissionOffsets.get(permission); + if (permissionOffset == null) { + return false; + } + + return event.getIssuer().getMember().hasPermission( + Permission.getFromOffset(permissionOffset) + ); + } +} diff --git a/jda/src/main/java/co/aikar/commands/JDAOptions.java b/jda/src/main/java/co/aikar/commands/JDAOptions.java index 92a3ea8a..7283ff48 100644 --- a/jda/src/main/java/co/aikar/commands/JDAOptions.java +++ b/jda/src/main/java/co/aikar/commands/JDAOptions.java @@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull; public class JDAOptions { CommandConfig defaultConfig = new JDACommandConfig(); CommandConfigProvider configProvider = null; - CommandPermissionResolver permissionResolver = null; + CommandPermissionResolver permissionResolver = new JDACommandPermissionResolver(); public JDAOptions() { }