src/Security/FrontAuthenticator.php line 111

Open in your IDE?
  1. <?php
  2. /*
  3.  * Unauthorized copying of this file, via any medium is strictly prohibited
  4.  * Proprietary and confidential.
  5.  *
  6.  * @author Bilel AZRI          <azri.bilel@gmail.com>
  7.  * @author Assma BEN SASSI     <bensassiasma.bws@gmail.com>
  8.  *
  9.  * Bicking man (c) 2019-present.
  10.  */
  11. declare(strict_types=1);
  12. namespace App\Security;
  13. use App\Entity\User\Admin;
  14. use App\Entity\User\Organizer;
  15. use App\Entity\User\User;
  16. use App\Repository\User\UserRepository;
  17. use Doctrine\ORM\EntityManagerInterface;
  18. use Symfony\Component\HttpFoundation\JsonResponse;
  19. use Symfony\Component\HttpFoundation\RedirectResponse;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\HttpFoundation\Session\Session;
  23. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  24. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  25. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  26. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  27. use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
  28. use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
  29. use Symfony\Component\Security\Core\Security;
  30. use Symfony\Component\Security\Core\User\UserInterface;
  31. use Symfony\Component\Security\Core\User\UserProviderInterface;
  32. use Symfony\Component\Security\Csrf\CsrfToken;
  33. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  34. use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
  35. use Symfony\Component\Security\Http\Util\TargetPathTrait;
  36. class FrontAuthenticator extends AbstractFormLoginAuthenticator
  37. {
  38.     use TargetPathTrait;
  39.     public const LOGIN_ROUTE 'front.security.app_login';
  40.     /**
  41.      * The Entity manager used to retrieve users.
  42.      *
  43.      * @var EntityManagerInterface
  44.      */
  45.     private $entityManager;
  46.     /**
  47.      * The Url generator used to generate urls.
  48.      *
  49.      * @var UrlGeneratorInterface
  50.      */
  51.     private $urlGenerator;
  52.     /**
  53.      * The Csrf token manager used to validate the csrf token.
  54.      *
  55.      * @var CsrfTokenManagerInterface
  56.      */
  57.     private $csrfTokenManager;
  58.     /**
  59.      * The Password Encoder used to validate the password.
  60.      *
  61.      * @var UserPasswordEncoderInterface
  62.      */
  63.     private $passwordEncoder;
  64.     public function __construct(EntityManagerInterface $entityManagerUrlGeneratorInterface $urlGeneratorCsrfTokenManagerInterface $csrfTokenManagerUserPasswordEncoderInterface $passwordEncoder)
  65.     {
  66.         $this->entityManager $entityManager;
  67.         $this->urlGenerator $urlGenerator;
  68.         $this->csrfTokenManager $csrfTokenManager;
  69.         $this->passwordEncoder $passwordEncoder;
  70.     }
  71.     public function supports(Request $request): bool
  72.     {
  73.         return self::LOGIN_ROUTE === $request->attributes->get('_route')
  74.             && $request->isMethod('POST');
  75.     }
  76.     /**
  77.      * @return array{username: string, password: string, csrf_token: string}
  78.      */
  79.     public function getCredentials(Request $request): array
  80.     {
  81.         /**
  82.          * @var string
  83.          */
  84.         $username $request->request->get('username');
  85.         /**
  86.          * @var string
  87.          */
  88.         $password $request->request->get('password');
  89.         /**
  90.          * @var string
  91.          */
  92.         $csrf $request->request->get('_csrf_token');
  93.         $credentials = ['username' => $username'password' => $password'csrf_token' => $csrf];
  94.         /** @var Session $session */
  95.         $session $request->getSession();
  96.         $session->set(Security::LAST_USERNAME$credentials['username']);
  97.         return $credentials;
  98.     }
  99.     public function getUser($credentialsUserProviderInterface $userProvider): User
  100.     {
  101.         /** @var array{username: string, password: string, csrf_token: string} $credentials */
  102.         $token = new CsrfToken('authenticate'$credentials['csrf_token']);
  103.         if (!$this->csrfTokenManager->isTokenValid($token)) {
  104.             throw new InvalidCsrfTokenException('Invalid Csrf Token.');
  105.         }
  106.         /** @var UserRepository $repo */
  107.         $repo $this->entityManager->getRepository(User::class);
  108.         $user $repo->findOneByUsername($credentials['username']);
  109.         if (null === $user) {
  110.             // fail authentication with a custom error
  111.             throw new CustomUserMessageAuthenticationException('User could not be found.');
  112.         }
  113.         return $user;
  114.     }
  115.     public function checkCredentials($credentialsUserInterface $user): bool
  116.     {
  117.         /** @var array{username: string, password: string, csrf_token: string} $credentials */
  118.         return $this->passwordEncoder->isPasswordValid($user$credentials['password']);
  119.     }
  120.     /**
  121.      * @param string $providerKey
  122.      */
  123.     public function onAuthenticationSuccess(Request $requestTokenInterface $token$providerKey): Response
  124.     {
  125.         if (null !== $headerAccept $request->headers->get('accept')) {
  126.             if (false !== strpos($headerAccept'json')) {
  127.                 return new JsonResponse(['status' => 'failed''message' => 'You entered in secure area without login!'], Response::HTTP_UNAUTHORIZED);
  128.             }
  129.         }
  130.         /** @var SessionInterface $session */
  131.         $session $request->getSession();
  132.         $targetPath $this->getTargetPath($session$providerKey);
  133.         if (null !== $targetPath) {
  134.             return new RedirectResponse($targetPath);
  135.         }
  136.         $user $token->getUser();
  137.         if ($user instanceof Admin || $user instanceof Organizer) {
  138.             return new RedirectResponse($this->urlGenerator->generate('back.dashboard.index'));
  139.         }
  140.         return new RedirectResponse($this->urlGenerator->generate('front.course.index'));
  141.     }
  142.     protected function getLoginUrl(): string
  143.     {
  144.         return $this->urlGenerator->generate(self::LOGIN_ROUTE);
  145.     }
  146. }