]> BookStack Code Mirror - bookstack/commitdiff
Added entity user permission scenarios
authorDan Brown <redacted>
Tue, 20 Dec 2022 15:50:41 +0000 (15:50 +0000)
committerDan Brown <redacted>
Tue, 20 Dec 2022 15:50:41 +0000 (15:50 +0000)
Also added definitions for general expected behaviour to readme doc, and
added some entity role inherit scenarios to check they meet expectations.
Currently failing role test but not an issue with test, needs fixing to
app logic.

dev/docs/permission-scenario-testing.md
tests/Helpers/UserRoleProvider.php
tests/Permissions/Scenarios/EntityRolePermissions.php
tests/Permissions/Scenarios/EntityUserPermissions.php [new file with mode: 0644]

index 5797ee3625e0d2cd1684fd67dbb13d44ca5197e6..f39329ee53f453edb12f0ed4df69097174426a5b 100644 (file)
@@ -4,12 +4,26 @@ Due to complexity that can arise in the various combinations of permissions, thi
 
 Test cases are written ability abstract, since all abilities should act the same in theory. Functional test cases may test abilities separate due to implementation differences.
 
+Tests are categorised by the most specific element involved in the scenario, where the below list is most specific to least:
+
+- User entity permissions.
+- Role entity permissions.
+- Role permissions.
+
+## General Permission Logical Rules
+
+The below are some general rules we follow to standardise the behaviour of permissions in the platform:
+
+- Most specific permission application (as above) take priority and can deny less specific permissions.
+- Parent user/role entity permissions that may be inherited, are considered to essentially be applied on the item they are inherited to unless a lower level has its own permission rule for an already specific role/user.
+- Where both grant and deny exist at the same specificity, we side towards grant.
+
 ## Cases
 
-TODO - User permissions
 TODO - Role & entity-role interplay
-TODO - entity-user permissions
-TODO - entity-user & entity-role interplay
+TODO - Role & entity-user interplay
+TODO - Role content relations?
+TODO - Role system permissions?
 
 ### Content Role Permissions
 
@@ -140,4 +154,116 @@ User granted page permission.
 - Role A has entity deny page permission.
 - User has Role A.
 
+User denied page permission.
+
+#### test_40_multi_role_inherit_conflict_override_deny
+
+- Page permissions have inherit enabled.
+- Chapter permissions has inherit disabled.
+- Role A has entity deny page permission.
+- Role B has entity allow chapter permission.
+- User has Role A & B.
+
+User granted page permission.
+
+#### test_41_multi_role_inherit_conflict_retain_allow
+
+- Page permissions have inherit enabled.
+- Chapter permissions has inherit disabled.
+- Role A has entity allow page permission.
+- Role B has entity deny chapter permission.
+- User has Role A & B.
+
+User granted page permission.
+
+---
+
+### Entity User Permissions
+
+These are tests related to entity-level user-specific permission overrides.
+
+#### test_01_explicit_allow
+
+- Page permissions have inherit disabled.
+- User has entity allow page permission.
+
+User granted page permission.
+
+#### test_02_explicit_deny
+
+- Page permissions have inherit disabled.
+- User has entity deny page permission.
+
+User denied page permission.
+
+#### test_10_allow_inherit
+
+- Page permissions have inherit enabled.
+- Chapter permissions have inherit disabled.
+- User has entity allow chapter permission.
+
+User granted page permission.
+
+#### test_11_deny_inherit
+
+- Page permissions have inherit enabled.
+- Chapter permissions have inherit disabled.
+- User has entity deny chapter permission.
+
+User denied page permission.
+
+#### test_12_allow_inherit_override
+
+- Page permissions have inherit enabled.
+- Chapter permissions have inherit disabled.
+- User has entity deny chapter permission.
+- User has entity allow page permission.
+
+User granted page permission.
+
+#### test_13_deny_inherit_override
+
+- Page permissions have inherit enabled.
+- Chapter permissions have inherit disabled.
+- User has entity allow chapter permission.
+- User has entity deny page permission.
+
+User denied page permission.
+
+#### test_40_entity_role_override_allow
+
+- Page permissions have inherit disabled.
+- User has entity allow page permission.
+- Role A has entity deny page permission.
+- User has role A.
+
+User granted page permission.
+
+#### test_41_entity_role_override_deny
+
+- Page permissions have inherit disabled.
+- User has entity deny page permission.
+- Role A has entity allow page permission.
+- User has role A.
+
+User denied page permission.
+
+#### test_42_entity_role_override_allow_via_inherit
+
+- Page permissions have inherit enabled.
+- Chapter permissions have inherit disabled.
+- User has entity allow chapter permission.
+- Role A has entity deny page permission.
+- User has role A.
+
+User granted page permission.
+
+#### test_43_entity_role_override_deny_via_inherit
+
+- Page permissions have inherit enabled.
+- Chapter permissions have inherit disabled.
+- User has entity deny chapter permission.
+- Role A has entity allow page permission.
+- User has role A.
+
 User denied page permission.
