3 namespace Tests\Helpers;
5 use BookStack\Auth\Permissions\EntityPermission;
6 use BookStack\Auth\Permissions\RolePermission;
7 use BookStack\Auth\Role;
8 use BookStack\Auth\User;
9 use BookStack\Entities\Models\Entity;
11 class PermissionsProvider
13 protected UserRoleProvider $userRoleProvider;
15 public function __construct(UserRoleProvider $userRoleProvider)
17 $this->userRoleProvider = $userRoleProvider;
21 * Grant role permissions to the provided user.
23 public function grantUserRolePermissions(User $user, array $permissions): void
25 $newRole = $this->userRoleProvider->createRole($permissions);
26 $user->attachRole($newRole);
28 $user->clearPermissionCache();
32 * Completely remove specific role permissions from the provided user.
34 public function removeUserRolePermissions(User $user, array $permissions): void
36 foreach ($permissions as $permissionName) {
37 /** @var RolePermission $permission */
38 $permission = RolePermission::query()
39 ->where('name', '=', $permissionName)
42 $roles = $user->roles()->whereHas('permissions', function ($query) use ($permission) {
43 $query->where('id', '=', $permission->id);
46 /** @var Role $role */
47 foreach ($roles as $role) {
48 $role->detachPermission($permission);
51 $user->clearPermissionCache();
56 * Change the owner of the given entity to the given user.
58 public function changeEntityOwner(Entity $entity, User $newOwner): void
60 $entity->owned_by = $newOwner->id;
62 $entity->rebuildPermissions();
66 * Regenerate the permission for an entity.
67 * Centralised to manage clearing of cached elements between requests.
69 public function regenerateForEntity(Entity $entity): void
71 $entity->rebuildPermissions();
75 * Set the given entity as having restricted permissions, and apply the given
76 * permissions for the given roles.
77 * @param string[] $actions
78 * @param Role[] $roles
80 public function setEntityPermissions(Entity $entity, array $actions = [], array $roles = [], $inherit = false): void
82 $entity->permissions()->delete();
87 // Set default permissions to not allow actions so that only the provided role permissions are at play.
88 $permissions[] = ['role_id' => 0, 'view' => false, 'create' => false, 'update' => false, 'delete' => false];
91 foreach ($roles as $role) {
92 $permissions[] = $this->actionListToEntityPermissionData($actions, $role->id);
95 $this->addEntityPermissionEntries($entity, $permissions);
98 public function addEntityPermission(Entity $entity, array $actionList, Role $role)
100 $permissionData = $this->actionListToEntityPermissionData($actionList, $role->id);
101 $this->addEntityPermissionEntries($entity, [$permissionData]);
104 public function setFallbackPermissions(Entity $entity, array $actionList)
106 $entity->permissions()->where('role_id', '=', 0)->delete();
107 $permissionData = $this->actionListToEntityPermissionData($actionList, 0);
108 $this->addEntityPermissionEntries($entity, [$permissionData]);
112 * Disable inherited permissions on the given entity.
113 * Effectively sets the "Other Users" UI permission option to not inherit, with no permissions.
115 public function disableEntityInheritedPermissions(Entity $entity): void
117 $entity->permissions()->where('role_id', '=', 0)->delete();
118 $fallback = $this->actionListToEntityPermissionData([]);
119 $this->addEntityPermissionEntries($entity, [$fallback]);
122 protected function addEntityPermissionEntries(Entity $entity, array $entityPermissionData): void
124 $entity->permissions()->createMany($entityPermissionData);
125 $entity->load('permissions');
126 $this->regenerateForEntity($entity);
130 * For the given simple array of string actions (view, create, update, delete), convert
131 * the format to entity permission data, where permission is granted if the action is in the
132 * given actionList array.
134 protected function actionListToEntityPermissionData(array $actionList, int $roleId = 0): array
136 $permissionData = ['role_id' => $roleId];
137 foreach (EntityPermission::PERMISSIONS as $possibleAction) {
138 $permissionData[$possibleAction] = in_array($possibleAction, $actionList);
141 return $permissionData;