2022-08-18 12:43:38 +03:00

98 lines
2.4 KiB
JavaScript

'use strict';
const { cloneDeep, has } = require('lodash/fp');
const { hooks } = require('@strapi/utils');
const domain = require('../domain');
/**
* Create a hook map used by the permission Engine
*
* @return {import('../..').PermissionEngineHooks}
*/
const createEngineHooks = () => ({
'before-format::validate.permission': hooks.createAsyncBailHook(),
'format.permission': hooks.createAsyncSeriesWaterfallHook(),
'after-format::validate.permission': hooks.createAsyncBailHook(),
'before-evaluate.permission': hooks.createAsyncSeriesHook(),
'before-register.permission': hooks.createAsyncSeriesHook(),
});
/**
* Create a context from a domain {@link Permission} used by the validate hooks
* @param {Permission} permission
* @return {{ readonly permission: Permission }}
*/
const createValidateContext = (permission) => ({
get permission() {
return cloneDeep(permission);
},
});
/**
* Create a context from a domain {@link Permission} used by the before valuate hook
* @param {Permission} permission
* @return {{readonly permission: Permission, addCondition(string): this}}
*/
const createBeforeEvaluateContext = (permission) => ({
get permission() {
return cloneDeep(permission);
},
addCondition(condition) {
Object.assign(permission, domain.permission.addCondition(condition, permission));
return this;
},
});
/**
* Create a context from a casl Permission & some options
* @param caslPermission
* @param {object} options
* @param {Permission} options.permission
* @param {object} options.user
*/
const createWillRegisterContext = ({ permission, options }) => ({
...options,
get permission() {
return cloneDeep(permission);
},
condition: {
and(rawConditionObject) {
if (!permission.condition) {
Object.assign(permission, { condition: { $and: [] } });
}
permission.condition.$and.push(rawConditionObject);
return this;
},
or(rawConditionObject) {
if (!permission.condition) {
Object.assign(permission, { condition: { $and: [] } });
}
const orClause = permission.condition.$and.find(has('$or'));
if (orClause) {
orClause.$or.push(rawConditionObject);
} else {
permission.condition.$and.push({ $or: [rawConditionObject] });
}
return this;
},
},
});
module.exports = {
createEngineHooks,
createValidateContext,
createBeforeEvaluateContext,
createWillRegisterContext,
};