Skip to content

Commit

Permalink
deprecate the Role and SwitchUserRole classes
Browse files Browse the repository at this point in the history
  • Loading branch information
xabbuh committed Mar 18, 2017
1 parent 3ae36f4 commit a8df9f2
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 78 deletions.
Expand Up @@ -93,7 +93,13 @@ public function authenticate(TokenInterface $token)
throw $e;
}

$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token));
$previousToken = null;

if ($token instanceof UsernamePasswordToken) {
$previousToken = $token->getPreviousToken();
}

$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token), $previousToken);
$authenticatedToken->setAttributes($token->getAttributes());

return $authenticatedToken;
Expand Down
Expand Up @@ -20,18 +20,20 @@ class UsernamePasswordToken extends AbstractToken
{
private $credentials;
private $providerKey;
private $previousToken;

/**
* Constructor.
*
* @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method
* @param string $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param (RoleInterface|string)[] $roles An array of roles
* @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method
* @param string $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param (RoleInterface|string)[] $roles An array of roles
* @param TokenInterface|null $previousToken The token of the user that switched to the current user
*
* @throws \InvalidArgumentException
*/
public function __construct($user, $credentials, $providerKey, array $roles = array())
public function __construct($user, $credentials, $providerKey, array $roles = array(), TokenInterface $previousToken = null)
{
parent::__construct($roles);

Expand All @@ -42,6 +44,7 @@ public function __construct($user, $credentials, $providerKey, array $roles = ar
$this->setUser($user);
$this->credentials = $credentials;
$this->providerKey = $providerKey;
$this->previousToken = $previousToken;

parent::setAuthenticated(count($roles) > 0);
}
Expand Down Expand Up @@ -76,6 +79,16 @@ public function getProviderKey()
return $this->providerKey;
}

public function isUserSwitched()
{
return null !== $this->previousToken;
}

public function getPreviousToken()
{
return $this->previousToken;
}

/**
* {@inheritdoc}
*/
Expand Down
15 changes: 15 additions & 0 deletions src/Symfony/Component/Security/Core/Role/SwitchUserRole.php
Expand Up @@ -18,9 +18,12 @@
* another one.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since version 3.3 and will be removed in 4.0. Use strings as roles instead.
*/
class SwitchUserRole extends Role
{
private static $deprecationTriggered = false;
private $source;

/**
Expand All @@ -31,6 +34,12 @@ class SwitchUserRole extends Role
*/
public function __construct($role, TokenInterface $source)
{
if (!self::$deprecationTriggered && (func_num_args() < 3 || func_get_arg(2))) {
@trigger_error(sprintf('The "%s" class is deprecated since version 3.3 and will be removed in 4.0. Use strings as roles instead.', __CLASS__), E_USER_DEPRECATED);

self::$deprecationTriggered = true;
}

parent::__construct($role);

$this->source = $source;
Expand All @@ -43,6 +52,12 @@ public function __construct($role, TokenInterface $source)
*/
public function getSource()
{
if (!self::$deprecationTriggered) {
@trigger_error(sprintf('The "%s" class is deprecated since version 3.3 and will be removed in 4.0. Use strings as roles instead.', __CLASS__), E_USER_DEPRECATED);

self::$deprecationTriggered = true;
}

return $this->source;
}
}
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
Expand Down Expand Up @@ -190,6 +191,9 @@ public function testAuthenticate()
$this->assertEquals(array('foo' => 'bar'), $authToken->getAttributes(), '->authenticate() copies token attributes');
}

/**
* @group legacy
*/
public function testAuthenticateWithPreservingRoleSwitchUserRole()
{
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
Expand Down Expand Up @@ -226,6 +230,35 @@ public function testAuthenticateWithPreservingRoleSwitchUserRole()
$this->assertEquals(array('foo' => 'bar'), $authToken->getAttributes(), '->authenticate() copies token attributes');
}

public function testAuthenticatePreservesOriginalToken()
{
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$user->expects($this->once())
->method('getRoles')
->will($this->returnValue(array('ROLE_FOO')))
;

$provider = $this->getProvider();
$provider->expects($this->once())
->method('retrieveUser')
->will($this->returnValue($user))
;

$originalToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token = new UsernamePasswordToken($this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(), 'foo', 'key', array(), $originalToken);
$token->setAttributes(array('foo' => 'bar'));

$authToken = $provider->authenticate($token);

$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $authToken);
$this->assertTrue($authToken->isUserSwitched());
$this->assertSame($originalToken, $authToken->getPreviousToken());
$this->assertSame($user, $authToken->getUser());
$this->assertContains(new Role('ROLE_FOO'), $authToken->getRoles(), '', false, false);
$this->assertEquals('foo', $authToken->getCredentials());
$this->assertEquals(array('foo' => 'bar'), $authToken->getAttributes(), '->authenticate() copies token attributes');
}

protected function getSupportedToken()
{
$mock = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken')->setMethods(array('getCredentials', 'getProviderKey', 'getRoles'))->disableOriginalConstructor()->getMock();
Expand Down
Expand Up @@ -14,6 +14,9 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Role\SwitchUserRole;

/**
* @group legacy
*/
class SwitchUserRoleTest extends TestCase
{
public function testGetSource()
Expand Down
Expand Up @@ -138,9 +138,9 @@ private function attemptSwitchUser(Request $request)
$this->userChecker->checkPostAuth($user);

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

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

if (null !== $this->dispatcher) {
$switchEvent = new SwitchUserEvent($request, $token->getUser());
Expand Down Expand Up @@ -183,12 +183,14 @@ private function attemptExitUser(Request $request)
*/
private function getOriginalToken(TokenInterface $token)
{
foreach ($token->getRoles() as $role) {
if ($role instanceof SwitchUserRole) {
return $role->getSource();
}
if (!$token instanceof UsernamePasswordToken) {
return false;
}

if (!$token->isUserSwitched()) {
return false;
}

return false;
return $token->getPreviousToken();
}
}

0 comments on commit a8df9f2

Please sign in to comment.