src/Security/Authentication/AuthenticationSubscriber.php line 59

  1. <?php
  2. namespace App\Security\Authentication;
  3. use Symfony\Component\EventDispatcher\EventSubscriberInterface,
  4.     Symfony\Component\Security\Http\Event\CheckPassportEvent,
  5.     Symfony\Component\HttpFoundation\RequestStack;
  6. use Lexik\Bundle\JWTAuthenticationBundle\Events as LexikEvents,
  7.     Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent,
  8.     Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationFailureEvent;
  9. use App\Entity\Admin,
  10.     App\Entity\LoginEntry,
  11.     App\Security\Authentication\LoginBlockedChecker,
  12.     App\Repository\AdminRepository,
  13.     App\Repository\LoginEntryRepository;
  14. final class AuthenticationSubscriber implements EventSubscriberInterface
  15. {
  16.     private AdminRepository $adminRepository;
  17.     private LoginEntryRepository $loginEntryRepository;
  18.     private LoginBlockedChecker $loginBlockedChecker;
  19.     private RequestStack $requestStack;
  20.     public function __construct(
  21.         AdminRepository $adminRepository,
  22.         LoginEntryRepository $loginEntryRepository,
  23.         LoginBlockedChecker $loginBlockedChecker,
  24.         RequestStack $requestStack
  25.     ) {
  26.         $this->adminRepository $adminRepository;
  27.         $this->loginEntryRepository $loginEntryRepository;
  28.         $this->loginBlockedChecker $loginBlockedChecker;
  29.         $this->requestStack $requestStack;
  30.     }
  31.     public static function getSubscribedEvents() : array
  32.     {
  33.         return [
  34.             CheckPassportEvent::class => [
  35.                 ['onAuthenticationCheck'10]
  36.             ],
  37.             LexikEvents::AUTHENTICATION_SUCCESS => [
  38.                 ['onAuthenticationSuccess'10],
  39.             ],
  40.             LexikEvents::AUTHENTICATION_FAILURE => [
  41.                 ['onAuthenticationFailure'10]
  42.             ]
  43.         ];
  44.     }
  45.     public function onAuthenticationCheck(CheckPassportEvent $event): void
  46.     {
  47.         $this->loginBlockedChecker->check($this->getClientIp());
  48.         return;
  49.     }
  50.     public function onAuthenticationSuccess(AuthenticationSuccessEvent $event): void
  51.     {
  52.         /** @var Admin */
  53.         $admin $event->getUser();
  54.         $admin->setLastActivityAt(new \DateTimeImmutable());
  55.         $this->adminRepository->persist($admin);
  56.         $this->persistLoginEntry(
  57.             username$admin->getUserIdentifier(),
  58.             ip$this->getClientIp(),
  59.             resulttrue
  60.         );
  61.         return;
  62.     }
  63.     public function onAuthenticationFailure(AuthenticationFailureEvent $event): void
  64.     {
  65.         $content json_decode($this->getRequestContent());
  66.         $this->persistLoginEntry(
  67.             usernameproperty_exists($content'email') ? $content->email 'unkown',
  68.             ip$this->getClientIp(),
  69.             resultfalse
  70.         );
  71.         return;
  72.     }
  73.     private function persistLoginEntry(string $usernamestring $ipbool $result): void
  74.     {
  75.         $loginEntry = new LoginEntry($username$ip$result);
  76.         $this->loginEntryRepository->persist($loginEntrytrue);
  77.         return;
  78.     }
  79.     private function getClientIp(): string
  80.     {
  81.         return $this->requestStack->getCurrentRequest()?->getClientIp() ?? '';
  82.     }
  83.     private function getRequestContent(): string
  84.     {
  85.         return $this->requestStack->getCurrentRequest()?->getContent() ?? '';
  86.     }
  87. }