mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-05-10 12:25:02 +00:00
Improve permission utils, make them bigint-aware
This commit is contained in:
parent
a404c7a97f
commit
8af64a6944
11 changed files with 97 additions and 34 deletions
|
@ -1,10 +1,7 @@
|
|||
import { Constants, GuildChannel } from "eris";
|
||||
import { hasChannelPermissions } from "./hasChannelPermissions";
|
||||
import { Constants, GuildChannel, Member } from "eris";
|
||||
import { memberHasChannelPermissions } from "./memberHasChannelPermissions";
|
||||
import { readChannelPermissions } from "./readChannelPermissions";
|
||||
|
||||
export function canReadChannel(channel: GuildChannel, memberId: string) {
|
||||
const channelPermissions = channel.permissionsOf(memberId);
|
||||
return hasChannelPermissions(channelPermissions, [
|
||||
Constants.Permissions.readMessages,
|
||||
Constants.Permissions.readMessageHistory,
|
||||
]);
|
||||
export function canReadChannel(channel: GuildChannel, member: Member) {
|
||||
return memberHasChannelPermissions(member, channel, readChannelPermissions);
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import { Constants, Permission } from "eris";
|
||||
|
||||
export function hasChannelPermissions(channelPermissions: Permission, permissions: number | number[]) {
|
||||
if (Boolean(channelPermissions.allow & Constants.Permissions.administrator)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Array.isArray(permissions)) {
|
||||
permissions = [permissions];
|
||||
}
|
||||
|
||||
for (const permission of permissions) {
|
||||
if (!(channelPermissions.allow & permission)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
16
backend/src/utils/hasDiscordPermissions.ts
Normal file
16
backend/src/utils/hasDiscordPermissions.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Constants, Permission } from "eris";
|
||||
|
||||
/**
|
||||
* @param resolvedPermissions A Permission object from e.g. GuildChannel#permissionsOf() or Member#permission
|
||||
* @param requiredPermissions Bitmask of required permissions
|
||||
*/
|
||||
export function hasDiscordPermissions(resolvedPermissions: Permission, requiredPermissions: number | bigint) {
|
||||
const allowedPermissions = BigInt(resolvedPermissions.allow);
|
||||
const nRequiredPermissions = BigInt(requiredPermissions);
|
||||
|
||||
if (Boolean(allowedPermissions & BigInt(Constants.Permissions.administrator))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Boolean(allowedPermissions & nRequiredPermissions);
|
||||
}
|
|
@ -1,8 +1,15 @@
|
|||
import { Constants, GuildChannel, Member, Permission } from "eris";
|
||||
import { PluginData } from "knub";
|
||||
import { hasChannelPermissions } from "./hasChannelPermissions";
|
||||
import { hasDiscordPermissions } from "./hasDiscordPermissions";
|
||||
|
||||
export function memberHasChannelPermissions(member: Member, channel: GuildChannel, permissions: number | number[]) {
|
||||
/**
|
||||
* @param requiredPermissions Bitmask of required permissions
|
||||
*/
|
||||
export function memberHasChannelPermissions(
|
||||
member: Member,
|
||||
channel: GuildChannel,
|
||||
requiredPermissions: number | bigint,
|
||||
) {
|
||||
const memberChannelPermissions = channel.permissionsOf(member.id);
|
||||
return hasChannelPermissions(memberChannelPermissions, permissions);
|
||||
return hasDiscordPermissions(memberChannelPermissions, requiredPermissions);
|
||||
}
|
||||
|
|
7
backend/src/utils/readChannelPermissions.ts
Normal file
7
backend/src/utils/readChannelPermissions.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { Constants } from "eris";
|
||||
|
||||
/**
|
||||
* Bitmask of permissions required to read messages in a channel
|
||||
*/
|
||||
export const readChannelPermissions =
|
||||
BigInt(Constants.Permissions.readMessages) | BigInt(Constants.Permissions.readMessageHistory);
|
54
backend/src/utils/verifyPermissions.ts
Normal file
54
backend/src/utils/verifyPermissions.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import { Constants, Permission } from "eris";
|
||||
import { PluginData } from "knub";
|
||||
import { hasDiscordPermissions } from "./hasDiscordPermissions";
|
||||
import { LogsPlugin } from "../plugins/Logs/LogsPlugin";
|
||||
import { LogType } from "../data/LogType";
|
||||
|
||||
const defaultErrorText = `Missing permissions.`;
|
||||
|
||||
const camelCaseToTitleCase = str =>
|
||||
str
|
||||
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
||||
.split(" ")
|
||||
.map(w => w[0].toUpperCase() + w.slice(1))
|
||||
.join(" ");
|
||||
|
||||
const permissionNumberToName: Map<bigint, string> = new Map();
|
||||
for (const key in Constants.Permissions) {
|
||||
permissionNumberToName.set(BigInt(Constants.Permissions[key]), camelCaseToTitleCase(key));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param resolvedPermissions A Permission object from e.g. GuildChannel#permissionsOf() or Member#permission
|
||||
* @param requiredPermissions Bitmask of required permissions
|
||||
* @param errorText Custom error text
|
||||
*/
|
||||
export function verifyPermissions(
|
||||
pluginData: PluginData<any>,
|
||||
resolvedPermissions: Permission,
|
||||
requiredPermissions: number | bigint,
|
||||
errorText?: string,
|
||||
) {
|
||||
const nRequiredPermissions = BigInt(requiredPermissions);
|
||||
|
||||
if (!hasDiscordPermissions(resolvedPermissions, nRequiredPermissions)) {
|
||||
const requiredPermissionNames = [];
|
||||
for (const [permissionNumber, permissionName] of permissionNumberToName.entries()) {
|
||||
if (nRequiredPermissions & permissionNumber) {
|
||||
requiredPermissionNames.push(permissionName);
|
||||
}
|
||||
}
|
||||
|
||||
const logs = pluginData.getPlugin(LogsPlugin);
|
||||
logs.log(LogType.BOT_ALERT, {
|
||||
body: `${errorText ||
|
||||
defaultErrorText} Please ensure I have the following permissions: **${requiredPermissionNames.join(
|
||||
"**, **",
|
||||
)}**`.trim(),
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue