180 lines
4.8 KiB
JavaScript
Raw Permalink Normal View History

2021-09-07 09:45:45 +02:00
'use strict';
const _ = require('lodash');
2021-10-27 18:54:58 +02:00
const { NotFoundError } = require('@strapi/utils').errors;
const { getService } = require('../utils');
2021-09-07 09:45:45 +02:00
module.exports = ({ strapi }) => ({
async createRole(params) {
if (!params.type) {
params.type = _.snakeCase(_.deburr(_.toLower(params.name)));
}
2024-03-13 15:40:30 +01:00
const role = await strapi.db
2021-09-07 09:45:45 +02:00
.query('plugin::users-permissions.role')
.create({ data: _.omit(params, ['users', 'permissions']) });
2021-09-07 10:53:37 +02:00
const createPromises = _.flatMap(params.permissions, (type, typeName) => {
return _.flatMap(type.controllers, (controller, controllerName) => {
return _.reduce(
controller,
(acc, action, actionName) => {
const { enabled /* policy */ } = action;
2021-09-07 09:45:45 +02:00
2021-09-07 10:53:37 +02:00
if (enabled) {
const actionID = `${typeName}.${controllerName}.${actionName}`;
2021-09-07 09:45:45 +02:00
2021-09-07 10:53:37 +02:00
acc.push(
2024-03-13 15:40:30 +01:00
strapi.db
2021-09-07 10:53:37 +02:00
.query('plugin::users-permissions.permission')
.create({ data: { action: actionID, role: role.id } })
);
}
return acc;
2021-09-07 09:45:45 +02:00
},
2021-09-07 10:53:37 +02:00
[]
);
});
});
2021-09-07 09:45:45 +02:00
2021-09-07 10:53:37 +02:00
await Promise.all(createPromises);
2021-09-07 09:45:45 +02:00
},
async findOne(roleID) {
2024-03-13 15:40:30 +01:00
const role = await strapi.db
2021-09-07 09:45:45 +02:00
.query('plugin::users-permissions.role')
.findOne({ where: { id: roleID }, populate: ['permissions'] });
if (!role) {
2021-10-27 18:54:58 +02:00
throw new NotFoundError('Role not found');
2021-09-07 09:45:45 +02:00
}
const allActions = getService('users-permissions').getActions();
2021-09-07 09:45:45 +02:00
// Group by `type`.
2022-08-08 23:33:39 +02:00
role.permissions.forEach((permission) => {
2021-09-07 09:45:45 +02:00
const [type, controller, action] = permission.action.split('.');
_.set(allActions, `${type}.controllers.${controller}.${action}`, {
2021-09-07 09:45:45 +02:00
enabled: true,
policy: '',
});
});
2021-09-07 09:45:45 +02:00
return {
...role,
permissions: allActions,
2021-09-07 09:45:45 +02:00
};
},
async find() {
2024-03-13 15:40:30 +01:00
const roles = await strapi.db
.query('plugin::users-permissions.role')
.findMany({ sort: ['name'] });
2021-09-07 09:45:45 +02:00
for (const role of roles) {
2024-03-13 15:40:30 +01:00
role.nb_users = await strapi.db
2021-09-07 09:45:45 +02:00
.query('plugin::users-permissions.user')
.count({ where: { role: { id: role.id } } });
}
return roles;
},
2021-09-07 10:53:37 +02:00
async updateRole(roleID, data) {
2024-03-13 15:40:30 +01:00
const role = await strapi.db
2021-09-07 10:53:37 +02:00
.query('plugin::users-permissions.role')
.findOne({ where: { id: roleID }, populate: ['permissions'] });
if (!role) {
2021-10-27 18:54:58 +02:00
throw new NotFoundError('Role not found');
2021-09-07 10:53:37 +02:00
}
2021-09-07 09:45:45 +02:00
2024-03-13 15:40:30 +01:00
await strapi.db.query('plugin::users-permissions.role').update({
2021-09-07 09:45:45 +02:00
where: { id: roleID },
2021-09-07 10:53:37 +02:00
data: _.pick(data, ['name', 'description']),
2021-09-07 09:45:45 +02:00
});
2021-09-07 10:53:37 +02:00
const { permissions } = data;
const newActions = _.flatMap(permissions, (type, typeName) => {
return _.flatMap(type.controllers, (controller, controllerName) => {
return _.reduce(
controller,
(acc, action, actionName) => {
const { enabled /* policy */ } = action;
if (enabled) {
acc.push(`${typeName}.${controllerName}.${actionName}`);
2021-09-07 09:45:45 +02:00
}
2021-09-07 10:53:37 +02:00
return acc;
},
[]
);
});
});
const oldActions = role.permissions.map(({ action }) => action);
2021-09-07 09:45:45 +02:00
2021-09-07 10:53:37 +02:00
const toDelete = role.permissions.reduce((acc, permission) => {
if (!newActions.includes(permission.action)) {
acc.push(permission);
}
return acc;
}, []);
2021-09-07 09:45:45 +02:00
2021-09-07 10:53:37 +02:00
const toCreate = newActions
2022-08-08 23:33:39 +02:00
.filter((action) => !oldActions.includes(action))
.map((action) => ({ action, role: role.id }));
2021-09-07 10:53:37 +02:00
await Promise.all(
2022-08-08 23:33:39 +02:00
toDelete.map((permission) =>
2024-03-13 15:40:30 +01:00
strapi.db
2021-09-07 10:53:37 +02:00
.query('plugin::users-permissions.permission')
.delete({ where: { id: permission.id } })
)
);
await Promise.all(
2022-08-08 23:33:39 +02:00
toCreate.map((permissionInfo) =>
2024-03-13 15:40:30 +01:00
strapi.db.query('plugin::users-permissions.permission').create({ data: permissionInfo })
2021-09-07 10:53:37 +02:00
)
);
2021-09-07 09:45:45 +02:00
},
async deleteRole(roleID, publicRoleID) {
2024-03-13 15:40:30 +01:00
const role = await strapi.db
2021-09-07 09:45:45 +02:00
.query('plugin::users-permissions.role')
.findOne({ where: { id: roleID }, populate: ['users', 'permissions'] });
if (!role) {
2021-10-27 18:54:58 +02:00
throw new NotFoundError('Role not found');
2021-09-07 09:45:45 +02:00
}
// Move users to guest role.
await Promise.all(
2022-08-08 23:33:39 +02:00
role.users.map((user) => {
2024-03-13 15:40:30 +01:00
return strapi.db.query('plugin::users-permissions.user').update({
2021-09-07 09:45:45 +02:00
where: { id: user.id },
data: { role: publicRoleID },
});
})
);
// Remove permissions related to this role.
// TODO: use delete many
await Promise.all(
2022-08-08 23:33:39 +02:00
role.permissions.map((permission) => {
2024-03-13 15:40:30 +01:00
return strapi.db.query('plugin::users-permissions.permission').delete({
2021-09-07 09:45:45 +02:00
where: { id: permission.id },
});
})
);
// Delete the role.
2024-03-13 15:40:30 +01:00
await strapi.db.query('plugin::users-permissions.role').delete({ where: { id: roleID } });
2021-09-07 09:45:45 +02:00
},
});