Browse Source

Cleaned up permission checks, added Permissions.Has(enum) methods

tags/1.0-rc
RogueException 9 years ago
parent
commit
dcb603acd7
4 changed files with 40 additions and 35 deletions
  1. +15
    -16
      src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs
  2. +17
    -17
      src/Discord.Net.Commands/Attributes/Preconditions/RequirePermission.cs
  3. +5
    -1
      src/Discord.Net/Entities/Permissions/ChannelPermissions.cs
  4. +3
    -1
      src/Discord.Net/Entities/Permissions/GuildPermissions.cs

+ 15
- 16
src/Discord.Net.Commands/Attributes/Preconditions/RequireContextAttribute.cs View File

@@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;


namespace Discord.Commands namespace Discord.Commands
@@ -8,35 +6,36 @@ namespace Discord.Commands
[Flags] [Flags]
public enum ContextType public enum ContextType
{ {
Guild = 1, // 01
DM = 2 // 10
Guild = 0x01,
DM = 0x02,
Group = 0x04
} }



[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequireContextAttribute : PreconditionAttribute public class RequireContextAttribute : PreconditionAttribute
{ {
public ContextType Context { get; set; }
public ContextType Contexts { get; }


public RequireContextAttribute(ContextType context)
public RequireContextAttribute(ContextType contexts)
{ {
Context = context;
Contexts = contexts;
} }


public override Task<PreconditionResult> CheckPermissions(IMessage context, Command executingCommand, object moduleInstance) public override Task<PreconditionResult> CheckPermissions(IMessage context, Command executingCommand, object moduleInstance)
{ {
var validContext = false;

if (Context.HasFlag(ContextType.Guild))
validContext = validContext || context.Channel is IGuildChannel;
bool isValid = false;


if (Context.HasFlag(ContextType.DM))
validContext = validContext || context.Channel is IDMChannel;
if ((Contexts & ContextType.Guild) != 0)
isValid = isValid || context.Channel is IGuildChannel;
if ((Contexts & ContextType.DM) != 0)
isValid = isValid || context.Channel is IDMChannel;
if ((Contexts & ContextType.Group) != 0)
isValid = isValid || context.Channel is IGroupChannel;


if (validContext)
if (isValid)
return Task.FromResult(PreconditionResult.FromSuccess()); return Task.FromResult(PreconditionResult.FromSuccess());
else else
return Task.FromResult(PreconditionResult.FromError($"Invalid context for command; accepted contexts: {Context}"));
return Task.FromResult(PreconditionResult.FromError($"Invalid context for command; accepted contexts: {Contexts}"));
} }
} }
} }

+ 17
- 17
src/Discord.Net.Commands/Attributes/Preconditions/RequirePermission.cs View File

@@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;


