## 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.
- Role A has entity allow page permission.
- User has Role A.
-User should have page permission.
+User granted page permission.
#### test_02_explicit_deny
- 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
- 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.
- 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
- 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
}
}
+ /**
+ * 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.
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()
{
$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);
- }
}
--- /dev/null
+<?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);
+ }
+}
--- /dev/null
+<?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);
+ }
+}