<?php
namespace App\EventListener;
use App\Entity\Utilisateur;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\RememberMeToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Event\AuthenticationFailureEvent;
use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
final class LoginListener
{
/** @var EntityManagerInterface $em */
private $em;
/** @var LoggerInterface $logger */
private $logger;
/** @var RequestStack $requestStack */
private $requestStack;
/** @var int $session */
private $login_attempts = 3;
/** @var string $session */
private $jail_duration = '15 minutes';
public function __construct(
EntityManagerInterface $em,
LoggerInterface $logger,
RequestStack $requestStack,
$login_attempts,
$jail_duration
) {
$this->em = $em;
$this->logger = $logger;
$this->requestStack = $requestStack;
$this->login_attempts = $login_attempts;
$this->jail_duration = $jail_duration;
}
public function onInteractiveLogin(InteractiveLoginEvent $event)
{
$request = $event->getRequest();
$login = $request->request->get('_username');
$this->logger->info("Connexion : " . $login);
}
public function onAuthenticationFailure(AuthenticationFailureEvent $event)
{
$login = $event->getAuthenticationToken()->getUsername();
$query = "
INSERT INTO login_attempts_errors ( login, date_attempt, ip_attempt, jailed )
VALUES (
'" . $login . "',
now(),
'" . @$_SERVER['REMOTE_ADDR'] . "',
CASE WHEN (
SELECT COUNT(*)
FROM login_attempts_errors
WHERE login = '" . $login . "'
AND date_attempt >= ( now() - interval '" . $this->jail_duration . "' )
) >= " . $this->login_attempts . "
THEN true
ELSE false
END
)
";
$this->em->getConnection()->executeStatement($query);
$this->logger->info("Connexion echouée");
}
public function onAuthenticationSuccess(AuthenticationSuccessEvent $event)
{
$session = $this->requestStack->getSession();
$token = $event->getAuthenticationToken();
/** @var Utilisateur $user */
$user = $token->getUser();
$user->setDateConnexion(new \DateTime());
$this->em->persist($user);
$this->em->flush();
$this->logger->info("Connexion reussie");
// Tokens instances implementing the getFirewallName method
if (!(
$token instanceof PreAuthenticatedToken
|| $token instanceof RememberMeToken
|| $token instanceof UsernamePasswordToken
)) {
return;
}
if ('factuwall' === $token->getFirewallName()) {
$session->set('activeStructure', null);
$session->set('userLevel', null);
return;
}
$qb = $this->em->createQueryBuilder();
$qb->select('s')
->from(\App\Entity\UtilisateurStructure::class, 'us')
->from(\App\Entity\Structure::class, 's')
->andWhere('s.idstructure = us.idstructure')
->andWhere("us.idutilisateur = " . $user->getId())
->orderBy('s.niveau', 'ASC')
->setFirstResult(0)
->setMaxResults(1);
$structure = $qb->getQuery()->getResult();
$session->set('activeStructure', $structure[0] ?? null);
$qb->select('us');
$droits = $qb->getQuery()->getResult();
$userLevel = 'membre';
if ($droits[0]->getIssuperv()) {
$userLevel = 'superv';
}
if ($droits[0]->getIsadmin()) {
$userLevel = 'admin';
}
$session->set('userLevel', $userLevel);
}
}