Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit daf09cb

Browse files
committed
deprecate the Role and SwitchUserRole classes
1 parent bdcc357 commit daf09cb

File tree

11 files changed

+200
-31
lines changed

11 files changed

+200
-31
lines changed

src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php

Lines changed: 7 additions & 1 deletion
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\User\UserInterface;
1516
use Symfony\Component\Security\Core\User\UserCheckerInterface;
1617
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
@@ -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;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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 (Role|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 = array(), 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+
public function serialize()
48+
{
49+
return serialize(array(clone $this->originalToken, parent::serialize()));
50+
}
51+
52+
/**
53+
* {@inheritdoc}
54+
*/
55+
public function unserialize($serialized)
56+
{
57+
list($this->originalToken, $parentStr) = unserialize($serialized);
58+
59+
parent::unserialize($parentStr);
60+
}
61+
}

src/Symfony/Component/Security/Core/Authentication/Token/TokenInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function __toString();
3333
/**
3434
* Returns the user roles.
3535
*
36-
* @return Role[] An array of Role instances
36+
* @return string[] An array of Role instances
3737
*/
3838
public function getRoles();
3939

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,9 @@ public function getRole()
3434
{
3535
return $this->role;
3636
}
37+
38+
public function __toString(): string
39+
{
40+
return $this->role;
41+
}
3742
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@
1818
* another one.
1919
*
2020
* @author Fabien Potencier <[email protected]>
21+
*
22+
* @deprecated since version 4.1, to be removed in 5.0. Use strings as roles instead.
2123
*/
2224
class SwitchUserRole extends Role
2325
{
26+
private $deprecationTriggered = false;
2427
private $source;
2528

2629
/**
@@ -29,6 +32,12 @@ class SwitchUserRole extends Role
2932
*/
3033
public function __construct(string $role, TokenInterface $source)
3134
{
35+
if (func_num_args() < 3 || func_get_arg(2)) {
36+
@trigger_error(sprintf('The "%s" class is deprecated since version 4.1 and will be removed in 5.0. Use strings as roles instead.', __CLASS__), E_USER_DEPRECATED);
37+
38+
$this->deprecationTriggered = true;
39+
}
40+
3241
parent::__construct($role);
3342

3443
$this->source = $source;
@@ -41,6 +50,12 @@ public function __construct(string $role, TokenInterface $source)
4150
*/
4251
public function getSource()
4352
{
53+
if (!$this->deprecationTriggered) {
54+
@trigger_error(sprintf('The "%s" class is deprecated since version 4.1 and will be removed in 5.0. Use strings as roles instead.', __CLASS__), E_USER_DEPRECATED);
55+
56+
$this->deprecationTriggered = true;
57+
}
58+
4459
return $this->source;
4560
}
4661
}

src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
16+
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
1517
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
1618
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
1719
use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
@@ -194,6 +196,9 @@ public function testAuthenticate()
194196
$this->assertEquals(array('foo' => 'bar'), $authToken->getAttributes(), '->authenticate() copies token attributes');
195197
}
196198

199+
/**
200+
* @group legacy
201+
*/
197202
public function testAuthenticateWithPreservingRoleSwitchUserRole()
198203
{
199204
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
@@ -230,6 +235,34 @@ public function testAuthenticateWithPreservingRoleSwitchUserRole()
230235
$this->assertEquals(array('foo' => 'bar'), $authToken->getAttributes(), '->authenticate() copies token attributes');
231236
}
232237

238+
public function testAuthenticatePreservesOriginalToken()
239+
{
240+
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
241+
$user->expects($this->once())
242+
->method('getRoles')
243+
->will($this->returnValue(array('ROLE_FOO')))
244+
;
245+
246+
$provider = $this->getProvider();
247+
$provider->expects($this->once())
248+
->method('retrieveUser')
249+
->will($this->returnValue($user))
250+
;
251+
252+
$originalToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
253+
$token = new SwitchUserToken($this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(), 'foo', 'key', array(), $originalToken);
254+
$token->setAttributes(array('foo' => 'bar'));
255+
256+
$authToken = $provider->authenticate($token);
257+
258+
$this->assertInstanceOf(SwitchUserToken::class, $authToken);
259+
$this->assertSame($originalToken, $authToken->getOriginalToken());
260+
$this->assertSame($user, $authToken->getUser());
261+
$this->assertContains(new Role('ROLE_FOO'), $authToken->getRoles(), '', false, false);
262+
$this->assertEquals('foo', $authToken->getCredentials());
263+
$this->assertEquals(array('foo' => 'bar'), $authToken->getAttributes(), '->authenticate() copies token attributes');
264+
}
265+
233266
protected function getSupportedToken()
234267
{
235268
$mock = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken')->setMethods(array('getCredentials', 'getProviderKey', 'getRoles'))->disableOriginalConstructor()->getMock();

src/Symfony/Component/Security/Core/Tests/Authentication/Token/AbstractTokenTest.php

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -112,20 +112,6 @@ public function testSerializeWithRoleObjects()
112112
$this->assertEquals($roles, $user->getRoles());
113113
}
114114

