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

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