Skip to content

Commit

Permalink
minor #31723 [Security] remove deprecated role classes (xabbuh)
Browse files Browse the repository at this point in the history
This PR was merged into the 5.0-dev branch.

Discussion
----------

[Security] remove deprecated role classes

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | yes
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

Commits
-------

d64372d remove deprecated role classes
  • Loading branch information
Robin Chalas committed May 31, 2019
2 parents e5aaa8c + d64372d commit 343da8c
Show file tree
Hide file tree
Showing 29 changed files with 39 additions and 662 deletions.
6 changes: 1 addition & 5 deletions src/Symfony/Bridge/Monolog/Processor/TokenProcessor.php
Expand Up @@ -31,11 +31,7 @@ public function __invoke(array $records)
{
$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));
}
$roles = $token->getRoleNames();

$records['extra']['token'] = [
'username' => $token->getUsername(),
Expand Down
Expand Up @@ -22,9 +22,7 @@
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\RoleHierarchyInterface;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Http\Firewall\SwitchUserListener;
use Symfony\Component\Security\Http\FirewallMapInterface;
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
Expand Down Expand Up @@ -92,33 +90,15 @@ public function collect(Request $request, Response $response, \Exception $except
];
} else {
$inheritedRoles = [];

if (method_exists($token, 'getRoleNames')) {
$assignedRoles = $token->getRoleNames();
} else {
$assignedRoles = array_map(function (Role $role) { return $role->getRole(); }, $token->getRoles(false));
}
$assignedRoles = $token->getRoleNames();

$impersonatorUser = null;
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) {
if (method_exists($this->roleHierarchy, 'getReachableRoleNames')) {
$allRoles = $this->roleHierarchy->getReachableRoleNames($assignedRoles);
} else {
$allRoles = array_map(function (Role $role) { return (string) $role; }, $this->roleHierarchy->getReachableRoles($token->getRoles(false)));
}

foreach ($allRoles as $role) {
foreach ($this->roleHierarchy->getReachableRoleNames($assignedRoles) as $role) {
if (!\in_array($role, $assignedRoles, true)) {
$inheritedRoles[] = $role;
}
Expand Down
Expand Up @@ -28,9 +28,7 @@
use Symfony\Component\Security\Core\Authorization\TraceableAccessDecisionManager;
use Symfony\Component\Security\Core\Authorization\Voter\TraceableVoter;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Role\RoleHierarchy;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Http\FirewallMapInterface;
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
Expand Down Expand Up @@ -97,36 +95,6 @@ public function testCollectAuthenticationTokenAndRoles(array $roles, array $norm
$this->assertSame('hhamon', $collector->getUser());
}

/**
* @group legacy
*/
public function testCollectImpersonatedToken()
{
$adminToken = new UsernamePasswordToken('yceruto', 'P4$$w0rD', 'provider', ['ROLE_ADMIN']);

$userRoles = [
'ROLE_USER',
new SwitchUserRole('ROLE_PREVIOUS_ADMIN', $adminToken),
];

$tokenStorage = new TokenStorage();
$tokenStorage->setToken(new UsernamePasswordToken('hhamon', 'P4$$w0rD', 'provider', $userRoles));

$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('Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken', $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 testCollectSwitchUserToken()
{
$adminToken = new UsernamePasswordToken('yceruto', 'P4$$w0rD', 'provider', ['ROLE_ADMIN']);
Expand Down Expand Up @@ -391,22 +359,12 @@ public function provideRoles()
['ROLE_USER'],
[],
],
[
[new Role('ROLE_USER', false)],
['ROLE_USER'],
[],
],
// Inherited roles
[
['ROLE_ADMIN'],
['ROLE_ADMIN'],
['ROLE_USER', 'ROLE_ALLOWED_TO_SWITCH'],
],
[
[new Role('ROLE_ADMIN', false)],
['ROLE_ADMIN'],
['ROLE_USER', 'ROLE_ALLOWED_TO_SWITCH'],
],
[
['ROLE_ADMIN', 'ROLE_OPERATOR'],
['ROLE_ADMIN', 'ROLE_OPERATOR'],
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Security/CHANGELOG.md
Expand Up @@ -11,6 +11,11 @@ CHANGELOG
* `SimpleAuthenticatorInterface`, `SimpleFormAuthenticatorInterface`, `SimplePreAuthenticatorInterface`,
`SimpleAuthenticationProvider`, `SimpleAuthenticationHandler`, `SimpleFormAuthenticationListener` and
`SimplePreAuthenticationListener` have been removed. Use Guard instead.
* Removed the `Role` and `SwitchUserRole` classes. Use strings for roles instead.
* Removed the `getReachableRoles()` method from the `RoleHierarchyInterface`. Role hierarchies must implement
the `getReachableRoleNames()` method instead and return roles as strings.
* Removed the `getRoles()` method from the `TokenInterface`. Tokens must implement the `getRoleNames()` method
instead and return roles as strings.

4.3.0
-----
Expand Down
Expand Up @@ -18,7 +18,6 @@
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Role\SwitchUserRole;
use Symfony\Component\Security\Core\User\UserCheckerInterface;
use Symfony\Component\Security\Core\User\UserInterface;

Expand Down Expand Up @@ -89,9 +88,9 @@ public function authenticate(TokenInterface $token)
}

if ($token instanceof SwitchUserToken) {
$authenticatedToken = new SwitchUserToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token), $token->getOriginalToken());
$authenticatedToken = new SwitchUserToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles(), $token->getOriginalToken());
} else {
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $this->getRoles($user, $token));
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $this->providerKey, $user->getRoles());
}

