mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
137 lines
4.6 KiB
PHP
137 lines
4.6 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace Tests\Helpers;
|
||
|
|
||
|
use BookStack\Auth\Permissions\EntityPermission;
|
||
|
use BookStack\Auth\Permissions\RolePermission;
|
||
|
use BookStack\Auth\Role;
|
||
|
use BookStack\Auth\User;
|
||
|
use BookStack\Entities\Models\Entity;
|
||
|
|
||
|
class PermissionsProvider
|
||
|
{
|
||
|
protected UserRoleProvider $userRoleProvider;
|
||
|
|
||
|
public function __construct(UserRoleProvider $userRoleProvider)
|
||
|
{
|
||
|
$this->userRoleProvider = $userRoleProvider;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Grant role permissions to the provided user.
|
||
|
*/
|
||
|
public function grantUserRolePermissions(User $user, array $permissions): void
|
||
|
{
|
||
|
$newRole = $this->userRoleProvider->createRole($permissions);
|
||
|
$user->attachRole($newRole);
|
||
|
$user->load('roles');
|
||
|
$user->clearPermissionCache();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Completely remove specific role permissions from the provided user.
|
||
|
*/
|
||
|
public function removeUserRolePermissions(User $user, array $permissions): void
|
||
|
{
|
||
|
foreach ($permissions as $permissionName) {
|
||
|
/** @var RolePermission $permission */
|
||
|
$permission = RolePermission::query()
|
||
|
->where('name', '=', $permissionName)
|
||
|
->firstOrFail();
|
||
|
|
||
|
$roles = $user->roles()->whereHas('permissions', function ($query) use ($permission) {
|
||
|
$query->where('id', '=', $permission->id);
|
||
|
})->get();
|
||
|
|
||
|
/** @var Role $role */
|
||
|
foreach ($roles as $role) {
|
||
|
$role->detachPermission($permission);
|
||
|
}
|
||
|
|
||
|
$user->clearPermissionCache();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Change the owner of the given entity to the given user.
|
||
|
*/
|
||
|
public function changeEntityOwner(Entity $entity, User $newOwner): void
|
||
|
{
|
||
|
$entity->owned_by = $newOwner->id;
|
||
|
$entity->save();
|
||
|
$entity->rebuildPermissions();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Regenerate the permission for an entity.
|
||
|
* Centralised to manage clearing of cached elements between requests.
|
||
|
*/
|
||
|
public function regenerateForEntity(Entity $entity): void
|
||
|
{
|
||
|
$entity->rebuildPermissions();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the given entity as having restricted permissions, and apply the given
|
||
|
* permissions for the given roles.
|
||
|
* @param string[] $actions
|
||
|
* @param Role[] $roles
|
||
|
*/
|
||
|
public function setEntityPermissions(Entity $entity, array $actions = [], array $roles = [], $inherit = false): void
|
||
|
{
|
||
|
$entity->permissions()->delete();
|
||
|
|
||
|
$permissions = [];
|
||
|
|
||
|
if (!$inherit) {
|
||
|
// Set default permissions to not allow actions so that only the provided role permissions are at play.
|
||
|
$permissions[] = ['role_id' => null, 'user_id' => null, 'view' => false, 'create' => false, 'update' => false, 'delete' => false];
|
||
|
}
|
||
|
|
||
|
foreach ($roles as $role) {
|
||
|
$permissions[] = $this->actionListToEntityPermissionData($actions, $role->id);
|
||
|
}
|
||
|
|
||
|
$this->addEntityPermissionEntries($entity, $permissions);
|
||
|
}
|
||
|
|
||
|
public function addEntityPermission(Entity $entity, array $actionList, ?Role $role = null, ?User $user = null)
|
||
|
{
|
||
|
$permissionData = $this->actionListToEntityPermissionData($actionList, $role->id ?? null, $user->id ?? null);
|
||
|
$this->addEntityPermissionEntries($entity, [$permissionData]);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Disable inherited permissions on the given entity.
|
||
|
* Effectively sets the "Other Users" UI permission option to not inherit, with no permissions.
|
||
|
*/
|
||
|
public function disableEntityInheritedPermissions(Entity $entity): void
|
||
|
{
|
||
|
$entity->permissions()->whereNull(['user_id', 'role_id'])->delete();
|
||
|
$fallback = $this->actionListToEntityPermissionData([]);
|
||
|
$this->addEntityPermissionEntries($entity, [$fallback]);
|
||
|
}
|
||
|
|
||
|
protected function addEntityPermissionEntries(Entity $entity, array $entityPermissionData): void
|
||
|
{
|
||
|
$entity->permissions()->createMany($entityPermissionData);
|
||
|
$entity->load('permissions');
|
||
|
$this->regenerateForEntity($entity);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* For the given simple array of string actions (view, create, update, delete), convert
|
||
|
* the format to entity permission data, where permission is granted if the action is in the
|
||
|
* given actionList array.
|
||
|
*/
|
||
|
protected function actionListToEntityPermissionData(array $actionList, int $roleId = null, int $userId = null): array
|
||
|
{
|
||
|
$permissionData = ['role_id' => $roleId, 'user_id' => $userId];
|
||
|
foreach (EntityPermission::PERMISSIONS as $possibleAction) {
|
||
|
$permissionData[$possibleAction] = in_array($possibleAction, $actionList);
|
||
|
}
|
||
|
|
||
|
return $permissionData;
|
||
|
}
|
||
|
}
|