Validate token scopes

This commit is contained in:
Johannes Zellner
2022-09-23 12:57:13 +02:00
parent 56c567ac86
commit 70d3040135
4 changed files with 39 additions and 40 deletions

View File

@@ -8,8 +8,8 @@ exports = module.exports = {
authorizeOperator,
};
const accesscontrol = require('../accesscontrol.js'),
apps = require('../apps.js'),
const apps = require('../apps.js'),
tokens = require('../tokens.js'),
assert = require('assert'),
BoxError = require('../boxerror.js'),
externalLdap = require('../externalldap.js'),
@@ -58,27 +58,32 @@ async function passwordAuth(req, res, next) {
}
async function tokenAuth(req, res, next) {
let token;
let accessToken;
// this determines the priority
if (req.body && req.body.access_token) token = req.body.access_token;
if (req.query && req.query.access_token) token = req.query.access_token;
if (req.body && req.body.access_token) accessToken = req.body.access_token;
if (req.query && req.query.access_token) accessToken = req.query.access_token;
if (req.headers && req.headers.authorization) {
const parts = req.headers.authorization.split(' ');
if (parts.length == 2) {
const [scheme, credentials] = parts;
if (/^Bearer$/i.test(scheme)) token = credentials;
if (/^Bearer$/i.test(scheme)) accessToken = credentials;
}
}
if (!token) return next(new HttpError(401, 'Token required'));
if (!accessToken) return next(new HttpError(401, 'Token required'));
const [error, user] = await safe(accesscontrol.verifyToken(token));
if (error && error.reason === BoxError.INVALID_CREDENTIALS) return next(new HttpError(401, error.message));
if (error) return next(new HttpError(500, error.message));
const token = await tokens.getByAccessToken(accessToken);
if (!token) return next(new HttpError(401, 'No such token'));
req.access_token = token; // used in logout route
const user = await users.get(token.identifier);
if (!user) return next(new HttpError(401,'User not found'));
if (!user.active) return next(new HttpError(401,'User not active'));
await safe(tokens.update(token.id, { lastUsedTime: new Date() })); // ignore any error
req.token = token;
req.user = user;
next();
@@ -91,6 +96,7 @@ function authorize(requiredRole) {
assert.strictEqual(typeof req.user, 'object');
if (users.compareRoles(req.user.role, requiredRole) < 0) return next(new HttpError(403, `role '${requiredRole}' is required but user has only '${req.user.role}'`));
if (!tokens.hasScope(req.token, req.method, req.path)) return next(new HttpError(403, 'access token does not have this scope'));
next();
};
@@ -101,6 +107,7 @@ async function authorizeOperator(req, res, next) {
assert.strictEqual(typeof req.user, 'object');
assert.strictEqual(typeof req.app, 'object');
if (!tokens.hasScope(req.token, req.method, req.path)) return next(new HttpError(403, 'access token does not have this scope'));
if (apps.isOperator(req.app, req.user)) return next();
return next(new HttpError(403, 'user is not an operator'));