$authenticatedToken->setAttributes($token->getAttributes());
Expand All @@ -107,26 +106,6 @@ public function supports(TokenInterface $token)
return $token instanceof UsernamePasswordToken && $this->providerKey === $token->getProviderKey();
}

/**
* Retrieves roles from user and appends SwitchUserRole if original token contained one.
*
* @return array The user roles
*/
private function getRoles(UserInterface $user, TokenInterface $token)
{
$roles = $user->getRoles();

foreach ($token->getRoles(false) as $role) {
if ($role instanceof SwitchUserRole) {
$roles[] = $role;

break;
}
}

return $roles;
}

/**
* Retrieves the user from an implementation-specific location.
*
Expand Down
Expand Up @@ -11,7 +11,6 @@

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

use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Symfony\Component\Security\Core\User\UserInterface;

Expand All @@ -24,7 +23,6 @@
abstract class AbstractToken implements TokenInterface
{
private $user;
private $roles = [];
private $roleNames = [];
private $authenticated = false;
private $attributes = [];
Expand All @@ -37,32 +35,16 @@ abstract class AbstractToken implements TokenInterface
public function __construct(array $roles = [])
{
foreach ($roles as $role) {
if (\is_string($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;
$this->roleNames[] = $role;
}
}

public function getRoleNames(): array
{
return $this->roleNames;
}

/**
* {@inheritdoc}
*/
public function getRoles()
public function getRoleNames(): array
{
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;
return $this->roleNames;
}

/**
Expand Down Expand Up @@ -158,7 +140,7 @@ public function eraseCredentials()
*/
public function __serialize(): array
{
return [$this->user, $this->authenticated, $this->roles, $this->attributes, $this->roleNames];
return [$this->user, $this->authenticated, null, $this->attributes, $this->roleNames];
}

/**
Expand Down Expand Up @@ -198,15 +180,7 @@ public function serialize()
*/
public function __unserialize(array $data): void
{
[$this->user, $this->authenticated, $this->roles, $this->attributes] = $data;

// migration path to 4.3+
if (null === $this->roleNames = $data[4] ?? null) {
$this->roleNames = [];
foreach ($this->roles as $role) {
$this->roleNames[] = (string) $role;
}
}
[$this->user, $this->authenticated, , $this->attributes, $this->roleNames] = $data;
}

/**
Expand Down Expand Up @@ -291,8 +265,8 @@ public function __toString()
$class = substr($class, strrpos($class, '\\') + 1);

$roles = [];
foreach ($this->roles as $role) {
$roles[] = $role->getRole();
foreach ($this->roleNames as $role) {
$roles[] = $role;
}

return sprintf('%s(user="%s", authenticated=%s, roles="%s")', $class, $this->getUsername(), json_encode($this->authenticated), implode(', ', $roles));
Expand Down
Expand Up @@ -39,10 +39,6 @@ public function getToken()
*/
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;
}

Expand Down
Expand Up @@ -11,17 +11,14 @@

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

use Symfony\Component\Security\Core\Role\Role;

/**
* TokenInterface is the interface for the user authentication information.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*
* @method array __serialize() Returns all the necessary state of the object for serialization purposes - not implementing it is deprecated since Symfony 4.3
* @method void __unserialize(array $data) Restores the object state from an array given by __serialize() - not implementing it is deprecated since Symfony 4.3
* @method string[] getRoleNames() The associated roles - not implementing it is deprecated since Symfony 4.3
* @method array __serialize() Returns all the necessary state of the object for serialization purposes - not implementing it is deprecated since Symfony 4.3
* @method void __unserialize(array $data) Restores the object state from an array given by __serialize() - not implementing it is deprecated since Symfony 4.3
*/
interface TokenInterface extends \Serializable
{
Expand All @@ -37,11 +34,9 @@ public function __toString();
/**
* Returns the user roles.
*
* @return Role[] An array of Role instances
*
* @deprecated since Symfony 4.3, use the getRoleNames() method instead
* @return string[] The associated roles
*/
public function getRoles();
public function getRoleNames(): array;

/**
* Returns the user credentials.
Expand Down
Expand Up @@ -18,7 +18,6 @@
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\RoleHierarchyInterface;

/**
Expand Down Expand Up @@ -78,30 +77,17 @@ public function vote(TokenInterface $token, $subject, array $attributes)

private function getVariables(TokenInterface $token, $subject)
{
if (method_exists($token, 'getRoleNames')) {
$roleNames = $token->getRoleNames();
$roles = array_map(function (string $role) { return new Role($role, false); }, $roleNames);
} else {
@trigger_error(sprintf('Not implementing the getRoleNames() method in %s which implements %s is deprecated since Symfony 4.3.', \get_class($token), TokenInterface::class), E_USER_DEPRECATED);

$roles = $token->getRoles(false);
$roleNames = array_map(function (Role $role) { return $role->getRole(); }, $roles);
}
$roleNames = $token->getRoleNames();

if (null !== $this->roleHierarchy && method_exists($this->roleHierarchy, 'getReachableRoleNames')) {
if (null !== $this->roleHierarchy) {
$roleNames = $this->roleHierarchy->getReachableRoleNames($roleNames);
$roles = array_map(function (string $role) { return new Role($role, false); }, $roleNames);
} elseif (null !== $this->roleHierarchy) {
$roles = $this->roleHierarchy->getReachableRoles($roles);
$roleNames = array_map(function (Role $role) { return $role->getRole(); }, $roles);
}

$variables = [
'token' => $token,
'user' => $token->getUser(),
'object' => $subject,
'subject' => $subject,
'roles' => $roles,
'role_names' => $roleNames,
'trust_resolver' => $this->trustResolver,
'auth_checker' => $this->authChecker,
Expand Down

0 comments on commit 343da8c

Please sign in to comment.