<?php
declare(strict_types=1);
namespace App\EventSubscriber;
use App\Entity\LoginAttempt;
use App\Entity\User;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Event\LoginFailureEvent;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
final class LoginSubscriber implements EventSubscriberInterface
{
public function __construct(private EntityManagerInterface $entityManager) {}
public static function getSubscribedEvents(): array
{
return [
LoginSuccessEvent::class => 'onLoginSuccessEvent',
LoginFailureEvent::class => 'onLoginFailureEvent',
];
}
public function onLoginSuccessEvent(LoginSuccessEvent $event)
{
/** @var User $user */
$user = $event->getUser();
$user->lastLogin = new \DateTimeImmutable();
$this->entityManager->persist($user);
$loginAttempt = new LoginAttempt();
$loginAttempt->user = $user;
$loginAttempt->login = $user->getUsername();
$loginAttempt->result = LoginAttempt::RESULT_SUCCESS;
$loginAttempt->reason = 'OK';
$loginAttempt->createdAt = new DateTimeImmutable();
$this->entityManager->persist($loginAttempt);
$this->entityManager->flush();
}
public function onLoginFailureEvent(LoginFailureEvent $event)
{
$username = $event->getRequest()->get('_username');
$user = $this->entityManager->getRepository(User::class)->findOneBy(['username' => $username]);
$loginAttempt = new LoginAttempt();
$loginAttempt->login = $username;
$loginAttempt->user = $user;
$loginAttempt->result = LoginAttempt::RESULT_FAIL;
$loginAttempt->reason = 'Nieudane logowanie';
$loginAttempt->createdAt = new DateTimeImmutable();
$this->entityManager->persist($loginAttempt);
$this->entityManager->flush();
}
}