mirror of
https://github.com/strapi/strapi.git
synced 2025-11-14 17:19:01 +00:00
refacto
Signed-off-by: Pierre Noël <petersg83@gmail.com>
This commit is contained in:
parent
1bc8ae4d0f
commit
907d6c9d33
@ -20,7 +20,7 @@ module.exports = async () => {
|
|||||||
await strapi.admin.services.permission.ensureBoundPermissionsInDatabase();
|
await strapi.admin.services.permission.ensureBoundPermissionsInDatabase();
|
||||||
await strapi.admin.services.user.migrateUsers();
|
await strapi.admin.services.user.migrateUsers();
|
||||||
await strapi.admin.services.role.createRolesIfNoneExist();
|
await strapi.admin.services.role.createRolesIfNoneExist();
|
||||||
await strapi.admin.services.permission.resetSuperAdminPermissions();
|
await strapi.admin.services.role.resetSuperAdminPermissions();
|
||||||
await strapi.admin.services.role.displayWarningIfNoSuperAdmin();
|
await strapi.admin.services.role.displayWarningIfNoSuperAdmin();
|
||||||
await strapi.admin.services.user.displayWarningIfUsersDontHaveRole();
|
await strapi.admin.services.user.displayWarningIfUsersDontHaveRole();
|
||||||
};
|
};
|
||||||
|
|||||||
@ -168,11 +168,11 @@ describe('Role controller', () => {
|
|||||||
admin: {
|
admin: {
|
||||||
services: {
|
services: {
|
||||||
role: {
|
role: {
|
||||||
|
assignPermissions,
|
||||||
findOne: findOneRole,
|
findOne: findOneRole,
|
||||||
getSuperAdmin: jest.fn(() => undefined),
|
getSuperAdmin: jest.fn(() => undefined),
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
assign: assignPermissions,
|
|
||||||
conditionProvider: {
|
conditionProvider: {
|
||||||
getAll: jest.fn(() => [{ id: 'admin::is-creator' }]),
|
getAll: jest.fn(() => [{ id: 'admin::is-creator' }]),
|
||||||
},
|
},
|
||||||
|
|||||||
@ -129,7 +129,10 @@ module.exports = {
|
|||||||
permissionsToAssign = input.permissions;
|
permissionsToAssign = input.permissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
const permissions = await strapi.admin.services.permission.assign(role.id, permissionsToAssign);
|
const permissions = await strapi.admin.services.role.assignPermissions(
|
||||||
|
role.id,
|
||||||
|
permissionsToAssign
|
||||||
|
);
|
||||||
|
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
data: permissions,
|
data: permissions,
|
||||||
|
|||||||
@ -96,7 +96,10 @@ module.exports = {
|
|||||||
return ctx.notFound('role.notFound');
|
return ctx.notFound('role.notFound');
|
||||||
}
|
}
|
||||||
|
|
||||||
const permissions = await strapi.admin.services.permission.assign(role.id, input.permissions);
|
const permissions = await strapi.admin.services.role.assignPermissions(
|
||||||
|
role.id,
|
||||||
|
input.permissions
|
||||||
|
);
|
||||||
|
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
data: permissions,
|
data: permissions,
|
||||||
|
|||||||
@ -19,86 +19,6 @@ describe('Permission Service', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Assign permissions', () => {
|
|
||||||
test('Delete previous permissions', async () => {
|
|
||||||
const createMany = jest.fn(() => Promise.resolve([]));
|
|
||||||
const getSuperAdmin = jest.fn(() => Promise.resolve({ id: 0 }));
|
|
||||||
const sendDidUpdateRolePermissions = jest.fn();
|
|
||||||
const find = jest.fn(() => Promise.resolve([{ id: 3 }]));
|
|
||||||
const deleteFn = jest.fn();
|
|
||||||
const getAll = jest.fn(() => []);
|
|
||||||
|
|
||||||
global.strapi = {
|
|
||||||
admin: {
|
|
||||||
services: {
|
|
||||||
metrics: { sendDidUpdateRolePermissions },
|
|
||||||
permission: { actionProvider: { getAll } },
|
|
||||||
role: { getSuperAdmin },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
query() {
|
|
||||||
return { delete: deleteFn, createMany, find };
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
await permissionService.assign(1, []);
|
|
||||||
|
|
||||||
expect(deleteFn).toHaveBeenCalledWith({ id_in: [3] });
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Create new permissions', async () => {
|
|
||||||
const permissions = Array(5)
|
|
||||||
.fill(0)
|
|
||||||
.map((v, i) => ({ action: `action-${i}` }));
|
|
||||||
|
|
||||||
const deleteFn = jest.fn(() => Promise.resolve([]));
|
|
||||||
const createMany = jest.fn(() => Promise.resolve([]));
|
|
||||||
const getSuperAdmin = jest.fn(() => Promise.resolve({ id: 0 }));
|
|
||||||
const sendDidUpdateRolePermissions = jest.fn();
|
|
||||||
const find = jest.fn(() => Promise.resolve([]));
|
|
||||||
const getAll = jest.fn(() => permissions.map(perm => ({ actionId: perm.action })));
|
|
||||||
const removeUnkownConditionIds = jest.fn(conds => _.intersection(conds, ['cond']));
|
|
||||||
|
|
||||||
global.strapi = {
|
|
||||||
admin: {
|
|
||||||
services: {
|
|
||||||
metrics: { sendDidUpdateRolePermissions },
|
|
||||||
role: { getSuperAdmin },
|
|
||||||
permission: {
|
|
||||||
actionProvider: { getAll },
|
|
||||||
conditionProvider: {
|
|
||||||
getAll: jest.fn(() => [{ id: 'admin::is-creator' }]),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
condition: {
|
|
||||||
removeUnkownConditionIds,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
query() {
|
|
||||||
return { delete: deleteFn, createMany, find };
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const permissionsToAssign = [...permissions];
|
|
||||||
permissionsToAssign[4] = {
|
|
||||||
...permissions[4],
|
|
||||||
conditions: ['cond', 'unknown-cond'],
|
|
||||||
};
|
|
||||||
|
|
||||||
await permissionService.assign(1, permissionsToAssign);
|
|
||||||
|
|
||||||
expect(createMany).toHaveBeenCalledTimes(1);
|
|
||||||
expect(createMany).toHaveBeenCalledWith([
|
|
||||||
{ action: 'action-0', conditions: [], fields: null, role: 1, subject: null },
|
|
||||||
{ action: 'action-1', conditions: [], fields: null, role: 1, subject: null },
|
|
||||||
{ action: 'action-2', conditions: [], fields: null, role: 1, subject: null },
|
|
||||||
{ action: 'action-3', conditions: [], fields: null, role: 1, subject: null },
|
|
||||||
{ action: 'action-4', conditions: ['cond'], fields: null, role: 1, subject: null },
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Find User Permissions', () => {
|
describe('Find User Permissions', () => {
|
||||||
test('Find calls the right db query', async () => {
|
test('Find calls the right db query', async () => {
|
||||||
const find = jest.fn(({ role_in }) => role_in);
|
const find = jest.fn(({ role_in }) => role_in);
|
||||||
@ -229,70 +149,4 @@ describe('Permission Service', () => {
|
|||||||
permissionService.actionProvider.getAllByMap = prevGetAllByMap;
|
permissionService.actionProvider.getAllByMap = prevGetAllByMap;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('resetSuperAdminPermissions', () => {
|
|
||||||
test('No superAdmin role exist', async () => {
|
|
||||||
const getSuperAdmin = jest.fn(() => Promise.resolve(undefined));
|
|
||||||
const createMany = jest.fn();
|
|
||||||
|
|
||||||
global.strapi = {
|
|
||||||
query: () => ({ createMany }),
|
|
||||||
admin: { services: { role: { getSuperAdmin } } },
|
|
||||||
};
|
|
||||||
|
|
||||||
await permissionService.resetSuperAdminPermissions();
|
|
||||||
|
|
||||||
expect(createMany).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
test('Reset super admin permissions', async () => {
|
|
||||||
const actions = [
|
|
||||||
{
|
|
||||||
actionId: 'action-1',
|
|
||||||
subjects: ['country'],
|
|
||||||
section: 'contentTypes',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const permissions = [
|
|
||||||
{
|
|
||||||
action: 'action-1',
|
|
||||||
subject: 'country',
|
|
||||||
fields: ['name'],
|
|
||||||
conditions: [],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const getAll = jest.fn(() => actions);
|
|
||||||
const getAllConditions = jest.fn(() => []);
|
|
||||||
const find = jest.fn(() => [{ action: 'action-2', id: 2 }]);
|
|
||||||
const deleteFn = jest.fn(() => []);
|
|
||||||
const getPermissionsWithNestedFields = jest.fn(() => [...permissions]); // cloned, otherwise it is modified inside resetSuperAdminPermissions()
|
|
||||||
const getSuperAdmin = jest.fn(() => Promise.resolve({ id: 1 }));
|
|
||||||
const createMany = jest.fn(() => Promise.resolve([{ ...permissions[0], role: { id: 1 } }]));
|
|
||||||
const removeUnkownConditionIds = jest.fn(conds => conds);
|
|
||||||
|
|
||||||
global.strapi = {
|
|
||||||
query: () => ({ createMany, find, delete: deleteFn }),
|
|
||||||
admin: {
|
|
||||||
services: {
|
|
||||||
permission: {
|
|
||||||
actionProvider: { getAll },
|
|
||||||
conditionProvider: { getAll: getAllConditions },
|
|
||||||
},
|
|
||||||
condition: { removeUnkownConditionIds },
|
|
||||||
'content-type': { getPermissionsWithNestedFields },
|
|
||||||
role: { getSuperAdmin },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
await permissionService.resetSuperAdminPermissions();
|
|
||||||
|
|
||||||
expect(deleteFn).toHaveBeenCalledWith({ id_in: [2] });
|
|
||||||
expect(createMany).toHaveBeenCalledWith([
|
|
||||||
{
|
|
||||||
...permissions[0],
|
|
||||||
role: 1,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -275,7 +275,6 @@ describe('Role', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Count roles', () => {
|
describe('Count roles', () => {
|
||||||
test('Count roles without params', async () => {
|
test('Count roles without params', async () => {
|
||||||
const count = jest.fn(() => Promise.resolve(2));
|
const count = jest.fn(() => Promise.resolve(2));
|
||||||
@ -302,7 +301,6 @@ describe('Role', () => {
|
|||||||
expect(count).toHaveBeenCalledWith(params);
|
expect(count).toHaveBeenCalledWith(params);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('createRolesIfNoneExist', () => {
|
describe('createRolesIfNoneExist', () => {
|
||||||
test("Don't create roles if one already exist", async () => {
|
test("Don't create roles if one already exist", async () => {
|
||||||
const count = jest.fn(() => Promise.resolve(1));
|
const count = jest.fn(() => Promise.resolve(1));
|
||||||
@ -405,21 +403,26 @@ describe('Role', () => {
|
|||||||
restrictedSubjects: ['plugins::users-permissions.user'],
|
restrictedSubjects: ['plugins::users-permissions.user'],
|
||||||
});
|
});
|
||||||
expect(createMany).toHaveBeenCalledTimes(2);
|
expect(createMany).toHaveBeenCalledTimes(2);
|
||||||
expect(createMany).toHaveBeenNthCalledWith(1, 2, [
|
expect(createMany).toHaveBeenNthCalledWith(
|
||||||
|
1,
|
||||||
|
[
|
||||||
...permissions,
|
...permissions,
|
||||||
...defaultPermissions.map(d => ({
|
...defaultPermissions.map(d => ({
|
||||||
...d,
|
...d,
|
||||||
conditions: [],
|
conditions: [],
|
||||||
})),
|
})),
|
||||||
]);
|
].map(p => ({ ...p, role: 2 }))
|
||||||
|
);
|
||||||
|
|
||||||
expect(createMany).toHaveBeenNthCalledWith(2, 3, [
|
expect(createMany).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
|
[
|
||||||
{ ...permissions[0], conditions: ['admin::is-creator'] },
|
{ ...permissions[0], conditions: ['admin::is-creator'] },
|
||||||
...defaultPermissions,
|
...defaultPermissions,
|
||||||
]);
|
].map(p => ({ ...p, role: 3 }))
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('displayWarningIfNoSuperAdmin', () => {
|
describe('displayWarningIfNoSuperAdmin', () => {
|
||||||
test('superAdmin role exists & a user is superAdmin', async () => {
|
test('superAdmin role exists & a user is superAdmin', async () => {
|
||||||
const findOne = jest.fn(() => ({ id: 1 }));
|
const findOne = jest.fn(() => ({ id: 1 }));
|
||||||
@ -470,4 +473,145 @@ describe('Role', () => {
|
|||||||
expect(warn).toHaveBeenCalledWith("Your application doesn't have a super admin user.");
|
expect(warn).toHaveBeenCalledWith("Your application doesn't have a super admin user.");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('resetSuperAdminPermissions', () => {
|
||||||
|
test('No superAdmin role exist', async () => {
|
||||||
|
const getSuperAdmin = jest.fn(() => Promise.resolve(undefined));
|
||||||
|
const createMany = jest.fn();
|
||||||
|
|
||||||
|
global.strapi = {
|
||||||
|
query: () => ({ createMany }),
|
||||||
|
admin: { services: { role: { getSuperAdmin } } },
|
||||||
|
};
|
||||||
|
|
||||||
|
await roleService.resetSuperAdminPermissions();
|
||||||
|
|
||||||
|
expect(createMany).toHaveBeenCalledTimes(0);
|
||||||
|
});
|
||||||
|
test('Reset super admin permissions', async () => {
|
||||||
|
const actions = [
|
||||||
|
{
|
||||||
|
actionId: 'action-1',
|
||||||
|
subjects: ['country'],
|
||||||
|
section: 'contentTypes',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const permissions = [
|
||||||
|
{
|
||||||
|
action: 'action-1',
|
||||||
|
subject: 'country',
|
||||||
|
fields: ['name'],
|
||||||
|
conditions: [],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const getAll = jest.fn(() => actions);
|
||||||
|
const getAllConditions = jest.fn(() => []);
|
||||||
|
const find = jest.fn(() => [{ action: 'action-2', id: 2 }]);
|
||||||
|
const getPermissionsWithNestedFields = jest.fn(() => [...permissions]); // cloned, otherwise it is modified inside resetSuperAdminPermissions()
|
||||||
|
const deleteByIds = jest.fn();
|
||||||
|
const getSuperAdmin = jest.fn(() => Promise.resolve({ id: 1 }));
|
||||||
|
const createMany = jest.fn(() => Promise.resolve([{ ...permissions[0], role: { id: 1 } }]));
|
||||||
|
const removeUnkownConditionIds = jest.fn(conds => conds);
|
||||||
|
|
||||||
|
global.strapi = {
|
||||||
|
admin: {
|
||||||
|
services: {
|
||||||
|
permission: {
|
||||||
|
createMany,
|
||||||
|
find,
|
||||||
|
actionProvider: { getAll },
|
||||||
|
conditionProvider: { getAll: getAllConditions },
|
||||||
|
deleteByIds,
|
||||||
|
},
|
||||||
|
condition: { removeUnkownConditionIds },
|
||||||
|
'content-type': { getPermissionsWithNestedFields },
|
||||||
|
role: { getSuperAdmin },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await roleService.resetSuperAdminPermissions();
|
||||||
|
|
||||||
|
expect(deleteByIds).toHaveBeenCalledWith([2]);
|
||||||
|
expect(createMany).toHaveBeenCalledWith([
|
||||||
|
{
|
||||||
|
...permissions[0],
|
||||||
|
role: 1,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('Assign permissions', () => {
|
||||||
|
test('Delete previous permissions', async () => {
|
||||||
|
const createMany = jest.fn(() => Promise.resolve([]));
|
||||||
|
const getSuperAdmin = jest.fn(() => Promise.resolve({ id: 0 }));
|
||||||
|
const sendDidUpdateRolePermissions = jest.fn();
|
||||||
|
const find = jest.fn(() => Promise.resolve([{ id: 3 }]));
|
||||||
|
const deleteByIds = jest.fn();
|
||||||
|
const getAll = jest.fn(() => []);
|
||||||
|
|
||||||
|
global.strapi = {
|
||||||
|
admin: {
|
||||||
|
services: {
|
||||||
|
metrics: { sendDidUpdateRolePermissions },
|
||||||
|
permission: { find, createMany, actionProvider: { getAll }, deleteByIds },
|
||||||
|
role: { getSuperAdmin },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await roleService.assignPermissions(1, []);
|
||||||
|
|
||||||
|
expect(deleteByIds).toHaveBeenCalledWith([3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Create new permissions', async () => {
|
||||||
|
const permissions = Array(5)
|
||||||
|
.fill(0)
|
||||||
|
.map((v, i) => ({ action: `action-${i}` }));
|
||||||
|
|
||||||
|
const createMany = jest.fn(() => Promise.resolve([]));
|
||||||
|
const getSuperAdmin = jest.fn(() => Promise.resolve({ id: 0 }));
|
||||||
|
const sendDidUpdateRolePermissions = jest.fn();
|
||||||
|
const find = jest.fn(() => Promise.resolve([]));
|
||||||
|
const getAll = jest.fn(() => permissions.map(perm => ({ actionId: perm.action })));
|
||||||
|
const removeUnkownConditionIds = jest.fn(conds => _.intersection(conds, ['cond']));
|
||||||
|
|
||||||
|
global.strapi = {
|
||||||
|
admin: {
|
||||||
|
services: {
|
||||||
|
metrics: { sendDidUpdateRolePermissions },
|
||||||
|
role: { getSuperAdmin },
|
||||||
|
permission: {
|
||||||
|
find,
|
||||||
|
createMany,
|
||||||
|
actionProvider: { getAll },
|
||||||
|
conditionProvider: {
|
||||||
|
getAll: jest.fn(() => [{ id: 'admin::is-creator' }]),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
condition: {
|
||||||
|
removeUnkownConditionIds,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const permissionsToAssign = [...permissions];
|
||||||
|
permissionsToAssign[4] = {
|
||||||
|
...permissions[4],
|
||||||
|
conditions: ['cond', 'unknown-cond'],
|
||||||
|
};
|
||||||
|
|
||||||
|
await roleService.assignPermissions(1, permissionsToAssign);
|
||||||
|
|
||||||
|
expect(createMany).toHaveBeenCalledTimes(1);
|
||||||
|
expect(createMany).toHaveBeenCalledWith([
|
||||||
|
{ action: 'action-0', conditions: [], fields: null, role: 1, subject: null },
|
||||||
|
{ action: 'action-1', conditions: [], fields: null, role: 1, subject: null },
|
||||||
|
{ action: 'action-2', conditions: [], fields: null, role: 1, subject: null },
|
||||||
|
{ action: 'action-3', conditions: [], fields: null, role: 1, subject: null },
|
||||||
|
{ action: 'action-4', conditions: ['cond'], fields: null, role: 1, subject: null },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const { flatMap, filter } = require('lodash/fp');
|
const { flatMap, filter } = require('lodash/fp');
|
||||||
const pmap = require('p-map');
|
const pmap = require('p-map');
|
||||||
const { validatePermissionsExist } = require('../validation/permission');
|
|
||||||
const createPermissionsManager = require('./permission/permissions-manager');
|
const createPermissionsManager = require('./permission/permissions-manager');
|
||||||
const createConditionProvider = require('./permission/condition-provider');
|
const createConditionProvider = require('./permission/condition-provider');
|
||||||
const createPermissionEngine = require('./permission/engine');
|
const createPermissionEngine = require('./permission/engine');
|
||||||
@ -15,20 +14,6 @@ const { createPermission } = require('../domain/permission');
|
|||||||
const conditionProvider = createConditionProvider();
|
const conditionProvider = createConditionProvider();
|
||||||
const engine = createPermissionEngine(conditionProvider);
|
const engine = createPermissionEngine(conditionProvider);
|
||||||
|
|
||||||
const fieldsToCompare = ['action', 'subject', 'fields', 'conditions'];
|
|
||||||
const getPermissionWithSortedFields = perm => {
|
|
||||||
const sortedPerm = _.cloneDeep(perm);
|
|
||||||
if (Array.isArray(sortedPerm.fields)) {
|
|
||||||
sortedPerm.fields.sort();
|
|
||||||
}
|
|
||||||
return sortedPerm;
|
|
||||||
};
|
|
||||||
const arePermissionsEqual = (perm1, perm2) =>
|
|
||||||
_.isEqual(
|
|
||||||
_.pick(getPermissionWithSortedFields(perm1), fieldsToCompare),
|
|
||||||
_.pick(getPermissionWithSortedFields(perm2), fieldsToCompare)
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes unwanted fields from a permission
|
* Removes unwanted fields from a permission
|
||||||
* @param perm
|
* @param perm
|
||||||
@ -62,9 +47,7 @@ const deleteByIds = ids => {
|
|||||||
* @param permissions
|
* @param permissions
|
||||||
* @returns {Promise<*[]|*>}
|
* @returns {Promise<*[]|*>}
|
||||||
*/
|
*/
|
||||||
const createMany = async (roleId, permissions) => {
|
const createMany = async permissions => {
|
||||||
permissions.forEach(p => p.role = roleId);
|
|
||||||
|
|
||||||
return strapi.query('permission', 'admin').createMany(permissions);
|
return strapi.query('permission', 'admin').createMany(permissions);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,57 +70,6 @@ const find = (params = {}) => {
|
|||||||
return strapi.query('permission', 'admin').find(params, []);
|
return strapi.query('permission', 'admin').find(params, []);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Assign permissions to a role
|
|
||||||
* @param {string|int} roleId - role ID
|
|
||||||
* @param {Array<Permission{action,subject,fields,conditions}>} permissions - permissions to assign to the role
|
|
||||||
*/
|
|
||||||
const assign = async (roleId, permissions = []) => {
|
|
||||||
try {
|
|
||||||
await validatePermissionsExist(permissions);
|
|
||||||
} catch (err) {
|
|
||||||
throw strapi.errors.badRequest('ValidationError', err);
|
|
||||||
}
|
|
||||||
|
|
||||||
const superAdmin = await strapi.admin.services.role.getSuperAdmin();
|
|
||||||
const isSuperAdmin = superAdmin && superAdmin.id === roleId;
|
|
||||||
|
|
||||||
const permissionsWithRole = permissions.map(permission =>
|
|
||||||
createPermission({
|
|
||||||
...permission,
|
|
||||||
conditions: strapi.admin.services.condition.removeUnkownConditionIds(permission.conditions),
|
|
||||||
role: roleId,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const existingPermissions = await find({ role: roleId, _limit: -1 });
|
|
||||||
const permissionsToAdd = _.differenceWith(
|
|
||||||
permissionsWithRole,
|
|
||||||
existingPermissions,
|
|
||||||
arePermissionsEqual
|
|
||||||
);
|
|
||||||
const permissionsToDelete = _.differenceWith(
|
|
||||||
existingPermissions,
|
|
||||||
permissionsWithRole,
|
|
||||||
arePermissionsEqual
|
|
||||||
);
|
|
||||||
const permissionsToReturn = _.differenceBy(existingPermissions, permissionsToDelete, 'id');
|
|
||||||
|
|
||||||
if (permissionsToDelete.length > 0) {
|
|
||||||
await deleteByIds(permissionsToDelete.map(p => p.id));
|
|
||||||
}
|
|
||||||
if (permissionsToAdd.length > 0) {
|
|
||||||
const createdPermissions = await createMany(roleId, permissionsToAdd);
|
|
||||||
permissionsToReturn.push(...createdPermissions.map(p => ({ ...p, role: p.role.id })));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isSuperAdmin && (permissionsToAdd.length || permissionsToDelete.length)) {
|
|
||||||
await strapi.admin.services.metrics.sendDidUpdateRolePermissions();
|
|
||||||
}
|
|
||||||
|
|
||||||
return permissionsToReturn;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all permissions for a user
|
* Find all permissions for a user
|
||||||
* @param roles
|
* @param roles
|
||||||
@ -250,49 +182,16 @@ const ensureBoundPermissionsInDatabase = async () => {
|
|||||||
fields: BOUND_ACTIONS_FOR_FIELDS.includes(action) ? fields : null,
|
fields: BOUND_ACTIONS_FOR_FIELDS.includes(action) ? fields : null,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
await createMany(editorRole.id, permissions);
|
await createMany(permissions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset super admin permissions (giving it all permissions)
|
|
||||||
* @returns {Promise<>}
|
|
||||||
*/
|
|
||||||
const resetSuperAdminPermissions = async () => {
|
|
||||||
const superAdminRole = await strapi.admin.services.role.getSuperAdmin();
|
|
||||||
if (!superAdminRole) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const allActions = strapi.admin.services.permission.actionProvider.getAll();
|
|
||||||
const contentTypesActions = allActions.filter(a => a.section === 'contentTypes');
|
|
||||||
|
|
||||||
const permissions = strapi.admin.services['content-type'].getPermissionsWithNestedFields(
|
|
||||||
contentTypesActions
|
|
||||||
);
|
|
||||||
|
|
||||||
const otherActions = allActions.filter(a => a.section !== 'contentTypes');
|
|
||||||
otherActions.forEach(action => {
|
|
||||||
if (action.subjects) {
|
|
||||||
const newPerms = action.subjects.map(subject =>
|
|
||||||
createPermission({ action: action.actionId, subject })
|
|
||||||
);
|
|
||||||
permissions.push(...newPerms);
|
|
||||||
} else {
|
|
||||||
permissions.push(createPermission({ action: action.actionId }));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await assign(superAdminRole.id, permissions);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createMany,
|
createMany,
|
||||||
find,
|
find,
|
||||||
deleteByRolesIds,
|
deleteByRolesIds,
|
||||||
deleteByIds,
|
deleteByIds,
|
||||||
assign,
|
|
||||||
sanitizePermission,
|
sanitizePermission,
|
||||||
findUserPermissions,
|
findUserPermissions,
|
||||||
actionProvider,
|
actionProvider,
|
||||||
@ -300,6 +199,5 @@ module.exports = {
|
|||||||
engine,
|
engine,
|
||||||
conditionProvider,
|
conditionProvider,
|
||||||
cleanPermissionInDatabase,
|
cleanPermissionInDatabase,
|
||||||
resetSuperAdminPermissions,
|
|
||||||
ensureBoundPermissionsInDatabase,
|
ensureBoundPermissionsInDatabase,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,6 +5,7 @@ const { set } = require('lodash/fp');
|
|||||||
const { generateTimestampCode, stringIncludes } = require('strapi-utils');
|
const { generateTimestampCode, stringIncludes } = require('strapi-utils');
|
||||||
const { SUPER_ADMIN_CODE } = require('./constants');
|
const { SUPER_ADMIN_CODE } = require('./constants');
|
||||||
const { createPermission } = require('../domain/permission');
|
const { createPermission } = require('../domain/permission');
|
||||||
|
const { validatePermissionsExist } = require('../validation/permission');
|
||||||
|
|
||||||
const ACTIONS = {
|
const ACTIONS = {
|
||||||
publish: 'plugins::content-manager.explorer.publish',
|
publish: 'plugins::content-manager.explorer.publish',
|
||||||
@ -14,6 +15,22 @@ const sanitizeRole = role => {
|
|||||||
return _.omit(role, ['users', 'permissions']);
|
return _.omit(role, ['users', 'permissions']);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fieldsToCompare = ['action', 'subject', 'fields', 'conditions'];
|
||||||
|
|
||||||
|
const getPermissionWithSortedFields = perm => {
|
||||||
|
const sortedPerm = _.cloneDeep(perm);
|
||||||
|
if (Array.isArray(sortedPerm.fields)) {
|
||||||
|
sortedPerm.fields.sort();
|
||||||
|
}
|
||||||
|
return sortedPerm;
|
||||||
|
};
|
||||||
|
|
||||||
|
const arePermissionsEqual = (perm1, perm2) =>
|
||||||
|
_.isEqual(
|
||||||
|
_.pick(getPermissionWithSortedFields(perm1), fieldsToCompare),
|
||||||
|
_.pick(getPermissionWithSortedFields(perm2), fieldsToCompare)
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and save a role in database
|
* Create and save a role in database
|
||||||
* @param attributes A partial role object
|
* @param attributes A partial role object
|
||||||
@ -233,8 +250,8 @@ const createRolesIfNoneExist = async ({ createPermissionsForAdmin = false } = {}
|
|||||||
authorPermissions.push(...getDefaultPluginPermissions({ isAuthor: true }));
|
authorPermissions.push(...getDefaultPluginPermissions({ isAuthor: true }));
|
||||||
|
|
||||||
// assign permissions to roles
|
// assign permissions to roles
|
||||||
await strapi.admin.services.permission.createMany(editorRole.id, editorPermissions);
|
await addPermissions(editorRole.id, editorPermissions);
|
||||||
await strapi.admin.services.permission.createMany(authorRole.id, authorPermissions);
|
await addPermissions(authorRole.id, authorPermissions);
|
||||||
|
|
||||||
if (createPermissionsForAdmin) {
|
if (createPermissionsForAdmin) {
|
||||||
await strapi.admin.services.permission.resetSuperAdminPermissions();
|
await strapi.admin.services.permission.resetSuperAdminPermissions();
|
||||||
@ -268,6 +285,101 @@ const displayWarningIfNoSuperAdmin = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign permissions to a role
|
||||||
|
* @param {string|int} roleId - role ID
|
||||||
|
* @param {Array<Permission{action,subject,fields,conditions}>} permissions - permissions to assign to the role
|
||||||
|
*/
|
||||||
|
const assignPermissions = async (roleId, permissions = []) => {
|
||||||
|
try {
|
||||||
|
await validatePermissionsExist(permissions);
|
||||||
|
} catch (err) {
|
||||||
|
throw strapi.errors.badRequest('ValidationError', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const superAdmin = await strapi.admin.services.role.getSuperAdmin();
|
||||||
|
const isSuperAdmin = superAdmin && superAdmin.id === roleId;
|
||||||
|
|
||||||
|
const permissionsWithRole = permissions.map(permission =>
|
||||||
|
createPermission({
|
||||||
|
...permission,
|
||||||
|
conditions: strapi.admin.services.condition.removeUnkownConditionIds(permission.conditions),
|
||||||
|
role: roleId,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingPermissions = await strapi.admin.services.permission.find({
|
||||||
|
role: roleId,
|
||||||
|
_limit: -1,
|
||||||
|
});
|
||||||
|
const permissionsToAdd = _.differenceWith(
|
||||||
|
permissionsWithRole,
|
||||||
|
existingPermissions,
|
||||||
|
arePermissionsEqual
|
||||||
|
);
|
||||||
|
const permissionsToDelete = _.differenceWith(
|
||||||
|
existingPermissions,
|
||||||
|
permissionsWithRole,
|
||||||
|
arePermissionsEqual
|
||||||
|
);
|
||||||
|
const permissionsToReturn = _.differenceBy(existingPermissions, permissionsToDelete, 'id');
|
||||||
|
|
||||||
|
if (permissionsToDelete.length > 0) {
|
||||||
|
await strapi.admin.services.permission.deleteByIds(permissionsToDelete.map(p => p.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permissionsToAdd.length > 0) {
|
||||||
|
const createdPermissions = await addPermissions(roleId, permissionsToAdd);
|
||||||
|
permissionsToReturn.push(...createdPermissions.map(p => ({ ...p, role: p.role.id })));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSuperAdmin && (permissionsToAdd.length || permissionsToDelete.length)) {
|
||||||
|
await strapi.admin.services.metrics.sendDidUpdateRolePermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissionsToReturn;
|
||||||
|
};
|
||||||
|
|
||||||
|
const addPermissions = async (roleId, permissions) => {
|
||||||
|
permissions.forEach(p => {
|
||||||
|
p.role = roleId;
|
||||||
|
});
|
||||||
|
|
||||||
|
return strapi.admin.services.permission.createMany(permissions);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset super admin permissions (giving it all permissions)
|
||||||
|
* @returns {Promise<>}
|
||||||
|
*/
|
||||||
|
const resetSuperAdminPermissions = async () => {
|
||||||
|
const superAdminRole = await strapi.admin.services.role.getSuperAdmin();
|
||||||
|
if (!superAdminRole) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const allActions = strapi.admin.services.permission.actionProvider.getAll();
|
||||||
|
const contentTypesActions = allActions.filter(a => a.section === 'contentTypes');
|
||||||
|
|
||||||
|
const permissions = strapi.admin.services['content-type'].getPermissionsWithNestedFields(
|
||||||
|
contentTypesActions
|
||||||
|
);
|
||||||
|
|
||||||
|
const otherActions = allActions.filter(a => a.section !== 'contentTypes');
|
||||||
|
otherActions.forEach(action => {
|
||||||
|
if (action.subjects) {
|
||||||
|
const newPerms = action.subjects.map(subject =>
|
||||||
|
createPermission({ action: action.actionId, subject })
|
||||||
|
);
|
||||||
|
permissions.push(...newPerms);
|
||||||
|
} else {
|
||||||
|
permissions.push(createPermission({ action: action.actionId }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await assignPermissions(superAdminRole.id, permissions);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
sanitizeRole,
|
sanitizeRole,
|
||||||
create,
|
create,
|
||||||
@ -284,4 +396,7 @@ module.exports = {
|
|||||||
getSuperAdminWithUsersCount,
|
getSuperAdminWithUsersCount,
|
||||||
createRolesIfNoneExist,
|
createRolesIfNoneExist,
|
||||||
displayWarningIfNoSuperAdmin,
|
displayWarningIfNoSuperAdmin,
|
||||||
|
addPermissions,
|
||||||
|
assignPermissions,
|
||||||
|
resetSuperAdminPermissions,
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user