vendor/shopware/core/Framework/DataAbstractionLayer/EntityProtection/EntityProtectionValidator.php line 69

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\DataAbstractionLayer\EntityProtection;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntitySearchedEvent;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Field\AssociationField;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Write\Validation\PreWriteValidationEvent;
  9. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  11. class EntityProtectionValidator implements EventSubscriberInterface
  12. {
  13.     public static function getSubscribedEvents()
  14.     {
  15.         return [
  16.             PreWriteValidationEvent::class => 'validateWriteCommands',
  17.             EntitySearchedEvent::class => 'validateEntitySearch',
  18.         ];
  19.     }
  20.     /**
  21.      * @param string[] $protections FQCN of the protections that need to be validated
  22.      */
  23.     public function validateEntityPath(array $pathSegments, array $protectionsContext $context): void
  24.     {
  25.         foreach ($pathSegments as $pathSegment) {
  26.             /** @var EntityDefinition $definition */
  27.             $definition $pathSegment['definition'];
  28.             foreach ($protections as $protection) {
  29.                 $protectionInstance $definition->getProtections()->get($protection);
  30.                 if (!$protectionInstance || $protectionInstance->isAllowed($context->getScope())) {
  31.                     continue;
  32.                 }
  33.                 throw new AccessDeniedHttpException(
  34.                     sprintf('API access for entity "%s" not allowed.'$pathSegment['entity'])
  35.                 );
  36.             }
  37.         }
  38.     }
  39.     public function validateEntitySearch(EntitySearchedEvent $event): void
  40.     {
  41.         $definition $event->getDefinition();
  42.         $readProtection $definition->getProtections()->get(ReadProtection::class);
  43.         $context $event->getContext();
  44.         if ($readProtection && !$readProtection->isAllowed($context->getScope())) {
  45.             throw new AccessDeniedHttpException(
  46.                 sprintf(
  47.                     'Read access to entity "%s" not allowed for scope "%s".',
  48.                     $definition->getEntityName(),
  49.                     $context->getScope()
  50.                 )
  51.             );
  52.         }
  53.         $this->validateCriteriaAssociation(
  54.             $definition,
  55.             $event->getCriteria()->getAssociations(),
  56.             $context
  57.         );
  58.     }
  59.     public function validateWriteCommands(PreWriteValidationEvent $event): void
  60.     {
  61.         foreach ($event->getCommands() as $command) {
  62.             $writeProtection $command->getDefinition()->getProtections()->get(WriteProtection::class);
  63.             if ($writeProtection && !$writeProtection->isAllowed($event->getContext()->getScope())) {
  64.                 throw new AccessDeniedHttpException(
  65.                     sprintf(
  66.                         'Write access to entity %s" are not allowed in scope "%s".',
  67.                         $command->getDefinition()->getEntityName(),
  68.                         $event->getContext()->getScope()
  69.                     )
  70.                 );
  71.             }
  72.         }
  73.     }
  74.     private function validateCriteriaAssociation(EntityDefinition $definition, array $associationsContext $context): void
  75.     {
  76.         /** @var Criteria $criteria */
  77.         foreach ($associations as $associationName => $criteria) {
  78.             $field $definition->getField($associationName);
  79.             if (!$field instanceof AssociationField) {
  80.                 continue;
  81.             }
  82.             $associationDefinition $field->getReferenceDefinition();
  83.             $readProtection $associationDefinition->getProtections()->get(ReadProtection::class);
  84.             if ($readProtection && !$readProtection->isAllowed($context->getScope())) {
  85.                 throw new AccessDeniedHttpException(
  86.                     sprintf(
  87.                         'Read access to nested association "%s" on entity "%s" not allowed for scope "%s".',
  88.                         $associationName,
  89.                         $definition->getEntityName(),
  90.                         $context->getScope()
  91.                     )
  92.                 );
  93.             }
  94.             $this->validateCriteriaAssociation($associationDefinition$criteria->getAssociations(), $context);
  95.         }
  96.     }
  97. }