/[sudobot]/branches/8.x/src/services/CommandPermissionOverwriteManager.ts
ViewVC logotype

Annotation of /branches/8.x/src/services/CommandPermissionOverwriteManager.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (hide annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 6671 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 rakinar2 577 /**
2     * This file is part of SudoBot.
3     *
4     * Copyright (C) 2021-2023 OSN Developers.
5     *
6     * SudoBot is free software; you can redistribute it and/or modify it
7     * under the terms of the GNU Affero General Public License as published by
8     * the Free Software Foundation, either version 3 of the License, or
9     * (at your option) any later version.
10     *
11     * SudoBot is distributed in the hope that it will be useful, but
12     * WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU Affero General Public License for more details.
15     *
16     * You should have received a copy of the GNU Affero General Public License
17     * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18     */
19    
20     import { CommandPermissionOverwrite } from "@prisma/client";
21     import { Awaitable, GuildMember, PermissionsString, Snowflake } from "discord.js";
22     import Service from "../core/Service";
23     import { GatewayEventListener } from "../decorators/GatewayEventListener";
24     import { HasEventListeners } from "../types/HasEventListeners";
25     import { log } from "../utils/Logger";
26     import { GetMemberPermissionInGuildResult } from "./PermissionManager";
27    
28     export const name = "commandPermissionOverwriteManager";
29    
30     export default class CommandPermissionOverwriteManager extends Service implements HasEventListeners {
31     readonly permissionOverwrites = new Map<`${Snowflake}____${string}`, CommandPermissionOverwrite[]>();
32     readonly validators: Array<keyof this> = [
33     "validatePermissionOverwriteUsers",
34     "validatePermissionOverwriteChannels",
35     "validatePermissionOverwriteRoles",
36     "validatePermissionOverwriteLevels",
37     "validatePermissionOverwritePermissions"
38     ];
39    
40     @GatewayEventListener("ready")
41     async onReady() {
42     log("Syncing command permission overwrites...");
43    
44     const permissionOverwrites = await this.client.prisma.commandPermissionOverwrite.findMany();
45     this.permissionOverwrites.clear();
46    
47     for (const permissionOverwrite of permissionOverwrites) {
48     for (const command of permissionOverwrite.commands) {
49     const key = `${permissionOverwrite.guildId}____${command}` as const;
50     let existingOverwriteArray = this.permissionOverwrites.get(key);
51    
52     if (!existingOverwriteArray) {
53     existingOverwriteArray = [];
54     this.permissionOverwrites.set(key, existingOverwriteArray);
55     }
56    
57     existingOverwriteArray.push(permissionOverwrite);
58     }
59     }
60    
61     log("Successfully synced command permission overwrites");
62     }
63    
64     async validatePermissionOverwritePermissions(
65     permissionOverwrite: CommandPermissionOverwrite,
66     _: ValidatePermissionOverwritesOptions,
67     { permissions }: GetMemberPermissionInGuildResult
68     ) {
69     return (
70     (permissionOverwrite.requiredPermissionMode === "AND" &&
71     permissions.has(permissionOverwrite.requiredPermissions as PermissionsString[], true)) ||
72     (permissionOverwrite.requiredPermissionMode === "OR" &&
73     permissions.any(permissionOverwrite.requiredPermissions as PermissionsString[], true))
74     );
75     }
76    
77     validatePermissionOverwriteChannels(
78     permissionOverwrite: CommandPermissionOverwrite,
79     { channelId }: ValidatePermissionOverwritesOptions
80     ) {
81     if (permissionOverwrite.requiredChannels.length === 0) {
82     return true;
83     }
84    
85     return permissionOverwrite.requiredChannels.includes(channelId);
86     }
87    
88     validatePermissionOverwriteUsers(
89     permissionOverwrite: CommandPermissionOverwrite,
90     { member }: ValidatePermissionOverwritesOptions
91     ) {
92     if (permissionOverwrite.requiredUsers.length === 0) {
93     return true;
94     }
95    
96     return permissionOverwrite.requiredUsers.includes(member.user.id);
97     }
98    
99     validatePermissionOverwriteRoles(
100     permissionOverwrite: CommandPermissionOverwrite,
101     { member }: ValidatePermissionOverwritesOptions
102     ) {
103     if (permissionOverwrite.requiredRoles.length === 0) {
104     return true;
105     }
106    
107     for (const roleId of member.roles.cache.keys()) {
108     if (permissionOverwrite.requiredRoles.includes(roleId)) {
109     return true;
110     }
111     }
112    
113     return false;
114     }
115    
116     validatePermissionOverwriteLevels(
117     permissionOverwrite: CommandPermissionOverwrite,
118     _: ValidatePermissionOverwritesOptions,
119     permissions: GetMemberPermissionInGuildResult
120     ) {
121     if (permissions.type !== "levels" || permissionOverwrite.requiredLevel === null) {
122     return true;
123     }
124    
125     return permissions.level >= permissionOverwrite.requiredLevel;
126     }
127    
128     async validatePermissionOverwrites(options: ValidatePermissionOverwritesOptions) {
129     const { guildId, commandName, member } = options;
130     const permissionOverwrites = this.client.commandPermissionOverwriteManager.permissionOverwrites.get(
131     `${guildId!}____${commandName}`
132     );
133     const hasOverwrite = !!permissionOverwrites?.length;
134    
135     if (!permissionOverwrites?.length) {
136     return { hasOverwrite: false, result: true };
137     }
138    
139     const memberPermissions = await this.client.permissionManager.getMemberPermissions(member, true);
140     let result = true;
141    
142     outerLoop: for (const permissionOverwrite of permissionOverwrites) {
143     for (const validator of this.validators) {
144     const method = this[validator] as PermissionValidatorFunction | undefined;
145     const validationResult = !!(await method?.call(this, permissionOverwrite, options, memberPermissions));
146    
147     if (permissionOverwrite.mode === "AND" && !validationResult) {
148     return { hasOverwrite, result: false };
149     }
150    
151     if (permissionOverwrite.mode === "OR" && validationResult) {
152     result &&= true;
153     continue outerLoop;
154     }
155     }
156    
157     result &&= permissionOverwrite.mode === "AND";
158    
159     if (!result) {
160     break;
161     }
162     }
163    
164     return { hasOverwrite, result };
165     }
166     }
167    
168     type ValidatePermissionOverwritesOptions = {
169     guildId: Snowflake;
170     commandName: string;
171     member: GuildMember;
172     channelId: Snowflake;
173     };
174    
175     type PermissionValidatorFunction = (
176     permissionOverwrite: CommandPermissionOverwrite,
177     { member }: ValidatePermissionOverwritesOptions,
178     permissions?: GetMemberPermissionInGuildResult
179     ) => Awaitable<boolean>;

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26