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.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

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


[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
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)
{
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());
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.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Discord.Commands.Attributes.Preconditions
@@ -8,42 +6,44 @@ namespace Discord.Commands.Attributes.Preconditions
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
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)
{
GuildPermission = permission;
ChannelPermission = null;
}

public RequirePermission(ChannelPermission permission)
{
ChannelPermission = permission;
GuildPermission = null;
}
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)
{
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)
{
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());


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

@@ -8,9 +8,10 @@ namespace Discord
public struct ChannelPermissions
{
//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 _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>
public static ChannelPermissions None { get; } = new ChannelPermissions();
@@ -21,6 +22,7 @@ namespace Discord
if (channel is ITextChannel) return _allText;
if (channel is IVoiceChannel) return _allVoice;
if (channel is IDMChannel) return _allDM;
if (channel is IGroupChannel) return _allGroup;

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

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

public List<ChannelPermission> ToList()
{
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,
sendMessages, sendTTSMessages, manageMessages, embedLinks, attachFiles, mentionEveryone, connect, speak, muteMembers, deafenMembers,
moveMembers, useVoiceActivation, changeNickname, manageNicknames, manageRoles);

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

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


Loading…
Cancel
Save