refactor(bot): clean up cache extensions

This commit is contained in:
alyssa 2024-08-07 18:54:25 +09:00
parent ede9642a27
commit d305faf401
13 changed files with 27 additions and 34 deletions

View file

@ -100,7 +100,7 @@ public static class DiscordCacheExtensions
await cache.SaveChannel(thread); await cache.SaveChannel(thread);
} }
public static async Task<PermissionSet> PermissionsIn(this IDiscordCache cache, ulong channelId) public static async Task<PermissionSet> BotPermissionsIn(this IDiscordCache cache, ulong channelId)
{ {
var channel = await cache.GetRootChannel(channelId); var channel = await cache.GetRootChannel(channelId);
@ -108,7 +108,7 @@ public static class DiscordCacheExtensions
{ {
var userId = cache.GetOwnUser(); var userId = cache.GetOwnUser();
var member = await cache.TryGetSelfMember(channel.GuildId.Value); var member = await cache.TryGetSelfMember(channel.GuildId.Value);
return await cache.PermissionsFor(channelId, userId, member); return await cache.PermissionsFor2(channelId, userId, member);
} }
return PermissionSet.Dm; return PermissionSet.Dm;

View file

@ -31,16 +31,15 @@ public static class PermissionExtensions
PermissionSet.AttachFiles | PermissionSet.AttachFiles |
PermissionSet.EmbedLinks; PermissionSet.EmbedLinks;
public static Task<PermissionSet> PermissionsFor(this IDiscordCache cache, MessageCreateEvent message) => public static Task<PermissionSet> PermissionsForMCE(this IDiscordCache cache, MessageCreateEvent message) =>
PermissionsFor(cache, message.ChannelId, message.Author.Id, message.Member, message.WebhookId != null); PermissionsFor2(cache, message.ChannelId, message.Author.Id, message.Member, message.WebhookId != null);
public static Task<PermissionSet> public static Task<PermissionSet>
PermissionsFor(this IDiscordCache cache, ulong channelId, GuildMember member) => PermissionsForMemberInChannel(this IDiscordCache cache, ulong channelId, GuildMember member) =>
PermissionsFor(cache, channelId, member.User.Id, member); PermissionsFor2(cache, channelId, member.User.Id, member);
public static async Task<PermissionSet> PermissionsFor(this IDiscordCache cache, ulong channelId, ulong userId, public static async Task<PermissionSet> PermissionsFor2(this IDiscordCache cache, ulong channelId, ulong userId,
GuildMemberPartial? member, bool isWebhook = false, GuildMemberPartial? member, bool isThread = false)
bool isThread = false)
{ {
if (!(await cache.TryGetChannel(channelId) is Channel channel)) if (!(await cache.TryGetChannel(channelId) is Channel channel))
// todo: handle channel not found better // todo: handle channel not found better
@ -53,9 +52,6 @@ public static class PermissionExtensions
var guild = await cache.GetGuild(channel.GuildId.Value); var guild = await cache.GetGuild(channel.GuildId.Value);
if (isWebhook)
return EveryonePermissions(guild);
return PermissionsFor(guild, rootChannel, userId, member, isThread: isThread); return PermissionsFor(guild, rootChannel, userId, member, isThread: isThread);
} }
@ -79,9 +75,6 @@ public static class PermissionExtensions
return perms; return perms;
} }
public static PermissionSet PermissionsFor(Guild guild, Channel channel, MessageCreateEvent msg, bool isThread = false) =>
PermissionsFor(guild, channel, msg.Author.Id, msg.Member, isThread: isThread);
public static PermissionSet PermissionsFor(Guild guild, Channel channel, ulong userId, public static PermissionSet PermissionsFor(Guild guild, Channel channel, ulong userId,
GuildMemberPartial? member, bool isThread = false) GuildMemberPartial? member, bool isThread = false)
{ {

View file

@ -91,7 +91,7 @@ public class ApplicationCommandProxiedMessage
internal async Task DeleteMessageInner(InteractionContext ctx, ulong channelId, ulong messageId, bool isDM = false) internal async Task DeleteMessageInner(InteractionContext ctx, ulong channelId, ulong messageId, bool isDM = false)
{ {
if (!((await _cache.PermissionsIn(channelId)).HasFlag(PermissionSet.ManageMessages) || isDM)) if (!((await _cache.BotPermissionsIn(channelId)).HasFlag(PermissionSet.ManageMessages) || isDM))
throw new PKError("PluralKit does not have the *Manage Messages* permission in this channel, and thus cannot delete the message." throw new PKError("PluralKit does not have the *Manage Messages* permission in this channel, and thus cannot delete the message."
+ " Please contact a server administrator to remedy this."); + " Please contact a server administrator to remedy this.");
@ -110,7 +110,7 @@ public class ApplicationCommandProxiedMessage
// (if not, PK shouldn't send messages on their behalf) // (if not, PK shouldn't send messages on their behalf)
var member = await _rest.GetGuildMember(ctx.GuildId, ctx.User.Id); var member = await _rest.GetGuildMember(ctx.GuildId, ctx.User.Id);
var requiredPerms = PermissionSet.ViewChannel | PermissionSet.SendMessages; var requiredPerms = PermissionSet.ViewChannel | PermissionSet.SendMessages;
if (member == null || !(await _cache.PermissionsFor(ctx.ChannelId, member)).HasFlag(requiredPerms)) if (member == null || !(await _cache.PermissionsForMemberInChannel(ctx.ChannelId, member)).HasFlag(requiredPerms))
{ {
throw new PKError("You do not have permission to send messages in this channel."); throw new PKError("You do not have permission to send messages in this channel.");
}; };

View file

@ -249,7 +249,7 @@ public class Bot
return; return;
} }
var botPerms = await _cache.PermissionsIn(reportChannel.Value); var botPerms = await _cache.BotPermissionsIn(reportChannel.Value);
if (botPerms.HasFlag(PermissionSet.SendMessages | PermissionSet.EmbedLinks)) if (botPerms.HasFlag(PermissionSet.SendMessages | PermissionSet.EmbedLinks))
await _errorMessageService.SendErrorMessage(reportChannel.Value, sentryEvent.EventId.ToString()); await _errorMessageService.SendErrorMessage(reportChannel.Value, sentryEvent.EventId.ToString());
} }

