diff --git a/UPGRADE-4.3.md b/UPGRADE-4.3.md index 52165c10b539e..f91bdb8bf6b16 100644 --- a/UPGRADE-4.3.md +++ b/UPGRADE-4.3.md @@ -88,9 +88,8 @@ Security * The `Role` and `SwitchUserRole` classes are deprecated and will be removed in 5.0. Use strings for roles instead. - * The `RoleHierarchyInterface` is deprecated and will be removed in 5.0. - * The `getReachableRoles()` method of the `RoleHierarchy` class is deprecated and will be removed in 5.0. - Use the `getReachableRoleNames()` method instead. + * The `getReachableRoles()` method of the `RoleHierarchyInterface` is deprecated and will be removed in 5.0. + Role hierarchies must implement the `getReachableRoleNames()` method instead and return roles as strings. * The `getRoles()` method of the `TokenInterface` is deprecated. Tokens must implement the `getRoleNames()` method instead and return roles as strings. * The `ListenerInterface` is deprecated, turn your listeners into callables instead. diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 60b16b1c58df8..5757661bec94f 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -256,8 +256,8 @@ Security -------- * The `Role` and `SwitchUserRole` classes have been removed. - * The `RoleHierarchyInterface` has been removed. - * The `getReachableRoles()` method of the `RoleHierarchy` class has been removed. + * The `getReachableRoles()` method of the `RoleHierarchy` class has been removed. It has been replaced by the new + `getReachableRoleNames()` method. * The `getRoles()` method has been removed from the `TokenInterface`. It has been replaced by the new `getRoleNames()` method. * The `ContextListener::setLogoutOnUserChange()` method has been removed. diff --git a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php index d33d227ff137c..0d122efe7fd81 100644 --- a/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php +++ b/src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php @@ -23,7 +23,6 @@ use Symfony\Component\Security\Core\Authorization\TraceableAccessDecisionManager; use Symfony\Component\Security\Core\Authorization\Voter\TraceableVoter; use Symfony\Component\Security\Core\Role\Role; -use Symfony\Component\Security\Core\Role\RoleHierarchy; use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; use Symfony\Component\Security\Core\Role\SwitchUserRole; use Symfony\Component\Security\Http\Firewall\SwitchUserListener; @@ -113,7 +112,7 @@ public function collect(Request $request, Response $response, \Exception $except } if (null !== $this->roleHierarchy) { - if ($this->roleHierarchy instanceof RoleHierarchy) { + if (method_exists($this->roleHierarchy, 'getReachableRoleNames')) { $allRoles = $this->roleHierarchy->getReachableRoleNames($assignedRoles); } else { $allRoles = array_map(function (Role $role) { return (string) $role; }, $this->roleHierarchy->getReachableRoles($token->getRoles(false))); diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml index d4d6f1a2e362d..1d2f0c4e503b3 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml @@ -98,8 +98,6 @@ %security.role_hierarchy.roles% - - diff --git a/src/Symfony/Component/Security/CHANGELOG.md b/src/Symfony/Component/Security/CHANGELOG.md index e29070f0cc4ca..fc6b60a3a1309 100644 --- a/src/Symfony/Component/Security/CHANGELOG.md +++ b/src/Symfony/Component/Security/CHANGELOG.md @@ -6,9 +6,8 @@ CHANGELOG * The `Role` and `SwitchUserRole` classes are deprecated and will be removed in 5.0. Use strings for roles instead. - * The `RoleHierarchyInterface` is deprecated and will be removed in 5.0. - * The `getReachableRoles()` method of the `RoleHierarchy` class is deprecated and will be removed in 5.0. - Use the `getReachableRoleNames()` method instead. + * The `getReachableRoles()` method of the `RoleHierarchyInterface` is deprecated and will be removed in 5.0. + Role hierarchies must implement the `getReachableRoleNames()` method instead and return roles as strings. * The `getRoles()` method of the `TokenInterface` is deprecated. Tokens must implement the `getRoleNames()` method instead and return roles as strings. * Made the `serialize()` and `unserialize()` methods of `AbstractToken` and diff --git a/src/Symfony/Component/Security/Core/Authorization/Voter/ExpressionVoter.php b/src/Symfony/Component/Security/Core/Authorization/Voter/ExpressionVoter.php index c84fc5d9b43cc..e35583555d60e 100644 --- a/src/Symfony/Component/Security/Core/Authorization/Voter/ExpressionVoter.php +++ b/src/Symfony/Component/Security/Core/Authorization/Voter/ExpressionVoter.php @@ -19,7 +19,6 @@ use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Component\Security\Core\Authorization\ExpressionLanguage; use Symfony\Component\Security\Core\Role\Role; -use Symfony\Component\Security\Core\Role\RoleHierarchy; use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; /** @@ -43,6 +42,10 @@ public function __construct(ExpressionLanguage $expressionLanguage, Authenticati @trigger_error(sprintf('Passing a RoleHierarchyInterface to "%s()" is deprecated since Symfony 4.2. Pass an AuthorizationCheckerInterface instead.', __METHOD__), E_USER_DEPRECATED); $roleHierarchy = $authChecker; $authChecker = null; + + if (!method_exists($roleHierarchy, 'getReachableRoleNames')) { + @trigger_error(sprintf('Not implementing the getReachableRoleNames() method in %s which implements %s is deprecated since Symfony 4.3.', \get_class($this->roleHierarchy), RoleHierarchyInterface::class), E_USER_DEPRECATED); + } } elseif (null === $authChecker) { @trigger_error(sprintf('Argument 3 passed to "%s()" should be an instance of AuthorizationCheckerInterface, not passing it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); } elseif (!$authChecker instanceof AuthorizationCheckerInterface) { @@ -92,27 +95,23 @@ public function vote(TokenInterface $token, $subject, array $attributes) private function getVariables(TokenInterface $token, $subject) { - if ($this->roleHierarchy instanceof RoleHierarchy) { - if (method_exists($token, 'getRoleNames')) { - $rolesFromToken = $token->getRoleNames(); - } else { - @trigger_error(sprintf('Not implementing the getRoleNames() method in %s which implements %s is deprecated since Symfony 4.3.', \get_class($token), TokenInterface::class), E_USER_DEPRECATED); - - $rolesFromToken = $token->getRoles(false); - } - - $roles = $this->roleHierarchy->getReachableRoleNames($rolesFromToken); - } elseif (null !== $this->roleHierarchy) { - $roles = $this->roleHierarchy->getReachableRoles($token->getRoles(false)); - } elseif (method_exists($token, 'getRoleNames')) { - $roles = $token->getRoleNames(); + if (method_exists($token, 'getRoleNames')) { + $roleNames = $token->getRoleNames(); + $roles = array_map(function (string $role) { return new Role($role, false); }, $roleNames); } else { @trigger_error(sprintf('Not implementing the getRoleNames() method in %s which implements %s is deprecated since Symfony 4.3.', \get_class($token), TokenInterface::class), E_USER_DEPRECATED); $roles = $token->getRoles(false); + $roleNames = array_map(function (Role $role) { return $role->getRole(); }, $roles); } - $roles = array_map(function ($role) { return $role instanceof Role ? $role->getRole() : $role; }, $roles); + if (null !== $this->roleHierarchy && method_exists($this->roleHierarchy, 'getReachableRoleNames')) { + $roleNames = $this->roleHierarchy->getReachableRoleNames($roleNames); + $roles = array_map(function (string $role) { return new Role($role, false); }, $roleNames); + } elseif (null !== $this->roleHierarchy) { + $roles = $this->roleHierarchy->getReachableRoles($roles); + $roleNames = array_map(function (Role $role) { return $role->getRole(); }, $roles); + } $variables = [ 'token' => $token, @@ -120,6 +119,7 @@ private function getVariables(TokenInterface $token, $subject) 'object' => $subject, 'subject' => $subject, 'roles' => $roles, + 'role_names' => $roleNames, 'trust_resolver' => $this->trustResolver, 'auth_checker' => $this->authChecker, ]; diff --git a/src/Symfony/Component/Security/Core/Authorization/Voter/RoleHierarchyVoter.php b/src/Symfony/Component/Security/Core/Authorization/Voter/RoleHierarchyVoter.php index 4a1de12cf7fa8..d4524667c5715 100644 --- a/src/Symfony/Component/Security/Core/Authorization/Voter/RoleHierarchyVoter.php +++ b/src/Symfony/Component/Security/Core/Authorization/Voter/RoleHierarchyVoter.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Security\Core\Authorization\Voter; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use Symfony\Component\Security\Core\Role\Role; use Symfony\Component\Security\Core\Role\RoleHierarchy; use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; @@ -27,8 +28,8 @@ class RoleHierarchyVoter extends RoleVoter public function __construct(RoleHierarchyInterface $roleHierarchy, string $prefix = 'ROLE_') { - if (!$roleHierarchy instanceof RoleHierarchy) { - @trigger_error(sprintf('Passing a role hierarchy to "%s" that is not an instance of "%s" is deprecated since Symfony 4.3 and support for it will be dropped in Symfony 5.0 ("%s" given).', __CLASS__, RoleHierarchy::class, \get_class($roleHierarchy)), E_USER_DEPRECATED); + if (!method_exists($roleHierarchy, 'getReachableRoleNames')) { + @trigger_error(sprintf('Not implementing the getReachableRoleNames() method in %s which implements %s is deprecated since Symfony 4.3.', \get_class($roleHierarchy), RoleHierarchyInterface::class), E_USER_DEPRECATED); } $this->roleHierarchy = $roleHierarchy; @@ -41,13 +42,13 @@ public function __construct(RoleHierarchyInterface $roleHierarchy, string $prefi */ protected function extractRoles(TokenInterface $token) { - if ($this->roleHierarchy instanceof RoleHierarchy) { + if (method_exists($this->roleHierarchy, 'getReachableRoleNames')) { if (method_exists($token, 'getRoleNames')) { $roles = $token->getRoleNames(); } else { @trigger_error(sprintf('Not implementing the getRoleNames() method in %s which implements %s is deprecated since Symfony 4.3.', \get_class($token), TokenInterface::class), E_USER_DEPRECATED); - $roles = $token->getRoles(false); + $roles = array_map(function (Role $role) { return $role->getRole(); }, $token->getRoles(false)); } return $this->roleHierarchy->getReachableRoleNames($roles); diff --git a/src/Symfony/Component/Security/Core/Role/RoleHierarchy.php b/src/Symfony/Component/Security/Core/Role/RoleHierarchy.php index d725000d1b826..c1116cd2c3d55 100644 --- a/src/Symfony/Component/Security/Core/Role/RoleHierarchy.php +++ b/src/Symfony/Component/Security/Core/Role/RoleHierarchy.php @@ -36,7 +36,9 @@ public function __construct(array $hierarchy) */ public function getReachableRoles(array $roles) { - @trigger_error(sprintf('The %s() method is deprecated since Symfony 4.3 and will be removed in 5.0. Use roles as strings and the getReachableRoleNames() method instead.', __METHOD__), E_USER_DEPRECATED); + if (0 === \func_num_args() || func_get_arg(0)) { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 4.3 and will be removed in 5.0. Use roles as strings and the getReachableRoleNames() method instead.', __METHOD__), E_USER_DEPRECATED); + } $reachableRoles = $roles; foreach ($roles as $role) { @@ -59,16 +61,7 @@ public function getReachableRoles(array $roles) */ public function getReachableRoleNames(array $roles): array { - $reachableRoles = $roles = array_map( - function ($role) { - if ($role instanceof Role) { - return $role->getRole(); - } - - return $role; - }, - $roles - ); + $reachableRoles = $roles; foreach ($roles as $role) { if (!isset($this->map[$role])) { diff --git a/src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php b/src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php index 3a5112f7e5b91..9f54042db0e4b 100644 --- a/src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php +++ b/src/Symfony/Component/Security/Core/Role/RoleHierarchyInterface.php @@ -14,21 +14,13 @@ /** * RoleHierarchyInterface is the interface for a role hierarchy. * + * The getReachableRoles(Role[] $roles) method that returns an array of all reachable Role objects is deprecated + * since Symfony 4.3. + * * @author Fabien Potencier * - * @deprecated since Symfony 4.3, to be removed in 5.0. + * @method string[] getReachableRoleNames(string[] $roles) The associated roles - not implementing it is deprecated since Symfony 4.3 */ interface RoleHierarchyInterface { - /** - * Returns an array of all reachable roles by the given ones. - * - * Reachable roles are the roles directly assigned but also all roles that - * are transitively reachable from them in the role hierarchy. - * - * @param Role[] $roles An array of directly assigned roles - * - * @return Role[] An array of all reachable roles - */ - public function getReachableRoles(array $roles); } diff --git a/src/Symfony/Component/Workflow/EventListener/GuardListener.php b/src/Symfony/Component/Workflow/EventListener/GuardListener.php index 60cd00ed2084f..a1795b8f47b02 100644 --- a/src/Symfony/Component/Workflow/EventListener/GuardListener.php +++ b/src/Symfony/Component/Workflow/EventListener/GuardListener.php @@ -13,9 +13,9 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; use Symfony\Component\Security\Core\Role\Role; -use Symfony\Component\Security\Core\Role\RoleHierarchy; use Symfony\Component\Security\Core\Role\RoleHierarchyInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Workflow\Event\GuardEvent; @@ -37,6 +37,10 @@ class GuardListener public function __construct(array $configuration, ExpressionLanguage $expressionLanguage, TokenStorageInterface $tokenStorage, AuthorizationCheckerInterface $authorizationChecker, AuthenticationTrustResolverInterface $trustResolver, RoleHierarchyInterface $roleHierarchy = null, ValidatorInterface $validator = null) { + if (null !== $roleHierarchy && !method_exists($roleHierarchy, 'getReachableRoleNames')) { + @trigger_error(sprintf('Not implementing the getReachableRoleNames() method in %s which implements %s is deprecated since Symfony 4.3.', \get_class($roleHierarchy), RoleHierarchyInterface::class), E_USER_DEPRECATED); + } + $this->configuration = $configuration; $this->expressionLanguage = $expressionLanguage; $this->tokenStorage = $tokenStorage; @@ -83,15 +87,21 @@ private function getVariables(GuardEvent $event): array } if (method_exists($token, 'getRoleNames')) { - $roles = $token->getRoleNames(); + $roleNames = $token->getRoleNames(); + $roles = array_map(function (string $role) { return new Role($role, false); }, $roleNames); } else { - $roles = array_map(function (Role $role) { return $role->getRole(); }, $token->getRoles(false)); + @trigger_error(sprintf('Not implementing the getRoleNames() method in %s which implements %s is deprecated since Symfony 4.3.', \get_class($token), TokenInterface::class), E_USER_DEPRECATED); + + $roles = $token->getRoles(false); + $roleNames = array_map(function (Role $role) { return $role->getRole(); }, $roles); } - if ($this->roleHierarchy instanceof RoleHierarchy) { - $roles = $this->roleHierarchy->getReachableRoleNames($roles); + if (null !== $this->roleHierarchy && method_exists($this->roleHierarchy, 'getReachableRoleNames')) { + $roleNames = $this->roleHierarchy->getReachableRoleNames($roles); + $roles = array_map(function (string $role) { return new Role($role, false); }, $roleNames); } elseif (null !== $this->roleHierarchy) { $roles = $this->roleHierarchy->getReachableRoles($token->getRoles(false)); + $roleNames = array_map(function (Role $role) { return $role->getRole(); }, $roles); } $variables = [ @@ -99,6 +109,7 @@ private function getVariables(GuardEvent $event): array 'user' => $token->getUser(), 'subject' => $event->getSubject(), 'roles' => $roles, + 'role_names' => $roleNames, // needed for the is_granted expression function 'auth_checker' => $this->authorizationChecker, // needed for the is_* expression function pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy