mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 01:47:13 +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
	 Convly
						Convly