<?php
namespace App\Listener\Security;
use App\Entity\User;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class RoleChangeListener
{
/**
* @var TokenStorageInterface
*/
private $storage;
public function __construct(TokenStorageInterface $storage)
{
$this->storage = $storage;
}
public function onKernelRequest(RequestEvent $event)
{
$impersonating = null;
$source = null;
if (!$this->storage->getToken()) {
return;
}
$user = $this->storage->getToken()->getUser();
if (!$user instanceof User) {
return;
}
$current = $this->storage->getToken()->getRoleNames();
foreach ($current as $index => $role) {
if ('ROLE_PREVIOUS_ADMIN' !== $role) {
continue;
}
unset($current[$index]);
$impersonating = $role;
}
$new = $user->getRoles();
// Check that the roles are the same, in any order
$isEqual = $user->getGroups()->count() == count($current);
if ($isEqual) {
foreach ($current as $role) {
$isEqual = $isEqual && in_array($role, $new);
}
}
if ($isEqual) {
return;
}
if (null !== $impersonating) {
$new[] = $impersonating;
}
$token = new UsernamePasswordToken($user, null, 'main', $new);
$this->storage->setToken($token);
}
}