2020-05-29 17:23:42 +02:00
|
|
|
'use strict';
|
|
|
|
|
2020-05-22 12:58:14 +02:00
|
|
|
const _ = require('lodash');
|
2020-06-18 11:40:50 +02:00
|
|
|
const { SUPER_ADMIN_CODE } = require('./constants');
|
2020-05-22 12:58:14 +02:00
|
|
|
|
|
|
|
const sanitizeRole = role => {
|
2020-05-29 11:09:17 +02:00
|
|
|
return _.omit(role, ['users', 'permissions']);
|
2020-05-22 12:58:14 +02:00
|
|
|
};
|
|
|
|
|
2020-05-19 14:51:08 +02:00
|
|
|
/**
|
|
|
|
* Create and save a role in database
|
|
|
|
* @param attributes A partial role object
|
|
|
|
* @returns {Promise<role>}
|
|
|
|
*/
|
2020-05-22 12:58:14 +02:00
|
|
|
const create = async attributes => {
|
2020-05-25 11:22:35 +02:00
|
|
|
const alreadyExists = await exists({ name: attributes.name });
|
2020-06-19 18:54:37 +02:00
|
|
|
|
2020-05-25 11:22:35 +02:00
|
|
|
if (alreadyExists) {
|
|
|
|
throw strapi.errors.badRequest('ValidationError', {
|
|
|
|
name: [`The name must be unique and a role with name \`${attributes.name}\` already exists.`],
|
|
|
|
});
|
2020-05-22 12:58:14 +02:00
|
|
|
}
|
|
|
|
|
2020-06-19 18:54:37 +02:00
|
|
|
// Using timestamp (milliseconds) to be sure it is unique
|
|
|
|
// + converting timestamp to base 36 for better readibility
|
|
|
|
const autoGeneratedCode = `${_.kebabCase(attributes.name)}-${new Date().getTime().toString(36)}`;
|
|
|
|
|
|
|
|
const rolesWithCode = {
|
|
|
|
...attributes,
|
|
|
|
code: attributes.code || autoGeneratedCode,
|
|
|
|
};
|
|
|
|
|
|
|
|
return strapi.query('role', 'admin').create(rolesWithCode);
|
2020-05-19 14:51:08 +02:00
|
|
|
};
|
2020-05-19 11:53:34 +02:00
|
|
|
|
2020-05-19 14:51:08 +02:00
|
|
|
/**
|
|
|
|
* Find a role in database
|
|
|
|
* @param params query params to find the role
|
|
|
|
* @returns {Promise<role>}
|
|
|
|
*/
|
2020-05-29 17:23:42 +02:00
|
|
|
const findOne = (params = {}, populate = []) => {
|
2020-05-29 11:09:17 +02:00
|
|
|
return strapi.query('role', 'admin').findOne(params, populate);
|
2020-05-19 14:51:08 +02:00
|
|
|
};
|
|
|
|
|
2020-05-29 18:19:12 +02:00
|
|
|
/**
|
|
|
|
* Find a role in database with usersCounts
|
|
|
|
* @param params query params to find the role
|
|
|
|
* @returns {Promise<role>}
|
|
|
|
*/
|
2020-06-01 09:56:53 +02:00
|
|
|
const findOneWithUsersCount = async (params = {}, populate = []) => {
|
2020-05-29 18:19:12 +02:00
|
|
|
const role = await strapi.query('role', 'admin').findOne(params, populate);
|
|
|
|
|
|
|
|
if (role) {
|
2020-05-29 18:59:47 +02:00
|
|
|
const usersCounts = await getUsersCount(role.id);
|
|
|
|
role.usersCount = usersCounts;
|
2020-05-29 18:19:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return role;
|
|
|
|
};
|
|
|
|
|
2020-05-18 16:29:32 +02:00
|
|
|
/**
|
|
|
|
* Find roles in database
|
|
|
|
* @param params query params to find the roles
|
2020-05-19 15:34:33 +02:00
|
|
|
* @returns {Promise<array>}
|
2020-05-18 16:29:32 +02:00
|
|
|
*/
|
2020-05-29 17:23:42 +02:00
|
|
|
const find = (params = {}, populate = []) => {
|
2020-05-29 11:09:17 +02:00
|
|
|
return strapi.query('role', 'admin').find(params, populate);
|
2020-05-18 16:29:32 +02:00
|
|
|
};
|
|
|
|
|
2020-05-19 15:40:04 +02:00
|
|
|
/**
|
|
|
|
* Find all roles in database
|
|
|
|
* @returns {Promise<array>}
|
|
|
|
*/
|
2020-05-29 18:19:12 +02:00
|
|
|
const findAllWithUsersCount = async (populate = []) => {
|
|
|
|
const roles = await strapi.query('role', 'admin').find({ _limit: -1 }, populate);
|
2020-05-29 18:59:47 +02:00
|
|
|
for (let role of roles) {
|
|
|
|
const usersCount = await getUsersCount(role.id);
|
|
|
|
role.usersCount = usersCount;
|
|
|
|
}
|
2020-05-29 18:19:12 +02:00
|
|
|
|
|
|
|
return roles;
|
2020-05-19 15:40:04 +02:00
|
|
|
};
|
|
|
|
|
2020-05-19 16:11:19 +02:00
|
|
|
/**
|
|
|
|
* Update a role in database
|
|
|
|
* @param params query params to find the role to update
|
|
|
|
* @param attributes A partial role object
|
|
|
|
* @returns {Promise<role>}
|
|
|
|
*/
|
2020-05-22 12:58:14 +02:00
|
|
|
const update = async (params, attributes) => {
|
2020-06-18 18:10:12 +02:00
|
|
|
const sanitizedAttributes = _.omit(attributes, ['code']);
|
2020-06-15 11:54:44 +02:00
|
|
|
|
2020-06-18 18:10:12 +02:00
|
|
|
if (_.has(params, 'id') && _.has(sanitizedAttributes, 'name')) {
|
|
|
|
const alreadyExists = await exists({
|
|
|
|
name: sanitizedAttributes.name,
|
|
|
|
id_ne: params.id,
|
|
|
|
});
|
2020-05-25 11:22:35 +02:00
|
|
|
if (alreadyExists) {
|
|
|
|
throw strapi.errors.badRequest('ValidationError', {
|
|
|
|
name: [
|
2020-06-18 18:10:12 +02:00
|
|
|
`The name must be unique and a role with name \`${sanitizedAttributes.name}\` already exists.`,
|
2020-05-25 11:22:35 +02:00
|
|
|
],
|
|
|
|
});
|
2020-05-22 12:58:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-18 18:10:12 +02:00
|
|
|
return strapi.query('role', 'admin').update(params, sanitizedAttributes);
|
2020-05-19 16:11:19 +02:00
|
|
|
};
|
|
|
|
|
2020-05-25 11:22:35 +02:00
|
|
|
/**
|
|
|
|
* Check if a role exists in database
|
|
|
|
* @param params query params to find the role
|
|
|
|
* @returns {Promise<boolean>}
|
|
|
|
*/
|
|
|
|
const exists = async params => {
|
|
|
|
const foundCount = await strapi.query('role', 'admin').count(params);
|
|
|
|
|
|
|
|
return foundCount > 0;
|
|
|
|
};
|
|
|
|
|
2020-05-27 13:15:52 +02:00
|
|
|
/**
|
|
|
|
* Delete roles in database if they have no user assigned
|
2020-05-29 17:23:42 +02:00
|
|
|
* @param ids query params to find the roles
|
|
|
|
* @returns {Promise<array>}
|
2020-05-27 13:15:52 +02:00
|
|
|
*/
|
2020-05-28 17:32:44 +02:00
|
|
|
const deleteByIds = async (ids = []) => {
|
2020-06-18 11:40:50 +02:00
|
|
|
const superAdminRole = await getSuperAdmin();
|
|
|
|
if (superAdminRole && ids.map(String).includes(String(superAdminRole.id))) {
|
2020-06-15 11:54:44 +02:00
|
|
|
throw strapi.errors.badRequest('ValidationError', {
|
|
|
|
ids: ['You cannot delete the super admin role'],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-05-29 18:59:47 +02:00
|
|
|
for (let roleId of ids) {
|
|
|
|
const usersCount = await getUsersCount(roleId);
|
|
|
|
if (usersCount !== 0) {
|
|
|
|
throw strapi.errors.badRequest('ValidationError', {
|
|
|
|
ids: ['Some roles are still assigned to some users.'],
|
|
|
|
});
|
|
|
|
}
|
2020-05-27 13:15:52 +02:00
|
|
|
}
|
|
|
|
|
2020-05-29 11:09:17 +02:00
|
|
|
await strapi.admin.services.permission.deleteByRolesIds(ids);
|
2020-05-27 13:15:52 +02:00
|
|
|
|
2020-05-28 17:32:44 +02:00
|
|
|
let deletedRoles = await strapi.query('role', 'admin').delete({ id_in: ids });
|
2020-05-27 13:15:52 +02:00
|
|
|
|
|
|
|
if (!Array.isArray(deletedRoles)) {
|
|
|
|
deletedRoles = [deletedRoles];
|
|
|
|
}
|
|
|
|
|
|
|
|
return deletedRoles;
|
|
|
|
};
|
|
|
|
|
2020-05-29 18:19:12 +02:00
|
|
|
/** Count the number of users for some roles
|
|
|
|
* @param rolesIds
|
2020-06-01 09:56:53 +02:00
|
|
|
* @returns {Promise<integer>}
|
2020-05-29 18:19:12 +02:00
|
|
|
*/
|
2020-05-29 18:59:47 +02:00
|
|
|
const getUsersCount = async roleId => {
|
2020-06-12 18:42:07 +02:00
|
|
|
return strapi.query('user', 'admin').count({ roles: [roleId] });
|
2020-05-29 18:19:12 +02:00
|
|
|
};
|
|
|
|
|
2020-06-12 18:42:07 +02:00
|
|
|
/** Returns admin role
|
|
|
|
* @returns {Promise<role>}
|
|
|
|
*/
|
2020-06-18 11:40:50 +02:00
|
|
|
const getSuperAdmin = () => findOne({ code: SUPER_ADMIN_CODE });
|
2020-06-12 18:42:07 +02:00
|
|
|
|
|
|
|
/** Returns admin role with userCount
|
|
|
|
* @returns {Promise<role>}
|
|
|
|
*/
|
2020-06-18 11:40:50 +02:00
|
|
|
const getSuperAdminWithUsersCount = () => findOneWithUsersCount({ code: SUPER_ADMIN_CODE });
|
2020-06-12 18:42:07 +02:00
|
|
|
|
2020-05-19 14:51:08 +02:00
|
|
|
module.exports = {
|
2020-05-22 12:58:14 +02:00
|
|
|
sanitizeRole,
|
2020-05-19 14:51:08 +02:00
|
|
|
create,
|
|
|
|
findOne,
|
2020-06-01 09:56:53 +02:00
|
|
|
findOneWithUsersCount,
|
2020-05-18 16:29:32 +02:00
|
|
|
find,
|
2020-05-29 18:19:12 +02:00
|
|
|
findAllWithUsersCount,
|
2020-05-19 16:11:19 +02:00
|
|
|
update,
|
2020-05-25 11:22:35 +02:00
|
|
|
exists,
|
2020-05-28 17:32:44 +02:00
|
|
|
deleteByIds,
|
2020-05-29 18:59:47 +02:00
|
|
|
getUsersCount,
|
2020-06-18 11:40:50 +02:00
|
|
|
getSuperAdmin,
|
|
|
|
getSuperAdminWithUsersCount,
|
2020-05-18 16:21:02 +02:00
|
|
|
};
|