Skip to content

Commit

Permalink
Enable security information mapping for RoleSecurityHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
core23 committed Jul 5, 2024
1 parent 0a212f3 commit 4ecfdde
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 6 deletions.
24 changes: 18 additions & 6 deletions src/Security/Handler/RoleSecurityHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,26 @@ private function hasAllRule(mixed $attributes): bool
*/
private function mapAttributes(mixed $attributes, AdminInterface $admin): array
{
// NEXT_MAJOR: Change the foreach to a single check.
foreach ($attributes as $pos => $attribute) {
// If the attribute is not already a ROLE_ we generate the related role.
if (\is_string($attribute) && !str_starts_with($attribute, 'ROLE_')) {
$attributes[$pos] = sprintf($this->getBaseRole($admin), $attribute);
$mappedAttributes = [];

foreach ($attributes as $attribute) {
if (!\is_string($attribute) || str_starts_with($attribute, 'ROLE_')) {
$mappedAttributes[] = $attribute;

continue;
}

$baseRole = $this->getBaseRole($admin);

$mappedAttributes[] = sprintf($baseRole, $attribute);

foreach ($admin->getSecurityInformation() as $role => $permissions) {
if (\in_array($attribute, $permissions, true)) {
$mappedAttributes[] = sprintf($baseRole, $role);
}
}
}

return $attributes;
return array_unique($mappedAttributes);
}
}
45 changes: 45 additions & 0 deletions tests/Security/Handler/RoleSecurityHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,51 @@ public function provideGetBaseRoleCases(): iterable
yield ['ROLE_FOO_BAR_%s', 'FOO.BAR'];
}

/**
* @dataProvider provideIsGrantedWithSecurityInformationCases
*/
public function testIsGrantedWithSecurityInformation(array $informationMapping, array $userRoles, bool $expected): void

Check failure on line 73 in tests/Security/Handler/RoleSecurityHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method Sonata\AdminBundle\Tests\Security\Handler\RoleSecurityHandlerTest::testIsGrantedWithSecurityInformation() has parameter $informationMapping with no value type specified in iterable type array.

Check failure on line 73 in tests/Security/Handler/RoleSecurityHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method Sonata\AdminBundle\Tests\Security\Handler\RoleSecurityHandlerTest::testIsGrantedWithSecurityInformation() has parameter $userRoles with no value type specified in iterable type array.
{
$handler = new RoleSecurityHandler($this->authorizationChecker, 'ROLE_SUPER_ADMIN');

$subject = new \stdClass();

$this->admin
->method('getCode')
->willReturn('test');
$this->admin->expects(static::once())
->method('getSecurityInformation')
->willReturn($informationMapping);

$this->authorizationChecker
->method('isGranted')
->willReturnCallback(static function (mixed $attribute, mixed $subject = null) use ($userRoles): bool {
if ($attribute instanceof Expression) {
$attribute = (string) $attribute;
}

if (\in_array($attribute, $userRoles, true)) {
return $subject instanceof \stdClass;
}

return false;
});

static::assertSame($expected, $handler->isGranted($this->admin, 'EDIT', $subject));
}

/**
* @phpstan-return iterable<array{string, string}>

Check failure on line 104 in tests/Security/Handler/RoleSecurityHandlerTest.php

View workflow job for this annotation

GitHub Actions / Psalm

InvalidReturnType

tests/Security/Handler/RoleSecurityHandlerTest.php:104:24: InvalidReturnType: The declared return type 'iterable<mixed, list{string, string}>' for Sonata\AdminBundle\Tests\Security\Handler\RoleSecurityHandlerTest::provideIsGrantedWithSecurityInformationCases is incorrect, got 'Generator<'default mapping'|'with all mapping'|'with missing permission'|'with multiple mappings'|'with single mapping', list{array{ADMIN?: list{'ALL'}, MANAGE?: list{'EDIT', 'SHOW', 'DELETE'}, SHOW?: list{'VIEW', 'SHOW'}, VIEW?: list{'EDIT', 'SHOW'}, WRITE?: list{'EDIT', 'SHOW'}}, list{'ROLE_TEST_ALL'|'ROLE_TEST_EDIT'|'ROLE_TEST_MANAGE'|'ROLE_TEST_VIEW'}, bool}, mixed, void>' (see https://psalm.dev/011)
*/
public function provideIsGrantedWithSecurityInformationCases(): iterable
{
yield 'default mapping' => [[], ['ROLE_TEST_EDIT'], true];

Check failure on line 108 in tests/Security/Handler/RoleSecurityHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Generator expects value type array{string, string}, array{array{}, array{'ROLE_TEST_EDIT'}, true} given.
yield 'with single mapping' => [['VIEW' => ['EDIT', 'SHOW']], ['ROLE_TEST_VIEW'], true];

Check failure on line 109 in tests/Security/Handler/RoleSecurityHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Generator expects value type array{string, string}, array{array{VIEW: array{'EDIT', 'SHOW'}}, array{'ROLE_TEST_VIEW'}, true} given.
yield 'with multiple mappings' => [['WRITE' => ['EDIT', 'SHOW'], 'MANAGE' => ['EDIT', 'SHOW', 'DELETE']], ['ROLE_TEST_MANAGE'], true];

Check failure on line 110 in tests/Security/Handler/RoleSecurityHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Generator expects value type array{string, string}, array{array{WRITE: array{'EDIT', 'SHOW'}, MANAGE: array{'EDIT', 'SHOW', 'DELETE'}}, array{'ROLE_TEST_MANAGE'}, true} given.
yield 'with all mapping' => [['ADMIN' => ['ALL']], ['ROLE_TEST_ALL'], true];

Check failure on line 111 in tests/Security/Handler/RoleSecurityHandlerTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Generator expects value type array{string, string}, array{array{ADMIN: array{'ALL'}}, array{'ROLE_TEST_ALL'}, true} given.
yield 'with missing permission' => [['SHOW' => ['VIEW', 'SHOW']], ['ROLE_TEST_VIEW'], false];
}

/**
* NEXT_MAJOR: Remove the group legacy and only keep string $superAdminRoles and string|Expression $operation in dataProvider.
*
Expand Down

0 comments on commit 4ecfdde

Please sign in to comment.