mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-08-09 10:22:51 +03:00
Added a bunch of role content permissions
This commit is contained in:
@@ -6,6 +6,64 @@ Test cases are written ability abstract, since all abilities should act the same
|
||||
|
||||
## Cases
|
||||
|
||||
TODO - User permissions
|
||||
TODO - Role & entity-role interplay
|
||||
TODO - entity-user permissions
|
||||
TODO - entity-user & entity-role interplay
|
||||
|
||||
### Content Role Permissions
|
||||
|
||||
These are tests related to item/entity permissions that are set only at a role level.
|
||||
|
||||
#### test_01_allow
|
||||
|
||||
- Role A has role all-page permission.
|
||||
- User has Role A.
|
||||
|
||||
User granted page permission.
|
||||
|
||||
#### test_02_deny
|
||||
|
||||
- Role A has no page permission.
|
||||
- User has Role A.
|
||||
|
||||
User denied page permission.
|
||||
|
||||
#### test_10_allow_on_own_with_own
|
||||
|
||||
- Role A has role own-page permission.
|
||||
- User has Role A.
|
||||
- User is owner of page.
|
||||
|
||||
User granted page permission.
|
||||
|
||||
#### test_11_deny_on_other_with_own
|
||||
|
||||
- Role A has role own-page permission.
|
||||
- User has Role A.
|
||||
- User is not owner of page.
|
||||
|
||||
User denied page permission.
|
||||
|
||||
#### test_20_multiple_role_conflicting_all
|
||||
|
||||
- Role A has role all-page permission.
|
||||
- Role B has no page permission.
|
||||
- User has Role A & B.
|
||||
|
||||
User granted page permission.
|
||||
|
||||
#### test_21_multiple_role_conflicting_own
|
||||
|
||||
- Role A has role own-page permission.
|
||||
- Role B has no page permission.
|
||||
- User has Role A & B.
|
||||
- User is owner of page.
|
||||
|
||||
User granted page permission.
|
||||
|
||||
---
|
||||
|
||||
### Entity Role Permissions
|
||||
|
||||
These are tests related to entity-level role-specific permission overrides.
|
||||
@@ -16,7 +74,7 @@ These are tests related to entity-level role-specific permission overrides.
|
||||
- Role A has entity allow page permission.
|
||||
- User has Role A.
|
||||
|
||||
User should have page permission.
|
||||
User granted page permission.
|
||||
|
||||
#### test_02_explicit_deny
|
||||
|
||||
@@ -33,7 +91,7 @@ User denied page permission.
|
||||
- Role B has entity deny page permission.
|
||||
- User has both Role A & B.
|
||||
|
||||
User should have page permission.
|
||||
User granted page permission.
|
||||
Explicit grant overrides entity deny at same level.
|
||||
|
||||
#### test_20_inherit_allow
|
||||
@@ -41,16 +99,16 @@ Explicit grant overrides entity deny at same level.
|
||||
- Page permissions have inherit enabled.
|
||||
- Chapter permissions has inherit disabled.
|
||||
- Role A has entity allow chapter permission.
|
||||
- User has both Role A.
|
||||
- User has Role A.
|
||||
|
||||
User should have page permission.
|
||||
User granted page permission.
|
||||
|
||||
#### test_21_inherit_deny
|
||||
|
||||
- Page permissions have inherit enabled.
|
||||
- Chapter permissions has inherit disabled.
|
||||
- Role A has entity deny chapter permission.
|
||||
- User has both Role A.
|
||||
- User has Role A.
|
||||
|
||||
User denied page permission.
|
||||
|
||||
@@ -62,7 +120,7 @@ User denied page permission.
|
||||
- Role B has entity allow chapter permission.
|
||||
- User has both Role A & B.
|
||||
|
||||
User should have page permission.
|
||||
User granted page permission.
|
||||
|
||||
#### test_30_child_inherit_override_allow
|
||||
|
||||
@@ -72,7 +130,7 @@ User should have page permission.
|
||||
- Role A has entity allow page permission.
|
||||
- User has Role A.
|
||||
|
||||
User should have page permission.
|
||||
User granted page permission.
|
||||
|
||||
#### test_31_child_inherit_override_deny
|
||||
|
||||
|
@@ -56,6 +56,16 @@ class PermissionsProvider
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@@ -2,13 +2,7 @@
|
||||
|
||||
namespace Tests\Permissions\Scenarios;
|
||||
|
||||
use BookStack\Auth\User;
|
||||
use BookStack\Entities\Models\Entity;
|
||||
use Tests\TestCase;
|
||||
|
||||
// Cases defined in dev/docs/permission-scenario-testing.md
|
||||
|
||||
class EntityRolePermissions extends TestCase
|
||||
class EntityRolePermissions extends PermissionScenarioTestCase
|
||||
{
|
||||
public function test_01_explicit_allow()
|
||||
{
|
||||
@@ -104,30 +98,4 @@ class EntityRolePermissions extends TestCase
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
|
||||
protected function assertVisibleToUser(Entity $entity, User $user)
|
||||
{
|
||||
$this->actingAs($user);
|
||||
$funcView = userCan($entity->getMorphClass() . '-view', $entity);
|
||||
$queryView = $entity->newQuery()->scopes(['visible'])->find($entity->id) !== null;
|
||||
|
||||
$id = $entity->getMorphClass() . ':' . $entity->id;
|
||||
$msg = "Item [{$id}] should be visible but was not found via ";
|
||||
$msg .= implode(' and ', array_filter([!$funcView ? 'userCan' : '', !$queryView ? 'query' : '']));
|
||||
|
||||
static::assertTrue($funcView && $queryView, $msg);
|
||||
}
|
||||
|
||||
protected function assertNotVisibleToUser(Entity $entity, User $user)
|
||||
{
|
||||
$this->actingAs($user);
|
||||
$funcView = userCan($entity->getMorphClass() . '-view', $entity);
|
||||
$queryView = $entity->newQuery()->scopes(['visible'])->find($entity->id) !== null;
|
||||
|
||||
$id = $entity->getMorphClass() . ':' . $entity->id;
|
||||
$msg = "Item [{$id}] should not be visible but was found via ";
|
||||
$msg .= implode(' and ', array_filter([$funcView ? 'userCan' : '', $queryView ? 'query' : '']));
|
||||
|
||||
static::assertTrue(!$funcView && !$queryView, $msg);
|
||||
}
|
||||
}
|
||||
|
38
tests/Permissions/Scenarios/PermissionScenarioTestCase.php
Normal file
38
tests/Permissions/Scenarios/PermissionScenarioTestCase.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Permissions\Scenarios;
|
||||
|
||||
use BookStack\Auth\User;
|
||||
use BookStack\Entities\Models\Entity;
|
||||
use Tests\TestCase;
|
||||
|
||||
// Cases defined in dev/docs/permission-scenario-testing.md
|
||||
|
||||
class PermissionScenarioTestCase extends TestCase
|
||||
{
|
||||
protected function assertVisibleToUser(Entity $entity, User $user)
|
||||
{
|
||||
$this->actingAs($user);
|
||||
$funcView = userCan($entity->getMorphClass() . '-view', $entity);
|
||||
$queryView = $entity->newQuery()->scopes(['visible'])->find($entity->id) !== null;
|
||||
|
||||
$id = $entity->getMorphClass() . ':' . $entity->id;
|
||||
$msg = "Item [{$id}] should be visible but was not found via ";
|
||||
$msg .= implode(' and ', array_filter([!$funcView ? 'userCan' : '', !$queryView ? 'query' : '']));
|
||||
|
||||
static::assertTrue($funcView && $queryView, $msg);
|
||||
}
|
||||
|
||||
protected function assertNotVisibleToUser(Entity $entity, User $user)
|
||||
{
|
||||
$this->actingAs($user);
|
||||
$funcView = userCan($entity->getMorphClass() . '-view', $entity);
|
||||
$queryView = $entity->newQuery()->scopes(['visible'])->find($entity->id) !== null;
|
||||
|
||||
$id = $entity->getMorphClass() . ':' . $entity->id;
|
||||
$msg = "Item [{$id}] should not be visible but was found via ";
|
||||
$msg .= implode(' and ', array_filter([$funcView ? 'userCan' : '', $queryView ? 'query' : '']));
|
||||
|
||||
static::assertTrue(!$funcView && !$queryView, $msg);
|
||||
}
|
||||
}
|
59
tests/Permissions/Scenarios/RoleContentPermissions.php
Normal file
59
tests/Permissions/Scenarios/RoleContentPermissions.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Permissions\Scenarios;
|
||||
|
||||
class RoleContentPermissions extends PermissionScenarioTestCase
|
||||
{
|
||||
public function test_01_allow()
|
||||
{
|
||||
[$user] = $this->users->newUserWithRole([], ['page-view-all']);
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
|
||||
public function test_02_deny()
|
||||
{
|
||||
[$user] = $this->users->newUserWithRole([], []);
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
|
||||
public function test_10_allow_on_own_with_own()
|
||||
{
|
||||
[$user] = $this->users->newUserWithRole([], ['page-view-own']);
|
||||
$page = $this->entities->page();
|
||||
$this->permissions->changeEntityOwner($page, $user);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
|
||||
public function test_11_deny_on_other_with_own()
|
||||
{
|
||||
[$user] = $this->users->newUserWithRole([], ['page-view-own']);
|
||||
$page = $this->entities->page();
|
||||
$this->permissions->changeEntityOwner($page, $this->users->editor());
|
||||
|
||||
$this->assertNotVisibleToUser($page, $user);
|
||||
}
|
||||
|
||||
public function test_20_multiple_role_conflicting_all()
|
||||
{
|
||||
[$user] = $this->users->newUserWithRole([], ['page-view-all']);
|
||||
$this->users->attachNewRole($user, []);
|
||||
$page = $this->entities->page();
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
|
||||
public function test_21_multiple_role_conflicting_own()
|
||||
{
|
||||
[$user] = $this->users->newUserWithRole([], ['page-view-own']);
|
||||
$this->users->attachNewRole($user, []);
|
||||
$page = $this->entities->page();
|
||||
$this->permissions->changeEntityOwner($page, $user);
|
||||
|
||||
$this->assertVisibleToUser($page, $user);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user