<?php
namespace App\Infrastructure\EventSubscriber;
use App\Http\Controller\Api\V2\TokenAuthenticatedController;
use App\Database\Domain\Entity\User\User;
use App\Database\Domain\Repository\AccessTokenRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
class ApiTokenSubscriber implements EventSubscriberInterface
{
private ContainerInterface $container;
private AccessTokenRepository $accessTokenRepository;
private ?string $redirectResponseUrl = null;
public function __construct(
ContainerInterface $container,
AccessTokenRepository $accessTokenRepository
) {
$this->container = $container;
$this->accessTokenRepository = $accessTokenRepository;
}
public function onKernelController(ControllerEvent $event)
{
$controller = $event->getController();
if (is_array($controller)) {
$controller = $controller[0];
}
// TODO define and add TokenAuthenticatedController to needed controllers
// if ($controller instanceof TokenAuthenticatedController) {
$request = $event->getRequest();
if ($request->query->has('referral_code')) {
$request->getSession()->set('referral_code', $request->query->get('referral_code'));
}
if (!preg_match('/^\/api\/v2\/*/', $request->getRequestUri())) {
$token = $this->container->get('security.token_storage')->getToken();
if ($token) {
$user = $token->getUser();
$cookies = $request->cookies;
if ($user instanceof User && (!$cookies->has('token') || !$cookies->has('token-expires-at'))) {
$this->redirectResponseUrl = $this->container->get('router')->generate('user_logout');
} elseif ($cookies->has('token') && $cookies->has('token-expires-at')) {
$accessToken = $this->accessTokenRepository->findByToken($cookies->get('token'));
if (null !== $accessToken && $accessToken->isValid()) {
$newToken = new UsernamePasswordToken($accessToken->getUser(), null, 'main', $accessToken->getUser()->getRoles());
$session = $this->container->get('session');
$this->container->get('security.token_storage')->setToken($newToken);
$session->set('_security_main', serialize($newToken));
if ($session->get('login_url')) {
$this->redirectResponseUrl = $session->get('login_url');
$session->remove('login_url');
}
}
}
}
}
// }
}
public function onKernelResponse(ResponseEvent $event)
{
if (null !== $this->redirectResponseUrl) {
$event->setResponse(
new RedirectResponse($this->redirectResponseUrl)
);
}
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => 'onKernelController',
KernelEvents::RESPONSE => 'onKernelResponse',
];
}
}