| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2021-09-07 12:26:01 +02:00
										 |  |  | 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))); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const role = await strapi | 
					
						
							|  |  |  |       .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( | 
					
						
							|  |  |  |                 strapi | 
					
						
							|  |  |  |                   .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
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-03 22:55:29 +09:00
										 |  |  |   async findOne(roleID) { | 
					
						
							| 
									
										
										
										
											2021-09-07 09:45:45 +02:00
										 |  |  |     const role = await strapi | 
					
						
							|  |  |  |       .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
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-07 12:26:01 +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('.'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-07 12:26:01 +02:00
										 |  |  |       _.set(allActions, `${type}.controllers.${controller}.${action}`, { | 
					
						
							| 
									
										
										
										
											2021-09-07 09:45:45 +02:00
										 |  |  |         enabled: true, | 
					
						
							|  |  |  |         policy: '', | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2021-09-07 12:26:01 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-09-07 09:45:45 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       ...role, | 
					
						
							| 
									
										
										
										
											2021-09-07 12:26:01 +02:00
										 |  |  |       permissions: allActions, | 
					
						
							| 
									
										
										
										
											2021-09-07 09:45:45 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-03 22:55:29 +09:00
										 |  |  |   async find() { | 
					
						
							| 
									
										
										
										
											2021-09-07 09:45:45 +02:00
										 |  |  |     const roles = await strapi.query('plugin::users-permissions.role').findMany({ sort: ['name'] }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const role of roles) { | 
					
						
							| 
									
										
										
										
											2021-09-29 11:27:45 +02:00
										 |  |  |       role.nb_users = await strapi | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							|  |  |  |     const role = await strapi | 
					
						
							|  |  |  |       .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
										 |  |  | 
 | 
					
						
							|  |  |  |     await strapi.query('plugin::users-permissions.role').update({ | 
					
						
							|  |  |  |       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) => | 
					
						
							| 
									
										
										
										
											2021-09-07 10:53:37 +02:00
										 |  |  |         strapi | 
					
						
							|  |  |  |           .query('plugin::users-permissions.permission') | 
					
						
							|  |  |  |           .delete({ where: { id: permission.id } }) | 
					
						
							|  |  |  |       ) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await Promise.all( | 
					
						
							| 
									
										
										
										
											2022-08-08 23:33:39 +02:00
										 |  |  |       toCreate.map((permissionInfo) => | 
					
						
							| 
									
										
										
										
											2021-09-07 10:53:37 +02:00
										 |  |  |         strapi.query('plugin::users-permissions.permission').create({ data: permissionInfo }) | 
					
						
							|  |  |  |       ) | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2021-09-07 09:45:45 +02:00
										 |  |  |   }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async deleteRole(roleID, publicRoleID) { | 
					
						
							|  |  |  |     const role = await strapi | 
					
						
							|  |  |  |       .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) => { | 
					
						
							| 
									
										
										
										
											2021-09-07 09:45:45 +02:00
										 |  |  |         return strapi.query('plugin::users-permissions.user').update({ | 
					
						
							|  |  |  |           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) => { | 
					
						
							| 
									
										
										
										
											2021-09-07 09:45:45 +02:00
										 |  |  |         return strapi.query('plugin::users-permissions.permission').delete({ | 
					
						
							|  |  |  |           where: { id: permission.id }, | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Delete the role.
 | 
					
						
							|  |  |  |     await strapi.query('plugin::users-permissions.role').delete({ where: { id: roleID } }); | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | }); |