From 93fc900e100f9d6ca9b51db21d93629cab3a5337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre=20No=C3=ABl?= Date: Tue, 16 Jun 2020 13:51:34 +0200 Subject: [PATCH] create admin permissions at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pierre Noël --- .../config/functions/bootstrap.js | 45 ++++++++++++++++--- packages/strapi-admin/controllers/role.js | 6 +++ packages/strapi-admin/ee/controllers/role.js | 6 +++ packages/strapi-admin/package.json | 1 + packages/strapi-admin/services/permission.js | 23 ++++++---- yarn.lock | 5 +++ 6 files changed, 71 insertions(+), 15 deletions(-) diff --git a/packages/strapi-admin/config/functions/bootstrap.js b/packages/strapi-admin/config/functions/bootstrap.js index dd7702f7f5..c8fd3d5b64 100644 --- a/packages/strapi-admin/config/functions/bootstrap.js +++ b/packages/strapi-admin/config/functions/bootstrap.js @@ -65,14 +65,8 @@ const createRolesIfNeeded = async () => { return; } - const defaultActionsIds = [ - 'plugins::content-manager.read', - 'plugins::content-manager.create', - 'plugins::content-manager.update', - 'plugins::content-manager.delete', - ]; const allActions = strapi.admin.services.permission.actionProvider.getAll(); - const contentTypesActions = allActions.filter(a => defaultActionsIds.includes(a.actionId)); + const contentTypesActions = allActions.filter(a => a.section === 'contentTypes'); await strapi.admin.services.role.create({ name: 'Super Admin', @@ -131,11 +125,48 @@ const displayWarningIfUsersDontHaveRole = async () => { } }; +const resetSuperAdminPermissions = async () => { + const adminRole = await strapi.admin.services.role.getAdmin(); + if (!adminRole) { + return; + } + + const allActions = strapi.admin.services.permission.actionProvider.getAll(); + const contentTypesActions = allActions.filter(a => a.section === 'contentTypes'); + + const permissions = []; + contentTypesActions.forEach(action => { + _.forIn(strapi.contentTypes, contentType => { + if (action.subjects.includes(contentType.uid)) { + const fields = getNestedFields(contentType.attributes, '', 1); + permissions.push({ + action: action.actionId, + subject: contentType.uid, + fields, + }); + } + }); + }); + + const otherActions = allActions.filter(a => a.section !== 'contentTypes'); + otherActions.forEach(action => { + if (action.subjects) { + const newPerms = action.subjects.map(subject => ({ action: action.actionId, subject })); + permissions.push(...newPerms); + } else { + permissions.push({ action: action.actionId }); + } + }); + + await strapi.admin.services.permission.assign(adminRole.id, permissions); +}; + module.exports = async () => { registerAdminConditions(); registerPermissionActions(); await cleanPermissionInDatabase(); await createRolesIfNeeded(); + await resetSuperAdminPermissions(); await displayWarningIfNoSuperAdmin(); await displayWarningIfUsersDontHaveRole(); }; diff --git a/packages/strapi-admin/controllers/role.js b/packages/strapi-admin/controllers/role.js index 1538fc7705..631becfc7b 100644 --- a/packages/strapi-admin/controllers/role.js +++ b/packages/strapi-admin/controllers/role.js @@ -1,6 +1,7 @@ 'use strict'; const _ = require('lodash'); +const { yup, formatYupErrors } = require('strapi-utils'); const { validateRoleUpdateInput } = require('../validation/role'); const { validatedUpdatePermissionsInput } = require('../validation/permission'); @@ -89,6 +90,11 @@ module.exports = { const input = _.cloneDeep(ctx.request.body); try { + const superAdminRole = await strapi.admin.services.role.getAdmin(); + if (String(superAdminRole.id) === String(id)) { + const err = new yup.ValidationError("Super admin permissions can't be edited."); + throw formatYupErrors(err); + } await validatedUpdatePermissionsInput(input); } catch (err) { ctx.badRequest('ValidationError', err); diff --git a/packages/strapi-admin/ee/controllers/role.js b/packages/strapi-admin/ee/controllers/role.js index ee95d3452a..1bdc2630a2 100644 --- a/packages/strapi-admin/ee/controllers/role.js +++ b/packages/strapi-admin/ee/controllers/role.js @@ -1,5 +1,6 @@ 'use strict'; +const { yup, formatYupErrors } = require('strapi-utils'); const { validateRoleCreateInput, validateRoleUpdateInput, @@ -102,6 +103,11 @@ module.exports = { const input = ctx.request.body; try { + const superAdminRole = await strapi.admin.services.role.getAdmin(); + if (String(superAdminRole.id) === String(id)) { + const err = new yup.ValidationError("Super admin permissions can't be edited."); + throw formatYupErrors(err); + } await validatedUpdatePermissionsInput(input); } catch (err) { return ctx.badRequest('ValidationError', err); diff --git a/packages/strapi-admin/package.json b/packages/strapi-admin/package.json index ed16031904..ce744499d1 100644 --- a/packages/strapi-admin/package.json +++ b/packages/strapi-admin/package.json @@ -45,6 +45,7 @@ "cross-env": "^5.0.5", "css-loader": "^2.1.1", "duplicate-package-checker-webpack-plugin": "^3.0.0", + "es6-promise-pool": "^2.5.0", "execa": "^1.0.0", "file-loader": "^3.0.1", "font-awesome": "^4.7.0", diff --git a/packages/strapi-admin/services/permission.js b/packages/strapi-admin/services/permission.js index 22475cfba3..9b431f791c 100644 --- a/packages/strapi-admin/services/permission.js +++ b/packages/strapi-admin/services/permission.js @@ -1,6 +1,7 @@ 'use strict'; const _ = require('lodash'); +const PromisePool = require('es6-promise-pool'); const { createPermission } = require('../domain/permission'); const actionProvider = require('./action-provider'); const { validatePermissionsExist } = require('../validation/permission'); @@ -43,14 +44,10 @@ const find = (params = {}) => { * @param {Array} permissions - permissions to assign to the role */ const assign = async (roleId, permissions = []) => { - const superAdminRole = await strapi.admin.services.role.getAdmin(); - if (String(superAdminRole.id) === String(roleId)) { - throw strapi.errors.badRequest('ValidationError', "Super admin permissions can't be edited."); - } - try { await validatePermissionsExist(permissions); } catch (err) { + console.log('err', err); throw strapi.errors.badRequest('ValidationError', err); } @@ -61,9 +58,19 @@ const assign = async (roleId, permissions = []) => { }); const newPermissions = []; - for (const permission of permissionsWithRole) { - const result = await strapi.query('permission', 'admin').create(permission); - newPermissions.push(result); + const errors = []; + const generatePromises = function*() { + for (let permission of permissionsWithRole) { + yield strapi.query('permission', 'admin').create(permission); + } + }; + const pool = new PromisePool(generatePromises(), 100); + pool.addEventListener('fulfilled', e => newPermissions.push(e.data.result)); + pool.addEventListener('reject', e => errors.push(e.error)); + await pool.start(); + + if (errors.length > 0) { + throw errors[0]; } return newPermissions; diff --git a/yarn.lock b/yarn.lock index 0204d52844..efb04ab575 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7274,6 +7274,11 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-promise-pool@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/es6-promise-pool/-/es6-promise-pool-2.5.0.tgz#147c612b36b47f105027f9d2bf54a598a99d9ccb" + integrity sha1-FHxhKza0fxBQJ/nSv1SlmKmdnMs= + es6-promise@^4.0.3: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"