src/Security/LoginAuthenticator.php line 30

Open in your IDE?
  1. <?php
  2.     namespace App\Security;
  3.     use App\Entity\User;
  4.     use App\Services\ConfigService;
  5.     use App\Services\DTV\YamlConfig\YamlReader;
  6.     use DateTime;
  7.     use Doctrine\ORM\EntityManagerInterface;
  8.     use Exception;
  9.     use Psr\Container\ContainerExceptionInterface;
  10.     use Psr\Container\NotFoundExceptionInterface;
  11.     use Symfony\Component\DependencyInjection\ServiceLocator;
  12.     use Symfony\Component\HttpFoundation\RedirectResponse;
  13.     use Symfony\Component\HttpFoundation\Request;
  14.     use Symfony\Component\HttpFoundation\Response;
  15.     use Symfony\Component\HttpKernel\KernelInterface;
  16.     use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  17.     use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  18.     use Symfony\Component\Security\Core\Exception\AuthenticationException;
  19.     use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
  20.     use Symfony\Component\Security\Core\Security;
  21.     use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
  22.     use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
  23.     use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  24.     use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
  25.     use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  26.     use Symfony\Component\Security\Http\Util\TargetPathTrait;
  27.     class LoginAuthenticator extends AbstractLoginFormAuthenticator
  28.     {
  29.         use TargetPathTrait;
  30.         public const LOGIN_ROUTE 'app_login';
  31.         private EntityManagerInterface $em;
  32.         private UrlGeneratorInterface  $urlGenerator;
  33.         private YamlReader             $yamlReader;
  34.         private ConfigService          $configService;
  35.         private KernelInterface        $kernel;
  36.         private ServiceLocator         $workflowUserServiceLocator;
  37.         public function __construct(
  38.             EntityManagerInterface $em,
  39.             UrlGeneratorInterface  $urlGenerator,
  40.             YamlReader             $yamlReader,
  41.             ConfigService          $configService,
  42.             KernelInterface        $kernel,
  43.             ServiceLocator         $workflowUserServiceLocator
  44.         ) {
  45.             $this->em                         $em;
  46.             $this->urlGenerator               $urlGenerator;
  47.             $this->yamlReader                 $yamlReader;
  48.             $this->configService              $configService;
  49.             $this->kernel                     $kernel;
  50.             $this->workflowUserServiceLocator $workflowUserServiceLocator;
  51.         }
  52.         /**
  53.          * @param Request $request
  54.          *
  55.          * @return Passport
  56.          *
  57.          * @throws Exception
  58.          */
  59.         public function authenticateRequest $request ): Passport
  60.         {
  61.             $credentials $request->request->get'login' );
  62.             $email       $credentials'email' ] ?? '';
  63.             $password    $credentials'password' ] ?? '';
  64.             $request->getSession()->setSecurity::LAST_USERNAME$email );
  65.             // Code commenté suite demande daikin
  66.             // Récupère l'utilisateur en fonction de l'e-mail
  67. //            $userRepo = $this->em->getRepository( User::class );
  68. //            $user     = $userRepo->findOneBy( [ 'email' => $email ] );
  69. //            $loginSecurity = $this->yamlReader->getGlobal()['login_security' ] ?? [];
  70. //            $failedAttempts = $loginSecurity['failed_attempts'] ?? 3;
  71. //            $delayBeforeNewAttempt = $loginSecurity['delay_before_new_attempt'] ?? 24;
  72. //            $passwordValidationDays = $loginSecurity['password_validation_days'] ?? 365;
  73. //            $env = $this->kernel->getEnvironment();
  74.             /*
  75.             if ($env !== 'test' || ($user instanceof User && !$user->isDeveloper())) {
  76.                 // Vérifie si l'utilisateur échoue à la connexion plus de 3 fois
  77.                 if ( $user && $user->getFailedAttempts() >= $failedAttempts ) {
  78.                     $lastFailed = $user->getLastFailedAttempt();
  79.                     $interval   = ( new DateTime() )->diff( $lastFailed );
  80.                     if ( $interval->days == 0 && $interval->h < $delayBeforeNewAttempt ) {
  81.                         throw new CustomUserMessageAuthenticationException(
  82.                             'Vous avez été bloqué pendant 24 heures en raison de trop nombreuses tentatives ' .
  83.                             'de connexion échouées.',
  84.                         );
  85.                     }
  86.                     else {
  87.                         // Réinitialiser les tentatives après 24 heures
  88.                         $user->setFailedAttempts( 0 );
  89.                         $this->em->flush();
  90.                     }
  91.                 }
  92.                 // Vérification de la durée de validité du mot de passe
  93.                 if ( $user ) {
  94.                     $passwordUpdated = $user->getPasswordUpdatedAt();
  95.                     if ( is_null( $passwordUpdated ) ) {
  96.                         $passwordUpdated = ( new DateTime() )->modify( '-370 days' );
  97.                         $user->setPasswordUpdatedAt( $passwordUpdated );
  98.                         $this->em->flush();
  99.                     }
  100.                     $interval = ( new DateTime() )->diff( $passwordUpdated );
  101.                     if ( $interval->days >= $passwordValidationDays ) {
  102.                         // On injecte le service de workflowUser (pour éviter une dépendance circulaire dans le constructor)
  103.                         // On envoie un mail à l'utilisateur pour qu'il puisse changer son mot de passe et revalider les CGU
  104.                         try {
  105.                             $workflowUser = $this->workflowUserServiceLocator->get('workflowUser');
  106.                             $workflowUser->resendCGU( $user );
  107.                         }
  108.                         catch ( NotFoundExceptionInterface|ContainerExceptionInterface $e ) {
  109.                             throw new Exception( $e->getMessage() );
  110.                         }
  111.                         throw new CustomUserMessageAuthenticationException(
  112.                             'Votre mot de passe a été créé il y a plus de 12 mois, pour des raisons de sécurités, ' .
  113.                             'un email vous a été envoyé afin que vous puissiez en changer. <br>' .
  114.                             'Veuillez vérifier votre boite mail et suivre les instructions.',
  115.                         );
  116.                     }
  117.                 }
  118.             }
  119.             */
  120.             // fin de code commenté suite demande daikin
  121.             return new Passport(
  122.                 new UserBadge$email ),
  123.                 new PasswordCredentials$password ),
  124.                 [
  125.                     new CsrfTokenBadge'authenticate'$request->request->get'_csrf_token' ) ),
  126.                 ],
  127.             );
  128.         }
  129.         /**
  130.          * @param Request        $request
  131.          * @param TokenInterface $token
  132.          * @param string         $firewallName
  133.          *
  134.          * @return Response|null
  135.          */
  136.         public
  137.         function onAuthenticationSuccess(
  138.             Request        $request,
  139.             TokenInterface $token,
  140.             string         $firewallName
  141.         ): ?Response {
  142.             if ( $this->yamlReader->getType() === 'api' ) {
  143.                 return new RedirectResponse$this->urlGenerator->generate'back_dashboard' ) );
  144.             }
  145.             if ( $targetPath $this->getTargetPath$request->getSession(), $firewallName ) ) {
  146.                 return new RedirectResponse$targetPath );
  147.             }
  148.             return new RedirectResponse$this->urlGenerator->generate'front_homepage' ) );
  149.         }
  150.         /**
  151.          * @param Request                 $request
  152.          * @param AuthenticationException $exception
  153.          *
  154.          * @return Response
  155.          */
  156.         public
  157.         function onAuthenticationFailure(
  158.             Request $requestAuthenticationException $exception
  159.         ): Response {
  160.             $credentials $request->request->get'login' );
  161.             $email       $credentials'email' ] ?? '';
  162.             $userRepo $this->em->getRepositoryUser::class );
  163.             $user     $userRepo->findOneBy( [ 'email' => $email ] );
  164.             if ( $user ) {
  165.                 $user->setFailedAttempts$user->getFailedAttempts() + );
  166.                 $user->setLastFailedAttempt( new DateTime() );
  167.                 $this->em->flush();
  168.             }
  169.             $request->getSession()->setSecurity::AUTHENTICATION_ERROR$exception );
  170.             return new RedirectResponse$this->urlGenerator->generateself::LOGIN_ROUTE ) );
  171.         }
  172.         /**
  173.          * @param Request $request
  174.          *
  175.          * @return string
  176.          */
  177.         protected
  178.         function getLoginUrl(
  179.             Request $request
  180.         ): string {
  181.             return $this->urlGenerator->generateself::LOGIN_ROUTE );
  182.         }
  183.     }