murph-core/src/core/EventSubscriber/RequestSecurityEventSubscriber.php

70 lines
1.9 KiB
PHP

<?php
namespace App\Core\EventSubscriber;
use App\Core\Repository\Site\NodeRepository;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
* class RequestSecurityEventSubscriber.
*
* @author Simon Vieille <simon@deblan.fr>
*/
class RequestSecurityEventSubscriber implements EventSubscriberInterface
{
protected AuthorizationChecker $authorizationChecker;
public function __construct(
protected NodeRepository $nodeRepository,
ContainerInterface $container
) {
$this->authorizationChecker = $container->get('security.authorization_checker');
}
public function onKernelRequest(RequestEvent $event)
{
$request = $event->getRequest();
if (!$request->attributes->has('_node')) {
return;
}
$node = $this->nodeRepository->findOneBy([
'id' => $request->attributes->get('_node'),
]);
$roles = $node->getSecurityRoles();
if (empty($roles)) {
return;
}
$operator = $node->getSecurityOperator();
$exception = new AccessDeniedException('Access denied.');
foreach ($roles as $role) {
$isGranted = $this->authorizationChecker->isGranted($role);
if ('or' === $operator && $isGranted) {
return;
}
if ('and' === $operator && !$isGranted) {
throw $exception;
}
}
throw $exception;
}
public static function getSubscribedEvents(): array
{
return [
RequestEvent::class => ['onKernelRequest', 1],
];
}
}