mirror of
https://github.com/strapi/strapi.git
synced 2025-07-24 17:40:18 +00:00
Add Publish permission & action
Signed-off-by: Convly <jean-sebastien.herbaux@epitech.eu>
This commit is contained in:
parent
38d896f0ea
commit
310a0d16f3
@ -10,8 +10,15 @@ const actionFields = [
|
||||
'pluginName',
|
||||
'subjects',
|
||||
'conditions',
|
||||
'options',
|
||||
];
|
||||
|
||||
const defaultAction = {
|
||||
options: {
|
||||
fieldsGranularity: true,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a prefixed id that depends on the pluginName
|
||||
* @param {Object} params
|
||||
@ -19,15 +26,13 @@ const actionFields = [
|
||||
* @param {Object} params.uid - uid defined by the developer
|
||||
*/
|
||||
const getActionId = ({ pluginName, uid }) => {
|
||||
let id = '';
|
||||
if (pluginName === 'admin') {
|
||||
id = `admin::${uid}`;
|
||||
return `admin::${uid}`;
|
||||
} else if (pluginName) {
|
||||
id = `plugins::${pluginName}.${uid}`;
|
||||
} else {
|
||||
id = `application::${uid}`;
|
||||
return `plugins::${pluginName}.${uid}`;
|
||||
}
|
||||
return id;
|
||||
|
||||
return `application::${uid}`;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -42,7 +47,7 @@ function createAction(attributes) {
|
||||
action.subCategory = attributes.subCategory || 'general';
|
||||
}
|
||||
|
||||
return action;
|
||||
return _.merge(action, defaultAction);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -1,10 +1,9 @@
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const domain = require('../../domain/action');
|
||||
const actionProviderService = require('../permission/action-provider');
|
||||
|
||||
describe('Action Provider Service', () => {
|
||||
const createdActions = [];
|
||||
|
||||
beforeEach(() => {
|
||||
global.strapi = {
|
||||
plugins: { aPlugin: {} },
|
||||
@ -37,8 +36,6 @@ describe('Action Provider Service', () => {
|
||||
..._.omit(readAction, ['uid']),
|
||||
actionId: 'admin::marketplace.read',
|
||||
});
|
||||
|
||||
createdActions.push(createdAction);
|
||||
});
|
||||
|
||||
test('Can register a settings action without subCategory', async () => {
|
||||
@ -50,7 +47,6 @@ describe('Action Provider Service', () => {
|
||||
actionId: 'admin::marketplace.create',
|
||||
subCategory: 'general',
|
||||
});
|
||||
createdActions.push(createdAction);
|
||||
});
|
||||
|
||||
test('Can get all registered entries (array)', () => {
|
||||
@ -61,6 +57,12 @@ describe('Action Provider Service', () => {
|
||||
expect(actionProviderService.getAllByMap().size).toBe(2);
|
||||
});
|
||||
|
||||
test('Can get an action by its actionId', () => {
|
||||
const actionId = 'admin::marketplace.create';
|
||||
const expected = domain.createAction(createAction);
|
||||
expect(actionProviderService.getByActionId(actionId)).toStrictEqual(expected);
|
||||
});
|
||||
|
||||
test('Can register a settings action with a pluginName other than "admin"', async () => {
|
||||
const action = {
|
||||
uid: 'marketplace.update',
|
||||
|
@ -110,24 +110,20 @@ const getNestedFieldsWithIntermediate = (
|
||||
* @param {array} actions array of actions
|
||||
* @param {object} options
|
||||
* @param {number} options.nestingLevel level of nesting
|
||||
* @param {array} options.fieldsNullFor actionIds where the fields should be null
|
||||
* @param {array} options.restrictedSubjects subjectsId to ignore
|
||||
* @returns {array<permissions>}
|
||||
*/
|
||||
const getPermissionsWithNestedFields = (
|
||||
actions,
|
||||
{ nestingLevel, fieldsNullFor = [], restrictedSubjects = [] } = {}
|
||||
) =>
|
||||
const getPermissionsWithNestedFields = (actions, { nestingLevel, restrictedSubjects = [] } = {}) =>
|
||||
actions.reduce((perms, action) => {
|
||||
action.subjects
|
||||
.filter(subject => !restrictedSubjects.includes(subject))
|
||||
.forEach(contentTypeUid => {
|
||||
const fields = fieldsNullFor.includes(action.actionId)
|
||||
? null
|
||||
: getNestedFields(strapi.contentTypes[contentTypeUid], {
|
||||
const fields = action.options.fieldsGranularity
|
||||
? getNestedFields(strapi.contentTypes[contentTypeUid], {
|
||||
components: strapi.components,
|
||||
nestingLevel,
|
||||
});
|
||||
})
|
||||
: null;
|
||||
perms.push({
|
||||
action: action.actionId,
|
||||
subject: contentTypeUid,
|
||||
@ -143,28 +139,30 @@ const getPermissionsWithNestedFields = (
|
||||
* @param {object} permissions array of existing permissions in db
|
||||
* @param {object} options
|
||||
* @param {number} options.nestingLevel level of nesting
|
||||
* @param {array} options.fieldsNullFor actionIds where the fields should be null
|
||||
* @returns {array<permissions>}
|
||||
*/
|
||||
const cleanPermissionFields = (permissions, { nestingLevel, fieldsNullFor = [] }) =>
|
||||
const cleanPermissionFields = (permissions, { nestingLevel }) =>
|
||||
permissions.map(perm => {
|
||||
let newFields = perm.fields;
|
||||
if (fieldsNullFor.includes(perm.action)) {
|
||||
const { action: actionId, fields, subject } = perm;
|
||||
const action = strapi.admin.services.permission.actionProvider.getByActionId(actionId);
|
||||
let newFields = fields;
|
||||
|
||||
if (!action.options.fieldsGranularity) {
|
||||
newFields = null;
|
||||
} else if (perm.subject && strapi.contentTypes[perm.subject]) {
|
||||
const possiblefields = getNestedFieldsWithIntermediate(strapi.contentTypes[perm.subject], {
|
||||
} else if (subject && strapi.contentTypes[subject]) {
|
||||
const possibleFields = getNestedFieldsWithIntermediate(strapi.contentTypes[subject], {
|
||||
components: strapi.components,
|
||||
nestingLevel,
|
||||
});
|
||||
|
||||
const requiredFields = getNestedFields(strapi.contentTypes[perm.subject], {
|
||||
const requiredFields = getNestedFields(strapi.contentTypes[subject], {
|
||||
components: strapi.components,
|
||||
requiredOnly: true,
|
||||
nestingLevel,
|
||||
existingFields: perm.fields,
|
||||
existingFields: fields,
|
||||
});
|
||||
const badNestedFields = _.uniq([
|
||||
..._.intersection(perm.fields, possiblefields),
|
||||
..._.intersection(fields, possibleFields),
|
||||
...requiredFields,
|
||||
]);
|
||||
newFields = badNestedFields.filter(
|
||||
|
@ -28,7 +28,7 @@ const arePermissionsEqual = (perm1, perm2) =>
|
||||
|
||||
/**
|
||||
* Removes unwanted fields from a permission
|
||||
* @param permission
|
||||
* @param perm
|
||||
* @returns {*}
|
||||
*/
|
||||
const sanitizePermission = perm => ({
|
||||
@ -157,10 +157,7 @@ const cleanPermissionInDatabase = async () => {
|
||||
// Second, clean fields of permissions (add required ones, remove the non-existing anymore ones)
|
||||
const permissionsInDb = dbPermissions.filter(perm => !permissionsToRemoveIds.includes(perm.id));
|
||||
const permissionsWithCleanFields = strapi.admin.services['content-type'].cleanPermissionFields(
|
||||
permissionsInDb,
|
||||
{
|
||||
fieldsNullFor: ['plugins::content-manager.explorer.delete'],
|
||||
}
|
||||
permissionsInDb
|
||||
);
|
||||
|
||||
// Update only the ones that need to be updated
|
||||
@ -197,10 +194,7 @@ const resetSuperAdminPermissions = async () => {
|
||||
const contentTypesActions = allActions.filter(a => a.section === 'contentTypes');
|
||||
|
||||
const permissions = strapi.admin.services['content-type'].getPermissionsWithNestedFields(
|
||||
contentTypesActions,
|
||||
{
|
||||
fieldsNullFor: ['plugins::content-manager.explorer.delete'],
|
||||
}
|
||||
contentTypesActions
|
||||
);
|
||||
|
||||
const otherActions = allActions.filter(a => a.section !== 'contentTypes');
|
||||
|
@ -16,8 +16,16 @@ const createActionProvider = () => {
|
||||
*/
|
||||
get(uid, pluginName) {
|
||||
const actionId = getActionId({ pluginName, uid });
|
||||
const action = actions.get(actionId);
|
||||
return action;
|
||||
return actions.get(actionId);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get an action by its actionId
|
||||
* @param {string} actionId
|
||||
* @returns {Action}
|
||||
*/
|
||||
getByActionId(actionId) {
|
||||
return actions.get(actionId);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@ const registerProviderActionSchema = yup
|
||||
then: yup
|
||||
.array()
|
||||
.of(yup.string())
|
||||
.required(),
|
||||
.requiredAllowEmpty(),
|
||||
otherwise: yup
|
||||
.mixed()
|
||||
.oneOf([undefined], 'subjects should only be defined for the "contentTypes" section'),
|
||||
@ -62,6 +62,9 @@ const registerProviderActionSchema = yup
|
||||
}
|
||||
),
|
||||
}),
|
||||
options: yup.object({
|
||||
fieldsGranularity: yup.boolean(),
|
||||
}),
|
||||
})
|
||||
.noUnknown()
|
||||
);
|
||||
|
@ -94,6 +94,8 @@ const registerPermissions = () => {
|
||||
'content-manager'
|
||||
].services.contenttypes.getDisplayedContentTypesUids();
|
||||
|
||||
const hasDraftAndPublish = uid => strapi.contentTypes[uid].options.draftAndPublish;
|
||||
|
||||
const actions = [
|
||||
{
|
||||
section: 'contentTypes',
|
||||
@ -122,6 +124,19 @@ const registerPermissions = () => {
|
||||
uid: 'explorer.delete',
|
||||
pluginName: 'content-manager',
|
||||
subjects: contentTypesUids,
|
||||
options: {
|
||||
fieldsGranularity: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
section: 'contentTypes',
|
||||
displayName: 'Publish',
|
||||
uid: 'explorer.publish',
|
||||
pluginName: 'content-manager',
|
||||
subjects: contentTypesUids.filter(hasDraftAndPublish),
|
||||
options: {
|
||||
fieldsGranularity: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
section: 'plugins',
|
||||
|
Loading…
x
Reference in New Issue
Block a user