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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show 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 /**
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