Skip to content
This repository was archived by the owner on May 31, 2024. It is now read-only.

Commit d8b337c

Browse files
committed
deprecate the Role and SwitchUserRole classes
1 parent baa22f6 commit d8b337c

40 files changed

+553
-159
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ CHANGELOG
44
4.3.0
55
-----
66

7+
* The `Role` and `SwitchUserRole` classes are deprecated and will be removed in 5.0. Use strings for roles
8+
instead.
9+
* The `RoleHierarchyInterface` is deprecated and will be removed in 5.0.
10+
* The `getReachableRoles()` method of the `RoleHierarchy` class is deprecated and will be removed in 5.0.
11+
Use the `getReachableRoleNames()` method instead.
12+
* The `getRoles()` method of the `TokenInterface` is deprecated. Tokens must implement the `getRoleNames()`
13+
method instead and return roles as strings.
714
* Made the `serialize()` and `unserialize()` methods of `AbstractToken` and
815
`AuthenticationException` final, use `getState()`/`setState()` instead
916

Core/Authentication/Provider/UserAuthenticationProvider.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Security\Core\Authentication\Provider;
1313

14+
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
1415
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1516
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
1617
use Symfony\Component\Security\Core\Exception\AuthenticationException;
@@ -87,7 +88,12 @@ public function authenticate(TokenInterface $token)
8788
throw $e;
8889
}
8990

90-
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token));
91+
if ($token instanceof SwitchUserToken) {
92+
$authenticatedToken = new SwitchUserToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token), $token->getOriginalToken());
93+
} else {
94+
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token));
95+
}
96+
9197
$authenticatedToken->setAttributes($token->getAttributes());
9298

