src/Bundles/TemplateBundle/Security/Voter/TemplateViewVoter.php line 17

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Bundles\TemplateBundle\Security\Voter;
  4. use App\Bundles\OrganizationBundle\Entity\Organization;
  5. use App\Bundles\OrganizationBundle\Exception\UserOrganizationNotFoundException;
  6. use App\Bundles\OrganizationBundle\Service\UserOrganization\UserOrganizationProvider;
  7. use App\Bundles\TemplateBundle\Entity\Template;
  8. use App\Bundles\UserBundle\Entity\User;
  9. use App\Bundles\UserBundle\Enum\SystemPermissionEnum;
  10. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  11. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  12. use Symfony\Component\Security\Core\Security;
  13. class TemplateViewVoter extends Voter
  14. {
  15.     public function __construct(
  16.         private readonly Security $security,
  17.         private readonly UserOrganizationProvider $userOrganizationProvider,
  18.     ) {
  19.     }
  20.     protected function supports(string $attribute$subject): bool
  21.     {
  22.         return $attribute === SystemPermissionEnum::SINGLE_TEMPLATE_VIEW->value;
  23.     }
  24.     /**
  25.      * @param Template $subject
  26.      * @throws UserOrganizationNotFoundException
  27.      */
  28.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  29.     {
  30.         $user $this->security->getUser();
  31.         if (!$user instanceof User) {
  32.             return false;
  33.         }
  34.         if ($subject->getUser() === $user && $subject->isPersonal()) {
  35.             return true;
  36.         }
  37.         $organizationFromSession $this->resolveOrganization();
  38.         if (
  39.             $subject->isSharedForOrganization() &&
  40.             $this->checkAccessForOrganization($subject$organizationFromSession)
  41.         ) {
  42.             return true;
  43.         }
  44.         if (
  45.             $subject->isSharedForChildOrganization() &&
  46.             $this->checkAccessForChildOrganization($subject$organizationFromSession)
  47.         ) {
  48.             return true;
  49.         }
  50.         return false;
  51.     }
  52.     /**
  53.      * @throws UserOrganizationNotFoundException
  54.      */
  55.     private function resolveOrganization(): Organization
  56.     {
  57.         $userOrganization $this->userOrganizationProvider->provideFromSession();
  58.         return $userOrganization->getOrganization();
  59.     }
  60.     private function checkAccessForOrganization(Template $subjectOrganization $organizationFromSession): bool
  61.     {
  62.         $organization $subject->getOrganization();
  63.         return $organization->getId() === $organizationFromSession->getId();
  64.     }
  65.     private function checkAccessForChildOrganization(Template $subjectOrganization $organizationFromSession): bool
  66.     {
  67.         $parentOrganization $subject->getOrganization();
  68.         return $this->checkAccessForOrganization($subject$organizationFromSession) ||
  69.             in_array($organizationFromSession->getId(), $this->provideOrganizationsIds($parentOrganization));
  70.     }
  71.     private function provideOrganizationsIds(Organization $parentOrganization): array
  72.     {
  73.         return array_map(function (Organization $organization) {
  74.             return $organization->getId();
  75.         }, $parentOrganization->getChildOrganizations()->toArray());
  76.     }
  77. }