src/Security/Authentication/AuthenticationSubscriber.php line 59
<?php
namespace App\Security\Authentication;
use Symfony\Component\EventDispatcher\EventSubscriberInterface,
Symfony\Component\Security\Http\Event\CheckPassportEvent,
Symfony\Component\HttpFoundation\RequestStack;
use Lexik\Bundle\JWTAuthenticationBundle\Events as LexikEvents,
Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent,
Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationFailureEvent;
use App\Entity\Admin,
App\Entity\LoginEntry,
App\Security\Authentication\LoginBlockedChecker,
App\Repository\AdminRepository,
App\Repository\LoginEntryRepository;
final class AuthenticationSubscriber implements EventSubscriberInterface
{
private AdminRepository $adminRepository;
private LoginEntryRepository $loginEntryRepository;
private LoginBlockedChecker $loginBlockedChecker;
private RequestStack $requestStack;
public function __construct(
AdminRepository $adminRepository,
LoginEntryRepository $loginEntryRepository,
LoginBlockedChecker $loginBlockedChecker,
RequestStack $requestStack
) {
$this->adminRepository = $adminRepository;
$this->loginEntryRepository = $loginEntryRepository;
$this->loginBlockedChecker = $loginBlockedChecker;
$this->requestStack = $requestStack;
}
public static function getSubscribedEvents() : array
{
return [
CheckPassportEvent::class => [
['onAuthenticationCheck', 10]
],
LexikEvents::AUTHENTICATION_SUCCESS => [
['onAuthenticationSuccess', 10],
],
LexikEvents::AUTHENTICATION_FAILURE => [
['onAuthenticationFailure', 10]
]
];
}
public function onAuthenticationCheck(CheckPassportEvent $event): void
{
$this->loginBlockedChecker->check($this->getClientIp());
return;
}
public function onAuthenticationSuccess(AuthenticationSuccessEvent $event): void
{
/** @var Admin */
$admin = $event->getUser();
$admin->setLastActivityAt(new \DateTimeImmutable());
$this->adminRepository->persist($admin);
$this->persistLoginEntry(
username: $admin->getUserIdentifier(),
ip: $this->getClientIp(),
result: true
);
return;
}
public function onAuthenticationFailure(AuthenticationFailureEvent $event): void
{
$content = json_decode($this->getRequestContent());
$this->persistLoginEntry(
username: property_exists($content, 'email') ? $content->email : 'unkown',
ip: $this->getClientIp(),
result: false
);
return;
}
private function persistLoginEntry(string $username, string $ip, bool $result): void
{
$loginEntry = new LoginEntry($username, $ip, $result);
$this->loginEntryRepository->persist($loginEntry, true);
return;
}
private function getClientIp(): string
{
return $this->requestStack->getCurrentRequest()?->getClientIp() ?? '';
}
private function getRequestContent(): string
{
return $this->requestStack->getCurrentRequest()?->getContent() ?? '';
}
}