]> BookStack Code Mirror - bookstack/blob - tests/Helpers/PermissionsProvider.php
Images: Added nulling of image page relation on page delete
[bookstack] / tests / Helpers / PermissionsProvider.php
1 <?php
2
3 namespace Tests\Helpers;
4
5 use BookStack\Entities\Models\Entity;
6 use BookStack\Permissions\Models\EntityPermission;
7 use BookStack\Permissions\Models\RolePermission;
8 use BookStack\Permissions\Permission;
9 use BookStack\Settings\SettingService;
10 use BookStack\Users\Models\Role;
11 use BookStack\Users\Models\User;
12
13 class PermissionsProvider
14 {
15     public function __construct(
16         protected UserRoleProvider $userRoleProvider
17     ) {
18     }
19
20     public function makeAppPublic(): void
21     {
22         $settings = app(SettingService::class);
23         $settings->put('app-public', 'true');
24     }
25
26     /**
27      * Grant role permissions to the provided user.
28      */
29     public function grantUserRolePermissions(User $user, array $permissions): void
30     {
31         $newRole = $this->userRoleProvider->createRole($permissions);
32         $user->attachRole($newRole);
33         $user->load('roles');
34         $user->clearPermissionCache();
35     }
36
37     /**
38      * Completely remove specific role permissions from the provided user.
39      */
40     public function removeUserRolePermissions(User $user, array $permissions): void
41     {
42         foreach ($permissions as $permissionName) {
43             /** @var RolePermission $permission */
44             $permission = RolePermission::query()
45                 ->where('name', '=', $permissionName)
46                 ->firstOrFail();
47
48             $roles = $user->roles()->whereHas('permissions', function ($query) use ($permission) {
49                 $query->where('id', '=', $permission->id);
50             })->get();
51
52             /** @var Role $role */
53             foreach ($roles as $role) {
54                 $role->detachPermission($permission);
55             }
56
57             $user->clearPermissionCache();
58         }
59     }
60
61     /**
62      * Change the owner of the given entity to the given user.
63      */
64     public function changeEntityOwner(Entity $entity, User $newOwner): void
65     {
66         $entity->owned_by = $newOwner->id;
67         $entity->save();
68         $entity->rebuildPermissions();
69     }
70
71     /**
72      * Regenerate the permission for an entity.
73      * Centralised to manage clearing of cached elements between requests.
74      */
75     public function regenerateForEntity(Entity $entity): void
76     {
77         $entity->rebuildPermissions();
78     }
79
80     /**
81      * Set the given entity as having restricted permissions, and apply the given
82      * permissions for the given roles.
83      * @param string[] $actions
84      * @param Role[] $roles
85      */
86     public function setEntityPermissions(Entity $entity, array $actions = [], array $roles = [], $inherit = false): void
87     {
88         $entity->permissions()->delete();
89
90         $permissions = [];
91
92         if (!$inherit) {
93             // Set default permissions to not allow actions so that only the provided role permissions are at play.
94             $permissions[] = ['role_id' => 0, 'view' => false, 'create' => false, 'update' => false, 'delete' => false];
95         }
96
97         foreach ($roles as $role) {
98             $permissions[] = $this->actionListToEntityPermissionData($actions, $role->id);
99         }
100
101         $this->addEntityPermissionEntries($entity, $permissions);
102     }
103
104     public function addEntityPermission(Entity $entity, array $actionList, Role $role)
105     {
106         $permissionData = $this->actionListToEntityPermissionData($actionList, $role->id);
107         $this->addEntityPermissionEntries($entity, [$permissionData]);
108     }
109
110     public function setFallbackPermissions(Entity $entity, array $actionList)
111     {
112         $entity->permissions()->where('role_id', '=', 0)->delete();
113         $permissionData = $this->actionListToEntityPermissionData($actionList, 0);
114         $this->addEntityPermissionEntries($entity, [$permissionData]);
115     }
116
117     /**
118      * Disable inherited permissions on the given entity.
119      * Effectively sets the "Other Users" UI permission option to not inherit, with no permissions.
120      */
121     public function disableEntityInheritedPermissions(Entity $entity): void
122     {
123         $entity->permissions()->where('role_id', '=', 0)->delete();
124         $fallback = $this->actionListToEntityPermissionData([]);
125         $this->addEntityPermissionEntries($entity, [$fallback]);
126     }
127
128     protected function addEntityPermissionEntries(Entity $entity, array $entityPermissionData): void
129     {
130         $entity->permissions()->createMany($entityPermissionData);
131         $entity->load('permissions');
132         $this->regenerateForEntity($entity);
133     }
134
135     /**
136      * For the given simple array of string actions (view, create, update, delete), convert
137      * the format to entity permission data, where permission is granted if the action is in the
138      * given actionList array.
139      */
140     protected function actionListToEntityPermissionData(array $actionList, int $roleId = 0): array
141     {
142         $permissionData = ['role_id' => $roleId];
143         foreach (Permission::genericForEntity() as $permission) {
144             $permissionData[$permission->value] = in_array($permission->value, $actionList);
145         }
146
147         return $permissionData;
148     }
149 }