using System;
using System.Threading.Tasks;
namespace Discord.Commands
{
///
/// This attribute requires that the user invoking the command has a specified permission.
///
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class RequireUserPermissionAttribute : PreconditionAttribute
{
public GuildPermission? GuildPermission { get; }
public ChannelPermission? ChannelPermission { get; }
public override string ErrorMessage { get; set; }
public string NotAGuild { get; set; }
///
/// Require that the user invoking the command has a specified GuildPermission
///
/// This precondition will always fail if the command is being invoked in a private channel.
/// The GuildPermission that the user must have. Multiple permissions can be specified by ORing the permissions together.
public RequireUserPermissionAttribute(GuildPermission permission)
{
GuildPermission = permission;
ChannelPermission = null;
}
///
/// Require that the user invoking the command has a specified ChannelPermission.
///
/// The ChannelPermission that the user must have. Multiple permissions can be specified by ORing the permissions together.
///
///
/// [Command("permission")]
/// [RequireUserPermission(ChannelPermission.ReadMessageHistory | ChannelPermission.ReadMessages)]
/// public async Task HasPermission()
/// {
/// await ReplyAsync("You can read messages and the message history!");
/// }
///
///
public RequireUserPermissionAttribute(ChannelPermission permission)
{
ChannelPermission = permission;
GuildPermission = null;
}
public override Task CheckPermissionsAsync(ICommandContext context, CommandInfo command, IServiceProvider services)
{
var guildUser = context.User as IGuildUser;
if (GuildPermission.HasValue)
{
if (guildUser == null)
return Task.FromResult(PreconditionResult.FromError(NotAGuild ?? "Command must be used in a guild channel"));
if (!guildUser.GuildPermissions.Has(GuildPermission.Value))
return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"User requires guild permission {GuildPermission.Value}"));
}
if (ChannelPermission.HasValue)
{
ChannelPermissions perms;
if (context.Channel is IGuildChannel guildChannel)
perms = guildUser.GetPermissions(guildChannel);
else
perms = ChannelPermissions.All(context.Channel);
if (!perms.Has(ChannelPermission.Value))
return Task.FromResult(PreconditionResult.FromError(ErrorMessage ?? $"User requires channel permission {ChannelPermission.Value}"));
}
return Task.FromResult(PreconditionResult.FromSuccess());
}
}
}