115-
public function testSerializeParent()
116-
{
117-
$user = new TestUser('fabien');
118-
$token = new ConcreteToken($user, array('ROLE_FOO'));
119-
120-
$parentToken = new ConcreteToken($user, array(new SwitchUserRole('ROLE_PREVIOUS', $token)));
121-
$uToken = unserialize(serialize($parentToken));
122-
123-
$this->assertEquals(
124-
current($parentToken->getRoles())->getSource()->getUser(),
125-
current($uToken->getRoles())->getSource()->getUser()
126-
);
127-
}
128-
129115
public function testConstructor()
130116
{
131117
$token = $this->getToken(array('ROLE_FOO'));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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\Tests\Authentication\Token;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
16+
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
17+
use Symfony\Component\Security\Core\Role\Role;
18+
19+
class SwitchUserTokenTest extends TestCase
20+
{
21+
public function testSerialize()
22+
{
23+
$originalToken = new UsernamePasswordToken('user', 'foo', 'provider-key', array('ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'));
24+
$token = new SwitchUserToken('admin', 'bar', 'provider-key', array('ROLE_USER'), $originalToken);
25+
26+
$unserializedToken = unserialize(serialize($token));
27+
28+
$this->assertInstanceOf(SwitchUserToken::class, $unserializedToken);
29+
$this->assertSame('admin', $unserializedToken->getUsername());
30+
$this->assertSame('bar', $unserializedToken->getCredentials());
31+
$this->assertSame('provider-key', $unserializedToken->getProviderKey());
32+
$this->assertEquals(array(new Role('ROLE_USER')), $unserializedToken->getRoles());
33+
34+
$unserializedOriginalToken = $unserializedToken->getOriginalToken();
35+
36+
$this->assertInstanceOf(UsernamePasswordToken::class, $unserializedOriginalToken);
37+
$this->assertSame('user', $unserializedOriginalToken->getUsername());
38+
$this->assertSame('foo', $unserializedOriginalToken->getCredentials());
39+
$this->assertSame('provider-key', $unserializedOriginalToken->getProviderKey());
40+
$this->assertEquals(array(new Role('ROLE_ADMIN'), new Role('ROLE_ALLOWED_TO_SWITCH')), $unserializedOriginalToken->getRoles());
41+
}
42+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Security\Core\Role\SwitchUserRole;
1616

17+
/**
18+
* @group legacy
19+
*/
1720
class SwitchUserRoleTest extends TestCase
1821
{
1922
public function testGetSource()

src/Symfony/Component/Security/Http/Firewall/SwitchUserListener.php

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

1212
namespace Symfony\Component\Security\Http\Firewall;
1313

14+
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
1415
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
1516
use Symfony\Component\Security\Core\User\UserInterface;
1617
use Symfony\Component\Security\Core\User\UserProviderInterface;
@@ -22,7 +23,6 @@
2223
use Symfony\Component\HttpFoundation\RedirectResponse;
2324
use Symfony\Component\HttpFoundation\Request;
2425
use Symfony\Component\Security\Core\Role\SwitchUserRole;
25-
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
2626
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
2727
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
2828
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
@@ -118,7 +118,7 @@ private function attemptSwitchUser(Request $request, $username)
118118
$token = $this->tokenStorage->getToken();
119119
$originalToken = $this->getOriginalToken($token);
120120

121-
if (false !== $originalToken) {
121+
if (null !== $originalToken) {
122122
if ($token->getUsername() === $username) {
123123
return $token;
124124
}
@@ -141,9 +141,9 @@ private function attemptSwitchUser(Request $request, $username)
141141
$this->userChecker->checkPostAuth($user);
142142

143143
$roles = $user->getRoles();
144-
$roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $this->tokenStorage->getToken());
144+
$roles[] = new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $this->tokenStorage->getToken(), false);
145145

146-
$token = new UsernamePasswordToken($user, $user->getPassword(), $this->providerKey, $roles);
146+
$token = new SwitchUserToken($user, $user->getPassword(), $this->providerKey, $roles, $token);
147147

148148
if (null !== $this->dispatcher) {
149149
$switchEvent = new SwitchUserEvent($request, $token->getUser(), $token);
@@ -164,7 +164,7 @@ private function attemptSwitchUser(Request $request, $username)
164164
*/
165165
private function attemptExitUser(Request $request)
166166
{
167-
if (null === ($currentToken = $this->tokenStorage->getToken()) || false === $original = $this->getOriginalToken($currentToken)) {
167+
if (null === ($currentToken = $this->tokenStorage->getToken()) || null === $original = $this->getOriginalToken($currentToken)) {
168168
throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
169169
}
170170

@@ -178,19 +178,18 @@ private function attemptExitUser(Request $request)
178178
return $original;
179179
}
180180

181-
/**
182-
* Gets the original Token from a switched one.
183-
*
184-
* @return TokenInterface|false The original TokenInterface instance, false if the current TokenInterface is not switched
185-
*/
186-
private function getOriginalToken(TokenInterface $token)
181+
private function getOriginalToken(TokenInterface $token): ?TokenInterface
187182
{
183+
if ($token instanceof SwitchUserToken) {
184+
return $token->getOriginalToken();
185+
}
186+
188187
foreach ($token->getRoles() as $role) {
189188
if ($role instanceof SwitchUserRole) {
190189
return $role->getSource();
191190
}
192191
}
193192

194-
return false;
193+
return null;
195194
}
196195
}

0 commit comments

Comments
 (0)