<?php
namespace App\Infrastructure\EventSubscriber;
use App\Database\Domain\Entity\User\UserAccessToken;
use App\Database\Domain\Repository\AccessTokenRepository;
use App\Infrastructure\Security\AuthManager;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class AuthByApiTokenSubscriber implements EventSubscriberInterface
{
private ContainerInterface $container;
private AuthManager $authManager;
private AccessTokenRepository $accessTokenRepository;
public function __construct(
ContainerInterface $container,
AuthManager $authManager,
AccessTokenRepository $accessTokenRepository
) {
$this->container = $container;
$this->authManager = $authManager;
$this->accessTokenRepository = $accessTokenRepository;
}
public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
if ($event->getRequest()->query->has('referral_code')) {
$code = $event->getRequest()->query->get('referral_code');
$request->getSession()->set('referral_code', $code);
}
if (strpos($request->getPathInfo(), 'api') !== false) {
return;
}
$token = $this->container->get('security.token_storage')->getToken();
$logoutResponse = new RedirectResponse($this->container->get('router')->generate('user_logout'));
if ($token && $token->getUser() && !is_string($token->getUser()) &&
(!$request->cookies->has('token') || !$request->cookies->has('token-expires-at'))
) {
$event->setResponse($logoutResponse);
}
if ($token && is_string($token->getUser())) {
if ($request->cookies->has('token') && $request->cookies->has('token-expires-at')) {
/** @var UserAccessToken $accessToken */
$accessToken = $this->accessTokenRepository->findOneBy(['token' => $request->cookies->get('token')]);
if ((null === $accessToken || !$accessToken->isValid()) && $token->getUser()) {
$event->setResponse($logoutResponse);
}
if (null !== $accessToken && $accessToken->isValid() && is_string($token->getUser())) {
$token = new UsernamePasswordToken($accessToken->getUser(), null, 'main', $accessToken->getUser()->getRoles());
$this->container->get('security.token_storage')->setToken($token);
$session = $this->container->get('session');
$session->set('_security_main', serialize($token));
if (null !== $session->get('login_url')) {
$redirectUrl = $session->get('login_url');
$session->remove('login_url');
$response = new RedirectResponse($redirectUrl);
$event->setResponse($response);
}
}
}
}
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest', 7]
];
}
}