From f96fe12ad4db576bf49b6d9b1a0d8b9c8180094a Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Sat, 21 Oct 2023 16:15:20 -0400 Subject: [PATCH] add config options to disable room creation (#1111) --- server/api/room.ts | 23 ++++++++++++++++++++++- server/ott-config.ts | 10 ++++++++++ server/tests/unit/api/room.spec.ts | 27 +++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/server/api/room.ts b/server/api/room.ts index 977406118..c49d6a800 100644 --- a/server/api/room.ts +++ b/server/api/room.ts @@ -3,7 +3,7 @@ import { getLogger } from "../logger"; import roommanager from "../roommanager"; import { QueueMode, Visibility } from "../../common/models/types"; import { consumeRateLimitPoints } from "../rate-limit"; -import { BadApiArgumentException } from "../exceptions"; +import { BadApiArgumentException, FeatureDisabledException } from "../exceptions"; import { OttException } from "../../common/exceptions"; import express, { RequestHandler, ErrorRequestHandler } from "express"; import clientmanager from "../clientmanager"; @@ -29,6 +29,7 @@ import { import { getApiKey } from "../admin"; import { v4 as uuidv4 } from "uuid"; import { counterHttpErrors } from "../metrics"; +import { conf } from "../ott-config"; const router = express.Router(); const log = getLogger("api/room"); @@ -90,6 +91,10 @@ const generateRoom: RequestHandler { + if (!conf.get("room.enable_create_temporary")) { + throw new FeatureDisabledException("Temporary rooms are disabled."); + } + let points = 50; if (!(await consumeRateLimitPoints(res, req.ip, points))) { return; @@ -119,6 +124,13 @@ const createRoom: RequestHandler< if (!isValidCreateRoom(req.body)) { throw new BadApiArgumentException("name", "missing"); } + + if (req.body.isTemporary && !conf.get("room.enable_create_temporary")) { + throw new FeatureDisabledException("Temporary rooms are disabled."); + } else if (!req.body.isTemporary && !conf.get("room.enable_create_permanent")) { + throw new FeatureDisabledException("Permanent rooms are disabled."); + } + if (!req.body.name) { throw new BadApiArgumentException("name", "missing"); } @@ -467,6 +479,15 @@ const errorHandler: ErrorRequestHandler = (err: Error, req, res) => { reason: e.reason, }, }); + } else if (err.name === "FeatureDisabledException") { + const e = err as FeatureDisabledException; + res.status(403).json({ + success: false, + error: { + name: "FeatureDisabledException", + message: err.message, + }, + }); } else { res.status(400).json({ success: false, diff --git a/server/ott-config.ts b/server/ott-config.ts index 4af52ab55..750ee2070 100644 --- a/server/ott-config.ts +++ b/server/ott-config.ts @@ -407,6 +407,16 @@ export const conf = convict({ nullable: true, }, room: { + enable_create_temporary: { + doc: "Whether to allow creating temporary rooms.", + format: Boolean, + default: true, + }, + enable_create_permanent: { + doc: "Whether to allow creating permanent rooms.", + format: Boolean, + default: true, + }, unload_after: { doc: "The interval in seconds to after a room is considered inactive that the server will keep the room alive.", format: Number, diff --git a/server/tests/unit/api/room.spec.ts b/server/tests/unit/api/room.spec.ts index cba3f804f..5f291e74b 100644 --- a/server/tests/unit/api/room.spec.ts +++ b/server/tests/unit/api/room.spec.ts @@ -7,6 +7,8 @@ import { RoomNotFoundException } from "../../../../server/exceptions"; import { main } from "../../../app"; import { Room as RoomModel, User as UserModel } from "../../../models"; import usermanager from "../../../usermanager"; +import { OttApiRequestRoomCreate } from "common/models/rest-api"; +import { conf } from "../../../../server/ott-config"; expect.extend({ toBeRoomNotFound(error) { @@ -281,5 +283,30 @@ describe("Room API", () => { await roommanager.unloadRoom("testowner"); await RoomModel.destroy({ where: { name: "testowner" } }); }); + + const requests: [string, OttApiRequestRoomCreate | undefined][] = [ + ["/api/room/create", { name: "testtempdisabled", isTemporary: true }], + ["/api/room/create", { name: "testpermdisabled", isTemporary: false }], + ["/api/room/generate", undefined], + ]; + + for (const [path, body] of requests) { + it(`should fail to create room if feature is disabled: Endpoint ${path} body ${JSON.stringify( + body + )}`, async () => { + conf.set("room.enable_create_temporary", false); + conf.set("room.enable_create_permanent", false); + + const resp = await request(app) + .post(path) + .send(body) + .expect("Content-Type", /json/) + .expect(403); + expect(resp.body.success).toEqual(false); + expect(resp.body.error).toMatchObject({ + name: "FeatureDisabledException", + }); + }); + } }); });