diff --git a/src/main/java/net/pingex/dcf/commands/permissions/PermissionsCommands.java b/src/main/java/net/pingex/dcf/commands/permissions/PermissionsCommands.java new file mode 100644 index 0000000..58ccc3f --- /dev/null +++ b/src/main/java/net/pingex/dcf/commands/permissions/PermissionsCommands.java @@ -0,0 +1,122 @@ +package net.pingex.dcf.commands.permissions; + +import net.pingex.dcf.commands.Command; +import net.pingex.dcf.commands.CommandRegistry; +import net.pingex.dcf.commands.Context; +import net.pingex.dcf.commands.IWithCommands; +import net.pingex.dcf.commands.audit.AuditResult; +import net.pingex.dcf.commands.audit.IAuditComponentProvider; +import net.pingex.dcf.util.ArgumentParser; +import net.pingex.dcf.util.DiscordInteractionsUtil; +import org.apache.commons.lang3.StringUtils; +import sx.blah.discord.handle.obj.IGuild; +import sx.blah.discord.handle.obj.IUser; +import java.util.*; + +/** + * Contains every command about the permissions system. + */ +public class PermissionsCommands implements IWithCommands +{ + @Override + public Set getCommands() + { + return new HashSet<>(Arrays.asList( + permissionAudit + )); + } + + private static final Command permissionAudit = Command.builder("permissions:audit") + .aliases("perm:audit", "auditperm") + .description("Audits permissions status for an user to run a command.") + .usage(" [serverid]") + .options(Collections.singleton(new DefaultPermissionOption(DefaultPermissionOption.Value.EVERYONE))) + .build(PermissionsCommands::permissionAuditImpl); + + private static void permissionAuditImpl(Context context) + { + // argchk#1 arg counts + if(context.getArguments().size() != 2 && context.getArguments().size() != 3) + { + DiscordInteractionsUtil.sendMessage(context.getChannel(), "Invalid arguments."); + return; + } + + // argchk#2 command + Optional targetCommand = CommandRegistry.getCommandOrAliasByName(context.getArguments().get(0)); + if(!targetCommand.isPresent()) + { + DiscordInteractionsUtil.sendMessage(context.getChannel(), "Target command not found."); + return; + } + + // argchk#3 user + Optional targetUser; + if(context.getArguments().get(1).equalsIgnoreCase("me")) targetUser = Optional.of(context.getUser()); + else + { + try + { + targetUser = ArgumentParser.checkParseUsernameOrID(context.getArguments().get(1), context.getClient()); + } + catch(ArgumentParser.ParserException e) + { + DiscordInteractionsUtil.sendMessage(context.getChannel(), "Invalid arguments."); + return; + } + + if(!targetUser.isPresent()) + { + DiscordInteractionsUtil.sendMessage(context.getChannel(), "Target user not found."); + return; + } + } + + // argchk#4 serverid + Optional targetGuild = Optional.empty(); + if(context.getArguments().size() == 3) + { + targetGuild = ArgumentParser.checkParseGuildOrID(context.getArguments().get(2), context.getClient()); + if(!targetGuild.isPresent()) + { + DiscordInteractionsUtil.sendMessage(context.getChannel(), "Target guild not found."); + return; + } + } + + Context parsedContext = new Context(targetCommand.get(), null, targetUser.get(), null, targetGuild.orElseGet(() -> null), context.getClient()); + AuditResult result = new PermissionCheck().doAudit(parsedContext); + + StringBuilder sb = new StringBuilder() + .append("**Permissions audit**\n") + .append("```"); + + // Target infos + sb.append("Target infos\n") + .append("=> User: ").append(parsedContext.getUser().getName()).append("#").append(parsedContext.getUser().getDiscriminator()).append(" - ").append(parsedContext.getUser().getID()).append("\n") + .append("=> Command: ").append(parsedContext.getCommand().getName()).append(" (").append(parsedContext.getCommand().getDescription()).append(")").append("\n") + .append("=> Guild: "); + if(parsedContext.getGuild() == null) sb.append("N/A"); + else sb.append(parsedContext.getGuild().getName()).append(" - ").append(parsedContext.getGuild().getID()); + sb.append("\n\n"); + + // Result + sb.append("Audit Results\n") + .append("=> OPCode: ").append(result.getOpcode()).append("\n") + .append("=> Message: ").append(result.getMessage() != null ? result.getMessage() : "N/A").append("\n\n"); + + // Walkthrough + sb.append("Walkthrough\n"); + int maxPadding = result.getSubAuditsResults().stream().max(Comparator.comparingInt(i -> i.getKey().name().length())).get().getKey().name().length()+2; + for(Map.Entry i : result.getSubAuditsResults()) + { + sb.append("=> ").append(StringUtils.rightPad(i.getKey().name() + ":", maxPadding)) + .append(i.getValue().getOpcode()).append(" - ") + .append(i.getValue().getMessage() != null ? i.getValue().getMessage() : "N/A") + .append("\n"); + } + + sb.append("```"); + DiscordInteractionsUtil.sendMessage(context.getChannel(), sb.toString()); + } +}