| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | namespace BookStack\Permissions; | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | use BookStack\Activity\ActivityType; | 
					
						
							| 
									
										
										
										
											2018-09-25 23:58:03 +08:00
										 |  |  | use BookStack\Exceptions\PermissionsException; | 
					
						
							| 
									
										
										
										
											2020-11-21 02:53:01 +08:00
										 |  |  | use BookStack\Facades\Activity; | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | use BookStack\Permissions\Models\RolePermission; | 
					
						
							|  |  |  | use BookStack\Users\Models\Role; | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  | use Exception; | 
					
						
							|  |  |  | use Illuminate\Database\Eloquent\Collection; | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class PermissionsRepo | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |     protected array $systemRoles = ['admin', 'public']; | 
					
						
							| 
									
										
										
										
											2016-05-02 02:36:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-26 00:59:04 +08:00
										 |  |  |     public function __construct( | 
					
						
							|  |  |  |         protected JointPermissionBuilder $permissionBuilder | 
					
						
							|  |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get all the user roles from the system. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  |     public function getAllRoles(): Collection | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-07-13 03:15:41 +08:00
										 |  |  |         return Role::query()->get(); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get all the roles except for the provided one. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  |     public function getAllRolesExcept(Role $role): Collection | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-07-13 02:38:11 +08:00
										 |  |  |         return Role::query()->where('id', '!=', $role->id)->get(); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get a role via its ID. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |     public function getRoleById(int $id): Role | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-07-13 02:38:11 +08:00
										 |  |  |         return Role::query()->findOrFail($id); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Save a new role into the system. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  |     public function saveNewRole(array $roleData): Role | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-07-13 02:38:11 +08:00
										 |  |  |         $role = new Role($roleData); | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |         $role->mfa_enforced = boolval($roleData['mfa_enforced'] ?? false); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |         $role->save(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |         $permissions = $roleData['permissions'] ?? []; | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |         $this->assignRolePermissions($role, $permissions); | 
					
						
							| 
									
										
										
										
											2022-07-13 03:15:41 +08:00
										 |  |  |         $this->permissionBuilder->rebuildForRole($role); | 
					
						
							| 
									
										
										
										
											2022-07-13 02:38:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-21 02:53:01 +08:00
										 |  |  |         Activity::add(ActivityType::ROLE_CREATE, $role); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |         return $role; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Updates an existing role. | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |      * Ensures Admin system role always have core permissions. | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |     public function updateRole($roleId, array $roleData): Role | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-07-13 02:38:11 +08:00
										 |  |  |         $role = $this->getRoleById($roleId); | 
					
						
							| 
									
										
										
										
											2016-05-02 02:36:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |         if (isset($roleData['permissions'])) { | 
					
						
							|  |  |  |             $this->assignRolePermissions($role, $roleData['permissions']); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $role->fill($roleData); | 
					
						
							|  |  |  |         $role->save(); | 
					
						
							| 
									
										
										
										
											2022-07-13 03:15:41 +08:00
										 |  |  |         $this->permissionBuilder->rebuildForRole($role); | 
					
						
							| 
									
										
										
										
											2022-07-13 02:38:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-21 02:53:01 +08:00
										 |  |  |         Activity::add(ActivityType::ROLE_UPDATE, $role); | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return $role; | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |      * Assign a list of permission names to the given role. | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |     protected function assignRolePermissions(Role $role, array $permissionNameArray = []): void | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $permissions = []; | 
					
						
							| 
									
										
										
										
											2016-03-05 20:09:09 +08:00
										 |  |  |         $permissionNameArray = array_values($permissionNameArray); | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |         // Ensure the admin system role retains vital system permissions
 | 
					
						
							|  |  |  |         if ($role->system_name === 'admin') { | 
					
						
							|  |  |  |             $permissionNameArray = array_unique(array_merge($permissionNameArray, [ | 
					
						
							|  |  |  |                 'users-manage', | 
					
						
							|  |  |  |                 'user-roles-manage', | 
					
						
							|  |  |  |                 'restrictions-manage-all', | 
					
						
							|  |  |  |                 'restrictions-manage-own', | 
					
						
							|  |  |  |                 'settings-manage', | 
					
						
							|  |  |  |             ])); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!empty($permissionNameArray)) { | 
					
						
							| 
									
										
										
										
											2022-07-13 03:15:41 +08:00
										 |  |  |             $permissions = RolePermission::query() | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  |                 ->whereIn('name', $permissionNameArray) | 
					
						
							|  |  |  |                 ->pluck('id') | 
					
						
							|  |  |  |                 ->toArray(); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |         $role->permissions()->sync($permissions); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Delete a role from the system. | 
					
						
							|  |  |  |      * Check it's not an admin role or set as default before deleting. | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |      * If a migration Role ID is specified the users assign to the current role | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |      * will be added to the role of the specified id. | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |      * @throws PermissionsException | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  |      * @throws Exception | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |     public function deleteRole(int $roleId, int $migrateRoleId = 0): void | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-07-13 02:38:11 +08:00
										 |  |  |         $role = $this->getRoleById($roleId); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Prevent deleting admin role or default registration role.
 | 
					
						
							| 
									
										
										
										
											2016-05-02 02:36:53 +08:00
										 |  |  |         if ($role->system_name && in_array($role->system_name, $this->systemRoles)) { | 
					
						
							| 
									
										
										
										
											2016-12-05 00:51:39 +08:00
										 |  |  |             throw new PermissionsException(trans('errors.role_system_cannot_be_deleted')); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |         } elseif ($role->id === intval(setting('registration-role'))) { | 
					
						
							| 
									
										
										
										
											2016-12-05 00:51:39 +08:00
										 |  |  |             throw new PermissionsException(trans('errors.role_registration_default_cannot_delete')); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-19 02:36:34 +08:00
										 |  |  |         if ($migrateRoleId !== 0) { | 
					
						
							| 
									
										
										
										
											2022-07-13 02:38:11 +08:00
										 |  |  |             $newRole = Role::query()->find($migrateRoleId); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |             if ($newRole) { | 
					
						
							| 
									
										
										
										
											2020-08-04 21:55:01 +08:00
										 |  |  |                 $users = $role->users()->pluck('id')->toArray(); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |                 $newRole->users()->sync($users); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-07 20:12:33 +08:00
										 |  |  |         $role->entityPermissions()->delete(); | 
					
						
							| 
									
										
										
										
											2022-07-13 02:38:11 +08:00
										 |  |  |         $role->jointPermissions()->delete(); | 
					
						
							| 
									
										
										
										
											2020-11-21 02:53:01 +08:00
										 |  |  |         Activity::add(ActivityType::ROLE_DELETE, $role); | 
					
						
							| 
									
										
										
										
											2016-03-03 06:35:01 +08:00
										 |  |  |         $role->delete(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-01-29 00:58:52 +08:00
										 |  |  | } |