<?php namespace Lc\CaracoleBundle\EventSubscriber\User; use Doctrine\ORM\EntityManagerInterface; use Lc\CaracoleBundle\Resolver\MerchantResolver; use Lc\SovBundle\Definition\RolesDefinition; use Lc\SovBundle\Model\User\UserInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Http\SecurityEvents; class UserRolesEventSubscriber implements EventSubscriberInterface { protected $em; protected $tokenStorage; protected $router; protected $merchantResolver; public function __construct( TokenStorageInterface $tokenStorage, EntityManagerInterface $entityManager, RouterInterface $router, MerchantResolver $merchantResolver ) { $this->em = $entityManager; $this->tokenStorage = $tokenStorage; $this->router = $router; $this->merchantResolver = $merchantResolver; } public static function getSubscribedEvents() { return [ KernelEvents::REQUEST => ['setUserRolesFromKernelRequest'], SecurityEvents::INTERACTIVE_LOGIN => ['setUserRolesAuthenticationSuccess'], ]; } public function setUserRolesFromKernelRequest(RequestEvent $event) { if (!$event->isMasterRequest()) { return; } if ($this->setUserRoles($event->getRequest())) { $response = new RedirectResponse($this->router->generate('app_admin_dashboard')); $event->setResponse($response); } } public function setUserRolesAuthenticationSuccess(InteractiveLoginEvent $interactiveLoginEvent) { $this->setUserRoles($interactiveLoginEvent->getRequest()); } public function setUserRoles(Request $request): bool { if ($this->tokenStorage && $this->tokenStorage->getToken()) { $token = $this->tokenStorage->getToken(); $sessionUser = $token->getUser(); if ($sessionUser instanceof UserInterface) { $userMerchant = $this->merchantResolver->getUserMerchant($sessionUser); if ($userMerchant) { $roles = $userMerchant->getRoles(); } else { $roles = [RolesDefinition::ROLE_USER]; } if ($roles != $sessionUser->getRoles()) { $sessionUser->setRoles($roles); $this->em->update($sessionUser); $this->em->flush(); $token = new UsernamePasswordToken( $sessionUser, null, 'main', $sessionUser->getRoles() ); $this->tokenStorage->setToken($token); return true; } } } return false; } }