@resin/pinejs
Version:
Pine.js is a sophisticated rules-driven API engine that enables you to define rules in a structured subset of English. Those rules are used in order for Pine.js to generate a database schema and the associated [OData](http://www.odata.org/) API. This make
998 lines (964 loc) • 35.2 kB
JavaScript
// Generated by CoffeeScript 1.12.7
(function() {
var BadRequestError, DEFAULT_ACTOR_BIND, DEFAULT_ACTOR_BIND_REGEX, ODataParser, PermissionError, PermissionParsingError, Promise, _, _parsePermissions, addRelationshipBypasses, checkPermissions, collapsePermissionFilters, deepFreezeExceptDefinition, env, generateConstrainedAbstractSql, getPermissionsLookup, memoize, memoizeWeak, memoizedGetConstrainedModel, memoizedParseOdata, metadataEndpoints, methodPermissions, nestedCheck, onceGetter, parsePermissions, ref, ref1, rewriteBinds, rootRead, sqlNameToODataName, userModel,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
_ = require('lodash');
Promise = require('bluebird');
env = require('../config-loader/env');
userModel = require('./user.sbvr');
ref = require('./uri-parser'), metadataEndpoints = ref.metadataEndpoints, memoizedParseOdata = ref.memoizedParseOdata;
ref1 = require('./errors'), BadRequestError = ref1.BadRequestError, PermissionError = ref1.PermissionError, PermissionParsingError = ref1.PermissionParsingError;
ODataParser = require('@resin/odata-parser').ODataParser;
memoize = require('memoizee');
memoizeWeak = require('memoizee/weak');
sqlNameToODataName = require('@resin/odata-to-abstract-sql').sqlNameToODataName;
DEFAULT_ACTOR_BIND = '@__ACTOR_ID';
DEFAULT_ACTOR_BIND_REGEX = new RegExp(_.escapeRegExp(DEFAULT_ACTOR_BIND), 'g');
exports.PermissionError = PermissionError;
exports.PermissionParsingError = PermissionParsingError;
exports.root = {
user: {
permissions: ['resource.all']
}
};
exports.rootRead = rootRead = {
user: {
permissions: ['resource.get']
}
};
methodPermissions = {
GET: {
or: ['get', 'read']
},
PUT: {
or: [
'set', {
and: ['create', 'update']
}
]
},
POST: {
or: ['set', 'create']
},
PATCH: {
or: ['set', 'update']
},
MERGE: {
or: ['set', 'update']
},
DELETE: 'delete'
};
_parsePermissions = (function() {
var odataParser;
odataParser = ODataParser.createInstance();
return memoize(function(filter) {
var tree;
odataParser.binds = [];
tree = odataParser.matchAll(['FilterByExpression', filter], 'ProcessRule');
return {
tree: tree,
extraBinds: odataParser.binds
};
}, {
primitive: true,
max: env.cache.parsePermissions.max
});
})();
rewriteBinds = function(arg, odataBinds) {
var bindsLength, extraBinds, tree;
tree = arg.tree, extraBinds = arg.extraBinds;
bindsLength = odataBinds.length;
odataBinds.push.apply(odataBinds, extraBinds);
return _.cloneDeepWith(tree, function(value) {
var bind;
bind = value != null ? value.bind : void 0;
if (_.isInteger(bind)) {
return {
bind: value.bind + bindsLength
};
}
});
};
parsePermissions = function(filter, odataBinds) {
var odata;
odata = _parsePermissions(filter);
return rewriteBinds(odata, odataBinds);
};
exports.nestedCheck = nestedCheck = function(check, stringCallback) {
var checkType, checkTypes, i, j, len, len1, ref2, result, results, subcheck;
if (_.isString(check)) {
return stringCallback(check);
} else if (_.isBoolean(check)) {
return check;
} else if (_.isArray(check)) {
results = [];
for (i = 0, len = check.length; i < len; i++) {
subcheck = check[i];
result = nestedCheck(subcheck, stringCallback);
if (result === false) {
return false;
} else if (result !== true) {
results = results.concat(result);
}
}
if (results.length === 1) {
return results[0];
} else if (results.length > 1) {
return _.uniq(results);
} else {
return true;
}
} else if (_.isObject(check)) {
checkTypes = _.keys(check);
if (checkTypes.length > 1) {
throw new Error('More than one check type: ' + checkTypes);
}
checkType = checkTypes[0];
switch (checkType.toUpperCase()) {
case 'AND':
return nestedCheck(check[checkType], stringCallback);
case 'OR':
results = [];
ref2 = check[checkType];
for (j = 0, len1 = ref2.length; j < len1; j++) {
subcheck = ref2[j];
result = nestedCheck(subcheck, stringCallback);
if (result === true) {
return true;
} else if (result !== false) {
results = results.concat(result);
}
}
if (results.length === 1) {
return results[0];
} else if (results.length > 1) {
return _.uniq(results);
} else {
return false;
}
break;
default:
throw new Error('Cannot parse required checking logic: ' + checkType);
}
} else {
throw new Error('Cannot parse required checks: ' + check);
}
};
collapsePermissionFilters = function(v) {
if (_.isArray(v)) {
return collapsePermissionFilters({
or: v
});
} else if (_.isObject(v)) {
if (v.hasOwnProperty('filter')) {
return v.filter;
} else {
return _(v).toPairs().flattenDeep().map(collapsePermissionFilters).value();
}
} else {
return v;
}
};
addRelationshipBypasses = function(relationships) {
return _.each(relationships, function(relationship, key) {
var mapping;
if (key === '$') {
return;
}
mapping = relationship.$;
if ((mapping != null) && mapping.length === 2) {
mapping = _.cloneDeep(mapping);
mapping[1][0] = mapping[1][0] + "$bypass";
relationships[key + "$bypass"] = {
$: mapping
};
}
return addRelationshipBypasses(relationship);
});
};
getPermissionsLookup = memoize(function(permissions) {
var condition, i, len, permission, permissionsLookup, ref2, target;
permissionsLookup = {};
for (i = 0, len = permissions.length; i < len; i++) {
permission = permissions[i];
ref2 = permission.split('?'), target = ref2[0], condition = ref2[1];
if (condition == null) {
permissionsLookup[target] = true;
} else if (permissionsLookup[target] !== true) {
if (permissionsLookup[target] == null) {
permissionsLookup[target] = [];
}
permissionsLookup[target].push(condition);
}
}
return permissionsLookup;
}, {
primitive: true,
max: env.cache.permissionsLookup.max
});
checkPermissions = function(permissionsLookup, actionList, vocabulary, resourceName) {
var checkObject;
checkObject = {
or: ['all', actionList]
};
return nestedCheck(checkObject, function(permissionCheck) {
var conditionalPermissions, resourcePermission, vocabularyPermission, vocabularyResourcePermission;
resourcePermission = permissionsLookup['resource.' + permissionCheck];
if (resourcePermission === true) {
return true;
}
if (vocabulary != null) {
vocabularyPermission = permissionsLookup[vocabulary + '.' + permissionCheck];
if (vocabularyPermission === true) {
return true;
}
if (resourceName != null) {
vocabularyResourcePermission = permissionsLookup[vocabulary + '.' + resourceName + '.' + permissionCheck];
if (vocabularyResourcePermission === true) {
return true;
}
}
}
conditionalPermissions = [].concat(resourcePermission, vocabularyPermission, vocabularyResourcePermission);
conditionalPermissions = _.filter(conditionalPermissions);
if (conditionalPermissions.length === 1) {
return conditionalPermissions[0];
} else if (conditionalPermissions.length > 1) {
return {
or: conditionalPermissions
};
}
return false;
});
};
generateConstrainedAbstractSql = function(permissionsLookup, actionList, vocabulary, resourceName) {
var abstractSqlQuery, conditionalPerms, odata, odataBinds, permissionFilters, ref2, select, selectIndex, uriParser;
uriParser = require('./uri-parser');
conditionalPerms = checkPermissions(permissionsLookup, actionList, vocabulary, resourceName);
if (conditionalPerms === false) {
throw new PermissionError();
}
if (conditionalPerms === true) {
return false;
}
odata = memoizedParseOdata("/" + resourceName);
permissionFilters = nestedCheck(conditionalPerms, function(permissionCheck) {
var e;
try {
permissionCheck = parsePermissions(permissionCheck, odata.binds);
return {
filter: permissionCheck
};
} catch (error) {
e = error;
console.warn('Failed to parse conditional permissions: ', permissionCheck);
throw new PermissionParsingError(e);
}
});
permissionFilters = collapsePermissionFilters(permissionFilters);
_.set(odata, ['tree', 'options', '$filter'], permissionFilters);
ref2 = uriParser.translateUri({
method: 'GET',
resourceName: resourceName,
vocabulary: vocabulary,
odataBinds: odata.binds,
odataQuery: odata.tree,
values: {}
}), odataBinds = ref2.odataBinds, abstractSqlQuery = ref2.abstractSqlQuery;
abstractSqlQuery = _.clone(abstractSqlQuery);
selectIndex = _.findIndex(abstractSqlQuery, {
0: 'Select'
});
select = abstractSqlQuery[selectIndex] = _.clone(abstractSqlQuery[selectIndex]);
select[1] = _.map(select[1], function(selectField) {
if (selectField.length === 2 && _.isArray(selectField[0])) {
return selectField[0];
}
return selectField;
});
return {
extraBinds: odataBinds,
abstractSqlQuery: abstractSqlQuery
};
};
onceGetter = function(obj, propName, fn) {
var thrownErr;
thrownErr = void 0;
return Object.defineProperty(obj, propName, {
enumerable: true,
configurable: true,
get: function() {
var result;
if (thrownErr != null) {
throw thrownErr;
}
try {
result = fn();
fn = void 0;
delete this[propName];
return this[propName] = result;
} catch (error) {
thrownErr = error;
throw thrownErr;
}
}
});
};
deepFreezeExceptDefinition = function(obj) {
Object.freeze(obj);
Object.getOwnPropertyNames(obj).forEach(function(prop) {
var ref2;
if (prop !== 'definition' && obj.hasOwnProperty(prop) && obj[prop] !== null && ((ref2 = typeof obj[prop]) !== 'object' && ref2 !== 'function')) {
return deepFreezeExceptDefinition(obj);
}
});
};
memoizedGetConstrainedModel = memoizeWeak(function(abstractSqlModel, permissionsLookup, vocabulary) {
abstractSqlModel = _.cloneDeep(abstractSqlModel);
addRelationshipBypasses(abstractSqlModel.relationships);
_.each(abstractSqlModel.synonyms, function(canonicalForm, synonym) {
return abstractSqlModel.synonyms[synonym + "$bypass"] = canonicalForm + "$bypass";
});
addRelationshipBypasses(abstractSqlModel.relationships);
_.each(abstractSqlModel.relationships, function(relationship, key) {
return abstractSqlModel.relationships[key + "$bypass"] = relationship;
});
_.each(abstractSqlModel.tables, function(table) {
abstractSqlModel.tables[table.resourceName + "$bypass"] = _.clone(table);
return onceGetter(table, 'definition', function() {
return generateConstrainedAbstractSql(permissionsLookup, methodPermissions.GET, vocabulary, sqlNameToODataName(table.name));
});
});
deepFreezeExceptDefinition(abstractSqlModel);
return abstractSqlModel;
}, {
normalizer: function(abstractSqlModel, args) {
return JSON.stringify(args);
}
});
exports.config = {
models: [
{
apiRoot: 'Auth',
modelText: userModel,
customServerCode: exports
}
]
};
exports.setup = function(app, sbvrUtils) {
var addODataPermissions, addPermissions, apiKeyMiddleware, checkApiKey, customApiKeyMiddleware, customAuthorizationMiddleware, getApiKeyActorId, getApiKeyPermissions, getPermissions, getReqPermissions, getUserPermissions, memoizedRewriteODataOptions, parseRewrittenPermissions, resolveSubRequest;
sbvrUtils.addPureHook('all', 'all', 'all', {
PREPARSE: function(arg) {
var req;
req = arg.req;
return apiKeyMiddleware(req);
},
POSTPARSE: function(arg) {
var abstractSqlModel, action, idField, method, ref2, ref3, req, request, resourceName, resourceTable;
req = arg.req, request = arg.request;
if (request.abstractSqlQuery != null) {
return;
}
if (request.method === 'POST' && ((ref2 = request.odataQuery.property) != null ? ref2.resource : void 0) === 'canAccess') {
if (request.odataQuery.key == null) {
throw new BadRequestError();
}
ref3 = request.values, action = ref3.action, method = ref3.method;
if ((method != null) && (action != null)) {
throw new BadRequestError();
} else if ((method != null) && (methodPermissions[method] != null)) {
request.permissionType = methodPermissions[method];
} else if (action != null) {
request.permissionType = action;
} else {
throw new BadRequestError();
}
abstractSqlModel = sbvrUtils.getAbstractSqlModel(request);
request.resourceName = request.resourceName.slice(0, -'#canAccess'.length);
resourceName = sbvrUtils.resolveSynonym(request);
resourceTable = abstractSqlModel.tables[resourceName];
if (resourceTable == null) {
throw new Error('Unknown resource: ' + request.resourceName);
}
idField = resourceTable.idField;
request.odataQuery.options = {
'$select': {
'properties': [
{
'name': idField
}
]
},
$top: 1
};
request.odataQuery.resource = request.resourceName;
delete request.odataQuery.property;
request.method = 'GET';
request.custom.isAction = 'canAccess';
}
return addPermissions(req, request);
},
PRERESPOND: function(arg) {
var data, request;
request = arg.request, data = arg.data;
if (request.custom.isAction === 'canAccess') {
if (_.isEmpty(data)) {
throw new PermissionError();
}
}
}
});
sbvrUtils.addPureHook('POST', 'Auth', 'user', {
POSTPARSE: function(arg) {
var api, request;
request = arg.request, api = arg.api;
return api.post({
resource: 'actor',
options: {
returnResource: false
}
}).then(function(result) {
return request.values.actor = result.id;
});
}
});
sbvrUtils.addPureHook('DELETE', 'Auth', 'user', {
POSTRUN: function(arg) {
var api, request;
request = arg.request, api = arg.api;
return api["delete"]({
resource: 'actor',
id: request.values.actor
});
}
});
exports.checkPassword = function(username, password, callback) {
var authApi;
authApi = sbvrUtils.api.Auth;
return authApi.get({
resource: 'user',
passthrough: {
req: rootRead
},
options: {
$select: ['id', 'actor', 'password'],
$filter: {
username: username
}
}
}).then(function(result) {
var actorId, hash, userId;
if (result.length === 0) {
throw new Error('User not found');
}
hash = result[0].password;
userId = result[0].id;
actorId = result[0].actor;
return sbvrUtils.sbvrTypes.Hashed.compare(password, hash).then(function(res) {
if (!res) {
throw new Error('Passwords do not match');
}
return getUserPermissions(userId).then(function(permissions) {
return {
id: userId,
actor: actorId,
username: username,
permissions: permissions
};
});
});
}).nodeify(callback);
};
getPermissions = function(permsFilter, callback) {
var authApi;
authApi = sbvrUtils.api.Auth;
return authApi.get({
resource: 'permission',
passthrough: {
req: rootRead
},
options: {
$select: 'name',
$filter: permsFilter,
$orderby: {
name: 'asc'
}
}
}).map(function(permission) {
return permission.name;
}).tapCatch(function(err) {
return authApi.logger.error('Error loading permissions', err, err.stack);
}).nodeify(callback);
};
exports.getUserPermissions = getUserPermissions = function(userId, callback) {
var permsFilter;
if (_.isString(userId)) {
userId = _.parseInt(userId);
}
if (!_.isFinite(userId)) {
return Promise.rejected(new Error('User ID has to be numeric, got: ' + typeof userId));
}
permsFilter = {
$or: {
is_of__user: {
$any: {
$alias: 'uhp',
$expr: {
uhp: {
user: userId
},
$or: [
{
uhp: {
expiry_date: null
}
}, {
uhp: {
expiry_date: {
$gt: {
$now: null
}
}
}
}
]
}
}
},
is_of__role: {
$any: {
$alias: 'rhp',
$expr: {
rhp: {
role: {
$any: {
$alias: 'r',
$expr: {
r: {
is_of__user: {
$any: {
$alias: 'uhr',
$expr: {
uhr: {
user: userId
},
$or: [
{
uhr: {
expiry_date: null
}
}, {
uhr: {
expiry_date: {
$gt: {
$now: null
}
}
}
}
]
}
}
}
}
}
}
}
}
}
}
}
}
};
return getPermissions(permsFilter, callback);
};
exports.getApiKeyPermissions = getApiKeyPermissions = (function() {
var _getApiKeyPermissions;
_getApiKeyPermissions = memoize(function(apiKey) {
var permsFilter;
permsFilter = {
$or: {
is_of__api_key: {
$any: {
$alias: 'khp',
$expr: {
khp: {
api_key: {
$any: {
$alias: 'k',
$expr: {
k: {
key: apiKey
}
}
}
}
}
}
}
},
is_of__role: {
$any: {
$alias: 'rhp',
$expr: {
'rhp': {
role: {
$any: {
$alias: 'r',
$expr: {
r: {
is_of__api_key: {
$any: {
$alias: 'khr',
$expr: {
khr: {
api_key: {
$any: {
$alias: 'k',
$expr: {
k: {
key: apiKey
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
};
return getPermissions(permsFilter);
}, {
primitive: true,
max: env.cache.apiKeys.max,
maxAge: env.cache.apiKeys.maxAge
});
return function(apiKey, callback) {
var promise;
promise = _.isString(apiKey) ? _getApiKeyPermissions(apiKey) : Promise.rejected(new Error('API key has to be a string, got: ' + typeof apiKey));
return promise.nodeify(callback);
};
})();
getApiKeyActorId = memoize(function(apiKey) {
return sbvrUtils.api.Auth.get({
resource: 'api_key',
passthrough: {
req: rootRead
},
options: {
$select: 'is_of__actor',
$filter: {
key: apiKey
}
}
}).then(function(apiKeys) {
var apiKeyActorID;
if (apiKeys.length === 0) {
throw new Error('Could not find the api key');
}
apiKeyActorID = apiKeys[0].is_of__actor.__id;
if (apiKeyActorID == null) {
throw new Error('API key is not linked to a actor?!');
}
return apiKeyActorID;
});
}, {
primitive: true,
promise: true,
maxAge: env.cache.apiKeys.maxAge
});
checkApiKey = function(req, apiKey) {
return Promise["try"](function() {
if ((apiKey == null) || (req.apiKey != null)) {
return;
}
return getApiKeyPermissions(apiKey)["catch"](function(err) {
console.warn('Error with API key:', err);
return [];
}).then(function(permissions) {
return req.apiKey = {
key: apiKey,
permissions: permissions
};
});
});
};
exports.customAuthorizationMiddleware = customAuthorizationMiddleware = function(expectedScheme) {
if (expectedScheme == null) {
expectedScheme = 'Bearer';
}
expectedScheme = expectedScheme.toLowerCase();
return function(req, res, next) {
return Promise["try"](function() {
var apiKey, auth, parts, scheme;
auth = req.header('Authorization');
if (!auth) {
return;
}
parts = auth.split(' ');
if (parts.length !== 2) {
return;
}
scheme = parts[0], apiKey = parts[1];
if (scheme.toLowerCase() !== expectedScheme) {
return;
}
return checkApiKey(req, apiKey);
}).then(function() {
if (typeof next === "function") {
next();
}
});
};
};
exports.authorizationMiddleware = customAuthorizationMiddleware();
exports.customApiKeyMiddleware = customApiKeyMiddleware = function(paramName) {
if (paramName == null) {
paramName = 'apikey';
}
return function(req, res, next) {
var apiKey, ref2, ref3;
apiKey = (ref2 = (ref3 = req.params[paramName]) != null ? ref3 : req.body[paramName]) != null ? ref2 : req.query[paramName];
return checkApiKey(req, apiKey).then(function() {
if (typeof next === "function") {
next();
}
});
};
};
exports.apiKeyMiddleware = apiKeyMiddleware = customApiKeyMiddleware();
exports.checkPermissions = function(req, actionList, resourceName, vocabulary) {
return getReqPermissions(req).then(function(permissionsLookup) {
return checkPermissions(permissionsLookup, actionList, vocabulary, resourceName);
});
};
exports.checkPermissionsMiddleware = function(action) {
return function(req, res, next) {
return exports.checkPermissions(req, action).then(function(allowed) {
switch (allowed) {
case false:
return res.sendStatus(401);
case true:
return next();
default:
throw new Error('checkPermissionsMiddleware returned a conditional permission');
}
})["catch"](function(err) {
sbvrUtils.api.Auth.logger.error('Error checking permissions', err, err.stack);
return res.sendStatus(503);
});
};
};
getReqPermissions = (function() {
var _getGuestPermissions;
_getGuestPermissions = (function() {
var _guestPermissions;
_guestPermissions = null;
return function() {
if ((_guestPermissions == null) || _guestPermissions.isRejected()) {
_guestPermissions = sbvrUtils.api.Auth.get({
resource: 'user',
passthrough: {
req: rootRead
},
options: {
$select: 'id',
$filter: {
username: 'guest'
}
}
}).then(function(result) {
if (result.length === 0) {
throw new Error('No guest permissions');
}
return getUserPermissions(result[0].id);
});
}
return _guestPermissions;
};
})();
return function(req, odataBinds) {
if (odataBinds == null) {
odataBinds = {};
}
return Promise.join(_getGuestPermissions(), Promise["try"](function() {
var ref2, ref3;
if (((ref2 = req.apiKey) != null ? (ref3 = ref2.permissions) != null ? ref3.length : void 0 : void 0) > 0) {
return getApiKeyActorId(req.apiKey.key);
}
}), function(guestPermissions, apiKeyActorID) {
var actorIndex, addActorPermissions, permissions, ref2, ref3;
if (_.some(guestPermissions, function(p) {
return DEFAULT_ACTOR_BIND_REGEX.test(p);
})) {
throw new Error('Guest permissions cannot reference actors');
}
permissions = guestPermissions;
actorIndex = 0;
addActorPermissions = function(actorId, actorPermissions) {
var actorBind;
actorBind = DEFAULT_ACTOR_BIND;
if (actorIndex > 0) {
actorBind += actorIndex;
actorPermissions = _.map(actorPermissions, function(actorPermission) {
return actorPermission.replace(DEFAULT_ACTOR_BIND_REGEX, actorBind);
});
}
odataBinds[actorBind] = ['Real', actorId];
actorIndex++;
return permissions = permissions.concat(actorPermissions);
};
if (((ref2 = req.user) != null ? ref2.permissions : void 0) != null) {
addActorPermissions(req.user.actor, req.user.permissions);
}
if (((ref3 = req.apiKey) != null ? ref3.permissions : void 0) != null) {
addActorPermissions(apiKeyActorID, req.apiKey.permissions);
}
permissions = _.uniq(permissions);
return getPermissionsLookup(permissions);
});
};
})();
resolveSubRequest = function(request, lambda, propertyName, v) {
var newResourceName, ref2;
if (lambda[propertyName] == null) {
v.name = propertyName + "$bypass";
}
newResourceName = (ref2 = lambda[propertyName]) != null ? ref2 : sbvrUtils.resolveNavigationResource(request, propertyName);
return {
abstractSqlModel: request.abstractSqlModel,
vocabulary: request.vocabulary,
resourceName: newResourceName
};
};
memoizedRewriteODataOptions = (function() {
var rewriteODataOptions;
rewriteODataOptions = function(request, data, lambda) {
if (lambda == null) {
lambda = {};
}
return _.each(data, function(v, k) {
var newLambda, propertyName, subRequest;
if (_.isArray(v)) {
return rewriteODataOptions(request, v, lambda);
} else if (_.isObject(v)) {
propertyName = v.name;
if (propertyName != null) {
if (v.lambda != null) {
newLambda = _.clone(lambda);
newLambda[v.lambda.identifier] = sbvrUtils.resolveNavigationResource(request, propertyName);
subRequest = resolveSubRequest(request, lambda, propertyName, v);
return rewriteODataOptions(subRequest, v, newLambda);
} else if (v.options != null) {
return _.each(v.options, function(option, optionName) {
subRequest = resolveSubRequest(request, lambda, propertyName, v);
return rewriteODataOptions(subRequest, option, lambda);
});
} else if (v.property != null) {
subRequest = resolveSubRequest(request, lambda, propertyName, v);
return rewriteODataOptions(subRequest, v, lambda);
} else {
return rewriteODataOptions(request, v, lambda);
}
} else {
return rewriteODataOptions(request, v, lambda);
}
}
});
};
return memoizeWeak(function(abstractSqlModel, vocabulary, resourceName, filter, tree) {
tree = _.cloneDeep(tree);
rewriteODataOptions({
abstractSqlModel: abstractSqlModel,
vocabulary: vocabulary,
resourceName: resourceName
}, [tree]);
return tree;
}, {
normalizer: function(abstractSqlModel, arg) {
var filter, resourceName, vocabulary;
vocabulary = arg[0], resourceName = arg[1], filter = arg[2];
return filter + vocabulary + resourceName;
}
});
})();
parseRewrittenPermissions = function(abstractSqlModel, vocabulary, resourceName, filter, odataBinds) {
var extraBinds, ref2, tree;
ref2 = _parsePermissions(filter), tree = ref2.tree, extraBinds = ref2.extraBinds;
tree = memoizedRewriteODataOptions(abstractSqlModel, vocabulary, resourceName, filter, tree);
return rewriteBinds({
tree: tree,
extraBinds: extraBinds
}, odataBinds);
};
addODataPermissions = function(permissionsLookup, permissionType, vocabulary, resourceName, odataQuery, odataBinds, abstractSqlModel) {
var conditionalPerms, permissionFilters;
conditionalPerms = checkPermissions(permissionsLookup, permissionType, vocabulary, resourceName);
if (conditionalPerms === false) {
throw new PermissionError();
}
if (conditionalPerms !== true) {
permissionFilters = nestedCheck(conditionalPerms, function(permissionCheck) {
var e;
try {
permissionCheck = parseRewrittenPermissions(abstractSqlModel, vocabulary, resourceName, permissionCheck, odataBinds);
return {
filter: permissionCheck
};
} catch (error) {
e = error;
console.warn('Failed to parse conditional permissions: ', permissionCheck);
throw new PermissionParsingError(e);
}
});
if (permissionFilters === false) {
throw new PermissionError();
}
if (permissionFilters !== true) {
permissionFilters = collapsePermissionFilters(permissionFilters);
if (odataQuery.options == null) {
odataQuery.options = {};
}
if (odataQuery.options.$filter != null) {
return odataQuery.options.$filter = ['and', odataQuery.options.$filter, permissionFilters];
} else {
return odataQuery.options.$filter = permissionFilters;
}
}
}
};
return exports.addPermissions = addPermissions = function(req, request) {
var abstractSqlModel, isMetadataEndpoint, method, odataBinds, odataQuery, permissionType, permissions, ref2, ref3, resourceName, vocabulary;
method = request.method, vocabulary = request.vocabulary, resourceName = request.resourceName, permissionType = request.permissionType, odataQuery = request.odataQuery, odataBinds = request.odataBinds;
abstractSqlModel = sbvrUtils.getAbstractSqlModel(request);
method = method.toUpperCase();
isMetadataEndpoint = indexOf.call(metadataEndpoints, resourceName) >= 0 || method === 'OPTIONS';
if (permissionType == null) {
permissionType = isMetadataEndpoint ? 'model' : methodPermissions[method] != null ? methodPermissions[method] : (console.warn('Unknown method for permissions type check: ', method), 'all');
}
permissions = (((ref3 = req.user) != null ? ref3.permissions : void 0) || []).concat(((ref2 = req.apiKey) != null ? ref2.permissions : void 0) || []);
if (permissions.length > 0 && checkPermissions(getPermissionsLookup(permissions), permissionType, vocabulary) === true) {
return;
}
return getReqPermissions(req, odataBinds).then(function(permissionsLookup) {
var sqlName;
request.abstractSqlModel = abstractSqlModel = memoizedGetConstrainedModel(abstractSqlModel, permissionsLookup, vocabulary);
if (!_.isEqual(permissionType, methodPermissions.GET)) {
sqlName = sbvrUtils.resolveSynonym(request);
odataQuery.resource = sqlName + "$bypass";
return addODataPermissions(permissionsLookup, permissionType, vocabulary, resourceName, odataQuery, odataBinds, abstractSqlModel);
}
});
};
};
}).call(this);
//# sourceMappingURL=permissions.js.map