diff --git a/src/User.ts b/src/User.ts index 244ae11..147a7d6 100644 --- a/src/User.ts +++ b/src/User.ts @@ -22,6 +22,10 @@ export default class User { return this._model.username; } + get isAdmin(): boolean { + return !!this._model.isAdmin; + } + get accessToken(): string { return this._model.accessTokens.github; } diff --git a/src/database/users/users.schema.ts b/src/database/users/users.schema.ts index f4a9c59..1d98bdc 100644 --- a/src/database/users/users.schema.ts +++ b/src/database/users/users.schema.ts @@ -18,6 +18,7 @@ const UserSchema = new Schema({ default: Boolean, }, ], + isAdmin: { type: Boolean, default: false }, photo: String, repositories: [String], default: { diff --git a/src/database/users/users.types.ts b/src/database/users/users.types.ts index a45cbd3..97ddae5 100644 --- a/src/database/users/users.types.ts +++ b/src/database/users/users.types.ts @@ -8,6 +8,7 @@ export interface IUser { github: string; }; username: string; + isAdmin: boolean; emails: { email: string; default: boolean; diff --git a/src/routes/conference.ts b/src/routes/conference.ts index 02b1dfd..944eb82 100644 --- a/src/routes/conference.ts +++ b/src/routes/conference.ts @@ -3,7 +3,7 @@ import AnonymousError from "../AnonymousError"; import Conference from "../Conference"; import ConferenceModel from "../database/conference/conferences.model"; import { ensureAuthenticated } from "./connection"; -import { handleError, getUser } from "./route-utils"; +import { handleError, getUser, isOwnerOrAdmin } from "./route-utils"; const router = express.Router(); @@ -153,11 +153,7 @@ router.post( model = await ConferenceModel.findOne({ conferenceID: req.params.conferenceID, }); - if (model.owners.indexOf(user.model.id) == -1) - throw new AnonymousError("not_authorized", { - object: req.params.conferenceID, - httpStatus: 401, - }); + isOwnerOrAdmin(model.owners, user); } validateConferenceForm(req.body); model.name = req.body.name; @@ -229,11 +225,7 @@ router.get( httpStatus: 404, }); const conference = new Conference(data); - if (conference.ownerIDs.indexOf(user.model.id) == -1) - throw new AnonymousError("not_authorized", { - object: req.params.conferenceID, - httpStatus: 401, - }); + isOwnerOrAdmin(conference.ownerIDs, user); const o: any = conference.toJSON(); o.repositories = (await conference.repositories()).map((r) => r.toJSON()); res.json(o); @@ -257,11 +249,7 @@ router.delete( httpStatus: 400, }); const conference = new Conference(data); - if (conference.ownerIDs.indexOf(user.model.id) == -1) - throw new AnonymousError("not_authorized", { - object: req.params.conferenceID, - httpStatus: 401, - }); + isOwnerOrAdmin(conference.ownerIDs, user); await conference.remove(); res.send("ok"); } catch (error) { diff --git a/src/routes/repository-private.ts b/src/routes/repository-private.ts index 365b2b1..0d4a945 100644 --- a/src/routes/repository-private.ts +++ b/src/routes/repository-private.ts @@ -2,7 +2,7 @@ import * as express from "express"; import { ensureAuthenticated } from "./connection"; import * as db from "../database/database"; -import { getRepo, getUser, handleError } from "./route-utils"; +import { getRepo, getUser, handleError, isOwnerOrAdmin } from "./route-utils"; import { getRepositoryFromGitHub } from "../source/GitHubRepository"; import gh = require("parse-github-url"); import GitHubBase from "../source/GitHubBase"; @@ -81,12 +81,7 @@ router.post( if (repo.status == "preparing" || repo.status == "removing") return; const user = await getUser(req); - if (repo.owner.id != user.id) { - throw new AnonymousError("not_authorized", { - object: req.params.repoId, - httpStatus: 401, - }); - } + isOwnerOrAdmin([repo.owner.id], user); await repo.updateIfNeeded({ force: true }); res.json({ status: repo.status }); } catch (error) { @@ -109,12 +104,7 @@ router.delete( httpStatus: 410, }); const user = await getUser(req); - if (repo.owner.id != user.id) { - throw new AnonymousError("not_authorized", { - object: req.params.repoId, - httpStatus: 401, - }); - } + isOwnerOrAdmin([repo.owner.id], user); await repo.updateStatus("removing"); await removeQueue.add(repo, { jobId: repo.repoId }); return res.json({ status: repo.status }); @@ -200,12 +190,7 @@ router.get("/:repoId/", async (req: express.Request, res: express.Response) => { if (!repo) return; const user = await getUser(req); - if (repo.owner.id != user.id) { - throw new AnonymousError("not_authorized", { - object: req.params.repoId, - httpStatus: 401, - }); - } + isOwnerOrAdmin([repo.owner.id], user); res.json((await db.getRepository(req.params.repoId)).toJSON()); } catch (error) { handleError(error, res); @@ -295,12 +280,7 @@ router.post( if (!repo) return; const user = await getUser(req); - if (repo.owner.id != user.id) { - throw new AnonymousError("not_authorized", { - object: req.params.repoId, - httpStatus: 401, - }); - } + isOwnerOrAdmin([repo.owner.id], user); const repoUpdate = req.body; diff --git a/src/routes/route-utils.ts b/src/routes/route-utils.ts index 1a5cb87..2165539 100644 --- a/src/routes/route-utils.ts +++ b/src/routes/route-utils.ts @@ -1,11 +1,7 @@ import * as express from "express"; -import AnonymizedFile from "../AnonymizedFile"; import AnonymousError from "../AnonymousError"; import * as db from "../database/database"; import UserModel from "../database/users/users.model"; -import Repository from "../Repository"; -import GitHubBase from "../source/GitHubBase"; -import { GitHubRepository } from "../source/GitHubRepository"; import User from "../User"; import * as io from "@pm2/io"; @@ -37,6 +33,14 @@ export async function getRepo( } } +export function isOwnerOrAdmin(authorizedUsers: string[], user: User) { + if (authorizedUsers.indexOf(user.model.id) == -1 && !user.isAdmin) { + throw new AnonymousError("not_authorized", { + httpStatus: 401, + }); + } +} + function printError(error: any) { io.notifyError(error, error.value); if (error instanceof AnonymousError) {