\ No newline at end of file
index a85bd06cf43e5c732a5346e43ba4eef1793762f3..355c1687c6d6c70933f387e9d259c28a731cefb9 100644 (file)
@@ -50,6 +50,14 @@ class UserRoleProvider
         return $user;
     }
 
+    /**
+     * Create a new fresh user without any relations.
+     */
+    public function newUser(array $attrs = []): User
+    {
+        return User::factory()->create($attrs);
+    }
+
     /**
      * Create a new fresh user, with the given attrs, that has assigned a fresh role
      * that has the given role permissions.
@@ -58,7 +66,7 @@ class UserRoleProvider
      */
     public function newUserWithRole(array $userAttrs = [], array $rolePermissions = []): array
     {
-        $user = User::factory()->create($userAttrs);
+        $user = $this->newUser($userAttrs);
         $role = $this->attachNewRole($user, $rolePermissions);
 
         return [$user, $role];
index 908b07e8c9e8a543b331cef1c2bf8e888edab309..57801abdd7b31a54d3555afa349a70437beedab7 100644 (file)
@@ -98,4 +98,32 @@ class EntityRolePermissions extends PermissionScenarioTestCase
 
         $this->assertNotVisibleToUser($page, $user);
     }
+
+    public function test_40_multi_role_inherit_conflict_override_deny()
+    {
+        [$user, $roleA] = $this->users->newUserWithRole();
+        $roleB = $this->users->attachNewRole($user);
+        $page = $this->entities->pageWithinChapter();
+        $chapter = $page->chapter;
+
+        $this->permissions->disableEntityInheritedPermissions($chapter);
+        $this->permissions->addEntityPermission($page, [], $roleA);
+        $this->permissions->addEntityPermission($chapter, ['view'], $roleB);
+
+        $this->assertVisibleToUser($page, $user);
+    }
+
+    public function test_41_multi_role_inherit_conflict_retain_allow()
+    {
+        [$user, $roleA] = $this->users->newUserWithRole();
+        $roleB = $this->users->attachNewRole($user);
+        $page = $this->entities->pageWithinChapter();
+        $chapter = $page->chapter;
+
+        $this->permissions->disableEntityInheritedPermissions($chapter);
+        $this->permissions->addEntityPermission($page, ['view'], $roleA);
+        $this->permissions->addEntityPermission($chapter, [], $roleB);
+
+        $this->assertVisibleToUser($page, $user);
+    }
 }
