diff --git a/lib/www/server/api/middleware/auth/access.js b/lib/www/server/api/middleware/auth/access.js index d73a494..fa5b1a6 100644 --- a/lib/www/server/api/middleware/auth/access.js +++ b/lib/www/server/api/middleware/auth/access.js @@ -1,77 +1,34 @@ +const { projectOrganisations, orgAccess } = require('../../../lib/db/project/organisations'); - -async function read (req, res, next) { - if (req.user) { - next(); - } else { - next({status: 403, message: "Access denied"}); - } -} - -async function write (req, res, next) { - if (req.user && (req.user.role == "user" || req.user.role == "admin")) { - next(); - } else { - next({status: 403, message: "Access denied"}); - } -} - -async function admin (req, res, next) { - if (req.user && req.user.role == "admin") { - next(); - } else { - next({status: 403, message: "Access denied"}); - } -} - -/** Return a middleware to check for arbitrary roles. - * - * Examples: - * - * req1 = {user: {role: "admin"}}; - * - * role("admin")(req1) → true - * role("user")(req1) → false - * role(["user", "admin"])(req1) → true - * role("guest")(req1) → false - * - * req2 = {user: {role: ["admin", "user"]}} - * - * role("admin")(req2) → true - * role("user")(req2) → true - * role(["user", "admin"])(req2) → true - * role("guest")(req2) → false - * - * To check for role1 AND role2, use two middlewares: - * - * [role("role1"), role("role2")] - * +/** Second-order function. + * Returns a middleware that checks if the user has access to + * `operation` in the project identified by `req.params.project` */ -async function role (required_role) { - - const roles = Array.isArray(required_role) - ? required_role - : [ required_role ]; - - function check (user_role) { - if (Array.isArray(user_role)) { - return user_role.some(check); - } else { - return roles.includes(user_role); - } - } - - return (req, res, next) => { - if (req.user && check(req.user?.role)) { - next(); +function operation (operation) { + return async function (req, res, next) { + if (req.user) { + if (req.params.project) { + if (await orgAccess(req.user.organisations, req.params.project, operation)) { + next(); + return; + } + } else { + next(); + return; + } } next({status: 403, message: "Access denied"}); - }; + } } +const read = operation('read'); +const write = operation('write'); +const edit = operation('edit'); +const admin = edit; + module.exports = { read, write, + edit, admin, - role };