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.     /**
  50.      * @param string $attribute
  51.      * @param mixed $subject
  52.      *
  53.      * @return bool
  54.      */
  55.     protected function supports($attribute$subject)
  56.     {
  57.         return
  58.             $this->portalConfigService->isPortalEngineSite() &&
  59.             $attribute === Permission::DOWNLOAD &&
  60.             $subject instanceof DownloadAccess;
  61.     }
  62.     /**
  63.      * @param string $attribute
  64.      * @param DownloadAccess $subject
  65.      * @param TokenInterface $token
  66.      *
  67.      * @return bool
  68.      */
  69.     protected function voteOnAttribute($attribute$subjectTokenInterface $token)
  70.     {
  71.         $user $this->securityService->getPortalUser();
  72.         $allowed =
  73.             $user instanceof PortalUserInterface &&
  74.             $this->permissionService->isAllowed($user$subject->toPermission());
  75.         $downloadTypeFormatPermissions $this->getDownloadTypeFormatPerimssions($subject);
  76.         if (!isset($downloadTypeFormatPermissions[$subject->toPermission()])) {
  77.             $allowed false;
  78.         }
  79.         if (!$allowed && $user instanceof PortalUserInterface) {
  80.             // If download type itself is forbidden but one of its download formats is allowed, the download is permitted.
  81.             $allowed $this->isAnyFormatAllowed($subject$user$downloadTypeFormatPermissions);
  82.         } elseif ($allowed) {
  83.             // Do not allow formats which are not specificed in data pool or public share
  84.             $allowed $this->isAnyFormatAllowed($subject$user$downloadTypeFormatPermissionsfalse);
  85.         }
  86.         $event = new DataPoolDownloadAccessEvent($allowed$subject$token);
  87.         $this->eventDispatcher->dispatch($event);
  88.         return $event->isAllowed();
  89.     }
  90.     protected function isAnyFormatAllowed(DownloadAccess $downloadAccessPortalUserInterface $user, array $downloadTypeFormatPermissionsbool $checkFormatPermissions true): bool
  91.     {
  92.         foreach ($downloadAccess->getFormatAccess() as $formatAccess) {
  93.             if (!isset($downloadTypeFormatPermissions[$downloadAccess->toPermission()][$formatAccess->getFormat()])) {
  94.                 continue;
  95.             }
  96.             $allowed = !$checkFormatPermissions || $this->permissionService->isAllowed($user$formatAccess->toPermission());
  97.             if ($allowed) {
  98.                 return true;
  99.             }
  100.         }
  101.         return false;
  102.     }
  103.     protected function getDownloadTypeFormatPerimssions(DownloadAccess $downloadAccess)
  104.     {
  105.         $dataPoolConfig $this->dataPoolConfigService->getDataPoolConfigById($downloadAccess->getDataPoolConfigId());
  106.         if ($publicShare $this->publicShareService->getCurrentPublicShare()) {
  107.             $downloadTypes $this->downloadProviderService->getPublicShareAllowedDownloadTypes($dataPoolConfig$publicShare);
  108.         } else {
  109.             $downloadTypes $this->downloadProviderService->getDownloadTypes($dataPoolConfigfalse);
  110.         }
  111.         $result = [];
  112.         foreach ($downloadTypes as $downloadType) {
  113.             $formats array_map(function (array $format) {
  114.                 return $format['id'];
  115.             }, $downloadType->getFormats());
  116.             $formats array_flip($formats);
  117.             $result[DownloadAccess::fromDownloadType($downloadAccess->getDataPoolConfigId(), $downloadType)->toPermission()] = $formats;
  118.         }
  119.         return $result;
  120.     }
  121. }