/[sudobot]/branches/6.x/src/utils/LevelBasedPermissionManager.ts
ViewVC logotype

Contents of /branches/6.x/src/utils/LevelBasedPermissionManager.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: 3700 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 import { PermissionLevel } from "@prisma/client";
2 import { GuildMember, PermissionsBitField, PermissionsString, Snowflake } from "discord.js";
3 import { GetMemberPermissionInGuildResult } from "../services/PermissionManager";
4 import AbstractPermissionManager from "./AbstractPermissionManager";
5 import { log, logInfo } from "./logger";
6 import { isSystemAdmin } from "./utils";
7
8 export default class LevelBasedPermissionManager extends AbstractPermissionManager {
9 protected cache: Record<`${Snowflake}_${"r" | "u"}_${Snowflake}`, PermissionLevel> = {};
10
11 async sync() {
12 const levels = await this.client.prisma.permissionLevel.findMany();
13
14 this.cache = {};
15
16 for (const level of levels) {
17 for (const roleId of level.roles) {
18 this.cache[`${level.guildId}_r_${roleId}`] = level;
19 }
20
21 for (const userId of level.users) {
22 this.cache[`${level.guildId}_u_${userId}`] = level;
23 }
24 }
25
26 logInfo(`[${this.constructor.name}] Synchronized permission levels`);
27 }
28
29 shouldModerate(member: GuildMember, moderator: GuildMember) {
30 const memberLevel = this.getPermissionLevel(member);
31 const moderatorLevel = this.getPermissionLevel(moderator);
32
33 if (memberLevel >= moderatorLevel) {
34 log("Member has higher/equal permission level than moderator");
35 return false;
36 }
37
38 return true;
39 }
40
41 /**
42 * TODO: Introduce a configuration option that allows to specify a permission level that is immune to automod
43 */
44 isImmuneToAutoMod(member: GuildMember) {
45 const level = this.getPermissionLevel(member);
46 return level === 100;
47 }
48
49 protected getMemberPermissionsFromHighestLevel(member: GuildMember, level: number) {
50 const permissions = new PermissionsBitField();
51
52 for (const key in this.cache) {
53 if (!key.startsWith(`${member.guild.id}_r`)) {
54 continue;
55 }
56
57 const entry = this.cache[key as keyof typeof this.cache];
58
59 if (entry.level > level) {
60 continue;
61 }
62
63 for (const permission of entry.grantedPermissions) {
64 permissions.add(permission as PermissionsString);
65 }
66 }
67
68 return permissions;
69 }
70
71 getPermissionLevel(member: GuildMember) {
72 if (member.guild.ownerId === member.user.id || isSystemAdmin(this.client, member.user.id)) {
73 return 100;
74 }
75
76 let level = this.cache[`${member.guild.id}_u_${member.id}`]?.level ?? 0;
77
78 for (const roleId of member.roles.cache.keys()) {
79 if (this.cache[`${member.guild.id}_r_${roleId}`]) {
80 if (level < this.cache[`${member.guild.id}_r_${roleId}`].level) {
81 level = this.cache[`${member.guild.id}_r_${roleId}`].level;
82 }
83 }
84 }
85
86 return level;
87 }
88
89 getMemberPermissions(member: GuildMember, mergeWithDiscordPermissions = true): GetMemberPermissionInGuildResult {
90 const level = this.getPermissionLevel(member);
91 const permissions = this.getMemberPermissionsFromHighestLevel(member, level);
92
93 if (mergeWithDiscordPermissions) {
94 for (const permission of member.permissions.toArray()) {
95 permissions.add(permission);
96 }
97 }
98
99 for (const permission of this.cache[`${member.guild.id}_u_${member.id}`]?.grantedPermissions ?? []) {
100 permissions.add(permission as PermissionsString);
101 }
102
103 return {
104 type: "levels",
105 permissions,
106 level
107 };
108 }
109 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26