View file

@ -62,8 +62,8 @@ public class Context
public readonly int ShardId; public readonly int ShardId;
public readonly Cluster Cluster; public readonly Cluster Cluster;
public Task<PermissionSet> BotPermissions => Cache.PermissionsIn(Channel.Id); public Task<PermissionSet> BotPermissions => Cache.BotPermissionsIn(Channel.Id);
public Task<PermissionSet> UserPermissions => Cache.PermissionsFor((MessageCreateEvent)Message); public Task<PermissionSet> UserPermissions => Cache.PermissionsForMCE((MessageCreateEvent)Message);
public readonly PKSystem System; public readonly PKSystem System;

View file

@ -156,7 +156,7 @@ public class Checks
if (!await ctx.CheckPermissionsInGuildChannel(channel, PermissionSet.ViewChannel)) if (!await ctx.CheckPermissionsInGuildChannel(channel, PermissionSet.ViewChannel))
throw new PKError(error); throw new PKError(error);
var botPermissions = PermissionExtensions.PermissionsFor(guild, channel, _botConfig.ClientId, guildMember); var botPermissions = await _cache.BotPermissionsIn(channel.Id);
// We use a bitfield so we can set individual permission bits // We use a bitfield so we can set individual permission bits
ulong missingPermissions = 0; ulong missingPermissions = 0;

View file

@ -49,7 +49,7 @@ public class ServerConfig
if (channel.Type != Channel.ChannelType.GuildText && channel.Type != Channel.ChannelType.GuildPublicThread && channel.Type != Channel.ChannelType.GuildPrivateThread) if (channel.Type != Channel.ChannelType.GuildText && channel.Type != Channel.ChannelType.GuildPublicThread && channel.Type != Channel.ChannelType.GuildPrivateThread)
throw new PKError("PluralKit cannot log messages to this type of channel."); throw new PKError("PluralKit cannot log messages to this type of channel.");
var perms = await _cache.PermissionsIn(channel.Id); var perms = await _cache.BotPermissionsIn(channel.Id);
if (!perms.HasFlag(PermissionSet.SendMessages)) if (!perms.HasFlag(PermissionSet.SendMessages))
throw new PKError("PluralKit is missing **Send Messages** permissions in the new log channel."); throw new PKError("PluralKit is missing **Send Messages** permissions in the new log channel.");
if (!perms.HasFlag(PermissionSet.EmbedLinks)) if (!perms.HasFlag(PermissionSet.EmbedLinks))

