deprecate the Role and SwitchUserRole classes

This commit is contained in:
Christian Flothmann 2017-03-06 18:12:20 +01:00
parent fec0475e8c
commit d7aaa615b9
50 changed files with 658 additions and 212 deletions

View File

@ -53,6 +53,13 @@ HttpFoundation
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 `getRoles()` method of the `TokenInterface` is deprecated. Tokens must implement the `getRoleNames()`
method instead and return roles as strings.
* The `AbstractToken::serialize()`, `AbstractToken::unserialize()`,
`AuthenticationException::serialize()` and `AuthenticationException::unserialize()`
methods are now final, use `getState()` and `setState()` instead.

View File

@ -226,6 +226,11 @@ Process
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 `getRoles()` method has been removed from the `TokenInterface`. It has been replaced by the new
`getRoleNames()` method.
* The `ContextListener::setLogoutOnUserChange()` method has been removed.
* The `Symfony\Component\Security\Core\User\AdvancedUserInterface` has been removed.
* The `ExpressionVoter::addExpressionLanguageProvider()` method has been removed.

View File

@ -31,10 +31,16 @@ class TokenProcessor
{
$records['extra']['token'] = null;
if (null !== $token = $this->tokenStorage->getToken()) {
if (method_exists($token, 'getRoleNames')) {
$roles = $token->getRoleNames();
} else {
$roles = array_map(function ($role) { return $role->getRole(); }, $token->getRoles(false));
}
$records['extra']['token'] = [
'username' => $token->getUsername(),
'authenticated' => $token->isAuthenticated(),
'roles' => array_map(function ($role) { return $role->getRole(); }, $token->getRoles()),
'roles' => $roles,
];
}

View File

@ -36,7 +36,6 @@ class TokenProcessorTest extends TestCase
$this->assertArrayHasKey('token', $record['extra']);
$this->assertEquals($token->getUsername(), $record['extra']['token']['username']);
$this->assertEquals($token->isAuthenticated(), $record['extra']['token']['authenticated']);
$roles = array_map(function ($role) { return $role->getRole(); }, $token->getRoles());
$this->assertEquals($roles, $record['extra']['token']['roles']);
$this->assertEquals(['ROLE_USER'], $record['extra']['token']['roles']);
}
}

View File

