Addressed fallback override cases found during testing

Had misalignment between query and usercan, The nuance between fallback
and entity-role permissions was not taken into account by the query
system. Now added with new test cases to cover.
This commit is contained in:
Dan Brown 2023-01-24 20:42:20 +00:00
parent d1bd6d0e39
commit 8be36455ab
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
6 changed files with 192 additions and 9 deletions

View File

@ -25,22 +25,24 @@ class EntityPermissionEvaluator
$relevantPermissions = $this->getPermissionsMapByTypeId($typeIdChain, [...$userRoleIds, 0]);
$permitsByType = $this->collapseAndCategorisePermissions($typeIdChain, $relevantPermissions);
return $this->evaluatePermitsByType($permitsByType);
$status = $this->evaluatePermitsByType($permitsByType);
return is_null($status) ? null : $status === PermissionStatus::IMPLICIT_ALLOW || $status === PermissionStatus::EXPLICIT_ALLOW;
}
/**
* @param array<string, array<string, int>> $permitsByType
*/
protected function evaluatePermitsByType(array $permitsByType): ?bool
protected function evaluatePermitsByType(array $permitsByType): ?int
{
// Return grant or reject from role-level if exists
if (count($permitsByType['role']) > 0) {
return boolval(max($permitsByType['role']));
return max($permitsByType['role']) ? PermissionStatus::EXPLICIT_ALLOW : PermissionStatus::EXPLICIT_DENY;
}
// Return fallback permission if exists
if (count($permitsByType['fallback']) > 0) {
return boolval($permitsByType['fallback'][0]);
return $permitsByType['fallback'][0] ? PermissionStatus::IMPLICIT_ALLOW : PermissionStatus::IMPLICIT_DENY;
}
return null;

View File

@ -262,8 +262,7 @@ class JointPermissionBuilder
// Return evaluated entity permission status if it has an affect.
$entityPermissionStatus = $permissionMap->evaluateEntityForRole($entity, $roleId);
if ($entityPermissionStatus !== null) {
$status = $entityPermissionStatus ? PermissionStatus::EXPLICIT_ALLOW : PermissionStatus::EXPLICIT_DENY;
return $this->createJointPermissionDataArray($entity, $roleId, $status, $entityPermissionStatus);
return $this->createJointPermissionDataArray($entity, $roleId, $entityPermissionStatus, false);
}
// Otherwise default to the role-level permissions

View File

@ -16,7 +16,7 @@ class MassEntityPermissionEvaluator extends EntityPermissionEvaluator
parent::__construct($action);
}
public function evaluateEntityForRole(SimpleEntityData $entity, int $roleId): ?bool
public function evaluateEntityForRole(SimpleEntityData $entity, int $roleId): ?int
{
$typeIdChain = $this->gatherEntityChainTypeIds($entity);
$relevantPermissions = $this->getPermissionMapByTypeIdForChainAndRole($typeIdChain, $roleId);

View File

@ -229,7 +229,7 @@ User denied page permission.
User denied page permission.
#### test_80_multi_role_inherited_deny_via_parent
#### test_75_multi_role_inherited_deny_via_parent
- Page permissions have inherit enabled.
- Chapter permissions have inherit enabled.
@ -238,3 +238,83 @@ User denied page permission.
- User has Role A & B.
User denied page permission.
#### test_80_fallback_override_allow
- Page permissions have inherit disabled.
- Page fallback has entity deny permission.
- Role A has entity allow page permission.
- User has Role A.
User granted page permission.
#### test_81_fallback_override_deny
- Page permissions have inherit disabled.
- Page fallback has entity allow permission.
- Role A has entity deny page permission.
- User has Role A.
User denied page permission.
#### test_84_fallback_override_allow_multi_role
- Page permissions have inherit disabled.
- Page fallback has entity deny permission.
- Role A has entity allow page permission.
- Role B has no entity page permissions.
- User has Role A & B.
User granted page permission.
#### test_85_fallback_override_deny_multi_role
- Page permissions have inherit disabled.
- Page fallback has entity allow permission.
- Role A has entity deny page permission.
- Role B has no entity page permissions.
- User has Role A & B.
User denied page permission.
#### test_86_fallback_override_allow_inherit
- Chapter permissions have inherit disabled.
- Page permissions have inherit enabled.
- Chapter fallback has entity deny permission.
- Role A has entity allow chapter permission.
- User has Role A.
User granted page permission.
#### test_87_fallback_override_deny_inherit
- Chapter permissions have inherit disabled.
- Page permissions have inherit enabled.
- Chapter fallback has entity allow permission.
- Role A has entity deny chapter permission.
- User has Role A.
User denied page permission.
#### test_88_fallback_override_allow_multi_role_inherit
- Chapter permissions have inherit disabled.
- Page permissions have inherit enabled.
- Chapter fallback has entity deny permission.
- Role A has entity allow chapter permission.
- Role B has no entity chapter permissions.
- User has Role A & B.
User granted page permission.
#### test_89_fallback_override_deny_multi_role_inherit
- Chapter permissions have inherit disabled.
- Page permissions have inherit enabled.
- Chapter fallback has entity allow permission.
- Role A has entity deny chapter permission.
- Role B has no entity chapter permissions.
- User has Role A & B.
User denied page permission.

View File

@ -101,6 +101,13 @@ class PermissionsProvider
$this->addEntityPermissionEntries($entity, [$permissionData]);
}
public function setFallbackPermissions(Entity $entity, array $actionList)
{
$entity->permissions()->where('role_id', '=', 0)->delete();
$permissionData = $this->actionListToEntityPermissionData($actionList, 0);
$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.

View File

@ -187,7 +187,7 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
$this->assertNotVisibleToUser($page, $user);
}
public function test_80_multi_role_inherited_deny_via_parent()
public function test_75_multi_role_inherited_deny_via_parent()
{
[$user, $roleA] = $this->users->newUserWithRole([], ['page-view-all']);
$roleB = $this->users->attachNewRole($user);
@ -198,4 +198,99 @@ class EntityRolePermissionsTest extends PermissionScenarioTestCase
$this->assertNotVisibleToUser($page, $user);
}
public function test_80_fallback_override_allow()
{
[$user, $roleA] = $this->users->newUserWithRole();
$page = $this->entities->page();
$this->permissions->setFallbackPermissions($page, []);
$this->permissions->addEntityPermission($page, ['view'], $roleA);
$this->assertVisibleToUser($page, $user);
}
public function test_81_fallback_override_deny()
{
[$user, $roleA] = $this->users->newUserWithRole();
$page = $this->entities->page();
$this->permissions->setFallbackPermissions($page, ['view']);
$this->permissions->addEntityPermission($page, [], $roleA);
$this->assertNotVisibleToUser($page, $user);
}
public function test_84_fallback_override_allow_multi_role()
{
[$user, $roleA] = $this->users->newUserWithRole();
$roleB = $this->users->attachNewRole($user);
$page = $this->entities->page();
$this->permissions->setFallbackPermissions($page, []);
$this->permissions->addEntityPermission($page, ['view'], $roleA);
$this->assertVisibleToUser($page, $user);
}
public function test_85_fallback_override_deny_multi_role()
{
[$user, $roleA] = $this->users->newUserWithRole();
$roleB = $this->users->attachNewRole($user);
$page = $this->entities->page();
$this->permissions->setFallbackPermissions($page, ['view']);
$this->permissions->addEntityPermission($page, [], $roleA);
$this->assertNotVisibleToUser($page, $user);
}
public function test_86_fallback_override_allow_inherit()
{
[$user, $roleA] = $this->users->newUserWithRole();
$page = $this->entities->page();
$chapter = $page->chapter;
$this->permissions->setFallbackPermissions($chapter, []);
$this->permissions->addEntityPermission($chapter, ['view'], $roleA);
$this->assertVisibleToUser($page, $user);
}
public function test_87_fallback_override_deny_inherit()
{
[$user, $roleA] = $this->users->newUserWithRole();
$page = $this->entities->page();
$chapter = $page->chapter;
$this->permissions->setFallbackPermissions($chapter, ['view']);
$this->permissions->addEntityPermission($chapter, [], $roleA);
$this->assertNotVisibleToUser($page, $user);
}
public function test_88_fallback_override_allow_multi_role_inherit()
{
[$user, $roleA] = $this->users->newUserWithRole();
$roleB = $this->users->attachNewRole($user);
$page = $this->entities->page();
$chapter = $page->chapter;
$this->permissions->setFallbackPermissions($chapter, []);
$this->permissions->addEntityPermission($chapter, ['view'], $roleA);
$this->assertVisibleToUser($page, $user);
}
public function test_89_fallback_override_deny_multi_role_inherit()
{
[$user, $roleA] = $this->users->newUserWithRole();
$roleB = $this->users->attachNewRole($user);
$page = $this->entities->page();
$chapter = $page->chapter;
$this->permissions->setFallbackPermissions($chapter, ['view']);
$this->permissions->addEntityPermission($chapter, [], $roleA);
$this->assertNotVisibleToUser($page, $user);
}
}