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