9399
return $authenticatedToken;
@@ -110,7 +116,7 @@ private function getRoles(UserInterface $user, TokenInterface $token)
110116
{
111117
$roles = $user->getRoles();
112118

113-
foreach ($token->getRoles() as $role) {
119+
foreach ($token->getRoles(false) as $role) {
114120
if ($role instanceof SwitchUserRole) {
115121
$roles[] = $role;
116122

Core/Authentication/Token/AbstractToken.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,43 @@ abstract class AbstractToken implements TokenInterface
2626
{
2727
private $user;
2828
private $roles = [];
29+
private $roleNames = [];
2930
private $authenticated = false;
3031
private $attributes = [];
3132

3233
/**
33-
* @param (Role|string)[] $roles An array of roles
34+
* @param string[] $roles An array of roles
3435
*
3536
* @throws \InvalidArgumentException
3637
*/
3738
public function __construct(array $roles = [])
3839
{
3940
foreach ($roles as $role) {
4041
if (\is_string($role)) {
41-
$role = new Role($role);
42+
$role = new Role($role, false);
4243
} elseif (!$role instanceof Role) {
4344
throw new \InvalidArgumentException(sprintf('$roles must be an array of strings, or Role instances, but got %s.', \gettype($role)));
4445
}
4546

4647
$this->roles[] = $role;
48+
$this->roleNames[] = (string) $role;
4749
}
4850
}
4951

52+
public function getRoleNames(): array
53+
{
54+
return $this->roleNames;
55+
}
56+
5057
/**
5158
* {@inheritdoc}
5259
*/
5360
public function getRoles()
5461
{
62+
if (0 === \func_num_args() || func_get_arg(0)) {
63+
@trigger_error(sprintf('The %s() method is deprecated since Symfony 4.3. Use the getRoleNames() method instead.', __METHOD__), E_USER_DEPRECATED);
64+
}
65+
5566
return $this->roles;
5667
}
5768

@@ -172,7 +183,7 @@ public function unserialize($serialized)
172183
*/
173184
protected function getState(): array
174185
{
175-
return [$this->user, $this->authenticated, $this->roles, $this->attributes];
186+
return [$this->user, $this->authenticated, $this->roles, $this->attributes, $this->roleNames];
176187
}
177188

178189
/**
@@ -193,7 +204,7 @@ protected function getState(): array
193204
*/
194205
protected function setState(array $data)
195206
{
196-
[$this->user, $this->authenticated, $this->roles, $this->attributes] = $data;
207+
[$this->user, $this->authenticated, $this->roles, $this->attributes, $this->roleNames] = $data;
197208
}
198209

199210
/**
@@ -225,7 +236,7 @@ public function setAttributes(array $attributes)
225236
*/
226237
public function hasAttribute($name)
227238
{
228-
return array_key_exists($name, $this->attributes);
239+
return \array_key_exists($name, $this->attributes);
229240
}
230241

231242
/**
@@ -239,7 +250,7 @@ public function hasAttribute($name)
239250
*/
240251
public function getAttribute($name)
241252
{
242-
if (!array_key_exists($name, $this->attributes)) {
253+
if (!\array_key_exists($name, $this->attributes)) {
243254
throw new \InvalidArgumentException(sprintf('This token has no "%s" attribute.', $name));
244255
}
245256

Core/Authentication/Token/AnonymousToken.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
namespace Symfony\Component\Security\Core\Authentication\Token;
1313

14-
use Symfony\Component\Security\Core\Role\Role;
15-
1614
/**
1715
* AnonymousToken represents an anonymous token.
1816
*
@@ -25,7 +23,7 @@ class AnonymousToken extends AbstractToken
2523
/**
2624
* @param string $secret A secret used to make sure the token is created by the app and not by a malicious client
2725
* @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string
28-
* @param Role[] $roles An array of roles
26+
* @param string[] $roles An array of roles
2927
*/
3028
public function __construct(string $secret, $user, array $roles = [])
3129
{

Core/Authentication/Token/PreAuthenticatedToken.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
namespace Symfony\Component\Security\Core\Authentication\Token;
1313

14-
use Symfony\Component\Security\Core\Role\Role;
15-
1614
/**
1715
* PreAuthenticatedToken implements a pre-authenticated token.
1816
*
@@ -24,10 +22,10 @@ class PreAuthenticatedToken extends AbstractToken
2422
private $providerKey;
2523

2624
/**
27-
* @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string
28-
* @param mixed $credentials The user credentials
29-
* @param string $providerKey The provider key
30-
* @param (Role|string)[] $roles An array of roles
25+
* @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string
26+
* @param mixed $credentials The user credentials
27+
* @param string $providerKey The provider key
28+
* @param string[] $roles An array of roles
3129
*/
3230
public function __construct($user, $credentials, string $providerKey, array $roles = [])
3331
{

Core/Authentication/Token/Storage/TokenStorage.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ public function getToken()
3939
*/
4040
public function setToken(TokenInterface $token = null)
4141
{
42+
if (null !== $token && !method_exists($token, 'getRoleNames')) {
43+
@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);
44+
}
45+
4246
$this->token = $token;
4347
}
4448

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Core\Authentication\Token;
13+
14+
/**
15+
* Token representing a user who temporarily impersonates another one.
16+
*
17+
* @author Christian Flothmann <[email protected]>
18+
*/
19+
class SwitchUserToken extends UsernamePasswordToken
20+
{
21+
private $originalToken;
22+
23+
/**
24+
* @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method
25+
* @param mixed $credentials This usually is the password of the user
26+
* @param string $providerKey The provider key
27+
* @param string[] $roles An array of roles
28+
* @param TokenInterface $originalToken The token of the user who switched to the current user
29+
*
30+
* @throws \InvalidArgumentException
31+
*/
32+
public function __construct($user, $credentials, string $providerKey, array $roles = [], TokenInterface $originalToken)
33+
{
34+
parent::__construct($user, $credentials, $providerKey, $roles);
35+
36+
$this->originalToken = $originalToken;
37+
}
38+
39+
public function getOriginalToken(): TokenInterface
40+
{
41+
return $this->originalToken;
42+
}
43+
44+
/**
45+
* {@inheritdoc}
46+
*/
47+
protected function getState(): array
48+
{
49+
return [$this->originalToken, parent::getState()];
50+
}
51+
52+
/**
53+
* {@inheritdoc}
54+
*/
55+
protected function setState(array $data)
56+
{
57+
[$this->originalToken, $parentData] = $data;
58+
parent::setState($parentData);
59+
}
60+
}

Core/Authentication/Token/TokenInterface.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*
1919
* @author Fabien Potencier <[email protected]>
2020
* @author Johannes M. Schmitt <[email protected]>
21+
*
22+
* @method string[] getRoleNames() The associated roles - not implementing it is deprecated since Symfony 4.3
2123
*/
2224
interface TokenInterface extends \Serializable
2325
{
@@ -34,6 +36,8 @@ public function __toString();
3436
* Returns the user roles.
3537
*
3638
* @return Role[] An array of Role instances
39+
*
40+
* @deprecated since Symfony 4.3, use the getRoleNames() method instead
3741
*/
3842
public function getRoles();
3943

Core/Authentication/Token/UsernamePasswordToken.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
namespace Symfony\Component\Security\Core\Authentication\Token;
1313

14-
use Symfony\Component\Security\Core\Role\Role;
15-
1614
/**
1715
* UsernamePasswordToken implements a username and password token.
1816
*
@@ -24,10 +22,10 @@ class UsernamePasswordToken extends AbstractToken
2422
private $providerKey;
2523

2624
/**
27-
* @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method
28-
* @param mixed $credentials This usually is the password of the user
29-
* @param string $providerKey The provider key
30-
* @param (Role|string)[] $roles An array of roles
25+
* @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method
26+
* @param mixed $credentials This usually is the password of the user
27+
* @param string $providerKey The provider key
28+
* @param string[] $roles An array of roles
3129
*
3230
* @throws \InvalidArgumentException
3331
*/

Core/Authorization/Voter/ExpressionVoter.php

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
1919
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
2020
use Symfony\Component\Security\Core\Authorization\ExpressionLanguage;
21+
use Symfony\Component\Security\Core\Role\Role;
22+
use Symfony\Component\Security\Core\Role\RoleHierarchy;
2123
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
2224

2325
/**
@@ -90,18 +92,34 @@ public function vote(TokenInterface $token, $subject, array $attributes)
9092

9193
private function getVariables(TokenInterface $token, $subject)
9294
{
93-
if (null !== $this->roleHierarchy) {
94-
$roles = $this->roleHierarchy->getReachableRoles($token->getRoles());
95+
if ($this->roleHierarchy instanceof RoleHierarchy) {
96+
if (method_exists($token, 'getRoleNames')) {
97+
$rolesFromToken = $token->getRoleNames();
98+
} else {
99+
@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);
100+
101+
$rolesFromToken = $token->getRoles(false);
102+
}
103+
104+
$roles = $this->roleHierarchy->getReachableRoleNames($rolesFromToken);
105+
} elseif (null !== $this->roleHierarchy) {
106+
$roles = $this->roleHierarchy->getReachableRoles($token->getRoles(false));
107+
} elseif (method_exists($token, 'getRoleNames')) {
108+
$roles = $token->getRoleNames();
95109
} else {
96-
$roles = $token->getRoles();
110+
@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);
111+
112+
$roles = $token->getRoles(false);
97113
}
98114

115+
$roles = array_map(function ($role) { return $role instanceof Role ? $role->getRole() : $role; }, $roles);
116+
99117
$variables = [
100118
'token' => $token,
101119
'user' => $token->getUser(),
102120
'object' => $subject,
103121
'subject' => $subject,
104-
'roles' => array_map(function ($role) { return $role->getRole(); }, $roles),
122+
'roles' => $roles,
105123
'trust_resolver' => $this->trustResolver,
106124
'auth_checker' => $this->authChecker,
107125
];

0 commit comments

Comments
 (0)