Validate token scopes
This commit is contained in:
@@ -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'));
|
||||
|
||||
Reference in New Issue
Block a user