src/Core/Security/LoginFormAuthenticator.php line 40

  1. <?php
  2. /**
  3.  * Copyright (c) 2019 TECLA Consulting Group oü.
  4.  * All rights reserved.
  5.  *
  6.  * This unpublished material is proprietary to TECLA Consulting Group oü.
  7.  * All rights reserved. The methods and
  8.  * techniques described herein are considered trade secrets
  9.  * and/or confidential. Reproduction or distribution, in whole
  10.  * or in part, is forbidden except by express written permission
  11.  * of TECLA Consulting Group oü.
  12.  *
  13.  * @author    Matúš Sýkorjak <matus@tecla.no>
  14.  * @copyright 2019 TECLA Consulting Group oü
  15.  */
  16. namespace App\Core\Security;
  17. use App\Core\Model\UserInterface;
  18. use App\Core\Security\Encoder\LegacyUserPasswordEncoderInterface;
  19. use Symfony\Component\HttpFoundation\RedirectResponse;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactoryInterface;
  23. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  24. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  25. use Symfony\Component\Security\Core\Exception\BadCredentialsException;
  26. use Symfony\Component\Security\Core\Security;
  27. use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
  28. use Symfony\Component\Security\Core\User\UserProviderInterface;
  29. use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
  30. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
  31. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge;
  32. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
  33. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  34. use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
  35. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  36. use Symfony\Component\Security\Http\Util\TargetPathTrait;
  37. class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
  38. {
  39.     use TargetPathTrait;
  40.     public const LOGIN_ROUTE 'app_login';
  41.     public const SUCCESS_ROUTE 'app_homepage';
  42.     private UserProviderInterface $userProvider;
  43.     private UrlGeneratorInterface $urlGenerator;
  44.     private LegacyUserPasswordEncoderInterface $legacyUserPasswordEncoder;
  45.     private PasswordHasherFactoryInterface $hasherFactory;
  46.     public function __construct(
  47.         UserProviderInterface $userProvider,
  48.         UrlGeneratorInterface $urlGenerator,
  49.         LegacyUserPasswordEncoderInterface $legacyUserPasswordEncoder,
  50.         PasswordHasherFactoryInterface $hasherFactory
  51.     ) {
  52.         $this->userProvider $userProvider;
  53.         $this->urlGenerator $urlGenerator;
  54.         $this->legacyUserPasswordEncoder $legacyUserPasswordEncoder;
  55.         $this->hasherFactory $hasherFactory;
  56.     }
  57.     public function authenticate(Request $request): Passport
  58.     {
  59.         $credentials $this->getCredentials($request);
  60.         $passport = new Passport(
  61.             new UserBadge($credentials['username']),
  62.             new CustomCredentials(
  63.                 function ($passwordUserInterface $user) {
  64.                     if ('' === $password) {
  65.                         throw new BadCredentialsException('The presented password cannot be empty.');
  66.                     }
  67.                     if (null === $user->getPassword()) {
  68.                         throw new BadCredentialsException('The presented password is invalid.');
  69.                     }
  70.                     if (null !== $user->getLegacyPassword() && '' !== $user->getLegacyPassword()) {
  71.                         return $this->legacyUserPasswordEncoder->isPasswordValid($user$password);
  72.                     }
  73.                     return $this->hasherFactory->getPasswordHasher($user)->verify(
  74.                         $user->getPassword(),
  75.                         $password
  76.                     );
  77.                 },
  78.                 $credentials['password']
  79.             ),
  80.             [
  81.                 new RememberMeBadge(),
  82.                 new CsrfTokenBadge('authenticate'$credentials['csrf_token']),
  83.             ]
  84.         );
  85.         if ($this->userProvider instanceof PasswordUpgraderInterface) {
  86.             $passport->addBadge(new PasswordUpgradeBadge($request->request->get('password'), $this->userProvider));
  87.         }
  88.         return $passport;
  89.     }
  90.     public function onAuthenticationSuccess(Request $requestTokenInterface $tokenstring $firewallName): ?Response
  91.     {
  92.         $targetPath $this->getTargetPath($request->getSession(), $firewallName);
  93.         if (true === str_contains($targetPath'cid=')) {
  94.             return new RedirectResponse($targetPath);
  95.         }
  96.         $routeParams = [];
  97.         $user $token->getUser();
  98.         if (true === $user instanceof UserInterface) {
  99.             $routeParams = ['cid' => $user->getContact()->getId()];
  100.         }
  101.         return new RedirectResponse($this->urlGenerator->generate(self::SUCCESS_ROUTE$routeParams));
  102.     }
  103.     protected function getLoginUrl(Request $request): string
  104.     {
  105.         return $this->urlGenerator->generate(self::LOGIN_ROUTE);
  106.     }
  107.     private function getCredentials(Request $request): array
  108.     {
  109.         $credentials = [
  110.             'username' => $request->request->get('username'),
  111.             'password' => $request->request->get('password'),
  112.             'csrf_token' => $request->request->get('_token'),
  113.         ];
  114.         $request->getSession()->set(
  115.             Security::LAST_USERNAME,
  116.             $credentials['username']
  117.         );
  118.         return $credentials;
  119.     }
  120. }