<?php
namespace App\Security;
use App\Entity\Connection;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Util\Exception;
use Symfony\Component\HttpFoundation\JsonResponse;
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\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
class ClientAuthenticator extends AbstractAuthenticator
{
/**
* @var EntityManagerInterface $em
*/
private EntityManagerInterface $em;
/**
* TokenAuthenticator constructor.
*
* @param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function supports(Request $request): ?bool
{
$supports = $request->getSession()->has('clientId');
if ($request->getMethod() === Request::METHOD_POST) {
$supports = $supports || $request->request->has('clientId');
}
if ($request->getMethod() === Request::METHOD_GET) {
$supports = $supports || $request->query->has('clientId');
}
return $supports;
}
public function authenticate(Request $request): Passport
{
$token = $request->getSession()->get('clientId');
if ($request->getMethod() === Request::METHOD_POST) {
$token = $token ?? $request->request->get('clientId');
}
if ($request->getMethod() === Request::METHOD_GET) {
$token = $token ?? $request->query->get('clientId');
}
if (null === $token) {
throw new Exception('No token provided');
}
return new SelfValidatingPassport(
new UserBadge(
$token,
function ($token) {
return $this->em->getRepository(Connection::class)->findOneBy(['clientId' => $token]);
}
),
[]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
$data = [
'message' => strtr($exception->getMessageKey(), $exception->getMessageData())
];
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}
}