瀏覽代碼

feat: Add getUserPermissions job to API module

Owen Diffey 1 年之前
父節點
當前提交
76463517d5
共有 2 個文件被更改,包括 57 次插入30 次删除
  1. 21 29
      backend/src/JobContext.ts
  2. 36 1
      backend/src/modules/APIModule.ts

+ 21 - 29
backend/src/JobContext.ts

@@ -6,9 +6,7 @@ import { Log } from "./LogBook";
 import { SessionSchema } from "./schemas/session";
 import { JobOptions } from "./types/JobOptions";
 import { Jobs, Modules } from "./types/Modules";
-import { StationType } from "./schemas/station";
-import { UserRole, UserSchema } from "./schemas/user";
-import permissions from "./permissions";
+import { UserSchema } from "./schemas/user";
 import { Models } from "./types/Models";
 
 export default class JobContext {
@@ -20,6 +18,8 @@ export default class JobContext {
 
 	private user?: UserSchema;
 
+	private permissions?: Record<string, boolean>;
+
 	public constructor(job: Job, session?: SessionSchema) {
 		this.job = job;
 		this.jobQueue = JobQueue.getPrimaryInstance();
@@ -96,36 +96,28 @@ export default class JobContext {
 		if (!this.session?.userId) throw new Error("No user found for session");
 	}
 
-	public async assertPermission(
-		permission: string,
-		scope?: { stationId?: Types.ObjectId }
+	public async getUserPermissions(
+		scope?: { stationId?: Types.ObjectId },
+		refresh = false
 	) {
-		if (!this.session?.userId) throw new Error("Insufficient permissions");
-
-		const user = await this.getUser();
-
-		const roles: (UserRole | "owner" | "dj")[] = [user.role];
+		if (this.permissions && !refresh) return this.permissions;
 
-		if (scope?.stationId) {
-			const Station = await this.getModel("station");
+		this.permissions = await this.executeJob(
+			"api",
+			"getUserPermissions",
+			scope ?? {}
+		);
 
-			const station = await Station.findById(scope.stationId);
-
-			if (
-				station.type === StationType.COMMUNITY &&
-				station.owner === this.session.userId
-			)
-				roles.push("owner");
-			else if (station.djs.find(dj => dj === this.session?.userId))
-				roles.push("dj");
-		}
+		return this.permissions;
+	}
 
-		let hasPermission;
-		roles.forEach(role => {
-			if (permissions[role] && permissions[role][permission])
-				hasPermission = true;
-		});
+	public async assertPermission(
+		permission: string,
+		scope?: { stationId?: Types.ObjectId }
+	) {
+		const permissions = await this.getUserPermissions(scope);
 
-		if (!hasPermission) throw new Error("Insufficient permissions");
+		if (!permissions[permission])
+			throw new Error("Insufficient permissions");
 	}
 }

+ 36 - 1
backend/src/modules/APIModule.ts

@@ -1,10 +1,13 @@
 import config from "config";
-import { isObjectIdOrHexString } from "mongoose";
+import { Types, isObjectIdOrHexString } from "mongoose";
 import { IncomingMessage } from "node:http";
 import JobContext from "../JobContext";
 import BaseModule from "../BaseModule";
 import { Jobs, Modules, UniqueMethods } from "../types/Modules";
 import WebSocket from "../WebSocket";
+import { UserRole } from "../schemas/user";
+import { StationType } from "../schemas/station";
+import permissions from "../permissions";
 
 export default class APIModule extends BaseModule {
 	/**
@@ -163,6 +166,38 @@ export default class APIModule extends BaseModule {
 				: { loggedIn: false }
 		};
 	}
+
+	public async getUserPermissions(
+		context: JobContext,
+		{ stationId }: { stationId?: Types.ObjectId }
+	) {
+		const user = await context.getUser();
+
+		const roles: (UserRole | "owner" | "dj")[] = [user.role];
+
+		if (stationId) {
+			const Station = await context.getModel("station");
+
+			const station = await Station.findById(stationId);
+
+			if (!station) throw new Error("Station not found");
+
+			if (
+				station.type === StationType.COMMUNITY &&
+				station.owner === user._id
+			)
+				roles.push("owner");
+			else if (station.djs.find(dj => dj === user._id)) roles.push("dj");
+		}
+
+		let rolePermissions: Record<string, boolean> = {};
+		roles.forEach(role => {
+			if (permissions[role])
+				rolePermissions = { ...rolePermissions, ...permissions[role] };
+		});
+
+		return rolePermissions;
+	}
 }
 
 export type APIModuleJobs = {