]> BookStack Code Mirror - bookstack/blob - app/Auth/Permissions/PermissionsRepo.php
Merge branch 'master' into master
[bookstack] / app / Auth / Permissions / PermissionsRepo.php
1 <?php namespace BookStack\Auth\Permissions;
2
3 use BookStack\Actions\ActivityType;
4 use BookStack\Auth\Role;
5 use BookStack\Exceptions\PermissionsException;
6 use BookStack\Facades\Activity;
7 use Exception;
8 use Illuminate\Database\Eloquent\Collection;
9
10 class PermissionsRepo
11 {
12
13     protected $permission;
14     protected $role;
15     protected $permissionService;
16
17     protected $systemRoles = ['admin', 'public'];
18
19     /**
20      * PermissionsRepo constructor.
21      */
22     public function __construct(RolePermission $permission, Role $role, PermissionService $permissionService)
23     {
24         $this->permission = $permission;
25         $this->role = $role;
26         $this->permissionService = $permissionService;
27     }
28
29     /**
30      * Get all the user roles from the system.
31      */
32     public function getAllRoles(): Collection
33     {
34         return $this->role->all();
35     }
36
37     /**
38      * Get all the roles except for the provided one.
39      */
40     public function getAllRolesExcept(Role $role): Collection
41     {
42         return $this->role->where('id', '!=', $role->id)->get();
43     }
44
45     /**
46      * Get a role via its ID.
47      */
48     public function getRoleById($id): Role
49     {
50         return $this->role->newQuery()->findOrFail($id);
51     }
52
53     /**
54      * Save a new role into the system.
55      */
56     public function saveNewRole(array $roleData): Role
57     {
58         $role = $this->role->newInstance($roleData);
59         $role->save();
60
61         $permissions = isset($roleData['permissions']) ? array_keys($roleData['permissions']) : [];
62         $this->assignRolePermissions($role, $permissions);
63         $this->permissionService->buildJointPermissionForRole($role);
64         Activity::add(ActivityType::ROLE_CREATE, $role);
65         return $role;
66     }
67
68     /**
69      * Updates an existing role.
70      * Ensure Admin role always have core permissions.
71      */
72     public function updateRole($roleId, array $roleData)
73     {
74         /** @var Role $role */
75         $role = $this->role->newQuery()->findOrFail($roleId);
76
77         $permissions = isset($roleData['permissions']) ? array_keys($roleData['permissions']) : [];
78         if ($role->system_name === 'admin') {
79             $permissions = array_merge($permissions, [
80                 'users-manage',
81                 'user-roles-manage',
82                 'restrictions-manage-all',
83                 'restrictions-manage-own',
84                 'settings-manage',
85             ]);
86         }
87
88         $this->assignRolePermissions($role, $permissions);
89
90         $role->fill($roleData);
91         $role->save();
92         $this->permissionService->buildJointPermissionForRole($role);
93         Activity::add(ActivityType::ROLE_UPDATE, $role);
94     }
95
96     /**
97      * Assign an list of permission names to an role.
98      */
99     protected function assignRolePermissions(Role $role, array $permissionNameArray = [])
100     {
101         $permissions = [];
102         $permissionNameArray = array_values($permissionNameArray);
103
104         if ($permissionNameArray) {
105             $permissions = $this->permission->newQuery()
106                 ->whereIn('name', $permissionNameArray)
107                 ->pluck('id')
108                 ->toArray();
109         }
110
111         $role->permissions()->sync($permissions);
112     }
113
114     /**
115      * Delete a role from the system.
116      * Check it's not an admin role or set as default before deleting.
117      * If an migration Role ID is specified the users assign to the current role
118      * will be added to the role of the specified id.
119      * @throws PermissionsException
120      * @throws Exception
121      */
122     public function deleteRole($roleId, $migrateRoleId)
123     {
124         /** @var Role $role */
125         $role = $this->role->newQuery()->findOrFail($roleId);
126
127         // Prevent deleting admin role or default registration role.
128         if ($role->system_name && in_array($role->system_name, $this->systemRoles)) {
129             throw new PermissionsException(trans('errors.role_system_cannot_be_deleted'));
130         } else if ($role->id === intval(setting('registration-role'))) {
131             throw new PermissionsException(trans('errors.role_registration_default_cannot_delete'));
132         }
133
134         if ($migrateRoleId) {
135             $newRole = $this->role->newQuery()->find($migrateRoleId);
136             if ($newRole) {
137                 $users = $role->users()->pluck('id')->toArray();
138                 $newRole->users()->sync($users);
139             }
140         }
141
142         $this->permissionService->deleteJointPermissionsForRole($role);
143         Activity::add(ActivityType::ROLE_DELETE, $role);
144         $role->delete();
145     }
146 }