<?php declare(strict_types=1);namespace Shopware\Core\Framework\Api\Acl;use Doctrine\DBAL\Connection;use Shopware\Core\Framework\Api\Exception\MissingPrivilegeException;use Shopware\Core\Framework\Log\Package;use Shopware\Core\Framework\Routing\Annotation\Acl;use Shopware\Core\Framework\Routing\KernelListenerPriorities;use Shopware\Core\Framework\Uuid\Uuid;use Shopware\Core\PlatformRequest;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpKernel\Event\ControllerEvent;use Symfony\Component\HttpKernel\KernelEvents;/** * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0 */#[Package('core')]class AclAnnotationValidator implements EventSubscriberInterface{ private Connection $connection; /** * @internal */ public function __construct(Connection $connection) { $this->connection = $connection; } /** * @return array<string, string|array{0: string, 1: int}|list<array{0: string, 1?: int}>> */ public static function getSubscribedEvents() { return [ KernelEvents::CONTROLLER => [ ['validate', KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_SCOPE_VALIDATE], ], ]; } public function validate(ControllerEvent $event): void { $request = $event->getRequest(); $privileges = $request->attributes->get(PlatformRequest::ATTRIBUTE_ACL); if (!$privileges) { return; } if ($privileges instanceof Acl) { $privileges = $privileges->getValue(); } $context = $request->attributes->get(PlatformRequest::ATTRIBUTE_CONTEXT_OBJECT); if ($context === null) { throw new MissingPrivilegeException([]); } foreach ($privileges as $privilege) { if ($privilege === 'app') { if ($context->isAllowed('app.all')) { return; } $privilege = $this->getAppPrivilege($request); } if (!$context->isAllowed($privilege)) { throw new MissingPrivilegeException([$privilege]); } } } private function getAppPrivilege(Request $request): string { $actionId = $request->get('id'); if (empty($actionId)) { throw new MissingPrivilegeException(); } $appName = $this->connection->fetchOne( ' SELECT `app`.`name` AS `name` FROM `app` INNER JOIN `app_action_button` ON `app`.`id` = `app_action_button`.`app_id` WHERE `app_action_button`.`id` = :id ', ['id' => Uuid::fromHexToBytes($actionId)], ); return 'app.' . $appName; }}