View file

@ -63,7 +63,7 @@ public class MessageCreated: IEventHandler<MessageCreateEvent>
if (evt.Type != Message.MessageType.Default && evt.Type != Message.MessageType.Reply) return; if (evt.Type != Message.MessageType.Default && evt.Type != Message.MessageType.Reply) return;
if (IsDuplicateMessage(evt)) return; if (IsDuplicateMessage(evt)) return;
var botPermissions = await _cache.PermissionsIn(evt.ChannelId); var botPermissions = await _cache.BotPermissionsIn(evt.ChannelId);
if (!botPermissions.HasFlag(PermissionSet.SendMessages)) return; if (!botPermissions.HasFlag(PermissionSet.SendMessages)) return;
// spawn off saving the private channel into another thread // spawn off saving the private channel into another thread

View file

@ -69,7 +69,7 @@ public class MessageEdited: IEventHandler<MessageUpdateEvent>
ctx = await _repo.GetMessageContext(evt.Author.Value!.Id, channel.GuildId!.Value, rootChannel.Id, evt.ChannelId); ctx = await _repo.GetMessageContext(evt.Author.Value!.Id, channel.GuildId!.Value, rootChannel.Id, evt.ChannelId);
var equivalentEvt = await GetMessageCreateEvent(evt, lastMessage, channel); var equivalentEvt = await GetMessageCreateEvent(evt, lastMessage, channel);
var botPermissions = await _cache.PermissionsIn(channel.Id); var botPermissions = await _cache.BotPermissionsIn(channel.Id);
try try
{ {
@ -123,7 +123,7 @@ public class MessageEdited: IEventHandler<MessageUpdateEvent>
if (referencedMessageId == null) if (referencedMessageId == null)
return null; return null;
var botPermissions = await _cache.PermissionsIn(channelId); var botPermissions = await _cache.BotPermissionsIn(channelId);
if (!botPermissions.HasFlag(PermissionSet.ReadMessageHistory)) if (!botPermissions.HasFlag(PermissionSet.ReadMessageHistory))
{ {
_logger.Warning( _logger.Warning(

View file

@ -123,7 +123,7 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
private async ValueTask HandleProxyDeleteReaction(MessageReactionAddEvent evt, PKMessage msg) private async ValueTask HandleProxyDeleteReaction(MessageReactionAddEvent evt, PKMessage msg)
{ {
if (!(await _cache.PermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages)) if (!(await _cache.BotPermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages))
return; return;
var isSameSystem = msg.Member != null && await _repo.IsMemberOwnedByAccount(msg.Member.Value, evt.UserId); var isSameSystem = msg.Member != null && await _repo.IsMemberOwnedByAccount(msg.Member.Value, evt.UserId);
@ -150,7 +150,7 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
if (authorId != null && authorId != evt.UserId) if (authorId != null && authorId != evt.UserId)
return; return;
if (!((await _cache.PermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages) || isDM)) if (!((await _cache.BotPermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages) || isDM))
return; return;
// todo: don't try to delete the user's own messages in DMs // todo: don't try to delete the user's own messages in DMs
@ -206,14 +206,14 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
private async ValueTask HandlePingReaction(MessageReactionAddEvent evt, FullMessage msg) private async ValueTask HandlePingReaction(MessageReactionAddEvent evt, FullMessage msg)
{ {
if (!(await _cache.PermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages)) if (!(await _cache.BotPermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages))
return; return;
// Check if the "pinger" has permission to send messages in this channel // Check if the "pinger" has permission to send messages in this channel
// (if not, PK shouldn't send messages on their behalf) // (if not, PK shouldn't send messages on their behalf)
var member = await _rest.GetGuildMember(evt.GuildId!.Value, evt.UserId); var member = await _rest.GetGuildMember(evt.GuildId!.Value, evt.UserId);
var requiredPerms = PermissionSet.ViewChannel | PermissionSet.SendMessages; var requiredPerms = PermissionSet.ViewChannel | PermissionSet.SendMessages;
if (member == null || !(await _cache.PermissionsFor(evt.ChannelId, member)).HasFlag(requiredPerms)) return; if (member == null || !(await _cache.PermissionsForMemberInChannel(evt.ChannelId, member)).HasFlag(requiredPerms)) return;
if (msg.Member == null) return; if (msg.Member == null) return;
@ -266,7 +266,7 @@ public class ReactionAdded: IEventHandler<MessageReactionAddEvent>
private async Task TryRemoveOriginalReaction(MessageReactionAddEvent evt) private async Task TryRemoveOriginalReaction(MessageReactionAddEvent evt)
{ {
if ((await _cache.PermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages)) if ((await _cache.BotPermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages))
await _rest.DeleteUserReaction(evt.ChannelId, evt.MessageId, evt.Emoji, evt.UserId); await _rest.DeleteUserReaction(evt.ChannelId, evt.MessageId, evt.Emoji, evt.UserId);
} }
} }

View file

@ -102,7 +102,7 @@ public class ProxyService
// Check if the sender account can mention everyone/here + embed links // Check if the sender account can mention everyone/here + embed links
// we need to "mirror" these permissions when proxying to prevent exploits // we need to "mirror" these permissions when proxying to prevent exploits
var senderPermissions = PermissionExtensions.PermissionsFor(guild, rootChannel, message, isThread: rootChannel.Id != channel.Id); var senderPermissions = PermissionExtensions.PermissionsFor(guild, rootChannel, message.Author.Id, message.Member, isThread: rootChannel.Id != channel.Id);
var allowEveryone = senderPermissions.HasFlag(PermissionSet.MentionEveryone); var allowEveryone = senderPermissions.HasFlag(PermissionSet.MentionEveryone);
var allowEmbeds = senderPermissions.HasFlag(PermissionSet.EmbedLinks); var allowEmbeds = senderPermissions.HasFlag(PermissionSet.EmbedLinks);

View file

@ -101,7 +101,7 @@ public class LoggerCleanService
var channel = await _cache.GetChannel(msg.ChannelId); var channel = await _cache.GetChannel(msg.ChannelId);
if (channel.Type != Channel.ChannelType.GuildText) return; if (channel.Type != Channel.ChannelType.GuildText) return;
if (!(await _cache.PermissionsIn(channel.Id)).HasFlag(PermissionSet.ManageMessages)) return; if (!(await _cache.BotPermissionsIn(channel.Id)).HasFlag(PermissionSet.ManageMessages)) return;
// If this message is from a *webhook*, check if the application ID matches one of the bots we know // If this message is from a *webhook*, check if the application ID matches one of the bots we know
// If it's from a *bot*, check the bot ID to see if we know it. // If it's from a *bot*, check the bot ID to see if we know it.

View file

@ -40,7 +40,7 @@ public class SerilogGatewayEnricherFactory
if (await _cache.TryGetChannel(channel.Value) != null) if (await _cache.TryGetChannel(channel.Value) != null)
{ {
var botPermissions = await _cache.PermissionsIn(channel.Value); var botPermissions = await _cache.BotPermissionsIn(channel.Value);
props.Add(new LogEventProperty("BotPermissions", new ScalarValue(botPermissions))); props.Add(new LogEventProperty("BotPermissions", new ScalarValue(botPermissions)));
} }
} }
@ -52,7 +52,7 @@ public class SerilogGatewayEnricherFactory
props.Add(new LogEventProperty("UserId", new ScalarValue(user.Value))); props.Add(new LogEventProperty("UserId", new ScalarValue(user.Value)));
if (evt is MessageCreateEvent mce) if (evt is MessageCreateEvent mce)
props.Add(new LogEventProperty("UserPermissions", new ScalarValue(await _cache.PermissionsFor(mce)))); props.Add(new LogEventProperty("UserPermissions", new ScalarValue(await _cache.PermissionsForMCE(mce))));
return new Inner(props); return new Inner(props);
} }