<?php
namespace App\EventSubscriber;
use App\Controller\ApiController;
use App\Controller\AuthController;
use App\Controller\ClientController;
use App\Controller\FrontendController;
use App\Entity\User;
use Gregwar\CaptchaBundle\Controller\CaptchaController;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
class UserSecurityCheckSubscriber implements EventSubscriberInterface
{
public const SESSION_KEY = 'auth/securityCheckPassed';
/** @var UrlGeneratorInterface */
private $urlGenerator;
/** @var User */
private $user;
/**
* UserSecurityCheckSubscriber constructor.
* @param UrlGeneratorInterface $urlGenerator
* @param TokenStorageInterface $tokenStorage
* @param Security $security
*/
public function __construct(UrlGeneratorInterface $urlGenerator, TokenStorageInterface $tokenStorage)
{
$this->urlGenerator = $urlGenerator;
try {
$token = $tokenStorage->getToken();
if ($token instanceof PostAuthenticationGuardToken) {
$this->user = $token->getUser();
}
} catch (\Exception $e) {
$this->user = null;
}
}
public function onKernelController(KernelEvent $event) {
$request = $event->getRequest();
$controller = $event->getController();
$controllerClassName = null;
if (is_array($controller)) {
$controllerClassName = get_class($controller[0]);
} else {
$controllerClassName = get_class($controller);
}
$isLoggedIn = $this->user !== null;
$isFullUser = $isLoggedIn && $this->user->hasRole('FULL_USER');
$isSecurityCheckPassed = $request->getSession()->get(self::SESSION_KEY) === true;
$protectedControllers = [ClientController::class, ApiController::class];
$allowedControllers = [FrontendController::class, CaptchaController::class];
$isControllerAllowed = !in_array($controllerClassName, $protectedControllers);
$isEmailConfirmed = $isLoggedIn && $this->user->getIsEmailConfirmed();
if (in_array($controllerClassName, $allowedControllers)) {
return;
}
// if ($isLoggedIn && !$isEmailConfirmed) {
// if ($controllerClassName !== AuthController::class ||
// $controller[1] !== 'loginSecurityEmail'
// ) {
// $event->setController(function () {
// return new RedirectResponse($this->urlGenerator->generate('login_security_email'));
// });
// }
//
// return;
// }
if ($isFullUser && !$isControllerAllowed && !$isSecurityCheckPassed && $isEmailConfirmed) {
$event->setController(function() {
return new RedirectResponse($this->urlGenerator->generate('login_security_check'));
});
}
}
public static function getSubscribedEvents()
{
return [
KernelEvents::CONTROLLER => 'onKernelController',
];
}
}