src/Package/Admin/Tools/EventSubscriber/LoginSubscriber/LoginSubscriber.php line 102

Open in your IDE?
  1. <?php
  2. namespace App\Package\Admin\Tools\EventSubscriber\LoginSubscriber;
  3. use Symfony\Component\EventDispatcher\EventSubscriberInterface,
  4.     Symfony\Component\Security\Http\Authentication\AuthenticationUtils,
  5.     Symfony\Component\Security\Http\SecurityEvents,
  6.     Symfony\Component\Security\Http\Event\InteractiveLoginEvent,
  7.     Doctrine\ORM\EntityManagerInterface,
  8.     Symfony\Component\HttpFoundation\RequestStack;
  9. use App\Package\Toolkit\ApplicationMode\ApplicationMode,
  10.     App\Package\Toolkit\ConfigurationBag\ConfigurationBag,
  11.     App\Package\Toolkit\AdjacentFirewallLogin\AdjacentFirewallLogin;
  12. use App\Package\Admin\Main\EntityInterface\{ AdminInterfaceLoginHistoryInterface};
  13. use Symfony\Component\Security\Http\Event\LoginFailureEvent;
  14. /**
  15.  * LoginSubscriber
  16.  * 
  17.  * Persists login event (failed/successful) in database
  18.  * 
  19.  * @author     Daniel Balowski <d.balowski@openform.pl> (_creator)
  20.  * @copyright  Openform
  21.  * @since      03.2019
  22.  */
  23. class LoginSubscriber implements EventSubscriberInterface
  24. {
  25.     /**
  26.      * @var ApplicationMode
  27.      */
  28.     protected $applicationMode;
  29.     /**
  30.      * @var ConfigurationBag
  31.      */
  32.     protected $configBag;
  33.     /**
  34.      * @var EntityManagerInterface
  35.      */
  36.     protected $em;
  37.     /**
  38.      * @var AuthenticationUtils
  39.      */
  40.     protected $authUtils;
  41.     /**
  42.      * @var AdjacentFirewallLogin
  43.      */
  44.     protected $adjacentFirewallLogin;
  45.     /**
  46.      * @param ApplicationMode         $applicationMode
  47.      * @param ConfigurationBag        $configBag
  48.      * @param EntityManagerInterface  $em
  49.      * @param RequestStack            $requestStack
  50.      * @param AuthenticationUtils     $authUtils
  51.      */
  52.     public function __construct(
  53.         ApplicationMode        $applicationMode,
  54.         ConfigurationBag       $configBag,
  55.         EntityManagerInterface $em,
  56.         RequestStack           $requestStack,
  57.         AuthenticationUtils    $authUtils
  58.     ) {
  59.         $this->applicationMode $applicationMode;
  60.         $this->configBag $configBag;
  61.         $this->em        $em;
  62.         $this->authUtils $authUtils;
  63.         $this->adjacentFirewallLogin = new AdjacentFirewallLogin(
  64.             $requestStack->getMainRequest()
  65.         );
  66.     }
  67.     /**
  68.      * @return array
  69.      */
  70.     public static function getSubscribedEvents() : array
  71.     {
  72.         return [
  73.             SecurityEvents::INTERACTIVE_LOGIN => [
  74.                 [ 'onSecurityInteractiveLogin'10 ],
  75.             ],
  76.             LoginFailureEvent::class => [
  77.                 [ 'onAuthenticationFailure'10 ]
  78.             ]
  79.             
  80.         ];
  81.     }
  82.     /**
  83.      * On successful login
  84.      * 
  85.      * @param InteractiveLoginEvent  $event
  86.      * 
  87.      * @return void
  88.      */
  89.     public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) : void
  90.     {
  91.         if ($this->applicationMode->getCurrentMode() !== 'admin') {
  92.             return;
  93.         }
  94.         /** @var \App\Package\Admin\Main\Entity\Admin */
  95.         $admin $event->getAuthenticationToken()->getUser();
  96.         $this->adjacentFirewallLogin->setAdjacentToken($event);
  97.         $this->persistLoginHistory(true$admin);
  98.         if ($admin) {
  99.             $admin->setLastSeen(new \DateTime());
  100.             
  101.             $this->em->persist($admin);
  102.             $this->em->flush();
  103.         }
  104.         return;
  105.     }
  106.     /**
  107.      * On failed login
  108.      * 
  109.      * @param LoginFailureEvent $event
  110.      * 
  111.      * @return void
  112.      */
  113.     public function onAuthenticationFailure(LoginFailureEvent $event) : void
  114.     {
  115.         if ($this->applicationMode->getCurrentMode() !== 'admin') {
  116.             return;
  117.         }
  118.         $this->persistLoginHistory(falsenull$this->authUtils->getLastUsername());
  119.         return;
  120.     }
  121.     /**
  122.      * Persists login history entity
  123.      * 
  124.      * @param boolean              $status
  125.      * @param AdminInterface|null  $admin     (optional)
  126.      * @param string|null          $login     (optional)
  127.      * 
  128.      * @return void
  129.      */
  130.     protected function persistLoginHistory(
  131.         bool $status
  132.         AdminInterface $admin null
  133.         string         $login null
  134.     ) : void {
  135.         $loginHistory $this->createLoginHistory();
  136.         $login $admin $admin->getLogin() : $login;
  137.         if (! $login) {
  138.             return;
  139.         }
  140.         if (! empty($_SERVER'HTTP_CLIENT_IP' ])) {
  141.             $ip $_SERVER'HTTP_CLIENT_IP' ];
  142.         } elseif (! empty($_SERVER'HTTP_X_FORWARDED_FOR' ])) {
  143.             $ip $_SERVER'HTTP_X_FORWARDED_FOR' ];
  144.         } else {
  145.             $ip $_SERVER'REMOTE_ADDR' ];
  146.         }
  147.         $loginHistory
  148.             ->setStat($status)
  149.             ->setLogin($login)
  150.             ->setIp($ip);
  151.         $this->em->persist($loginHistory);
  152.         $this->em->flush();
  153.         return;
  154.     }
  155.     /**
  156.      * Creates login history entity
  157.      * 
  158.      * @return LoginHistoryInterface
  159.      */
  160.     protected function createLoginHistory() : LoginHistoryInterface
  161.     {
  162.         $loginHistoryClass $this->configBag->get('admin:entity:login_history');
  163.         
  164.         return new $loginHistoryClass();
  165.     }
  166. }