diff --git a/PluralKit.Bot/Services/WebhookExecutorService.cs b/PluralKit.Bot/Services/WebhookExecutorService.cs index 8ba7047c..5f7f62ea 100644 --- a/PluralKit.Bot/Services/WebhookExecutorService.cs +++ b/PluralKit.Bot/Services/WebhookExecutorService.cs @@ -66,7 +66,7 @@ namespace PluralKit.Bot var dwb = new DiscordWebhookBuilder(); dwb.WithUsername(FixClyde(name).Truncate(80)); dwb.WithContent(content); - dwb.AddMentions(content.ParseAllMentions(allowEveryone)); + dwb.AddMentions(content.ParseAllMentions(allowEveryone, channel.Guild)); if (avatarUrl != null) dwb.WithAvatarUrl(avatarUrl); var attachmentChunks = ChunkAttachmentsOrThrow(attachments, 8 * 1024 * 1024); diff --git a/PluralKit.Bot/Utils/DiscordUtils.cs b/PluralKit.Bot/Utils/DiscordUtils.cs index 0c58976a..124683bc 100644 --- a/PluralKit.Bot/Utils/DiscordUtils.cs +++ b/PluralKit.Bot/Utils/DiscordUtils.cs @@ -183,13 +183,20 @@ namespace PluralKit.Bot return false; } - public static IEnumerable ParseAllMentions(this string input, bool allowEveryone = false) + public static IEnumerable ParseAllMentions(this string input, bool allowEveryone = false, DiscordGuild guild = null) { var mentions = new List(); mentions.AddRange(USER_MENTION.Matches(input) .Select(x => new UserMention(ulong.Parse(x.Groups[1].Value)) as IMention)); + + // Only allow role mentions through where the role is actually listed as *mentionable* + // (ie. any user can @ them, regardless of permissions) + // Still let the allowEveryone flag override this though (privileged users can @ *any* role) + // Original fix by Gwen mentions.AddRange(ROLE_MENTION.Matches(input) - .Select(x => new RoleMention(ulong.Parse(x.Groups[1].Value)) as IMention)); + .Select(x => ulong.Parse(x.Groups[1].Value)) + .Where(x => allowEveryone || guild != null && guild.GetRole(x).IsMentionable) + .Select(x => new RoleMention(x) as IMention)); if (EVERYONE_HERE_MENTION.IsMatch(input) && allowEveryone) mentions.Add(new EveryoneMention()); return mentions;