8000 [Security] undeprecate the RoleHierarchyInterface by xabbuh · Pull Request #30388 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Security] undeprecate the RoleHierarchyInterface #30388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions UPGRADE-4.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions UPGRADE-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,6 @@
<argument>%security.role_hierarchy.roles%</argument>
</service>
<service id="Symfony\Component\Security\Core\Role\RoleHierarchyInterface" alias="security.role_hierarchy" />
<service id="Symfony\Component\Security\Core\Role\RoleHierarchy" alias="security.role_hierarchy" />


<!-- Security Voters -->
<service id="security.access.simple_role_voter" class="Symfony\Component\Security\Core\Authorization\Voter\RoleVoter">
Expand Down
5 changes: 2 additions & 3 deletions src/Symfony/Component/Security/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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) {
Expand Down Expand Up @@ -92,34 +95,31 @@ 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,
< 9E88 /td> 'user' => $token->getUser(),
'object' => $subject,
'subject' => $subject,
'roles' => $roles,
'role_names' => $roleNames,
'trust_resolver' => $this->trustResolver,
'auth_checker' => $this->authChecker,
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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);
Expand Down
15 changes: 4 additions & 11 deletions src/Symfony/Component/Security/Core/Role/RoleHierarchy.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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])) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <fabien@symfony.com>
*
* @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);
}
21 changes: 16 additions & 5 deletions src/Symfony/Component/Workflow/EventListener/GuardListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -83,22 +87,29 @@ 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 = [
'token' => $token,
'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
Expand Down
0