Allow multiple args in policies

Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
Alexandre Bodin 2020-07-02 17:52:27 +02:00
parent 1b460c76ff
commit cdc9bc2167
6 changed files with 47 additions and 15 deletions

View File

@ -6,7 +6,7 @@ const {
const { validateHasPermissionsInput } = require('../../validation/policies/hasPermissions');
module.exports = createPolicyFactory(
actions => (ctx, next) => {
(actions, { hasAtLeastOne = false } = {}) => (ctx, next) => {
const {
state: { userAbility, isAuthenticatedAdmin },
params: { model },
@ -16,7 +16,9 @@ module.exports = createPolicyFactory(
return next();
}
const isAuthorized = actions.every(action => userAbility.can(action, model));
const isAuthorized = hasAtLeastOne
? actions.some(action => userAbility.can(action, model))
: actions.every(action => userAbility.can(action, model));
if (!isAuthorized) {
throw strapi.errors.forbidden();

View File

@ -107,7 +107,15 @@
"config": {
"policies": [
"routing",
"admin::isAuthenticatedAdmin"
"admin::isAuthenticatedAdmin",
[
"plugins::content-manager.hasPermissions",
[
"plugins::content-manager.explorer.create",
"plugins::content-manager.explorer.update"
],
{ "hasAtLeastOne": true }
]
]
}
},

View File

@ -17,7 +17,14 @@ describe('ContentManager', () => {
);
const getModel = jest.fn();
global.strapi = { db: { getModel } };
global.strapi = {
db: { getModel },
plugins: {
'content-manager': {
services: {},
},
},
};
await ContentManager.findRelationList(ctx);
@ -39,7 +46,14 @@ describe('ContentManager', () => {
attributes: {},
}));
global.strapi = { db: { getModel } };
global.strapi = {
db: { getModel },
plugins: {
'content-manager': {
services: {},
},
},
};
await ContentManager.findRelationList(ctx);
@ -61,7 +75,14 @@ describe('ContentManager', () => {
const getModel = jest.fn(() => ({
attributes: { target: { model: 'test' } },
}));
global.strapi = { db: { getModel, getModelByAssoc } };
global.strapi = {
db: { getModel, getModelByAssoc },
plugins: {
'content-manager': {
services: {},
},
},
};
await ContentManager.findRelationList(ctx);

View File

@ -4,9 +4,9 @@ const { yup, formatYupErrors } = require('strapi-utils');
const hasPermissionsSchema = yup.array().of(yup.string());
const validateHasPermissionsInput = data => {
const validateHasPermissionsInput = actions => {
try {
return hasPermissionsSchema.validateSync(data, { strict: true, abortEarly: true });
return hasPermissionsSchema.validateSync(actions, { strict: true, abortEarly: true });
} catch (e) {
throw new Error(formatYupErrors(e));
}

View File

@ -19,7 +19,7 @@ const policyExistsIn = (container, policy) => !_.isUndefined(getPolicyIn(contain
const stripPolicy = (policy, prefix) => policy.replace(prefix, '');
const createPolicy = (policyName, args) => ({ policyName, args });
const createPolicy = (policyName, ...args) => ({ policyName, args });
const resolveHandler = policy => (_.isFunction(policy) ? policy : policy.handler);
@ -129,7 +129,7 @@ const get = (policy, plugin, apiName) => {
const resolvedPolicy = resolvePolicy(policyName);
if (resolvedPolicy !== undefined) {
return isPolicyFactory(policy) ? resolvedPolicy(args) : resolvedPolicy;
return isPolicyFactory(policy) ? resolvedPolicy(...args) : resolvedPolicy;
}
const localPolicy = searchLocalPolicy(policy, plugin, apiName);
@ -144,20 +144,20 @@ const get = (policy, plugin, apiName) => {
const createPolicyFactory = (factoryCallback, options) => {
const { validator, name = 'unnamed' } = options;
const validate = args => {
const validate = (...args) => {
try {
validator(args);
validator(...args);
} catch (e) {
throw new Error(`Invalid objects submitted to "${name}" policy.`);
}
};
return args => {
return (...args) => {
if (validator) {
validate(args);
validate(...args);
}
return factoryCallback(args);
return factoryCallback(...args);
};
};

View File

@ -4,6 +4,7 @@ module.exports = ({ params = {}, query = {}, body = {} }, overrides = {}) => ({
params,
query,
request: {
query,
body,
},
...overrides,