<?php
declare(strict_types=1);
namespace Slivki\Security;
use Slivki\Entity\User;
use Slivki\Exception\User\InvalidUserTokenException;
use Slivki\Repository\User\UserRepositoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
final class SlivkiMobileAuthenticator extends AbstractAuthenticator
{
public const HTTP_HEADERS_USER_TOKEN = 'HTTP-SLIVKi-USER-TOKEN';
private UserRepositoryInterface $userRepository;
public function __construct(UserRepositoryInterface $userRepository)
{
$this->userRepository = $userRepository;
}
public function supports(Request $request): ?bool
{
return $request->headers->has(self::HTTP_HEADERS_USER_TOKEN)
&& !$request->headers->has(SlivkiInternalAuthenticator::HTTP_HEADERS_USER_TOKEN);
}
public function authenticate(Request $request): PassportInterface
{
$userToken = $request->headers->get(self::HTTP_HEADERS_USER_TOKEN);
if (null === $userToken) {
throw new InvalidUserTokenException();
}
return new SelfValidatingPassport(
new UserBadge((string) $userToken, fn (): ?User => $this->userRepository->findByMobileToken((string) $userToken)),
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
return null;
}
}