diff --git a/PluralKit.Bot/CommandSystem/ContextChecksExt.cs b/PluralKit.Bot/CommandSystem/ContextChecksExt.cs index 25355837..0a300e58 100644 --- a/PluralKit.Bot/CommandSystem/ContextChecksExt.cs +++ b/PluralKit.Bot/CommandSystem/ContextChecksExt.cs @@ -1,7 +1,9 @@ using System.Linq; +using System.Threading.Tasks; using Autofac; +using Myriad.Extensions; using Myriad.Types; using PluralKit.Core; @@ -57,6 +59,28 @@ namespace PluralKit.Bot return ctx; } + public static async Task CheckPermissionsInGuildChannel(this Context ctx, Channel channel, PermissionSet neededPerms) + { + var guild = ctx.Cache.GetGuild(channel.GuildId.Value); + if (guild == null) + return false; + + var guildMember = ctx.Member; + + if (ctx.Guild?.Id != channel.GuildId) + { + guildMember = await ctx.Rest.GetGuildMember(channel.GuildId.Value, ctx.Author.Id); + if (guildMember == null) + return false; + } + + var userPermissions = PermissionExtensions.PermissionsFor(guild, channel, ctx.Author.Id, guildMember); + if ((userPermissions & neededPerms) == 0) + return false; + + return true; + } + public static bool CheckBotAdmin(this Context ctx) { var botConfig = ctx.Services.Resolve(); diff --git a/PluralKit.Bot/Commands/Checks.cs b/PluralKit.Bot/Commands/Checks.cs index 127dc48d..0d8bd6c4 100644 --- a/PluralKit.Bot/Commands/Checks.cs +++ b/PluralKit.Bot/Commands/Checks.cs @@ -169,29 +169,15 @@ namespace PluralKit.Bot throw new PKSyntaxError("You need to specify a channel."); var error = "Channel not found or you do not have permissions to access it."; - var channel = await ctx.MatchChannel(); if (channel == null || channel.GuildId == null) throw new PKError(error); - var guild = _cache.GetGuild(channel.GuildId.Value); - if (guild == null) + if (!await ctx.CheckPermissionsInGuildChannel(channel, PermissionSet.ViewChannel)) throw new PKError(error); - var guildMember = await _rest.GetGuildMember(channel.GuildId.Value, ctx.Author.Id); - if (guildMember == null) - throw new PKError(error); - - - var botPermissions = _bot.PermissionsIn(channel.Id); var webhookPermissions = _cache.EveryonePermissions(channel); - var userPermissions = PermissionExtensions.PermissionsFor(guild, channel, ctx.Author.Id, guildMember); - - if ((userPermissions & PermissionSet.ViewChannel) == 0) - throw new PKError(error); - - // We use a bitfield so we can set individual permission bits ulong missingPermissions = 0; diff --git a/PluralKit.Bot/Commands/Message.cs b/PluralKit.Bot/Commands/Message.cs index aa7fdb98..47d77e8d 100644 --- a/PluralKit.Bot/Commands/Message.cs +++ b/PluralKit.Bot/Commands/Message.cs @@ -105,6 +105,20 @@ namespace PluralKit.Bot throw new PKError("Could not find a recent message to edit."); } + if (msg.Message.Channel != ctx.Channel.Id) + { + var error = "The channel where the message was sent does not exist anymore, or you are missing permissions to access it."; + + var channel = _cache.GetChannel(msg.Message.Channel); + if (channel == null) + throw new PKError(error); + + if (!await ctx.CheckPermissionsInGuildChannel(channel, + PermissionSet.ViewChannel | PermissionSet.SendMessages + )) + throw new PKError(error); + } + return msg; } @@ -145,11 +159,20 @@ namespace PluralKit.Bot throw Errors.MessageNotFound(messageId.Value); } + var showContent = true; + var noShowContentError = "Message deleted or inaccessible."; + + var channel = _cache.GetChannel(message.Message.Channel); + if (channel == null) + showContent = false; + else if (!await ctx.CheckPermissionsInGuildChannel(channel, PermissionSet.ViewChannel)) + showContent = false; + if (ctx.MatchRaw()) { var discordMessage = await _rest.GetMessageOrNull(message.Message.Channel, message.Message.Mid); - if (discordMessage == null) - throw new PKError("Message deleted or inaccessible."); + if (discordMessage == null || !showContent) + throw new PKError(noShowContentError); var content = discordMessage.Content; if (content == null || content == "") @@ -174,12 +197,15 @@ namespace PluralKit.Bot if (isDelete) { + if (!showContent) + throw new PKError(noShowContentError); + if (message.System.Id != ctx.System.Id) throw new PKError("You can only delete your own messages."); await ctx.Rest.DeleteMessage(message.Message.Channel, message.Message.Mid); - if (ctx.Guild != null) + if (ctx.Channel.Id == message.Message.Channel) await ctx.Rest.DeleteMessage(ctx.Message); else await ctx.Rest.CreateReaction(ctx.Message.ChannelId, ctx.Message.Id, new() { Name = Emojis.Success }); @@ -197,7 +223,7 @@ namespace PluralKit.Bot return; } - await ctx.Reply(embed: await _embeds.CreateMessageInfoEmbed(message)); + await ctx.Reply(embed: await _embeds.CreateMessageInfoEmbed(message, showContent)); } private async Task DeleteCommandMessage(Context ctx, ulong messageId) diff --git a/PluralKit.Bot/Handlers/ReactionAdded.cs b/PluralKit.Bot/Handlers/ReactionAdded.cs index c76677c5..9b9d0dc2 100644 --- a/PluralKit.Bot/Handlers/ReactionAdded.cs +++ b/PluralKit.Bot/Handlers/ReactionAdded.cs @@ -175,7 +175,7 @@ namespace PluralKit.Bot await _rest.CreateMessage(dm.Id, new MessageRequest { - Embed = await _embeds.CreateMessageInfoEmbed(msg) + Embed = await _embeds.CreateMessageInfoEmbed(msg, true) }); } catch (ForbiddenException) { } // No permissions to DM, can't check for this :( diff --git a/PluralKit.Bot/Services/EmbedService.cs b/PluralKit.Bot/Services/EmbedService.cs index 77202a76..7d36b304 100644 --- a/PluralKit.Bot/Services/EmbedService.cs +++ b/PluralKit.Bot/Services/EmbedService.cs @@ -275,7 +275,7 @@ namespace PluralKit.Bot .Build(); } - public async Task CreateMessageInfoEmbed(FullMessage msg) + public async Task CreateMessageInfoEmbed(FullMessage msg, bool showContent) { var channel = await _cache.GetOrFetchChannel(_rest, msg.Message.Channel); var ctx = LookupContext.ByNonOwner; @@ -317,11 +317,15 @@ namespace PluralKit.Bot else if (userInfo != null) userStr = userInfo.NameAndMention(); else userStr = $"*(deleted user {msg.Message.Sender})*"; + var content = serverMsg?.Content?.NormalizeLineEndSpacing(); + if (content == null || !showContent) + content = "*(message contents deleted or inaccessible)*"; + // Put it all together var eb = new EmbedBuilder() .Author(new(msg.Member.NameFor(ctx), IconUrl: msg.Member.AvatarFor(ctx).TryGetCleanCdnUrl())) - .Description(serverMsg?.Content?.NormalizeLineEndSpacing() ?? "*(message contents deleted or inaccessible)*") - .Image(new(serverMsg?.Attachments?.FirstOrDefault()?.Url)) + .Description(content) + .Image(showContent ? new(serverMsg?.Attachments?.FirstOrDefault()?.Url) : null) .Field(new("System", msg.System.Name != null ? $"{msg.System.Name} (`{msg.System.Hid}`)" : $"`{msg.System.Hid}`", true)) .Field(new("Member", $"{msg.Member.NameFor(ctx)} (`{msg.Member.Hid}`)", true)) @@ -329,7 +333,7 @@ namespace PluralKit.Bot .Timestamp(DiscordUtils.SnowflakeToInstant(msg.Message.Mid).ToDateTimeOffset().ToString("O")); var roles = memberInfo?.Roles?.ToList(); - if (roles != null && roles.Count > 0) + if (roles != null && roles.Count > 0 && showContent) { var rolesString = string.Join(", ", roles .Select(id =>