src/Core/Framework/Api/Acl/AclAnnotationValidator.php line 41

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Api\Acl;
  3. use Doctrine\DBAL\Connection;
  4. use Shopware\Core\Framework\Api\Exception\MissingPrivilegeException;
  5. use Shopware\Core\Framework\Log\Package;
  6. use Shopware\Core\Framework\Routing\KernelListenerPriorities;
  7. use Shopware\Core\Framework\Uuid\Uuid;
  8. use Shopware\Core\PlatformRequest;
  9. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. use Symfony\Component\HttpFoundation\Request;
  11. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  12. use Symfony\Component\HttpKernel\KernelEvents;
  13. /**
  14.  * @internal
  15.  */
  16. #[Package('core')]
  17. class AclAnnotationValidator implements EventSubscriberInterface
  18. {
  19.     /**
  20.      * @internal
  21.      */
  22.     public function __construct(private readonly Connection $connection)
  23.     {
  24.     }
  25.     /**
  26.      * @return array<string, string|array{0: string, 1: int}|list<array{0: string, 1?: int}>>
  27.      */
  28.     public static function getSubscribedEvents(): array
  29.     {
  30.         return [
  31.             KernelEvents::CONTROLLER => [
  32.                 ['validate'KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_SCOPE_VALIDATE],
  33.             ],
  34.         ];
  35.     }
  36.     public function validate(ControllerEvent $event): void
  37.     {
  38.         $request $event->getRequest();
  39.         $privileges $request->attributes->get(PlatformRequest::ATTRIBUTE_ACL);
  40.         if (!$privileges) {
  41.             return;
  42.         }
  43.         $context $request->attributes->get(PlatformRequest::ATTRIBUTE_CONTEXT_OBJECT);
  44.         if ($context === null) {
  45.             throw new MissingPrivilegeException([]);
  46.         }
  47.         foreach ($privileges as $privilege) {
  48.             if ($privilege === 'app') {
  49.                 if ($context->isAllowed('app.all')) {
  50.                     return;
  51.                 }
  52.                 $privilege $this->getAppPrivilege($request);
  53.             }
  54.             if (!$context->isAllowed($privilege)) {
  55.                 throw new MissingPrivilegeException([$privilege]);
  56.             }
  57.         }
  58.     }
  59.     private function getAppPrivilege(Request $request): string
  60.     {
  61.         $actionId $request->get('id');
  62.         if (empty($actionId)) {
  63.             throw new MissingPrivilegeException();
  64.         }
  65.         $appName $this->connection->fetchOne(
  66.             '
  67.                 SELECT `app`.`name` AS `name`
  68.                 FROM `app`
  69.                 INNER JOIN `app_action_button` ON `app`.`id` = `app_action_button`.`app_id`
  70.                 WHERE `app_action_button`.`id` = :id
  71.             ',
  72.             ['id' => Uuid::fromHexToBytes($actionId)],
  73.         );
  74.         return 'app.' $appName;
  75.     }
  76. }