From 981071a64504a76a2becaa4150676142146f89b8 Mon Sep 17 00:00:00 2001 From: Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> Date: Sun, 3 Oct 2021 01:42:55 +0200 Subject: [PATCH] :sparkles: User instance rights --- util/src/entities/User.ts | 4 +- util/src/util/BitField.ts | 5 +++ util/src/util/Permissions.ts | 77 ++++++++++++++++++------------------ util/src/util/Rights.ts | 73 ++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 40 deletions(-) create mode 100644 util/src/util/Rights.ts diff --git a/util/src/entities/User.ts b/util/src/entities/User.ts index 68c147fb..aeb617eb 100644 --- a/util/src/entities/User.ts +++ b/util/src/entities/User.ts @@ -3,7 +3,6 @@ import { BaseClass } from "./BaseClass"; import { BitField } from "../util/BitField"; import { Relationship } from "./Relationship"; import { ConnectedAccount } from "./ConnectedAccount"; -import { HTTPError } from "lambert-server"; export enum PublicUserEnum { username, @@ -126,6 +125,9 @@ export class User extends BaseClass { @Column() public_flags: number; + @Column() + rights: string; // Rights + @JoinColumn({ name: "relationship_ids" }) @OneToMany(() => Relationship, (relationship: Relationship) => relationship.from, { cascade: true, diff --git a/util/src/util/BitField.ts b/util/src/util/BitField.ts index ac19763e..986077ba 100644 --- a/util/src/util/BitField.ts +++ b/util/src/util/BitField.ts @@ -141,3 +141,8 @@ export class BitField { throw new RangeError("BITFIELD_INVALID: " + bit); } } + +export function BitFlag(x: bigint | number) { + if (!x) throw new Error("You need to pass a bitflag"); + return BigInt(1) << BigInt(x); +} diff --git a/util/src/util/Permissions.ts b/util/src/util/Permissions.ts index f0012c96..e5459ab5 100644 --- a/util/src/util/Permissions.ts +++ b/util/src/util/Permissions.ts @@ -3,8 +3,7 @@ import { Channel, ChannelPermissionOverwrite, Guild, Member, Role } from "../entities"; import { BitField } from "./BitField"; import "missing-native-js-functions"; -import { BitFieldResolvable } from "."; -// TODO: check role hierarchy permission +import { BitFieldResolvable, BitFlag } from "./BitField"; var HTTPError: any; @@ -32,44 +31,44 @@ export class Permissions extends BitField { } static FLAGS = { - CREATE_INSTANT_INVITE: BigInt(1) << BigInt(0), - KICK_MEMBERS: BigInt(1) << BigInt(1), - BAN_MEMBERS: BigInt(1) << BigInt(2), - ADMINISTRATOR: BigInt(1) << BigInt(3), - MANAGE_CHANNELS: BigInt(1) << BigInt(4), - MANAGE_GUILD: BigInt(1) << BigInt(5), - ADD_REACTIONS: BigInt(1) << BigInt(6), - VIEW_AUDIT_LOG: BigInt(1) << BigInt(7), - PRIORITY_SPEAKER: BigInt(1) << BigInt(8), - STREAM: BigInt(1) << BigInt(9), - VIEW_CHANNEL: BigInt(1) << BigInt(10), - SEND_MESSAGES: BigInt(1) << BigInt(11), - SEND_TTS_MESSAGES: BigInt(1) << BigInt(12), - MANAGE_MESSAGES: BigInt(1) << BigInt(13), - EMBED_LINKS: BigInt(1) << BigInt(14), - ATTACH_FILES: BigInt(1) << BigInt(15), - READ_MESSAGE_HISTORY: BigInt(1) << BigInt(16), - MENTION_EVERYONE: BigInt(1) << BigInt(17), - USE_EXTERNAL_EMOJIS: BigInt(1) << BigInt(18), - VIEW_GUILD_INSIGHTS: BigInt(1) << BigInt(19), - CONNECT: BigInt(1) << BigInt(20), - SPEAK: BigInt(1) << BigInt(21), - MUTE_MEMBERS: BigInt(1) << BigInt(22), - DEAFEN_MEMBERS: BigInt(1) << BigInt(23), - MOVE_MEMBERS: BigInt(1) << BigInt(24), - USE_VAD: BigInt(1) << BigInt(25), - CHANGE_NICKNAME: BigInt(1) << BigInt(26), - MANAGE_NICKNAMES: BigInt(1) << BigInt(27), - MANAGE_ROLES: BigInt(1) << BigInt(28), - MANAGE_WEBHOOKS: BigInt(1) << BigInt(29), - MANAGE_EMOJIS_AND_STICKERS: BigInt(1) << BigInt(30), - USE_APPLICATION_COMMANDS: BigInt(1) << BigInt(31), - REQUEST_TO_SPEAK: BigInt(1) << BigInt(32), + CREATE_INSTANT_INVITE: BitFlag(0), + KICK_MEMBERS: BitFlag(1), + BAN_MEMBERS: BitFlag(2), + ADMINISTRATOR: BitFlag(3), + MANAGE_CHANNELS: BitFlag(4), + MANAGE_GUILD: BitFlag(5), + ADD_REACTIONS: BitFlag(6), + VIEW_AUDIT_LOG: BitFlag(7), + PRIORITY_SPEAKER: BitFlag(8), + STREAM: BitFlag(9), + VIEW_CHANNEL: BitFlag(10), + SEND_MESSAGES: BitFlag(11), + SEND_TTS_MESSAGES: BitFlag(12), + MANAGE_MESSAGES: BitFlag(13), + EMBED_LINKS: BitFlag(14), + ATTACH_FILES: BitFlag(15), + READ_MESSAGE_HISTORY: BitFlag(16), + MENTION_EVERYONE: BitFlag(17), + USE_EXTERNAL_EMOJIS: BitFlag(18), + VIEW_GUILD_INSIGHTS: BitFlag(19), + CONNECT: BitFlag(20), + SPEAK: BitFlag(21), + MUTE_MEMBERS: BitFlag(22), + DEAFEN_MEMBERS: BitFlag(23), + MOVE_MEMBERS: BitFlag(24), + USE_VAD: BitFlag(25), + CHANGE_NICKNAME: BitFlag(26), + MANAGE_NICKNAMES: BitFlag(27), + MANAGE_ROLES: BitFlag(28), + MANAGE_WEBHOOKS: BitFlag(29), + MANAGE_EMOJIS_AND_STICKERS: BitFlag(30), + USE_APPLICATION_COMMANDS: BitFlag(31), + REQUEST_TO_SPEAK: BitFlag(32), // TODO: what is permission 33? - MANAGE_THREADS: BigInt(1) << BigInt(34), - USE_PUBLIC_THREADS: BigInt(1) << BigInt(35), - USE_PRIVATE_THREADS: BigInt(1) << BigInt(36), - USE_EXTERNAL_STICKERS: BigInt(1) << BigInt(37), + MANAGE_THREADS: BitFlag(34), + USE_PUBLIC_THREADS: BitFlag(35), + USE_PRIVATE_THREADS: BitFlag(36), + USE_EXTERNAL_STICKERS: BitFlag(37), /** * CUSTOM PERMISSIONS ideas: diff --git a/util/src/util/Rights.ts b/util/src/util/Rights.ts new file mode 100644 index 00000000..a266e4f7 --- /dev/null +++ b/util/src/util/Rights.ts @@ -0,0 +1,73 @@ +import { BitField } from "./BitField"; +import "missing-native-js-functions"; +import { BitFieldResolvable, BitFlag } from "./BitField"; + +var HTTPError: any; + +try { + HTTPError = require("lambert-server").HTTPError; +} catch (e) { + HTTPError = Error; +} + +export type RightResolvable = bigint | number | Rights | RightResolvable[] | RightString; + +type RightString = keyof typeof Rights.FLAGS; +// TODO: just like roles for members, users should have privilidges which combine multiple rights into one and make it easy to assign + +export class Rights extends BitField { + constructor(bits: BitFieldResolvable = 0) { + super(bits); + if (this.bitfield & Rights.FLAGS.OPERATOR) { + this.bitfield = ALL_RIGHTS; + } + } + + static FLAGS = { + OPERATOR: BitFlag(0), // has all rights + MANAGE_APPLICATIONS: BitFlag(1), + MANAGE_GUILDS: BitFlag(2), + MANAGE_MESSAGES: BitFlag(3), // Can't see other messages but delete/edit them in channels that they can see + MANAGE_RATE_LIMITS: BitFlag(4), + MANAGE_ROUTING: BitFlag(5), // can create custom message routes to any channel/guild + MANAGE_TICKETS: BitFlag(6), + MANAGE_USERS: BitFlag(7), + ADD_MEMBERS: BitFlag(8), // can manually add any members in their guilds + BYPASS_RATE_LIMITS: BitFlag(9), + CREATE_APPLICATIONS: BitFlag(10), + CREATE_CHANNELS: BitFlag(11), + CREATE_DMS: BitFlag(12), + CREATE_DM_GROUPS: BitFlag(13), + CREATE_GUILDS: BitFlag(14), + CREATE_INVITES: BitFlag(15), + CREATE_ROLES: BitFlag(16), + CREATE_TEMPLATES: BitFlag(17), + CREATE_WEBHOOKS: BitFlag(18), + JOIN_GUILDS: BitFlag(19), + PIN_MESSAGES: BitFlag(20), + SELF_ADD_REACTIONS: BitFlag(21), + SELF_DELETE_MESSAGES: BitFlag(22), + SELF_EDIT_MESSAGES: BitFlag(23), + SELF_EDIT_NAME: BitFlag(24), + SEND_MESSAGES: BitFlag(25), + USE_SCREEN: BitFlag(26), + USE_VIDEO: BitFlag(27), + USE_VOICE: BitFlag(28), + }; + + any(permission: RightResolvable, checkOperator = true) { + return (checkOperator && super.any(Rights.FLAGS.OPERATOR)) || super.any(permission); + } + + has(permission: RightResolvable, checkOperator = true) { + return (checkOperator && super.has(Rights.FLAGS.OPERATOR)) || super.has(permission); + } + + hasThrow(permission: RightResolvable) { + if (this.has(permission)) return true; + // @ts-ignore + throw new HTTPError(`You are missing the following rights ${permission}`, 403); + } +} + +const ALL_RIGHTS = Object.values(Rights.FLAGS).reduce((total, val) => total | val, BigInt(0));