2018-04-26 15:54:53 -07:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
exports = module.exports = {
|
|
|
|
|
// keep this in sync with start.sh ADMIN_SCOPES that generates the cid-webadmin
|
|
|
|
|
SCOPE_APPS: 'apps',
|
|
|
|
|
SCOPE_DEVELOPER: 'developer', // obsolete
|
|
|
|
|
SCOPE_PROFILE: 'profile',
|
|
|
|
|
SCOPE_CLOUDRON: 'cloudron',
|
|
|
|
|
SCOPE_SETTINGS: 'settings',
|
|
|
|
|
SCOPE_USERS: 'users',
|
|
|
|
|
SCOPE_MAIL: 'mail',
|
|
|
|
|
SCOPE_CLIENTS: 'clients',
|
2018-04-29 18:09:41 -07:00
|
|
|
SCOPE_DOMAINS: 'domains',
|
2018-04-26 15:54:53 -07:00
|
|
|
|
2018-04-27 21:47:11 -07:00
|
|
|
SCOPE_ANY: '*',
|
|
|
|
|
|
2018-04-26 15:54:53 -07:00
|
|
|
validateScope: validateScope,
|
2018-04-30 21:21:18 -07:00
|
|
|
validateRequestedScopes: validateRequestedScopes,
|
|
|
|
|
normalizeScope: normalizeScope
|
2018-04-26 15:54:53 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var assert = require('assert'),
|
2018-04-30 21:21:18 -07:00
|
|
|
debug = require('debug')('box:accesscontrol'),
|
|
|
|
|
_ = require('underscore');
|
2018-04-26 15:54:53 -07:00
|
|
|
|
|
|
|
|
function validateScope(scope) {
|
|
|
|
|
assert.strictEqual(typeof scope, 'string');
|
|
|
|
|
|
|
|
|
|
var VALID_SCOPES = [
|
|
|
|
|
exports.SCOPE_APPS,
|
|
|
|
|
exports.SCOPE_DEVELOPER,
|
|
|
|
|
exports.SCOPE_PROFILE,
|
|
|
|
|
exports.SCOPE_CLOUDRON,
|
|
|
|
|
exports.SCOPE_SETTINGS,
|
|
|
|
|
exports.SCOPE_USERS,
|
2018-04-29 18:09:41 -07:00
|
|
|
exports.SCOPE_DOMAIN,
|
|
|
|
|
exports.SCOPE_CLIENTS,
|
|
|
|
|
exports.SCOPE_MAIL,
|
2018-04-30 23:03:28 -07:00
|
|
|
exports.SCOPE_ANY // includes all scopes
|
2018-04-26 15:54:53 -07:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
if (scope === '') return new Error('Empty scope not allowed');
|
|
|
|
|
|
|
|
|
|
var allValid = scope.split(',').every(function (s) { return VALID_SCOPES.indexOf(s) !== -1; });
|
|
|
|
|
if (!allValid) return new Error('Invalid scope. Available scopes are ' + VALID_SCOPES.join(', '));
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// tests if all requestedScopes are attached to the request
|
|
|
|
|
function validateRequestedScopes(authInfo, requestedScopes) {
|
|
|
|
|
assert.strictEqual(typeof authInfo, 'object');
|
|
|
|
|
assert(Array.isArray(requestedScopes));
|
|
|
|
|
|
|
|
|
|
if (!authInfo || !authInfo.scope) return new Error('No scope found');
|
|
|
|
|
|
|
|
|
|
var scopes = authInfo.scope.split(',');
|
|
|
|
|
|
2018-04-30 21:44:24 -07:00
|
|
|
if (scopes.indexOf(exports.SCOPE_ANY) !== -1) return null;
|
2018-04-26 15:54:53 -07:00
|
|
|
|
|
|
|
|
for (var i = 0; i < requestedScopes.length; ++i) {
|
|
|
|
|
if (scopes.indexOf(requestedScopes[i]) === -1) {
|
|
|
|
|
debug('scope: missing scope "%s".', requestedScopes[i]);
|
|
|
|
|
return new Error('Missing required scope "' + requestedScopes[i] + '"');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2018-04-30 21:21:18 -07:00
|
|
|
|
2018-05-01 13:17:34 -07:00
|
|
|
function normalizeScope(allowedScope, wantedScope) {
|
2018-04-30 21:21:18 -07:00
|
|
|
assert.strictEqual(typeof allowedScope, 'string');
|
2018-05-01 13:17:34 -07:00
|
|
|
assert.strictEqual(typeof wantedScope, 'string');
|
2018-04-30 21:21:18 -07:00
|
|
|
|
2018-04-30 22:06:51 -07:00
|
|
|
const allowedScopes = allowedScope.split(',');
|
2018-05-01 13:17:34 -07:00
|
|
|
const wantedScopes = wantedScope.split(',');
|
2018-04-30 21:21:18 -07:00
|
|
|
|
2018-05-01 13:17:34 -07:00
|
|
|
if (allowedScopes.indexOf(exports.SCOPE_ANY) !== -1) return wantedScope;
|
|
|
|
|
if (wantedScopes.indexOf(exports.SCOPE_ANY) !== -1) return allowedScope;
|
2018-04-30 22:06:51 -07:00
|
|
|
|
2018-05-01 13:17:34 -07:00
|
|
|
return _.intersection(allowedScopes, wantedScopes).join(',');
|
2018-04-30 21:21:18 -07:00
|
|
|
}
|