<?php
namespace App\EventSubscriber;
use App\Entity\User;
use App\Service\UserService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Security;
class KernelSubscriber implements EventSubscriberInterface
{
public const TWO_FACTOR_ROUTE = 'two_factor_confirm';
public const LOGIN_ROUTE = 'login';
public const HOME_ROUTE = 'home';
public const VALIDATE_ROUTE = 'two_factor_validate';
private const OPEN_ROUTES = [
self::TWO_FACTOR_ROUTE,
self::LOGIN_ROUTE,
self::VALIDATE_ROUTE
];
/** @var Security $security */
private $security;
/** @var RouterInterface $router */
private $router;
/** @var UserService $userService */
private $userService;
/**
* KernelSubscriber constructor.
* @param Security $security
* @param RouterInterface $router
* @param UserService $userService
*/
public function __construct(Security $security, RouterInterface $router, UserService $userService)
{
$this->security = $security;
$this->router = $router;
$this->userService = $userService;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => 'onKernelRequest'
];
}
/**
* @param RequestEvent $event
*/
public function onKernelRequest(RequestEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
if ($this->security->getUser()) {
$user = $this->security->getUser();
if ($user instanceof User) {
$route = $event->getRequest()->get('_route');
if (
$this->userService->isAdmin($user) &&
$user->getTwoFactorToken() && !in_array($route, self::OPEN_ROUTES)
) {
$event->setResponse(new RedirectResponse($this->router->generate(self::TWO_FACTOR_ROUTE)));
}
}
}
}
}