<?php
declare(strict_types=1);
namespace App\Authentication\EventSubscriber;
use App\Base\Component\GraphQL\Parser;
use App\Base\Model\GraphQLObject;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\ExecutorEvents;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ExecutorEvent;
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
class GraphQlSubscriber implements EventSubscriberInterface
{
/**
* @var TokenStorageInterface
*/
private TokenStorageInterface $tokenStorage;
/** @var ContainerBagInterface */
private ContainerBagInterface $params;
public function __construct(TokenStorageInterface $tokenStorage, ContainerBagInterface $params)
{
$this->tokenStorage = $tokenStorage;
$this->params = $params;
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [
ExecutorEvents::PRE_EXECUTE => 'onPreExecute',
];
}
/**
* @param ExecutorEvent $event
* @return void
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function onPreExecute(ExecutorEvent $event): void
{
if ($event->getQuery()) {
$token = $this->tokenStorage->getToken();
if (!$token instanceof TokenInterface || $token->getUser() === 'anon.') {
$graphQLObject = Parser::createFromQuery($event->getQuery());
$skipAuthCheck = $graphQLObject->getOperationType() === GraphQLObject::OPERATION_TYPE_MUTATION
&& in_array($graphQLObject->getOperationName(), $this->params->get('app.pimcore.graphql.notAuthorizedMutationList'));
if (!$skipAuthCheck) {
$skipAuthCheck = $graphQLObject->getOperationType() === GraphQLObject::OPERATION_TYPE_QUERY
&& in_array($graphQLObject->getOperationName(), $this->params->get('app.pimcore.graphql.notAuthorizedQueryList'));
}
if (!$skipAuthCheck) {
throw new \Exception('User not authorized');
}
}
}
}
}