diff --git a/tests/Permissions/Scenarios/EntityUserPermissions.php b/tests/Permissions/Scenarios/EntityUserPermissions.php
new file mode 100644 (file)
index 0000000..6bffdde
--- /dev/null
@@ -0,0 +1,118 @@
+<?php
+
+namespace Tests\Permissions\Scenarios;
+
+class EntityUserPermissions extends PermissionScenarioTestCase
+{
+    public function test_01_explicit_allow()
+    {
+        $user = $this->users->newUser();
+        $page = $this->entities->page();
+        $this->permissions->disableEntityInheritedPermissions($page);
+        $this->permissions->addEntityPermission($page, ['view'], null, $user);
+
+        $this->assertVisibleToUser($page, $user);
+    }
+
+    public function test_02_explicit_deny()
+    {
+        $user = $this->users->newUser();
+        $page = $this->entities->page();
+        $this->permissions->disableEntityInheritedPermissions($page);
+        $this->permissions->addEntityPermission($page, [], null, $user);
+
+        $this->assertNotVisibleToUser($page, $user);
+    }
+
+    public function test_10_allow_inherit()
+    {
+        $user = $this->users->newUser();
+        $page = $this->entities->pageWithinChapter();
+        $chapter = $page->chapter;
+        $this->permissions->disableEntityInheritedPermissions($chapter);
+        $this->permissions->addEntityPermission($chapter, ['view'], null, $user);
+
+        $this->assertVisibleToUser($page, $user);
+    }
+
+    public function test_11_deny_inherit()
+    {
+        $user = $this->users->newUser();
+        $page = $this->entities->pageWithinChapter();
+        $chapter = $page->chapter;
+        $this->permissions->disableEntityInheritedPermissions($chapter);
+        $this->permissions->addEntityPermission($chapter, [], null, $user);
+
+        $this->assertNotVisibleToUser($page, $user);
+    }
+
+    public function test_12_allow_inherit_override()
+    {
+        $user = $this->users->newUser();
+        $page = $this->entities->pageWithinChapter();
+        $chapter = $page->chapter;
+        $this->permissions->disableEntityInheritedPermissions($chapter);
+        $this->permissions->addEntityPermission($chapter, [], null, $user);
+        $this->permissions->addEntityPermission($page, ['view'], null, $user);
+
+        $this->assertVisibleToUser($page, $user);
+    }
+
+    public function test_13_deny_inherit_override()
+    {
+        $user = $this->users->newUser();
+        $page = $this->entities->pageWithinChapter();
+        $chapter = $page->chapter;
+        $this->permissions->disableEntityInheritedPermissions($chapter);
+        $this->permissions->addEntityPermission($chapter, ['view'], null, $user);
+        $this->permissions->addEntityPermission($page, ['deny'], null, $user);
+
+        $this->assertNotVisibleToUser($page, $user);
+    }
+
+    public function test_40_entity_role_override_allow()
+    {
+        [$user, $role] = $this->users->newUserWithRole();
+        $page = $this->entities->page();
+        $this->permissions->disableEntityInheritedPermissions($page);
+        $this->permissions->addEntityPermission($page, ['view'], null, $user);
+        $this->permissions->addEntityPermission($page, [], $role);
+
+        $this->assertVisibleToUser($page, $user);
+    }
+
+    public function test_41_entity_role_override_deny()
+    {
+        [$user, $role] = $this->users->newUserWithRole();
+        $page = $this->entities->page();
+        $this->permissions->disableEntityInheritedPermissions($page);
+        $this->permissions->addEntityPermission($page, [], null, $user);
+        $this->permissions->addEntityPermission($page, ['view'], $role);
+
+        $this->assertNotVisibleToUser($page, $user);
+    }
+
+    public function test_42_entity_role_override_allow_via_inherit()
+    {
+        [$user, $role] = $this->users->newUserWithRole();
+        $page = $this->entities->pageWithinChapter();
+        $chapter = $page->chapter;
+        $this->permissions->disableEntityInheritedPermissions($chapter);
+        $this->permissions->addEntityPermission($chapter, ['view'], null, $user);
+        $this->permissions->addEntityPermission($page, [], $role);
+
+        $this->assertVisibleToUser($page, $user);
+    }
+
+    public function test_43_entity_role_override_deny_via_inherit()
+    {
+        [$user, $role] = $this->users->newUserWithRole();
+        $page = $this->entities->pageWithinChapter();
+        $chapter = $page->chapter;
+        $this->permissions->disableEntityInheritedPermissions($chapter);
+        $this->permissions->addEntityPermission($chapter, [], null, $user);
+        $this->permissions->addEntityPermission($page, ['view'], $role);
+
+        $this->assertNotVisibleToUser($page, $user);
+    }
+}