src/Security/ApiAuthenticator.php line 67

Open in your IDE?
  1. <?php
  2. namespace App\Security;
  3. use App\Helper\UnaccentedHelper;
  4. use App\Infrastructure\RequestDto\LoginDto;
  5. use App\Infrastructure\Service\Impl\LoginServiceImpl;
  6. use App\Infrastructure\Traits\CookiesHelper;
  7. use Symfony\Component\HttpFoundation\RedirectResponse;
  8. use Symfony\Component\HttpFoundation\Request;
  9. use Symfony\Component\HttpFoundation\RequestStack;
  10. use Symfony\Component\HttpFoundation\Response;
  11. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  12. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  13. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  14. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  15. use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
  16. use Symfony\Component\Security\Core\Exception\UserNotFoundException;
  17. use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
  18. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  19. use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
  20. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  21. class ApiAuthenticator extends AbstractAuthenticator
  22. {
  23.     use CookiesHelper;
  24.     public const LOGIN_ROUTE = 'app_login';
  25.     private LoginServiceImpl $loginService;
  26.     private UrlGeneratorInterface $urlGenerator;
  27.     protected LoginDto $authenticatedUser;
  28.     protected UnaccentedHelper $unaccentedHelper;
  29.     protected SessionInterface $session;
  30.     /**
  31.      * @param LoginServiceImpl $loginService
  32.      * @param UrlGeneratorInterface $urlGenerator
  33.      * @param UnaccentedHelper $unaccentedHelper
  34.      * @param RequestStack $requestStack
  35.      */
  36.     public function __construct(
  37.         LoginServiceImpl $loginService,
  38.         UrlGeneratorInterface $urlGenerator,
  39.         UnaccentedHelper $unaccentedHelper,
  40.         RequestStack $requestStack
  41.     ) {
  42.         $this->loginService = $loginService;
  43.         $this->urlGenerator = $urlGenerator;
  44.         $this->unaccentedHelper = $unaccentedHelper;
  45.         $this->session = $requestStack->getSession();
  46.     }
  47.     public function supports(Request $request): ?bool
  48.     {
  49.         return self::LOGIN_ROUTE === $request->attributes->get('_route')
  50.             && $request->isMethod('POST');
  51.     }
  52.     public function authenticate(Request $request): Passport
  53.     {
  54.         $loginDto = new LoginDto();
  55.         $loginDto->setUsername($request->get('login_form')['username']);
  56.         $loginDto->setPassword($request->get('login_form')['password']);
  57.         $apiUser = $this->loginService->login($loginDto);
  58.         if (empty($apiUser)) {
  59.             throw new CustomUserMessageAuthenticationException('No API token provided');
  60.         }
  61.         $this->setAuthenticatedUser(LoginDto::createFromArray($apiUser));
  62.         return new Passport(
  63.             new UserBadge($loginDto->getUsername()),
  64.             new CustomCredentials(
  65.                 function ($credentials, LoginDto $user) {
  66.                     if (!$this->getAuthenticatedUser()) {
  67.                         throw new UserNotFoundException();
  68.                     }
  69.                     LoginDto::map($user, $this->getAuthenticatedUser());
  70.                     return $user->getUserIdentifier() === $credentials;
  71.                 },
  72.                 $loginDto->getUsername()
  73.             )
  74.         );
  75.     }
  76.     public function onAuthenticationSuccess(
  77.         Request $request,
  78.         TokenInterface $token,
  79.         string $firewallName
  80.     ): ?RedirectResponse {
  81.         /** @var LoginDto $user */
  82.         $user = $token->getUser();
  83.         $this->updateSecurityCookies($user->toArray());
  84.         return new RedirectResponse($this->urlGenerator->generate('app_redirect'));
  85.     }
  86.     public function onAuthenticationFailure(Request $request, AuthenticationException $exception): Response
  87.     {
  88.         return new RedirectResponse($this->urlGenerator->generate('app_login'));
  89.     }
  90.     /**
  91.      * @return LoginDto
  92.      */
  93.     public function getAuthenticatedUser(): LoginDto
  94.     {
  95.         return $this->authenticatedUser;
  96.     }
  97.     /**
  98.      * @param LoginDto $authenticatedUser
  99.      */
  100.     public function setAuthenticatedUser(LoginDto $authenticatedUser): void
  101.     {
  102.         $this->authenticatedUser = $authenticatedUser;
  103.     }
  104.     protected function getLoginUrl(Request $request): string
  105.     {
  106.         return $this->urlGenerator->generate(self::LOGIN_ROUTE);
  107.     }
  108. }