Skip to content

Commit f1cc872

Browse files
committed
[Security] Add retrieval of encompassing role names
The aim of this method is to provide a handy way of getting the roles that encompass (or are parent of) an array of roles. It is similar to the getReachableRoleNames from the same interface but instead of retrieving the children roles it retrieves the parent roles. A typical use case would be when we get a user role from a database and need to get all the roles that also have access to what this role can access.
1 parent b15a479 commit f1cc872

File tree

4 files changed

+39
-0
lines changed

4 files changed

+39
-0
lines changed

src/Symfony/Component/Security/Core/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ CHANGELOG
22
=========
33

44

5+
7.1
6+
---
7+
8+
* Add `getEncompassingRoleNames` method to `RoleHierarchyInterface`
9+
510
7.0
611
---
712

src/Symfony/Component/Security/Core/Role/RoleHierarchy.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ public function getReachableRoleNames(array $roles): array
5050
return array_values(array_unique($reachableRoles));
5151
}
5252

53+
public function getEncompassingRoleNames(array $roles): array
54+
{
55+
$encompassingRoles = $roles;
56+
57+
foreach ($roles as $role) {
58+
foreach ($this->map as $parent => $children) {
59+
if (\in_array($role, $children)) {
60+
$encompassingRoles[] = $parent;
61+
}
62+
}
63+
}
64+
65+
return array_values(array_unique($encompassingRoles));
66+
}
67+
5368
protected function buildRoleMap(): void
5469
{
5570
$this->map = [];

src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
/**
1515
* RoleHierarchyInterface is the interface for a role hierarchy.
1616
*
17+
* @method array getEncompassingRoleNames(array $roles)
18+
*
1719
* @author Fabien Potencier <fabien@symfony.com>
1820
*/
1921
interface RoleHierarchyInterface

src/Symfony/Component/Security/Core/Tests/Role/RoleHierarchyTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,21 @@ public function testGetReachableRoleNames()
3030
$this->assertEquals(['ROLE_SUPER_ADMIN', 'ROLE_ADMIN', 'ROLE_FOO', 'ROLE_USER'], $role->getReachableRoleNames(['ROLE_SUPER_ADMIN']));
3131
$this->assertEquals(['ROLE_SUPER_ADMIN', 'ROLE_ADMIN', 'ROLE_FOO', 'ROLE_USER'], $role->getReachableRoleNames(['ROLE_SUPER_ADMIN', 'ROLE_SUPER_ADMIN']));
3232
}
33+
34+
public function testGetEncompassingRoleNames()
35+
{
36+
$role = new RoleHierarchy([
37+
'ROLE_ADMIN' => ['ROLE_USER'],
38+
'ROLE_SUPER_ADMIN' => ['ROLE_ADMIN', 'ROLE_FOO'],
39+
'ROLE_USER' => ['ROLE_BAR'],
40+
]);
41+
42+
$this->assertEquals(['ROLE_SUPER_ADMIN'], $role->getEncompassingRoleNames(['ROLE_SUPER_ADMIN']));
43+
$this->assertEquals(['ROLE_ADMIN', 'ROLE_SUPER_ADMIN'], $role->getEncompassingRoleNames(['ROLE_ADMIN']));
44+
$this->assertEquals(['ROLE_USER', 'ROLE_ADMIN', 'ROLE_SUPER_ADMIN'], $role->getEncompassingRoleNames(['ROLE_USER']));
45+
$this->assertEquals(['ROLE_BAR', 'ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_USER'], $role->getEncompassingRoleNames(['ROLE_BAR']));
46+
$this->assertEquals(['ROLE_SUPER_ADMIN'], $role->getEncompassingRoleNames(['ROLE_SUPER_ADMIN', 'ROLE_SUPER_ADMIN']));
47+
$this->assertEquals(['ROLE_SUPER_ADMIN', 'ROLE_USER', 'ROLE_ADMIN'], $role->getEncompassingRoleNames(['ROLE_SUPER_ADMIN', 'ROLE_USER']));
48+
$this->assertEquals(['ROLE_BAR', 'ROLE_FOO', 'ROLE_ADMIN', 'ROLE_SUPER_ADMIN', 'ROLE_USER'], $role->getEncompassingRoleNames(['ROLE_BAR', 'ROLE_FOO']));
49+
}
3350
}

0 commit comments

Comments
 (0)