diff --git a/src/Symfony/Component/Security/Core/CHANGELOG.md b/src/Symfony/Component/Security/Core/CHANGELOG.md index 47b4a21082738..2b00735b74756 100644 --- a/src/Symfony/Component/Security/Core/CHANGELOG.md +++ b/src/Symfony/Component/Security/Core/CHANGELOG.md @@ -2,6 +2,11 @@ CHANGELOG ========= +7.1 +--- + +* Add `getEncompassingRoleNames` method to `RoleHierarchyInterface` + 7.0 --- diff --git a/src/Symfony/Component/Security/Core/Role/RoleHierarchy.php b/src/Symfony/Component/Security/Core/Role/RoleHierarchy.php index 15c5750d88c62..5de5f3bfcd447 100644 --- a/src/Symfony/Component/Security/Core/Role/RoleHierarchy.php +++ b/src/Symfony/Component/Security/Core/Role/RoleHierarchy.php @@ -50,6 +50,22 @@ public function getReachableRoleNames(array $roles): array return array_values(array_unique($reachableRoles)); } + public function getEncompassingRoleNames(array $roles): array + { + $encompassingRoles = $roles; + + foreach ($roles as $role) { + foreach ($this->map as $parent => $children) { + if (in_array($role, $children)) { + $encompassingRoles[] = $parent; + } + + } + } + + return array_values(array_unique($encompassingRoles)); + } + protected function buildRoleMap(): void { $this->map = []; diff --git a/src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php b/src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php index 6e8fa81d07f40..d0b967cdf7024 100644 --- a/src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php +++ b/src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php @@ -14,6 +14,8 @@ /** * RoleHierarchyInterface is the interface for a role hierarchy. * + * @method array getEncompassingRoleNames(array $roles) + * * @author Fabien Potencier */ interface RoleHierarchyInterface diff --git a/src/Symfony/Component/Security/Core/Tests/Role/RoleHierarchyTest.php b/src/Symfony/Component/Security/Core/Tests/Role/RoleHierarchyTest.php index 5c42e0b39f8bf..52f5b97897570 100644 --- a/src/Symfony/Component/Security/Core/Tests/Role/RoleHierarchyTest.php +++ b/src/Symfony/Component/Security/Core/Tests/Role/RoleHierarchyTest.php @@ -30,4 +30,21 @@ public function testGetReachableRoleNames() $this->assertEquals(['ROLE_SUPER_ADMIN', 'ROLE_ADMIN', 'ROLE_FOO', 'ROLE_USER'], $role->getReachableRoleNames(['ROLE_SUPER_ADMIN'])); $this->assertEquals(['ROLE_SUPER_ADMIN', 'ROLE_ADMIN', 'ROLE_FOO', 'ROLE_USER'], $role->getReachableRoleNames(['ROLE_SUPER_ADMIN', 'ROLE_SUPER_ADMIN'])); } + + public function testGetEncompassingRoleNames() + { + $role = new RoleHierarchy([ + 'ROLE_ADMIN' => ['ROLE_USER'], + 'ROLE_SUPER_ADMIN' => ['ROLE_ADMIN', 'ROLE_FOO'], + 'ROLE_USER' => ['ROLE_BAR'], + ]); + + $this->assertEquals(['ROLE_SUPER_ADMIN'], $role->getEncompassingRoleNames(['ROLE_SUPER_ADMIN'])); + $this->assertEquals(['ROLE_ADMIN', 'ROLE_SUPER_ADMIN'], $role->getEncompassingRoleNames(['ROLE_ADMIN'])); + $this->assertEquals(['ROLE_USER', 'ROLE_ADMIN', 'ROLE_SUPER_ADMIN'], $role->getEncompassingRoleNames(['ROLE_USER'])); + $this->assertEquals(['ROLE_BAR', 'ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_USER'], $role->getEncompassingRoleNames(['ROLE_BAR'])); + $this->assertEquals(['ROLE_SUPER_ADMIN'], $role->getEncompassingRoleNames(['ROLE_SUPER_ADMIN', 'ROLE_SUPER_ADMIN'])); + $this->assertEquals(['ROLE_SUPER_ADMIN', 'ROLE_USER', 'ROLE_ADMIN'], $role->getEncompassingRoleNames(['ROLE_SUPER_ADMIN', 'ROLE_USER'])); + $this->assertEquals(['ROLE_BAR', 'ROLE_FOO','ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_USER'], $role->getEncompassingRoleNames(['ROLE_BAR', 'ROLE_FOO'])); + } }