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