vendor/pimcore/portal-engine/src/Service/Security/Voter/DataPoolDownloadVoter.php line 29

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under following license:
  6.  * - Pimcore Commercial License (PCL)
  7.  *
  8.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  9.  *  @license    http://www.pimcore.org/license     PCL
  10.  */
  11. namespace Pimcore\Bundle\PortalEngineBundle\Service\Security\Voter;
  12. use Pimcore\Bundle\PortalEngineBundle\Enum\Permission;
  13. use Pimcore\Bundle\PortalEngineBundle\Event\Permission\DataPoolDownloadAccessEvent;
  14. use Pimcore\Bundle\PortalEngineBundle\Model\DataObject\PortalUserInterface;
  15. use Pimcore\Bundle\PortalEngineBundle\Model\Download\DownloadAccess;
  16. use Pimcore\Bundle\PortalEngineBundle\Service\DataPool\DataPoolConfigService;
  17. use Pimcore\Bundle\PortalEngineBundle\Service\Download\DownloadProviderService;
  18. use Pimcore\Bundle\PortalEngineBundle\Service\PortalConfig\PortalConfigService;
  19. use Pimcore\Bundle\PortalEngineBundle\Service\PublicShare\PublicShareService;
  20. use Pimcore\Bundle\PortalEngineBundle\Service\Security\PermissionService;
  21. use Pimcore\Bundle\PortalEngineBundle\Service\Security\Traits\SecurityServiceAware;
  22. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  23. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  24. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  25. class DataPoolDownloadVoter extends Voter
  26. {
  27.     use SecurityServiceAware;
  28.     protected $portalConfigService;
  29.     protected $dataPoolConfigService;
  30.     protected $permissionService;
  31.     protected $downloadProviderService;
  32.     protected $publicShareService;
  33.     protected $eventDispatcher;
  34.     public function __construct(
  35.         PortalConfigService $portalConfigService,
  36.         DataPoolConfigService $dataPoolConfigService,
  37.         PermissionService $permissionService,
  38.         DownloadProviderService $downloadProviderService,
  39.         PublicShareService $publicShareService,
  40.         EventDispatcherInterface $eventDispatcher
  41.     ) {
  42.         $this->portalConfigService $portalConfigService;
  43.         $this->dataPoolConfigService $dataPoolConfigService;
  44.         $this->permissionService $permissionService;
  45.         $this->downloadProviderService $downloadProviderService;
  46.         $this->publicShareService $publicShareService;
  47.         $this->eventDispatcher $eventDispatcher;
  48.     }
  49.     protected function supports(string $attributemixed $subject): bool
  50.     {
  51.         return
  52.             $this->portalConfigService->isPortalEngineSite() &&
  53.             $attribute === Permission::DOWNLOAD &&
  54.             $subject instanceof DownloadAccess;
  55.     }
  56.     /**
  57.      * @param DownloadAccess $subject
  58.      */
  59.     protected function voteOnAttribute(string $attributemixed $subjectTokenInterface $token): bool
  60.     {
  61.         $user $this->securityService->getPortalUser();
  62.         $allowed =
  63.             $user instanceof PortalUserInterface &&
  64.             $this->permissionService->isAllowed($user$subject->toPermission());
  65.         $downloadTypeFormatPermissions $this->getDownloadTypeFormatPerimssions($subject);
  66.         if (!isset($downloadTypeFormatPermissions[$subject->toPermission()])) {
  67.             $allowed false;
  68.         }
  69.         if (!$allowed && $user instanceof PortalUserInterface) {
  70.             // If download type itself is forbidden but one of its download formats is allowed, the download is permitted.
  71.             $allowed $this->isAnyFormatAllowed($subject$user$downloadTypeFormatPermissions);
  72.         } elseif ($allowed) {
  73.             // Do not allow formats which are not specificed in data pool or public share
  74.             $allowed $this->isAnyFormatAllowed($subject$user$downloadTypeFormatPermissionsfalse);
  75.         }
  76.         $event = new DataPoolDownloadAccessEvent($allowed$subject$token);
  77.         $this->eventDispatcher->dispatch($event);
  78.         return $event->isAllowed();
  79.     }
  80.     protected function isAnyFormatAllowed(DownloadAccess $downloadAccessPortalUserInterface $user, array $downloadTypeFormatPermissionsbool $checkFormatPermissions true): bool
  81.     {
  82.         foreach ($downloadAccess->getFormatAccess() as $formatAccess) {
  83.             if (!isset($downloadTypeFormatPermissions[$downloadAccess->toPermission()][$formatAccess->getFormat()])) {
  84.                 continue;
  85.             }
  86.             $allowed = !$checkFormatPermissions || $this->permissionService->isAllowed($user$formatAccess->toPermission());
  87.             if ($allowed) {
  88.                 return true;
  89.             }
  90.         }
  91.         return false;
  92.     }
  93.     /**
  94.      * @return array
  95.      */
  96.     protected function getDownloadTypeFormatPerimssions(DownloadAccess $downloadAccess)
  97.     {
  98.         $dataPoolConfig $this->dataPoolConfigService->getDataPoolConfigById($downloadAccess->getDataPoolConfigId());
  99.         if ($publicShare $this->publicShareService->getCurrentPublicShare()) {
  100.             $downloadTypes $this->downloadProviderService->getPublicShareAllowedDownloadTypes($dataPoolConfig$publicShare);
  101.         } else {
  102.             $downloadTypes $this->downloadProviderService->getDownloadTypes($dataPoolConfigfalse);
  103.         }
  104.         $result = [];
  105.         foreach ($downloadTypes as $downloadType) {
  106.             $formats array_map(function (array $format) {
  107.                 return $format['id'];
  108.             }, $downloadType->getFormats());
  109.             $formats array_flip($formats);
  110.             $result[DownloadAccess::fromDownloadType($downloadAccess->getDataPoolConfigId(), $downloadType)->toPermission()] = $formats;
  111.         }
  112.         return $result;
  113.     }
  114. }