src/EventListener/SecurityListener.php line 173

Open in your IDE?
  1. <?php
  2. namespace App\EventListener;
  3. use App\Entity\UserManagement\FailedLoginAttempt;
  4. use App\Entity\UserManagement\User;
  5. use App\Entity\UserManagement\Tracking;
  6. use App\Repository\UserManagement\FailedLoginAttemptRepository;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Psr\Log\LoggerInterface;
  9. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  10. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  11. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpFoundation\RequestStack;
  14. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  15. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  16. use Symfony\Component\HttpKernel\Event\RequestEvent;
  17. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  18. use Symfony\Component\HttpKernel\KernelEvents;
  19. use Symfony\Component\HttpKernel\HttpKernelInterface;
  20. use Symfony\Component\Messenger\MessageBusInterface;
  21. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  22. use Symfony\Component\Security\Core\AuthenticationEvents;
  23. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  24. use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
  25. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  26. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  27. use Symfony\Component\Security\Http\SecurityEvents;
  28. /**
  29.  * Listener responsible to change the redirection when a form is successfully filled.
  30.  */
  31. class SecurityListener implements EventSubscriberInterface
  32. {
  33.     protected $router;
  34.     protected $dispatcher;
  35.     protected $entityManager;
  36.     protected $messageBus;
  37.     protected $authenticationUtils;
  38.     protected $requestStack;
  39.     protected $failedLoginAttemptRepository;
  40.     protected $session;
  41.     protected $securityToken;
  42.     protected $parameter;
  43.     protected $logger;
  44.     public function __construct(UrlGeneratorInterface $routerEventDispatcherInterface $dispatcherMessageBusInterface $messageBusAuthenticationUtils $authenticationUtilsRequestStack $requestStackEntityManagerInterface $entityManagerFailedLoginAttemptRepository $failedLoginAttemptRepositorySessionInterface $sessionTokenStorageInterface $securityTokenParameterBagInterface $parameterLoggerInterface $logger)
  45.     {
  46.         $this->router $router;
  47.         $this->dispatcher $dispatcher;
  48.         $this->entityManager $entityManager;
  49.         $this->messageBus $messageBus;
  50.         $this->authenticationUtils $authenticationUtils;
  51.         $this->requestStack $requestStack;
  52.         $this->failedLoginAttemptRepository $failedLoginAttemptRepository;
  53.         $this->session $session;
  54.         $this->securityToken $securityToken;
  55.         $this->parameter $parameter;    
  56.         $this->logger $logger;    
  57.     }
  58.     /**
  59.      * {@inheritdoc}
  60.      */
  61.     public static function getSubscribedEvents()
  62.     {
  63.         return [
  64.             SecurityEvents::INTERACTIVE_LOGIN => 'onLogin',
  65.             AuthenticationEvents::AUTHENTICATION_FAILURE => 'onLoginFailure',
  66.             RequestEvent::class => 'onKernelRequest',
  67.         ];
  68.     }
  69.     public function onLogin(InteractiveLoginEvent $event)
  70.     {
  71.         $user $event->getAuthenticationToken()->getUser();
  72.         $request $event->getRequest();
  73.         $route $request->get('_route');
  74.         $userDetails = [
  75.             'id' =>             $user->getId(),
  76.             'username' =>       $user->getUsername(),
  77.             'email' =>          $user->getEmail(),
  78.             'authenticated' =>  true
  79.         ];
  80.         $entity = new Tracking();
  81.         $entity->setController('App\Controller\UserManagement\SecurityController');
  82.         $entity->setAction('loginAction');
  83.         $entity->setQueryRequest(json_encode($userDetails));
  84.         $entity->setPathInfo('/'.$request->getLocale().'/login');
  85.         $entity->setHttpMethod($request->getMethod());
  86.         $entity->setIpRequest($request->getClientIp());
  87.         $entity->setLang($request->getLocale());
  88.         $entity->setUriRequest($request->getUri());
  89.         $entity->setCreated((new \DateTime('now')));
  90.         $entity->setUser($user);
  91.         try {
  92.             $this->entityManager->persist($entity);
  93.             $this->entityManager->flush();            
  94.         } catch (\Throwable $exception) {
  95.             throw new \Exception($exception->getMessage());
  96.         }
  97.         if ($route != 'change_password' && null != $route) {
  98.             $duration 0;
  99.             if ($user->getLastChangePassword()) {
  100.                 $now = new \DateTime();
  101.                 $interval $user->getLastChangePassword()->diff($now);
  102.                 $duration $interval->format('%a');
  103.             } 
  104.             
  105.             if ($user->getChangePassword() || $user->getLastChangePassword() == null || $duration >= User::PASSWORD_AGE) {
  106.                 $this->dispatcher->addListener(KernelEvents::RESPONSE, [
  107.                             $this,
  108.                             'onKernelResponse'
  109.                 ]);
  110.             }
  111.         }
  112.     }
  113.     public function onKernelResponse(ResponseEvent $event)
  114.     {
  115.         $response = new RedirectResponse($this->router->generate('change_password'));
  116.         $event->setResponse($response);
  117.     }
  118.     public function onLoginFailure(AuthenticationFailureEvent $event)
  119.     {
  120.         $username $this->authenticationUtils->getLastUsername();
  121.         $request $this->requestStack->getCurrentRequest();
  122.         $this->failedLoginAttemptRepository->save(FailedLoginAttempt::createFromRequest($request));
  123.         $existingUser $this->entityManager->getRepository(User::class)->loadUserByUsername($username);
  124.         if ($existingUser) {
  125.             $userDetails = [
  126.                 'id' =>             $existingUser->getId(),
  127.                 'username' =>       $existingUser->getUsername(),
  128.                 'email' =>          $existingUser->getEmail(),
  129.                 'authenticated' =>  false
  130.             ];
  131.         } else {
  132.             $userDetails = [
  133.                 'username' =>           $username,
  134.                 'authenticated' =>  false
  135.             ];
  136.         }
  137.         $entity = new Tracking();
  138.         $entity->setController('App\Controller\UserManagement\SecurityController');
  139.         $entity->setAction('loginFailureAction');
  140.         $entity->setQueryRequest(json_encode($userDetails));
  141.         $entity->setPathInfo('/'.$request->getLocale().'/login');
  142.         $entity->setHttpMethod($request->getMethod());
  143.         $entity->setIpRequest($request->getClientIp());
  144.         $entity->setLang($request->getLocale());
  145.         $entity->setUriRequest($request->getUri());
  146.         $entity->setCreated((new \DateTime('now')));
  147.         try {
  148.             $this->entityManager->persist($entity);
  149.             $this->entityManager->flush($entity);
  150.         } catch (\Throwable $exception) {
  151.             throw new \Exception($exception->getMessage());
  152.         }
  153.     }
  154.     public function onKernelRequest(RequestEvent $event)
  155.     {
  156.         if (HttpKernelInterface::MASTER_REQUEST != $event->getRequestType()) {
  157.             return;
  158.         }
  159.         
  160.         $maxIdleTime $this->parameter->get('session_max_idle_time');
  161.         //$this->logger->critical($maxIdleTime);
  162.         if ($maxIdleTime 0) {
  163.             $this->session->start();
  164.             $lapse time() - $this->session->getMetadataBag()->getLastUsed();
  165.             //$this->logger->critical($this->session->getMetadataBag()->getLastUsed());
  166.             
  167.             if ($lapse $maxIdleTime) {
  168.                 $this->securityToken->setToken(null);
  169.                 //$this->session->getFlashBag()->set('info', 'You have been logged out due to inactivity.');
  170.                 $event->setResponse(new RedirectResponse($this->router->generate('app_login')));
  171.             }
  172.         }
  173.     }          
  174. }