@ -18,10 +18,12 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
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;
@ -91,18 +93,32 @@ class SecurityDataCollector extends DataCollector implements LateDataCollectorIn
];
} else {
$inheritedRoles = [];
$assignedRoles = $token->getRoles();
if (method_exists($token, 'getRoleNames')) {
$assignedRoles = $token->getRoleNames();
} else {
$assignedRoles = array_map(function (Role $role) { return $role->getRole(); }, $token->getRoles(false));
}
$impersonatorUser = null;
foreach ($assignedRoles as $role) {
if ($role instanceof SwitchUserRole) {
$impersonatorUser = $role->getSource()->getUsername();
break;
if ($token instanceof SwitchUserToken) {
$impersonatorUser = $token->getOriginalToken()->getUsername();
} else {
foreach ($token->getRoles(false) as $role) {
if ($role instanceof SwitchUserRole) {
$impersonatorUser = $role->getSource()->getUsername();
break;
}
}
}
if (null !== $this->roleHierarchy) {
$allRoles = $this->roleHierarchy->getReachableRoles($assignedRoles);
if ($this->roleHierarchy instanceof RoleHierarchy) {
$allRoles = $this->roleHierarchy->getReachableRoleNames($assignedRoles);
} else {
$allRoles = array_map(function (Role $role) { return (string) $role; }, $this->roleHierarchy->getReachableRoles($token->getRoles(false)));
}
foreach ($allRoles as $role) {
if (!\in_array($role, $assignedRoles, true)) {
$inheritedRoles[] = $role;
@ -129,8 +145,8 @@ class SecurityDataCollector extends DataCollector implements LateDataCollectorIn
'token_class' => $this->hasVarDumper ? new ClassStub(\get_class($token)) : \get_class($token),
'logout_url' => $logoutUrl,
'user' => $token->getUsername(),
'roles' => array_map(function (Role $role) { return $role->getRole(); }, $assignedRoles),
'inherited_roles' => array_unique(array_map(function (Role $role) { return $role->getRole(); }, $inheritedRoles)),
'roles' => $assignedRoles,
'inherited_roles' => array_unique($inheritedRoles),
'supports_role_hierarchy' => null !== $this->roleHierarchy,
];
}

View File

@ -98,6 +98,7 @@
<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 -->

View File

@ -18,9 +18,12 @@ use Symfony\Bundle\SecurityBundle\Security\FirewallConfig;
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
use Symfony\Component\Security\Core\Authorization\TraceableAccessDecisionManager;
@ -38,7 +41,7 @@ class SecurityDataCollectorTest extends TestCase
public function testCollectWhenSecurityIsDisabled()
{
$collector = new SecurityDataCollector();
$collector->collect($this->getRequest(), $this->getResponse());
$collector->collect(new Request(), new Response());
$this->assertSame('security', $collector->getName());
$this->assertFalse($collector->isEnabled());
@ -58,7 +61,7 @@ class SecurityDataCollectorTest extends TestCase
{
$tokenStorage = new TokenStorage();
$collector = new SecurityDataCollector($tokenStorage, $this->getRoleHierarchy());
$collector->collect($this->getRequest(), $this->getResponse());
$collector->collect(new Request(), new Response());
$this->assertTrue($collector->isEnabled());
$this->assertFalse($collector->isAuthenticated());
@ -80,7 +83,7 @@ class SecurityDataCollectorTest extends TestCase
$tokenStorage->setToken(new UsernamePasswordToken('hhamon', 'P4$$w0rD', 'provider', $roles));
$collector = new SecurityDataCollector($tokenStorage, $this->getRoleHierarchy());
$collector->collect($this->getRequest(), $this->getResponse());
$collector->collect(new Request(), new Response());
$collector->lateCollect();
$this->assertTrue($collector->isEnabled());
@ -95,6 +98,9 @@ class SecurityDataCollectorTest extends TestCase
$this->assertSame('hhamon', $collector->getUser());
}
/**
* @group legacy
*/
public function testCollectImpersonatedToken()
{
$adminToken = new UsernamePasswordToken('yceruto', 'P4$$w0rD', 'provider', ['ROLE_ADMIN']);
@ -108,7 +114,7 @@ class SecurityDataCollectorTest extends TestCase
$tokenStorage->setToken(new UsernamePasswordToken('hhamon', 'P4$$w0rD', 'provider', $userRoles));
$collector = new SecurityDataCollector($tokenStorage, $this->getRoleHierarchy());
$collector->collect($this->getRequest(), $this->getResponse());
$collector->collect(new Request(), new Response());
$collector->lateCollect();
$this->assertTrue($collector->isEnabled());
@ -122,10 +128,32 @@ class SecurityDataCollectorTest extends TestCase
$this->assertSame('hhamon', $collector->getUser());
}
public function testCollectSwitchUserToken()
{
$adminToken = new UsernamePasswordToken('yceruto', 'P4$$w0rD', 'provider', ['ROLE_ADMIN']);
$tokenStorage = new TokenStorage();
$tokenStorage->setToken(new SwitchUserToken('hhamon', 'P4$$w0rD', 'provider', ['ROLE_USER', 'ROLE_PREVIOUS_ADMIN'], $adminToken));
$collector = new SecurityDataCollector($tokenStorage, $this->getRoleHierarchy());
$collector->collect(new Request(), new Response());
$collector->lateCollect();
$this->assertTrue($collector->isEnabled());
$this->assertTrue($collector->isAuthenticated());
$this->assertTrue($collector->isImpersonated());
$this->assertSame('yceruto', $collector->getImpersonatorUser());
$this->assertSame(SwitchUserToken::class, $collector->getTokenClass()->getValue());
$this->assertTrue($collector->supportsRoleHierarchy());
$this->assertSame(['ROLE_USER', 'ROLE_PREVIOUS_ADMIN'], $collector->getRoles()->getValue(true));
$this->assertSame([], $collector->getInheritedRoles()->getValue(true));
$this->assertSame('hhamon', $collector->getUser());
}
public function testGetFirewall()
{
$firewallConfig = new FirewallConfig('dummy', 'security.request_matcher.dummy', 'security.user_checker.dummy');
$request = $this->getRequest();
$request = new Request();
$firewallMap = $this
->getMockBuilder(FirewallMap::class)
@ -138,7 +166,7 @@ class SecurityDataCollectorTest extends TestCase
->willReturn($firewallConfig);
$collector = new SecurityDataCollector(null, null, null, null, $firewallMap, new TraceableFirewallListener($firewallMap, new EventDispatcher(), new LogoutUrlGenerator()));
$collector->collect($request, $this->getResponse());
$collector->collect($request, new Response());
$collector->lateCollect();
$collected = $collector->getFirewall();
@ -158,8 +186,8 @@ class SecurityDataCollectorTest extends TestCase
public function testGetFirewallReturnsNull()
{
$request = $this->getRequest();
$response = $this->getResponse();
$request = new Request();
$response = new Response();
// Don't inject any firewall map
$collector = new SecurityDataCollector();
@ -192,9 +220,9 @@ class SecurityDataCollectorTest extends TestCase
*/
public function testGetListeners()
{
$request = $this->getRequest();
$request = new Request();
$event = new GetResponseEvent($this->getMockBuilder(HttpKernelInterface::class)->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
$event->setResponse($response = $this->getResponse());
$event->setResponse($response = new Response());
$listener = $this->getMockBuilder(ListenerInterface::class)->getMock();
$listener
->expects($this->once())
@ -345,7 +373,7 @@ class SecurityDataCollectorTest extends TestCase
->willReturn($decisionLog);
$dataCollector = new SecurityDataCollector(null, null, null, $accessDecisionManager);
$dataCollector->collect($this->getRequest(), $this->getResponse());
$dataCollector->collect(new Request(), new Response());
$this->assertEquals($dataCollector->getAccessDecisionLog(), $expectedDecisionLog, 'Wrong value returned by getAccessDecisionLog');
@ -367,7 +395,7 @@ class SecurityDataCollectorTest extends TestCase
[],
],
[
[new Role('ROLE_USER')],
[new Role('ROLE_USER', false)],
['ROLE_USER'],
[],
],
@ -378,7 +406,7 @@ class SecurityDataCollectorTest extends TestCase
['ROLE_USER', 'ROLE_ALLOWED_TO_SWITCH'],
],
[
[new Role('ROLE_ADMIN')],
[new Role('ROLE_ADMIN', false)],
['ROLE_ADMIN'],
['ROLE_USER', 'ROLE_ALLOWED_TO_SWITCH'],
],
@ -397,20 +425,4 @@ class SecurityDataCollectorTest extends TestCase
'ROLE_OPERATOR' => ['ROLE_USER'],
]);
}
private function getRequest()
{
return $this
->getMockBuilder('Symfony\Component\HttpFoundation\Request')
->disableOriginalConstructor()
->getMock();
}
private function getResponse()
{
return $this
->getMockBuilder('Symfony\Component\HttpFoundation\Response')
->disableOriginalConstructor()
->getMock();
}
}

View File

@ -21,7 +21,7 @@
"symfony/config": "^4.2",
"symfony/dependency-injection": "^4.2",
"symfony/http-kernel": "^4.1",
"symfony/security-core": "~4.2",
"symfony/security-core": "~4.3",
"symfony/security-csrf": "~4.2",
"symfony/security-guard": "~4.2",
"symfony/security-http": "~4.2"

View File

@ -4,6 +4,13 @@ CHANGELOG
4.3.0
-----
* 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 `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
`AuthenticationException` final, use `getState()`/`setState()` instead

View File

@ -11,6 +11,7 @@
namespace Symfony\Component\Security\Core\Authentication\Provider;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
@ -87,7 +88,12 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
throw $e;
}
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token));
if ($token instanceof SwitchUserToken) {
$authenticatedToken = new SwitchUserToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token), $token->getOriginalToken());
} else {
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token));
}
$authenticatedToken->setAttributes($token->getAttributes());
return $authenticatedToken;
@ -110,7 +116,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter
{
$roles = $user->getRoles();
foreach ($token->getRoles() as $role) {
foreach ($token->getRoles(false) as $role) {
if ($role instanceof SwitchUserRole) {
$roles[] = $role;

View File

@ -26,11 +26,12 @@ abstract class AbstractToken implements TokenInterface
{
private $user;
private $roles = [];
private $roleNames = [];
private $authenticated = false;
private $attributes = [];
/**
* @param (Role|string)[] $roles An array of roles
* @param string[] $roles An array of roles
*
* @throws \InvalidArgumentException
*/
@ -38,20 +39,30 @@ abstract class AbstractToken implements TokenInterface
{
foreach ($roles as $role) {
if (\is_string($role)) {
$role = new Role($role);
$role = new Role($role, false);
} elseif (!$role instanceof Role) {
throw new \InvalidArgumentException(sprintf('$roles must be an array of strings, or Role instances, but got %s.', \gettype($role)));
}
$this->roles[] = $role;
$this->roleNames[] = (string) $role;
}
}
public function getRoleNames(): array
{
return $this->roleNames;
}
/**
* {@inheritdoc}
*/
public function getRoles()
{
if (0 === \func_num_args() || func_get_arg(0)) {
@trigger_error(sprintf('The %s() method is deprecated since Symfony 4.3. Use the getRoleNames() method instead.', __METHOD__), E_USER_DEPRECATED);
}
return $this->roles;
}
@ -172,7 +183,7 @@ abstract class AbstractToken implements TokenInterface
*/
protected function getState(): array
{
return [$this->user, $this->authenticated, $this->roles, $this->attributes];
return [$this->user, $this->authenticated, $this->roles, $this->attributes, $this->roleNames];
}
/**
@ -193,7 +204,7 @@ abstract class AbstractToken implements TokenInterface
*/
protected function setState(array $data)
{
[$this->user, $this->authenticated, $this->roles, $this->attributes] = $data;
[$this->user, $this->authenticated, $this->roles, $this->attributes, $this->roleNames] = $data;
}
/**
@ -225,7 +236,7 @@ abstract class AbstractToken implements TokenInterface
*/
public function hasAttribute($name)
{
return array_key_exists($name, $this->attributes);
return \array_key_exists($name, $this->attributes);
}
/**
@ -239,7 +250,7 @@ abstract class AbstractToken implements TokenInterface
*/
public function getAttribute($name)
{
if (!array_key_exists($name, $this->attributes)) {
if (!\array_key_exists($name, $this->attributes)) {
throw new \InvalidArgumentException(sprintf('This token has no "%s" attribute.', $name));
}

View File

@ -11,8 +11,6 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
use Symfony\Component\Security\Core\Role\Role;
/**
* AnonymousToken represents an anonymous token.
*
@ -25,7 +23,7 @@ class AnonymousToken extends AbstractToken
/**
* @param string $secret A secret used to make sure the token is created by the app and not by a malicious client
* @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
* @param Role[] $roles An array of roles
* @param string[] $roles An array of roles
*/
public function __construct(string $secret, $user, array $roles = [])
{

View File

@ -11,8 +11,6 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
use Symfony\Component\Security\Core\Role\Role;
/**
* PreAuthenticatedToken implements a pre-authenticated token.
*
@ -24,10 +22,10 @@ class PreAuthenticatedToken extends AbstractToken
private $providerKey;
/**
* @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
* @param mixed $credentials The user credentials
* @param string $providerKey The provider key
* @param (Role|string)[] $roles An array of roles
* @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
* @param mixed $credentials The user credentials
* @param string $providerKey The provider key
* @param string[] $roles An array of roles
*/
public function __construct($user, $credentials, string $providerKey, array $roles = [])
{

View File

@ -39,6 +39,10 @@ class TokenStorage implements TokenStorageInterface, ResetInterface
*/
public function setToken(TokenInterface $token = null)
{
if (null !== $token && !method_exists($token, 'getRoleNames')) {
@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);
}
$this->token = $token;
}

View File

@ -0,0 +1,60 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Core\Authentication\Token;
/**
* Token representing a user who temporarily impersonates another one.
*
* @author Christian Flothmann <christian.flothmann@sensiolabs.de>
*/
class SwitchUserToken extends UsernamePasswordToken
{
private $originalToken;
/**
* @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method
* @param mixed $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param string[] $roles An array of roles
* @param TokenInterface $originalToken The token of the user who switched to the current user
*
* @throws \InvalidArgumentException
*/
public function __construct($user, $credentials, string $providerKey, array $roles = [], TokenInterface $originalToken)
{
parent::__construct($user, $credentials, $providerKey, $roles);
$this->originalToken = $originalToken;
}
public function getOriginalToken(): TokenInterface
{
return $this->originalToken;
}
/**
* {@inheritdoc}
*/
protected function getState(): array
{
return [$this->originalToken, parent::getState()];
}
/**
* {@inheritdoc}
*/
protected function setState(array $data)
{
[$this->originalToken, $parentData] = $data;
parent::setState($parentData);
}
}

View File

@ -18,6 +18,8 @@ use Symfony\Component\Security\Core\Role\Role;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*
* @method string[] getRoleNames() The associated roles - not implementing it is deprecated since Symfony 4.3
*/
interface TokenInterface extends \Serializable
{
@ -34,6 +36,8 @@ interface TokenInterface extends \Serializable
* Returns the user roles.
*
* @return Role[] An array of Role instances
*
* @deprecated since Symfony 4.3, use the getRoleNames() method instead
*/
public function getRoles();

View File

@ -11,8 +11,6 @@
namespace Symfony\Component\Security\Core\Authentication\Token;
use Symfony\Component\Security\Core\Role\Role;
/**
* UsernamePasswordToken implements a username and password token.
*
@ -24,10 +22,10 @@ class UsernamePasswordToken extends AbstractToken
private $providerKey;
/**
* @param string|object $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method
* @param mixed $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param (Role|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 mixed $credentials This usually is the password of the user
* @param string $providerKey The provider key
* @param string[] $roles An array of roles
*
* @throws \InvalidArgumentException
*/

View File

@ -18,6 +18,8 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverIn
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
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;
/**
@ -90,18 +92,34 @@ class ExpressionVoter implements VoterInterface
private function getVariables(TokenInterface $token, $subject)
{
if (null !== $this->roleHierarchy) {
$roles = $this->roleHierarchy->getReachableRoles($token->getRoles());
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();
} else {
$roles = $token->getRoles();
@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) { return $role instanceof Role ? $role->getRole() : $role; }, $roles);
$variables = [
'token' => $token,
'user' => $token->getUser(),
'object' => $subject,
'subject' => $subject,
'roles' => array_map(function ($role) { return $role->getRole(); }, $roles),
'roles' => $roles,
'trust_resolver' => $this->trustResolver,
'auth_checker' => $this->authChecker,
];

View File

@ -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\RoleHierarchy;
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
/**
@ -26,6 +27,10 @@ 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);
}
$this->roleHierarchy = $roleHierarchy;
parent::__construct($prefix);
@ -36,6 +41,18 @@ class RoleHierarchyVoter extends RoleVoter
*/
protected function extractRoles(TokenInterface $token)
{
return $this->roleHierarchy->getReachableRoles($token->getRoles());
if ($this->roleHierarchy instanceof RoleHierarchy) {
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);
}
return $this->roleHierarchy->getReachableRoleNames($roles);
}
return $this->roleHierarchy->getReachableRoles($token->getRoles(false));
}
}

View File

@ -47,7 +47,7 @@ class RoleVoter implements VoterInterface
$result = VoterInterface::ACCESS_DENIED;
foreach ($roles as $role) {
if ($attribute === $role->getRole()) {
if ($attribute === $role) {
return VoterInterface::ACCESS_GRANTED;
}
}
@ -58,6 +58,12 @@ class RoleVoter implements VoterInterface
protected function extractRoles(TokenInterface $token)
{
return $token->getRoles();
if (method_exists($token, 'getRoleNames')) {
return $token->getRoleNames();
}
@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);
return array_map(function (Role $role) { return $role->getRole(); }, $token->getRoles(false));
}
}

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Security\Core\Role;
* Role is a simple implementation representing a role identified by a string.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since Symfony 4.3, to be removed in 5.0. Use strings as roles instead.
*/
class Role
{
@ -22,6 +24,10 @@ class Role
public function __construct(string $role)
{
if (\func_num_args() < 2 || func_get_arg(1)) {
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3 and will be removed in 5.0. Use strings as roles instead.', __CLASS__), E_USER_DEPRECATED);
}
$this->role = $role;
}
@ -34,4 +40,9 @@ class Role
{
return $this->role;
}
public function __toString(): string
{
return $this->role;
}
}

View File

@ -36,6 +36,8 @@ class RoleHierarchy implements RoleHierarchyInterface
*/
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);
$reachableRoles = $roles;
foreach ($roles as $role) {
if (!isset($this->map[$role->getRole()])) {
@ -50,6 +52,37 @@ class RoleHierarchy implements RoleHierarchyInterface
return $reachableRoles;
}
/**
* @param string[] $roles
*
* @return string[]
*/
public function getReachableRoleNames(array $roles): array
{
$reachableRoles = $roles = array_map(
function ($role) {
if ($role instanceof Role) {
return $role->getRole();
}
return $role;
},
$roles
);
foreach ($roles as $role) {
if (!isset($this->map[$role])) {
continue;
}
foreach ($this->map[$role] as $r) {
$reachableRoles[] = $r;
}
}
return $reachableRoles;
}
protected function buildRoleMap()
{
$this->map = [];

View File

@ -15,6 +15,8 @@ namespace Symfony\Component\Security\Core\Role;
* RoleHierarchyInterface is the interface for a role hierarchy.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since Symfony 4.3, to be removed in 5.0.
*/
interface RoleHierarchyInterface
{

View File

@ -18,9 +18,12 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
* another one.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since version 4.3, to be removed in 5.0. Use strings as roles instead.
*/
class SwitchUserRole extends Role
{
private $deprecationTriggered = false;
private $source;
/**
@ -29,7 +32,13 @@ class SwitchUserRole extends Role
*/
public function __construct(string $role, TokenInterface $source)
{
parent::__construct($role);
if ($triggerDeprecation = \func_num_args() < 3 || func_get_arg(2)) {
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3 and will be removed in 5.0. Use strings as roles instead.', __CLASS__), E_USER_DEPRECATED);
$this->deprecationTriggered = true;
}
parent::__construct($role, $triggerDeprecation);
$this->source = $source;
}
@ -41,6 +50,12 @@ class SwitchUserRole extends Role
*/
public function getSource()
{
if (!$this->deprecationTriggered && (\func_num_args() < 1 || func_get_arg(0))) {
@trigger_error(sprintf('The "%s" class is deprecated since version 4.3 and will be removed in 5.0. Use strings as roles instead.', __CLASS__), E_USER_DEPRECATED);
$this->deprecationTriggered = true;
}
return $this->source;
}
}

View File

@ -70,7 +70,7 @@ class PreAuthenticatedAuthenticationProviderTest extends TestCase
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken', $token);
$this->assertEquals('pass', $token->getCredentials());
$this->assertEquals('key', $token->getProviderKey());
$this->assertEquals([], $token->getRoles());
$this->assertEquals([], $token->getRoleNames());
$this->assertEquals(['foo' => 'bar'], $token->getAttributes(), '->authenticate() copies token attributes');
$this->assertSame($user, $token->getUser());
}

View File

@ -14,7 +14,6 @@ namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Provider\RememberMeAuthenticationProvider;
use Symfony\Component\Security\Core\Exception\DisabledException;
use Symfony\Component\Security\Core\Role\Role;
class RememberMeAuthenticationProviderTest extends TestCase
{
@ -78,7 +77,7 @@ class RememberMeAuthenticationProviderTest extends TestCase
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\RememberMeToken', $authToken);
$this->assertSame($user, $authToken->getUser());
$this->assertEquals([new Role('ROLE_FOO')], $authToken->getRoles());
$this->assertEquals(['ROLE_FOO'], $authToken->getRoleNames());
$this->assertEquals('', $authToken->getCredentials());
}

View File

@ -12,11 +12,11 @@
namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Exception\AccountExpiredException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\CredentialsExpiredException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
class UserAuthenticationProviderTest extends TestCase
@ -189,11 +189,14 @@ class UserAuthenticationProviderTest extends TestCase
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $authToken);
$this->assertSame($user, $authToken->getUser());
$this->assertEquals([new Role('ROLE_FOO')], $authToken->getRoles());
$this->assertEquals(['ROLE_FOO'], $authToken->getRoleNames());
$this->assertEquals('foo', $authToken->getCredentials());
$this->assertEquals(['foo' => 'bar'], $authToken->getAttributes(), '->authenticate() copies token attributes');
}
/**
* @group legacy
*/
public function testAuthenticateWithPreservingRoleSwitchUserRole()
{
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
@ -224,12 +227,40 @@ class UserAuthenticationProviderTest extends TestCase
$this->assertInstanceOf('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $authToken);
$this->assertSame($user, $authToken->getUser());
$this->assertContains(new Role('ROLE_FOO'), $authToken->getRoles(), '', false, false);
$this->assertContains('ROLE_FOO', $authToken->getRoleNames(), '', false, false);
$this->assertContains($switchUserRole, $authToken->getRoles(), '', false, false);
$this->assertEquals('foo', $authToken->getCredentials());
$this->assertEquals(['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(['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 SwitchUserToken($this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock(), 'foo', 'key', [], $originalToken);
$token->setAttributes(['foo' => 'bar']);
$authToken = $provider->authenticate($token);
$this->assertInstanceOf(SwitchUserToken::class, $authToken);
$this->assertSame($originalToken, $authToken->getOriginalToken());
$this->assertSame($user, $authToken->getUser());
$this->assertContains('ROLE_FOO', $authToken->getRoleNames(), '', false, false);
$this->assertEquals('foo', $authToken->getCredentials());
$this->assertEquals(['foo' => 'bar'], $authToken->getAttributes(), '->authenticate() copies token attributes');
}
protected function getSupportedToken()
{
$mock = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken')->setMethods(['getCredentials', 'getProviderKey', 'getRoles'])->disableOriginalConstructor()->getMock();

View File

@ -14,61 +14,14 @@ namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Core\User\User;
class TestUser
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
public function __toString()
{
return $this->name;
}
}
class ConcreteToken extends AbstractToken
{
private $credentials = 'credentials_value';
public function __construct($user, array $roles = [])
{
parent::__construct($roles);
$this->setUser($user);
}
/**
* {@inheritdoc}
*/
public function serialize()
{
$serialized = [$this->credentials, parent::serialize(true)];
return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
}
public function unserialize($serialized)
{
list($this->credentials, $parentStr) = unserialize($serialized);
parent::unserialize($parentStr);
}
public function getCredentials()
{
}
}
use Symfony\Component\Security\Core\User\UserInterface;
class AbstractTokenTest extends TestCase
{
public function testGetUsername()
{
$token = $this->getToken(['ROLE_FOO']);
$token = new ConcreteToken(['ROLE_FOO']);
$token->setUser('fabien');
$this->assertEquals('fabien', $token->getUsername());
@ -83,7 +36,7 @@ class AbstractTokenTest extends TestCase
public function testEraseCredentials()
{
$token = $this->getToken(['ROLE_FOO']);
$token = new ConcreteToken(['ROLE_FOO']);
$user = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
$user->expects($this->once())->method('eraseCredentials');
@ -94,19 +47,22 @@ class AbstractTokenTest extends TestCase
public function testSerialize()
{
$token = $this->getToken(['ROLE_FOO', new Role('ROLE_BAR')]);
$token = new ConcreteToken(['ROLE_FOO', new Role('ROLE_BAR', false)]);
$token->setAttributes(['foo' => 'bar']);
$uToken = unserialize(serialize($token));
$this->assertEquals($token->getRoles(), $uToken->getRoles());
$this->assertEquals($token->getRoleNames(), $uToken->getRoleNames());
$this->assertEquals($token->getAttributes(), $uToken->getAttributes());
}
/**
* @group legacy
*/
public function testSerializeWithRoleObjects()
{
$user = new User('name', 'password', [new Role('ROLE_FOO'), new Role('ROLE_BAR')]);
$token = new ConcreteToken($user, $user->getRoles());
$token = new ConcreteToken($user->getRoles(), $user);
$serialized = serialize($token);
$unserialized = unserialize($serialized);
@ -116,35 +72,42 @@ class AbstractTokenTest extends TestCase
$this->assertEquals($roles, $user->getRoles());
}
public function testSerializeParent()
{
$user = new TestUser('fabien');
$token = new ConcreteToken($user, ['ROLE_FOO']);
$parentToken = new ConcreteToken($user, [new SwitchUserRole('ROLE_PREVIOUS', $token)]);
$uToken = unserialize(serialize($parentToken));
$this->assertEquals(
current($parentToken->getRoles())->getSource()->getUser(),
current($uToken->getRoles())->getSource()->getUser()
);
}
public function testConstructor()
{
$token = $this->getToken(['ROLE_FOO']);
$token = new ConcreteToken(['ROLE_FOO']);
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
}
/**
* @group legacy
*/
public function testConstructorWithRoleObjects()
{
$token = new ConcreteToken([new Role('ROLE_FOO')]);
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
$token = new ConcreteToken([new Role('ROLE_FOO'), 'ROLE_BAR']);
$this->assertEquals(['ROLE_FOO', 'ROLE_BAR'], $token->getRoleNames());
}
/**
* @group legacy
*/
public function testGetRoles()
{
$token = new ConcreteToken(['ROLE_FOO']);
$this->assertEquals([new Role('ROLE_FOO')], $token->getRoles());
$token = $this->getToken([new Role('ROLE_FOO')]);
$token = new ConcreteToken([new Role('ROLE_FOO')]);
$this->assertEquals([new Role('ROLE_FOO')], $token->getRoles());
$token = $this->getToken([new Role('ROLE_FOO'), 'ROLE_BAR']);
$token = new ConcreteToken([new Role('ROLE_FOO'), 'ROLE_BAR']);
$this->assertEquals([new Role('ROLE_FOO'), new Role('ROLE_BAR')], $token->getRoles());
}
public function testAuthenticatedFlag()
{
$token = $this->getToken();
$token = new ConcreteToken();
$this->assertFalse($token->isAuthenticated());
$token->setAuthenticated(true);
@ -157,7 +120,7 @@ class AbstractTokenTest extends TestCase
public function testAttributes()
{
$attributes = ['foo' => 'bar'];
$token = $this->getToken();
$token = new ConcreteToken();
$token->setAttributes($attributes);
$this->assertEquals($attributes, $token->getAttributes(), '->getAttributes() returns the token attributes');
@ -181,7 +144,7 @@ class AbstractTokenTest extends TestCase
*/
public function testSetUser($user)
{
$token = $this->getToken();
$token = new ConcreteToken();
$token->setUser($user);
$this->assertSame($user, $token->getUser());
}
@ -202,7 +165,7 @@ class AbstractTokenTest extends TestCase
*/
public function testSetUserSetsAuthenticatedToFalseWhenUserChanges($firstUser, $secondUser)
{
$token = $this->getToken();
$token = new ConcreteToken();
$token->setAuthenticated(true);
$this->assertTrue($token->isAuthenticated());
@ -236,7 +199,7 @@ class AbstractTokenTest extends TestCase
*/
public function testSetUserSetsAuthenticatedToFalseWhenUserChangesAdvancedUser($firstUser, $secondUser)
{
$token = $this->getToken();
$token = new ConcreteToken();
$token->setAuthenticated(true);
$this->assertTrue($token->isAuthenticated());
@ -275,7 +238,7 @@ class AbstractTokenTest extends TestCase
*/
public function testSetUserDoesNotSetAuthenticatedToFalseWhenUserDoesNotChange($user)
{
$token = $this->getToken();
$token = new ConcreteToken();
$token->setAuthenticated(true);
$this->assertTrue($token->isAuthenticated());
@ -285,9 +248,48 @@ class AbstractTokenTest extends TestCase
$token->setUser($user);
$this->assertTrue($token->isAuthenticated());
}
}
protected function getToken(array $roles = [])
class TestUser
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
public function __toString()
{
return $this->name;
}
}
class ConcreteToken extends AbstractToken
{
private $credentials = 'credentials_value';
public function __construct(array $roles = [], UserInterface $user = null)
{
parent::__construct($roles);
if (null !== $user) {
$this->setUser($user);
}
}
public function serialize()
{
return serialize([$this->credentials, parent::serialize()]);
}
public function unserialize($serialized)
{
list($this->credentials, $parentStr) = unserialize($serialized);
parent::unserialize($parentStr);
}
public function getCredentials()
{
return $this->getMockForAbstractClass('Symfony\Component\Security\Core\Authentication\Token\AbstractToken', [$roles]);
}
}

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Role\Role;
class AnonymousTokenTest extends TestCase
{
@ -23,7 +22,7 @@ class AnonymousTokenTest extends TestCase
$this->assertTrue($token->isAuthenticated());
$token = new AnonymousToken('foo', 'bar', ['ROLE_FOO']);
$this->assertEquals([new Role('ROLE_FOO')], $token->getRoles());
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
}
public function testGetKey()

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Role\Role;
class PreAuthenticatedTokenTest extends TestCase
{
@ -24,7 +23,7 @@ class PreAuthenticatedTokenTest extends TestCase
$token = new PreAuthenticatedToken('foo', 'bar', 'key', ['ROLE_FOO']);
$this->assertTrue($token->isAuthenticated());
$this->assertEquals([new Role('ROLE_FOO')], $token->getRoles());
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
$this->assertEquals('key', $token->getProviderKey());
}

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Role\Role;
class RememberMeTokenTest extends TestCase
{
@ -24,7 +23,7 @@ class RememberMeTokenTest extends TestCase
$this->assertEquals('fookey', $token->getProviderKey());
$this->assertEquals('foo', $token->getSecret());
$this->assertEquals([new Role('ROLE_FOO')], $token->getRoles());
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
$this->assertSame($user, $token->getUser());
$this->assertTrue($token->isAuthenticated());
}

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Core\Tests\Authentication\Token\Storage;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class TokenStorageTest extends TestCase
{
@ -20,7 +21,7 @@ class TokenStorageTest extends TestCase
{
$tokenStorage = new TokenStorage();
$this->assertNull($tokenStorage->getToken());
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token = new UsernamePasswordToken('username', 'password', 'provider');
$tokenStorage->setToken($token);
$this->assertSame($token, $tokenStorage->getToken());
}

View File

@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class SwitchUserTokenTest extends TestCase
{
public function testSerialize()
{
$originalToken = new UsernamePasswordToken('user', 'foo', 'provider-key', ['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH']);
$token = new SwitchUserToken('admin', 'bar', 'provider-key', ['ROLE_USER'], $originalToken);
$unserializedToken = unserialize(serialize($token));
$this->assertInstanceOf(SwitchUserToken::class, $unserializedToken);
$this->assertSame('admin', $unserializedToken->getUsername());
$this->assertSame('bar', $unserializedToken->getCredentials());
$this->assertSame('provider-key', $unserializedToken->getProviderKey());
$this->assertEquals(['ROLE_USER'], $unserializedToken->getRoleNames());
$unserializedOriginalToken = $unserializedToken->getOriginalToken();
$this->assertInstanceOf(UsernamePasswordToken::class, $unserializedOriginalToken);
$this->assertSame('user', $unserializedOriginalToken->getUsername());
$this->assertSame('foo', $unserializedOriginalToken->getCredentials());
$this->assertSame('provider-key', $unserializedOriginalToken->getProviderKey());
$this->assertEquals(['ROLE_ADMIN', 'ROLE_ALLOWED_TO_SWITCH'], $unserializedOriginalToken->getRoleNames());
}
}

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\Security\Core\Tests\Authentication\Token;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Role\Role;
class UsernamePasswordTokenTest extends TestCase
{
@ -23,7 +22,7 @@ class UsernamePasswordTokenTest extends TestCase
$this->assertFalse($token->isAuthenticated());
$token = new UsernamePasswordToken('foo', 'bar', 'key', ['ROLE_FOO']);
$this->assertEquals([new Role('ROLE_FOO')], $token->getRoles());
$this->assertEquals(['ROLE_FOO'], $token->getRoleNames());
$this->assertTrue($token->isAuthenticated());
$this->assertEquals('key', $token->getProviderKey());
}

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Core\Tests\Authorization;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
class AuthorizationCheckerTest extends TestCase
@ -37,10 +38,10 @@ class AuthorizationCheckerTest extends TestCase
public function testVoteAuthenticatesTokenIfNecessary()
{
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token = new UsernamePasswordToken('username', 'password', 'provider');
$this->tokenStorage->setToken($token);
$newToken = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$newToken = new UsernamePasswordToken('username', 'password', 'provider');
$this->authenticationManager
->expects($this->once())
@ -79,11 +80,7 @@ class AuthorizationCheckerTest extends TestCase
*/
public function testIsGranted($decide)
{
$token = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock();
$token
->expects($this->once())
->method('isAuthenticated')
->will($this->returnValue(true));
$token = new UsernamePasswordToken('username', 'password', 'provider', ['ROLE_USER']);
$this->accessDecisionManager
->expects($this->once())

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\ExpressionVoter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
@ -20,6 +21,7 @@ use Symfony\Component\Security\Core\Role\Role;
class ExpressionVoterTest extends TestCase
{
/**
* @group legacy
* @dataProvider getVoteTests
*/
public function testVote($roles, $attributes, $expected, $tokenExpectsGetRoles = true, $expressionLanguageExpectsEvaluate = true)
@ -29,6 +31,16 @@ class ExpressionVoterTest extends TestCase
$this->assertSame($expected, $voter->vote($this->getToken($roles, $tokenExpectsGetRoles), null, $attributes));
}
/**
* @dataProvider getVoteTests
*/
public function testVoteWithTokenThatReturnsRoleNames($roles, $attributes, $expected, $tokenExpectsGetRoles = true, $expressionLanguageExpectsEvaluate = true)
{
$voter = new ExpressionVoter($this->createExpressionLanguage($expressionLanguageExpectsEvaluate), $this->createTrustResolver(), $this->createAuthorizationChecker());
$this->assertSame($expected, $voter->vote($this->getTokenWithRoleNames($roles, $tokenExpectsGetRoles), null, $attributes));
}
public function getVoteTests()
{
return [
@ -58,6 +70,19 @@ class ExpressionVoterTest extends TestCase
return $token;
}
protected function getTokenWithRoleNames(array $roles, $tokenExpectsGetRoles = true)
{
$token = $this->getMockBuilder(AbstractToken::class)->getMock();
if ($tokenExpectsGetRoles) {
$token->expects($this->once())
->method('getRoleNames')
->will($this->returnValue($roles));
}
return $token;
}
protected function createExpressionLanguage($expressionLanguageExpectsEvaluate = true)
{
$mock = $this->getMockBuilder('Symfony\Component\Security\Core\Authorization\ExpressionLanguage')->getMock();

View File

@ -18,6 +18,7 @@ use Symfony\Component\Security\Core\Role\RoleHierarchy;
class RoleHierarchyVoterTest extends RoleVoterTest
{
/**
* @group legacy
* @dataProvider getVoteTests
*/
public function testVote($roles, $attributes, $expected)
@ -27,6 +28,16 @@ class RoleHierarchyVoterTest extends RoleVoterTest
$this->assertSame($expected, $voter->vote($this->getToken($roles), null, $attributes));
}
/**
* @dataProvider getVoteTests
*/
public function testVoteUsingTokenThatReturnsRoleNames($roles, $attributes, $expected)
{
$voter = new RoleHierarchyVoter(new RoleHierarchy(['ROLE_FOO' => ['ROLE_FOOBAR']]));
$this->assertSame($expected, $voter->vote($this->getTokenWithRoleNames($roles), null, $attributes));
}
public function getVoteTests()
{
return array_merge(parent::getVoteTests(), [
@ -35,6 +46,18 @@ class RoleHierarchyVoterTest extends RoleVoterTest
}
/**
* @group legacy
* @dataProvider getLegacyVoteOnRoleObjectsTests
*/
public function testVoteOnRoleObjects($roles, $attributes, $expected)
{
$voter = new RoleHierarchyVoter(new RoleHierarchy(['ROLE_FOO' => ['ROLE_FOOBAR']]));
$this->assertSame($expected, $voter->vote($this->getToken($roles), null, $attributes));
}
/**
* @group legacy
* @dataProvider getVoteWithEmptyHierarchyTests
*/
public function testVoteWithEmptyHierarchy($roles, $attributes, $expected)
@ -44,6 +67,16 @@ class RoleHierarchyVoterTest extends RoleVoterTest
$this->assertSame($expected, $voter->vote($this->getToken($roles), null, $attributes));
}
/**
* @dataProvider getVoteWithEmptyHierarchyTests
*/
public function testVoteWithEmptyHierarchyUsingTokenThatReturnsRoleNames($roles, $attributes, $expected)
{
$voter = new RoleHierarchyVoter(new RoleHierarchy([]));
$this->assertSame($expected, $voter->vote($this->getTokenWithRoleNames($roles), null, $attributes));
}
public function getVoteWithEmptyHierarchyTests()
{
return parent::getVoteTests();

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Core\Tests\Authorization\Voter;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\Authorization\Voter\RoleVoter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Role\Role;
@ -19,6 +20,7 @@ use Symfony\Component\Security\Core\Role\Role;
class RoleVoterTest extends TestCase
{
/**
* @group legacy
* @dataProvider getVoteTests
*/
public function testVote($roles, $attributes, $expected)
@ -28,6 +30,16 @@ class RoleVoterTest extends TestCase
$this->assertSame($expected, $voter->vote($this->getToken($roles), null, $attributes));
}
/**
* @dataProvider getVoteTests
*/
public function testVoteUsingTokenThatReturnsRoleNames($roles, $attributes, $expected)
{
$voter = new RoleVoter();
$this->assertSame($expected, $voter->vote($this->getTokenWithRoleNames($roles), null, $attributes));
}
public function getVoteTests()
{
return [
@ -41,6 +53,23 @@ class RoleVoterTest extends TestCase
// Test mixed Types
[[], [[]], VoterInterface::ACCESS_ABSTAIN],
[[], [new \stdClass()], VoterInterface::ACCESS_ABSTAIN],
];
}
/**
* @group legacy
* @dataProvider getLegacyVoteOnRoleObjectsTests
*/
public function testVoteOnRoleObjects($roles, $attributes, $expected)
{
$voter = new RoleVoter();
$this->assertSame($expected, $voter->vote($this->getToken($roles), null, $attributes));
}
public function getLegacyVoteOnRoleObjectsTests()
{
return [
[['ROLE_BAR'], [new Role('ROLE_BAR')], VoterInterface::ACCESS_GRANTED],
[['ROLE_BAR'], [new Role('ROLE_FOO')], VoterInterface::ACCESS_DENIED],
];
@ -58,4 +87,14 @@ class RoleVoterTest extends TestCase
return $token;
}
protected function getTokenWithRoleNames(array $roles)
{
$token = $this->getMockBuilder(AbstractToken::class)->getMock();
$token->expects($this->once())
->method('getRoleNames')
->will($this->returnValue($roles));
return $token;
}
}

View File

@ -17,6 +17,9 @@ use Symfony\Component\Security\Core\Role\RoleHierarchy;
class RoleHierarchyTest extends TestCase
{
/**
* @group legacy
*/
public function testGetReachableRoles()
{
$role = new RoleHierarchy([
@ -30,4 +33,18 @@ class RoleHierarchyTest extends TestCase
$this->assertEquals([new Role('ROLE_FOO'), new Role('ROLE_ADMIN'), new Role('ROLE_USER')], $role->getReachableRoles([new Role('ROLE_FOO'), new Role('ROLE_ADMIN')]));
$this->assertEquals([new Role('ROLE_SUPER_ADMIN'), new Role('ROLE_ADMIN'), new Role('ROLE_FOO'), new Role('ROLE_USER')], $role->getReachableRoles([new Role('ROLE_SUPER_ADMIN')]));
}
public function testGetReachableRoleNames()
{
$role = new RoleHierarchy(array(
'ROLE_ADMIN' => array('ROLE_USER'),
'ROLE_SUPER_ADMIN' => array('ROLE_ADMIN', 'ROLE_FOO'),
));
$this->assertEquals(array('ROLE_USER'), $role->getReachableRoleNames(array('ROLE_USER')));
$this->assertEquals(array('ROLE_FOO'), $role->getReachableRoleNames(array('ROLE_FOO')));
$this->assertEquals(array('ROLE_ADMIN', 'ROLE_USER'), $role->getReachableRoleNames(array('ROLE_ADMIN')));
$this->assertEquals(array('ROLE_FOO', 'ROLE_ADMIN', 'ROLE_USER'), $role->getReachableRoleNames(array('ROLE_FOO', 'ROLE_ADMIN')));
$this->assertEquals(array('ROLE_SUPER_ADMIN', 'ROLE_ADMIN', 'ROLE_FOO', 'ROLE_USER'), $role->getReachableRoleNames(array('ROLE_SUPER_ADMIN')));
}
}

View File

@ -14,6 +14,9 @@ namespace Symfony\Component\Security\Core\Tests\Role;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Role\Role;
/**
* @group legacy
*/
class RoleTest extends TestCase
{
public function testGetRole()

View File

@ -14,6 +14,9 @@ namespace Symfony\Component\Security\Core\Tests\Role;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
/**
* @group legacy
*/
class SwitchUserRoleTest extends TestCase
{
public function testGetSource()

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\Security\Guard\Token;
use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\User\UserInterface;
/**
@ -28,9 +27,9 @@ class PostAuthenticationGuardToken extends AbstractToken implements GuardTokenIn
private $providerKey;
/**
* @param UserInterface $user The user!
* @param string $providerKey The provider (firewall) key
* @param (Role|string)[] $roles An array of roles
* @param UserInterface $user The user!
* @param string $providerKey The provider (firewall) key
* @param string[] $roles An array of roles
*
* @throws \InvalidArgumentException
*/

View File

@ -21,6 +21,7 @@ use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverIn
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
@ -189,10 +190,14 @@ class ContextListener implements ListenerInterface
if (null !== $this->logger) {
$context = ['provider' => \get_class($provider), 'username' => $refreshedUser->getUsername()];
foreach ($token->getRoles() as $role) {
if ($role instanceof SwitchUserRole) {
$context['impersonator_username'] = $role->getSource()->getUsername();
break;
if ($token instanceof SwitchUserToken) {
$context['impersonator_username'] = $token->getOriginalToken()->getUsername();
} else {
foreach ($token->getRoles(false) as $role) {
if ($role instanceof SwitchUserRole) {
$context['impersonator_username'] = $role->getSource(false)->getUsername();
break;
}
}
}

View File

@ -17,8 +17,8 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
@ -122,7 +122,7 @@ class SwitchUserListener implements ListenerInterface
$token = $this->tokenStorage->getToken();
$originalToken = $this->getOriginalToken($token);
if (false !== $originalToken) {
if (null !== $originalToken) {
if ($token->getUsername() === $username) {
return $token;
}
@ -146,9 +146,9 @@ class SwitchUserListener implements ListenerInterface
$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 SwitchUserToken($user, $user->getPassword(), $this->providerKey, $roles, $token);
if (null !== $this->dispatcher) {
$switchEvent = new SwitchUserEvent($request, $token->getUser(), $token);
@ -169,7 +169,7 @@ class SwitchUserListener implements ListenerInterface
*/
private function attemptExitUser(Request $request)
{
if (false === $original = $this->getOriginalToken($this->tokenStorage->getToken())) {
if (null === ($currentToken = $this->tokenStorage->getToken()) || null === $original = $this->getOriginalToken($currentToken)) {
throw new AuthenticationCredentialsNotFoundException('Could not find original Token object.');
}
@ -183,19 +183,18 @@ class SwitchUserListener implements ListenerInterface
return $original;
}
/**
* Gets the original Token from a switched one.
*
* @return TokenInterface|false The original TokenInterface instance, false if the current TokenInterface is not switched
*/
private function getOriginalToken(TokenInterface $token)
private function getOriginalToken(TokenInterface $token): ?TokenInterface
{
foreach ($token->getRoles() as $role) {
if ($token instanceof SwitchUserToken) {
return $token->getOriginalToken();
}
foreach ($token->getRoles(false) as $role) {
if ($role instanceof SwitchUserRole) {
return $role->getSource();
}
}
return false;
return null;
}
}

View File

@ -18,6 +18,7 @@ use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolve
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Controller\UserValueResolver;
@ -35,7 +36,7 @@ class UserValueResolverTest extends TestCase
public function testResolveNoUser()
{
$mock = $this->getMockBuilder(UserInterface::class)->getMock();
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
$token = new UsernamePasswordToken('username', 'password', 'provider');
$tokenStorage = new TokenStorage();
$tokenStorage->setToken($token);
@ -57,8 +58,7 @@ class UserValueResolverTest extends TestCase
public function testResolve()
{
$user = $this->getMockBuilder(UserInterface::class)->getMock();
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
$token->expects($this->any())->method('getUser')->willReturn($user);
$token = new UsernamePasswordToken($user, 'password', 'provider');
$tokenStorage = new TokenStorage();
$tokenStorage->setToken($token);
@ -72,8 +72,7 @@ class UserValueResolverTest extends TestCase
public function testIntegration()
{
$user = $this->getMockBuilder(UserInterface::class)->getMock();
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
$token->expects($this->any())->method('getUser')->willReturn($user);
$token = new UsernamePasswordToken($user, 'password', 'provider');
$tokenStorage = new TokenStorage();
$tokenStorage->setToken($token);
@ -83,7 +82,7 @@ class UserValueResolverTest extends TestCase
public function testIntegrationNoUser()
{
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
$token = new UsernamePasswordToken('username', 'password', 'provider');
$tokenStorage = new TokenStorage();
$tokenStorage->setToken($token);

View File

@ -16,6 +16,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Core\User\User;
@ -93,7 +94,7 @@ class SwitchUserListenerTest extends TestCase
public function testExitUserUpdatesToken()
{
$originalToken = new UsernamePasswordToken('username', '', 'key', []);
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken)]));
$this->tokenStorage->setToken(new SwitchUserToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken, false)], $originalToken));
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
@ -107,6 +108,22 @@ class SwitchUserListenerTest extends TestCase
$this->assertSame($originalToken, $this->tokenStorage->getToken());
}
/**
* @group legacy
*/
public function testExitUserBasedOnSwitchUserRoleUpdatesToken()
{
$originalToken = new UsernamePasswordToken('username', '', 'key', array());
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', array(new SwitchUserRole('ROLE_PREVIOUS', $originalToken, false)), $originalToken));
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$listener = new SwitchUserListener($this->tokenStorage, $this->userProvider, $this->userChecker, 'provider123', $this->accessDecisionManager);
$listener->handle($this->event);
$this->assertSame($originalToken, $this->tokenStorage->getToken());
}
public function testExitUserDispatchesEventWithRefreshedUser()
{
$originalUser = $this->getMockBuilder('Symfony\Component\Security\Core\User\UserInterface')->getMock();
@ -118,7 +135,7 @@ class SwitchUserListenerTest extends TestCase
->with($originalUser)
->willReturn($refreshedUser);
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken)]));
$this->tokenStorage->setToken(new SwitchUserToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken, false)], $originalToken));
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
@ -142,7 +159,7 @@ class SwitchUserListenerTest extends TestCase
->expects($this->never())
->method('refreshUser');
$originalToken = new UsernamePasswordToken($originalUser, '', 'key');
$this->tokenStorage->setToken(new UsernamePasswordToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken)]));
$this->tokenStorage->setToken(new SwitchUserToken('username', '', 'key', [new SwitchUserRole('ROLE_PREVIOUS', $originalToken, false)], $originalToken));
$this->request->query->set('_switch_user', SwitchUserListener::EXIT_VALUE);
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();

View File

@ -95,7 +95,7 @@ class LogoutUrlGeneratorTest extends TestCase
public function testGuessFromTokenWithoutProviderKeyFallbacksToCurrentFirewall()
{
$this->tokenStorage->setToken($this->getMockBuilder(TokenInterface::class)->getMock());
$this->tokenStorage->setToken(new UsernamePasswordToken('username', 'password', 'provider'));
$this->generator->registerListener('secured_area', '/logout', null, null);
$this->generator->setCurrentFirewall('secured_area');

View File

@ -17,7 +17,7 @@
],
"require": {
"php": "^7.1.3",
"symfony/security-core": "~3.4|~4.0",
"symfony/security-core": "~4.3",
"symfony/event-dispatcher": "~3.4|~4.0",
"symfony/http-foundation": "~3.4|~4.0",
"symfony/http-kernel": "~3.4|~4.0",

View File

@ -14,6 +14,8 @@ namespace Symfony\Component\Workflow\EventListener;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
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;
@ -80,19 +82,23 @@ class GuardListener
throw new InvalidTokenConfigurationException(sprintf('There are no tokens available for workflow %s.', $event->getWorkflowName()));
}
if (null !== $this->roleHierarchy) {
$roles = $this->roleHierarchy->getReachableRoles($token->getRoles());
if (method_exists($token, 'getRoleNames')) {
$roles = $token->getRoleNames();
} else {
$roles = $token->getRoles();
$roles = array_map(function (Role $role) { return $role->getRole(); }, $token->getRoles(false));
}
if ($this->roleHierarchy instanceof RoleHierarchy) {
$roles = $this->roleHierarchy->getReachableRoleNames($roles);
} elseif (null !== $this->roleHierarchy) {
$roles = $this->roleHierarchy->getReachableRoles($token->getRoles(false));
}
$variables = [
'token' => $token,
'user' => $token->getUser(),
'subject' => $event->getSubject(),
'roles' => array_map(function ($role) {
return $role->getRole();
}, $roles),
'roles' => $roles,
// needed for the is_granted expression function
'auth_checker' => $this->authorizationChecker,
// needed for the is_* expression function

View File

@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase;
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\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Validator\Validator\ValidatorInterface;
@ -35,8 +36,7 @@ class GuardListenerTest extends TestCase
],
];
$expressionLanguage = new ExpressionLanguage();
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
$token->expects($this->any())->method('getRoles')->willReturn([new Role('ROLE_USER')]);
$token = new UsernamePasswordToken('username', 'credentials', 'provider', ['ROLE_USER']);
$tokenStorage = $this->getMockBuilder(TokenStorageInterface::class)->getMock();
$tokenStorage->expects($this->any())->method('getToken')->willReturn($token);
$this->authenticationChecker = $this->getMockBuilder(AuthorizationCheckerInterface::class)->getMock();