namespace Discord.Commands.Attributes.Preconditions namespace Discord.Commands.Attributes.Preconditions
@@ -8,42 +6,44 @@ namespace Discord.Commands.Attributes.Preconditions
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequirePermission : PreconditionAttribute public class RequirePermission : PreconditionAttribute
{ {
public GuildPermission? GuildPermission { get; set; }
public ChannelPermission? ChannelPermission { get; set; }
public GuildPermission? GuildPermission { get; }
public ChannelPermission? ChannelPermission { get; }


public RequirePermission(GuildPermission permission) public RequirePermission(GuildPermission permission)
{ {
GuildPermission = permission; GuildPermission = permission;
ChannelPermission = null; ChannelPermission = null;
} }

public RequirePermission(ChannelPermission permission) public RequirePermission(ChannelPermission permission)
{ {
ChannelPermission = permission; ChannelPermission = permission;
GuildPermission = null; GuildPermission = null;
} }
public override Task<PreconditionResult> CheckPermissions(IMessage context, Command executingCommand, object moduleInstance) public override Task<PreconditionResult> CheckPermissions(IMessage context, Command executingCommand, object moduleInstance)
{ {
if (!(context.Channel is IGuildChannel))
return Task.FromResult(PreconditionResult.FromError("Command must be used in a guild channel"));

var author = context.Author as IGuildUser;
var guildUser = context.Author as IGuildUser;


if (GuildPermission.HasValue) if (GuildPermission.HasValue)
{ {
var guildPerms = author.GuildPermissions.ToList();
if (!guildPerms.Contains(GuildPermission.Value))
return Task.FromResult(PreconditionResult.FromError($"User is missing guild permission {GuildPermission.Value}"));
if (guildUser == null)
return Task.FromResult(PreconditionResult.FromError("Command must be used in a guild channel"));
if (!guildUser.GuildPermissions.Has(GuildPermission.Value))
return Task.FromResult(PreconditionResult.FromError($"Command requires guild permission {GuildPermission.Value}"));
} }


if (ChannelPermission.HasValue) if (ChannelPermission.HasValue)
{ {
var channel = context.Channel as IGuildChannel;
var channelPerms = author.GetPermissions(channel).ToList();
var guildChannel = context.Channel as IGuildChannel;

ChannelPermissions perms;
if (guildChannel != null)
perms = guildUser.GetPermissions(guildChannel);
else
perms = ChannelPermissions.All(guildChannel);


if (!channelPerms.Contains(ChannelPermission.Value))
return Task.FromResult(PreconditionResult.FromError($"User is missing channel permission {ChannelPermission.Value}"));
if (!perms.Has(ChannelPermission.Value))
return Task.FromResult(PreconditionResult.FromError($"Command requires channel permission {ChannelPermission.Value}"));
} }


return Task.FromResult(PreconditionResult.FromSuccess()); return Task.FromResult(PreconditionResult.FromSuccess());


+ 5
- 1
src/Discord.Net/Entities/Permissions/ChannelPermissions.cs View File

@@ -8,9 +8,10 @@ namespace Discord
public struct ChannelPermissions public struct ChannelPermissions
{ {
//TODO: C#7 Candidate for binary literals //TODO: C#7 Candidate for binary literals
private static ChannelPermissions _allDM { get; } = new ChannelPermissions(Convert.ToUInt64("00010000000000111111110000011001", 2));
private static ChannelPermissions _allText { get; } = new ChannelPermissions(Convert.ToUInt64("00000000000000011100110000000000", 2)); private static ChannelPermissions _allText { get; } = new ChannelPermissions(Convert.ToUInt64("00000000000000011100110000000000", 2));
private static ChannelPermissions _allVoice { get; } = new ChannelPermissions(Convert.ToUInt64("00010011111100000000000000011001", 2)); private static ChannelPermissions _allVoice { get; } = new ChannelPermissions(Convert.ToUInt64("00010011111100000000000000011001", 2));
private static ChannelPermissions _allDM { get; } = new ChannelPermissions(Convert.ToUInt64("00010000000000111111110000011001", 2));
private static ChannelPermissions _allGroup { get; } = new ChannelPermissions(Convert.ToUInt64("00010000000000111111110000011001", 2));


/// <summary> Gets a blank ChannelPermissions that grants no permissions. </summary> /// <summary> Gets a blank ChannelPermissions that grants no permissions. </summary>
public static ChannelPermissions None { get; } = new ChannelPermissions(); public static ChannelPermissions None { get; } = new ChannelPermissions();
@@ -21,6 +22,7 @@ namespace Discord
if (channel is ITextChannel) return _allText; if (channel is ITextChannel) return _allText;
if (channel is IVoiceChannel) return _allVoice; if (channel is IVoiceChannel) return _allVoice;
if (channel is IDMChannel) return _allDM; if (channel is IDMChannel) return _allDM;
if (channel is IGroupChannel) return _allGroup;


throw new ArgumentException("Unknown channel type", nameof(channel)); throw new ArgumentException("Unknown channel type", nameof(channel));
} }
@@ -118,6 +120,8 @@ namespace Discord
embedLinks, attachFiles, readMessageHistory, mentionEveryone, connect, speak, muteMembers, deafenMembers, embedLinks, attachFiles, readMessageHistory, mentionEveryone, connect, speak, muteMembers, deafenMembers,
moveMembers, useVoiceActivation, managePermissions); moveMembers, useVoiceActivation, managePermissions);


public bool Has(ChannelPermission permission) => Permissions.GetValue(RawValue, permission);

public List<ChannelPermission> ToList() public List<ChannelPermission> ToList()
{ {
var perms = new List<ChannelPermission>(); var perms = new List<ChannelPermission>();


+ 3
- 1
src/Discord.Net/Entities/Permissions/GuildPermissions.cs View File

@@ -129,7 +129,9 @@ namespace Discord
=> new GuildPermissions(RawValue, createInstantInvite, manageRoles, kickMembers, banMembers, manageChannels, manageGuild, readMessages, => new GuildPermissions(RawValue, createInstantInvite, manageRoles, kickMembers, banMembers, manageChannels, manageGuild, readMessages,
sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles, mentionEveryone, connect, speak, muteMembers, deafenMembers, sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles, mentionEveryone, connect, speak, muteMembers, deafenMembers,
moveMembers, useVoiceActivation, changeNickname, manageNicknames, manageRoles); moveMembers, useVoiceActivation, changeNickname, manageNicknames, manageRoles);

public bool Has(GuildPermission permission) => Permissions.GetValue(RawValue, permission);

public List<GuildPermission> ToList() public List<GuildPermission> ToList()
{ {
var perms = new List<GuildPermission>(); var perms = new List<GuildPermission>();


Loading…
Cancel
Save