New permissions API. Deprecated old API until complete removal.
parent
a5938c6c0c
commit
d8b76f3d01
@ -0,0 +1,80 @@
|
||||
package net.pingex.dcf.permissions;
|
||||
|
||||
import net.pingex.dcf.commands.Context;
|
||||
import net.pingex.dcf.commands.options.ICommandOption;
|
||||
import net.pingex.dcf.core.Configuration;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* This class defines the default behavior of a command when checking for permissions.
|
||||
*/
|
||||
public class DefaultPermissionOption implements ICommandOption
|
||||
{
|
||||
private Value defaultValue;
|
||||
|
||||
public DefaultPermissionOption(Value defaultValue)
|
||||
{
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public Value getDefaultValue()
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOptionName()
|
||||
{
|
||||
return "Default permission";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOptionDescription()
|
||||
{
|
||||
return "This option defines the default behavior of a command when checking for permissions.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Default behavior when a permissions provider doesn't return any value
|
||||
*/
|
||||
public enum Value implements Predicate<Context>
|
||||
{
|
||||
/**
|
||||
* Everyone is allowed to run the command.
|
||||
*/
|
||||
EVERYONE(context -> true),
|
||||
|
||||
/**
|
||||
* Only the guild owner is allowed to run the command.
|
||||
*/
|
||||
GUILD_OWNER(context -> !context.getChannel().isPrivate() && context.getUser().getID().equals(context.getChannel().getGuild().getOwnerID())),
|
||||
|
||||
/**
|
||||
* Only the bot owner is allowed to run the command.
|
||||
*/
|
||||
BOT_OWNER(context -> context.getUser().getID().equals(Configuration.BOT_OWNER)),
|
||||
|
||||
/**
|
||||
* Guild Owner x Bot Owner
|
||||
*/
|
||||
ANY_OWNER(context -> GUILD_OWNER.test(context) || BOT_OWNER.test(context)),
|
||||
|
||||
/**
|
||||
* Nobody is allowed to run the command
|
||||
*/
|
||||
NONE(context -> false);
|
||||
|
||||
Value(Predicate<Context> predicate)
|
||||
{
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
private Predicate<Context> predicate;
|
||||
|
||||
@Override
|
||||
public boolean test(Context o)
|
||||
{
|
||||
return predicate.test(o);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package net.pingex.dcf.permissions;
|
||||
|
||||
import net.pingex.dcf.commands.Context;
|
||||
import net.pingex.dcf.commands.audit.AuditResult;
|
||||
import net.pingex.dcf.commands.audit.IAuditComponentProvider;
|
||||
import net.pingex.dcf.permissions.audit.DefaultPermissionCheck;
|
||||
import net.pingex.dcf.permissions.audit.UserGlobalCheck;
|
||||
import net.pingex.dcf.permissions.audit.UserGuildCheck;
|
||||
import net.pingex.dcf.permissions.audit.UserGuildRoleCheck;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* This class is used to check whether an user can run a command.
|
||||
*/
|
||||
public class PermissionCheck implements IAuditComponentProvider
|
||||
{
|
||||
private static final ICommandPermissionsProvider CURRENT_PROVIDER = new DefaultPermissionsProvider();
|
||||
|
||||
private static final Set<IAuditComponentProvider> SUB_CHECKS = new TreeSet<>(Comparator.comparingInt(IAuditComponentProvider::priority));
|
||||
|
||||
static
|
||||
{
|
||||
SUB_CHECKS.addAll(Arrays.asList(
|
||||
new DefaultPermissionCheck(),
|
||||
new UserGlobalCheck(getProvider()),
|
||||
new UserGuildCheck(getProvider()),
|
||||
new UserGuildRoleCheck(getProvider())
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get provider used to check for permissions.
|
||||
*/
|
||||
public static ICommandPermissionsProvider getProvider()
|
||||
{
|
||||
return CURRENT_PROVIDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuditResult doAudit(Context context)
|
||||
{
|
||||
AuditResult.Builder globalResult = new AuditResult.Builder();
|
||||
|
||||
for(IAuditComponentProvider i : SUB_CHECKS)
|
||||
{
|
||||
AuditResult interResult = i.doAudit(context);
|
||||
globalResult.appendAuditResult(i, interResult);
|
||||
|
||||
// Check opcode has not been written yet and interResult has opcode either FAIL or PASS.
|
||||
if(globalResult.getOpcode() == null && (interResult.getOpcode() == AuditResult.ResultCode.FAIL || interResult.getOpcode() == AuditResult.ResultCode.PASS))
|
||||
{
|
||||
globalResult.setOpcode(interResult.getOpcode());
|
||||
globalResult.setMessage(interResult.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if(globalResult.getOpcode() == null)
|
||||
{
|
||||
globalResult.setOpcode(globalResult.getSubAuditsResults().get(globalResult.getSubAuditsResults().size()-1).getValue().getOpcode());
|
||||
globalResult.setMessage(globalResult.getSubAuditsResults().get(globalResult.getSubAuditsResults().size()-1).getValue().getMessage());
|
||||
}
|
||||
|
||||
return globalResult.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name()
|
||||
{
|
||||
return "Permission check";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description()
|
||||
{
|
||||
return "Checks whether an user can run a command.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package net.pingex.dcf.permissions.audit;
|
||||
|
||||
import net.pingex.dcf.commands.Context;
|
||||
import net.pingex.dcf.commands.audit.AuditResult;
|
||||
import net.pingex.dcf.commands.audit.IAuditComponentProvider;
|
||||
import net.pingex.dcf.commands.options.ICommandOption;
|
||||
import net.pingex.dcf.permissions.DefaultPermissionOption;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* This class checks permission against a default behavior defined in a command.
|
||||
*/
|
||||
public class DefaultPermissionCheck implements IAuditComponentProvider
|
||||
{
|
||||
@Override
|
||||
public AuditResult doAudit(Context context)
|
||||
{
|
||||
Optional<ICommandOption> option = context.getCommand().getOptions().stream().filter(i -> i instanceof DefaultPermissionOption).findFirst();
|
||||
|
||||
if(!option.isPresent())
|
||||
return new AuditResult(AuditResult.ResultCode.NOOP, "No default permission defined.");
|
||||
|
||||
if(((DefaultPermissionOption) option.get()).getDefaultValue().test(context))
|
||||
return new AuditResult(AuditResult.ResultCode.PASS);
|
||||
else
|
||||
return new AuditResult(AuditResult.ResultCode.FAIL, "Default policy denied access to command.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name()
|
||||
{
|
||||
return "Default permission check";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description()
|
||||
{
|
||||
return "Checks against a default permission option defined in a command.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package net.pingex.dcf.permissions.audit;
|
||||
|
||||
import net.pingex.dcf.commands.Context;
|
||||
import net.pingex.dcf.commands.audit.AuditResult;
|
||||
import net.pingex.dcf.commands.audit.IAuditComponentProvider;
|
||||
import net.pingex.dcf.permissions.ICommandPermissionsProvider;
|
||||
|
||||
/**
|
||||
* This class checks permission against a rule defined for a specific user globally.
|
||||
*/
|
||||
public class UserGlobalCheck implements IAuditComponentProvider
|
||||
{
|
||||
/**
|
||||
* Permissions provider to use
|
||||
*/
|
||||
private ICommandPermissionsProvider provider;
|
||||
|
||||
/**
|
||||
* Provider for this object to use
|
||||
* @param provider Permissions provider this object will use
|
||||
*/
|
||||
public UserGlobalCheck(ICommandPermissionsProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuditResult doAudit(Context context)
|
||||
{
|
||||
Boolean returnedValue = provider.validateUser(null, context.getUser(), context.getCommand());
|
||||
|
||||
if(returnedValue == null) // No rule for user
|
||||
return new AuditResult(AuditResult.ResultCode.NOOP, "No global rule for this user.");
|
||||
else if(returnedValue) // Rule says yes
|
||||
return new AuditResult(AuditResult.ResultCode.PASS);
|
||||
else // Rule says no
|
||||
return new AuditResult(AuditResult.ResultCode.FAIL, "Global rule denied access for this user.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name()
|
||||
{
|
||||
return "User global check";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description()
|
||||
{
|
||||
return "Checks against a global rule defined for a specific user.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package net.pingex.dcf.permissions.audit;
|
||||
|
||||
import net.pingex.dcf.commands.Context;
|
||||
import net.pingex.dcf.commands.audit.AuditResult;
|
||||
import net.pingex.dcf.commands.audit.IAuditComponentProvider;
|
||||
import net.pingex.dcf.permissions.ICommandPermissionsProvider;
|
||||
|
||||
/**
|
||||
* This class checks permission against a rule defined for a specific user in a specific guild.
|
||||
*/
|
||||
public class UserGuildCheck implements IAuditComponentProvider
|
||||
{
|
||||
/**
|
||||
* Permissions provider to use
|
||||
*/
|
||||
private ICommandPermissionsProvider provider;
|
||||
|
||||
/**
|
||||
* Provider for this object to use
|
||||
* @param provider Permissions provider this object will use
|
||||
*/
|
||||
public UserGuildCheck(ICommandPermissionsProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuditResult doAudit(Context context)
|
||||
{
|
||||
// Check for guild
|
||||
if(context.getChannel().getGuild() == null)
|
||||
return new AuditResult(AuditResult.ResultCode.NOOP, "This channel is not part of a guild.");
|
||||
|
||||
Boolean returnedValue = provider.validateUser(context.getChannel().getGuild(), context.getUser(), context.getCommand());
|
||||
|
||||
if(returnedValue == null) // No rule for user in this guild
|
||||
return new AuditResult(AuditResult.ResultCode.NOOP, "No guild rule for this user.");
|
||||
else if(returnedValue) // Rule says yes
|
||||
return new AuditResult(AuditResult.ResultCode.PASS);
|
||||
else // Rule says no
|
||||
return new AuditResult(AuditResult.ResultCode.FAIL, "Guild rule denied access for this user.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name()
|
||||
{
|
||||
return "User vs guild check";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description()
|
||||
{
|
||||
return "Checks against a guild rule defined for an user.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package net.pingex.dcf.permissions.audit;
|
||||
|
||||
import net.pingex.dcf.commands.Context;
|
||||
import net.pingex.dcf.commands.audit.AuditResult;
|
||||
import net.pingex.dcf.commands.audit.IAuditComponentProvider;
|
||||
import net.pingex.dcf.permissions.ICommandPermissionsProvider;
|
||||
import sx.blah.discord.handle.obj.IRole;
|
||||
|
||||
/**
|
||||
* This class checks permission against a rule defined for a specific role in a guild.
|
||||
*/
|
||||
public class UserGuildRoleCheck implements IAuditComponentProvider
|
||||
{
|
||||
/**
|
||||
* Permissions provider to use
|
||||
*/
|
||||
private ICommandPermissionsProvider provider;
|
||||
|
||||
/**
|
||||
* Provider for this object to use
|
||||
* @param provider Permissions provider this object will use
|
||||
*/
|
||||
public UserGuildRoleCheck(ICommandPermissionsProvider provider)
|
||||
{
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuditResult doAudit(Context context)
|
||||
{
|
||||
// Check for guild
|
||||
if(context.getChannel().getGuild() == null)
|
||||
return new AuditResult(AuditResult.ResultCode.NOOP, "This channel is not part of a guild.");
|
||||
|
||||
if(context.getChannel().getGuild().getRolesForUser(context.getUser()) != null) // User has roles
|
||||
for(IRole i : context.getChannel().getGuild().getRolesForUser(context.getUser()))
|
||||
{
|
||||
Boolean returnedQuery = provider.validateGroup(i, context.getCommand());
|
||||
if(returnedQuery != null)
|
||||
{
|
||||
if(returnedQuery) return new AuditResult(AuditResult.ResultCode.PASS);
|
||||
else return new AuditResult(AuditResult.ResultCode.FAIL, "Role rule denied access for this user.");
|
||||
}
|
||||
}
|
||||
else // User has no role
|
||||
return new AuditResult(AuditResult.ResultCode.NOOP, "No role defined for this user.");
|
||||
|
||||
// No rule for any role
|
||||
return new AuditResult(AuditResult.ResultCode.NOOP, "No rule defined for any role this user has.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name()
|
||||
{
|
||||
return "Guild role check";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description()
|
||||
{
|
||||
return "Checks permission against a rule defined for a specific role in a guild.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* This package contains all sub-checks for PermissionCheck.
|
||||
*/
|
||||
package net.pingex.dcf.permissions.audit;
|
Reference in New Issue