// Copyright (C) 2021-present sam (starshines.gay) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . using Catalogger.Backend.Cache; using Catalogger.Backend.Cache.InMemoryCache; using Catalogger.Backend.Extensions; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.API.Objects; using Remora.Rest.Core; namespace Catalogger.Backend.Services; public class PermissionResolverService( IMemberCache memberCache, RoleCache roleCache, ChannelCache channelCache ) { public async Task GetGuildPermissionsAsync( Snowflake guildId, Snowflake userId ) { var member = await memberCache.TryGetAsync(guildId, userId); return member == null ? DiscordPermissionSet.Empty : GetGuildPermissions(guildId, member); } public async Task GetChannelPermissionsAsync( Snowflake guildId, Snowflake userId, Snowflake channelId ) { if (!channelCache.TryGet(channelId, out var channel)) return DiscordPermissionSet.Empty; return await GetChannelPermissionsAsync(guildId, userId, channel); } public async Task GetChannelPermissionsAsync( Snowflake guildId, Snowflake userId, IChannel channel ) { var member = await memberCache.TryGetAsync(guildId, userId); return member == null ? DiscordPermissionSet.Empty : GetChannelPermissions(guildId, member, channel); } public IDiscordPermissionSet GetGuildPermissions(Snowflake guildId, IGuildMember member) { var roles = roleCache.GuildRoles(guildId).ToList(); var everyoneRole = roles.First(r => r.ID == guildId); var memberRoles = roles.Where(r => member.Roles.Contains(r.ID)).ToList(); return DiscordPermissionSet.ComputePermissions( member.User.GetOrThrow().ID, everyoneRole, memberRoles ); } public IDiscordPermissionSet GetChannelPermissions( Snowflake guildId, IGuildMember member, IChannel channel ) { var roles = roleCache.GuildRoles(guildId).ToList(); var everyoneRole = roles.First(r => r.ID == guildId); var memberRoles = roles.Where(r => member.Roles.Contains(r.ID)).ToList(); return DiscordPermissionSet.ComputePermissions( member.User.GetOrThrow().ID, everyoneRole, memberRoles, channel.PermissionOverwrites.OrDefault() ); } }