src/Security/Voter/Procedure/ProcedureVoter.php line 18

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Security\Voter\Procedure;
  4. use App\Model\User\Entity\User\Role\Permission;
  5. use App\Model\User\Entity\User\Role\RoleConstants;
  6. use App\ReadModel\Procedure\InvitedMember\InvitedMemberFetcher;
  7. use App\ReadModel\Procedure\Lot\DetailView;
  8. use App\ReadModel\Profile\ProfileFetcher;
  9. use App\Security\UserIdentity;
  10. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  11. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  12. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  13. use Symfony\Component\Security\Core\Security;
  14. class ProcedureVoter extends Voter
  15. {
  16.     public const CONTRACTS_SHOW_TO_LOT 'contracts_show_to_lot';
  17.     public const PROCEDURE_SHOW 'procedure_show';
  18.     private Security $security;
  19.     private $user;
  20.     /** @var \App\ReadModel\Profile\DetailView */
  21.     private \App\ReadModel\Profile\DetailView $profile;
  22.     private InvitedMemberFetcher $invitedMemberFetcher;
  23.     private ProfileFetcher $profileFetcher;
  24.     public function __construct(Security $securityInvitedMemberFetcher $invitedMemberFetcherProfileFetcher $profileFetcher)
  25.     {
  26.         $this->security $security;
  27.         $this->invitedMemberFetcher $invitedMemberFetcher;
  28.         $this->profileFetcher $profileFetcher;
  29.     }
  30.     protected function supports(string $attribute$subject): bool
  31.     {
  32.         return in_array($attribute, [
  33.             self::CONTRACTS_SHOW_TO_LOT,
  34.             self::PROCEDURE_SHOW
  35.         ], true);
  36.     }
  37.     /**
  38.      * @param string $attribute
  39.      * @param DetailView $subject
  40.      * @param TokenInterface $token
  41.      * @return bool
  42.      */
  43.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  44.     {
  45.         // Moderators have full access
  46.         if ($this->security->isGranted('ROLE_MODERATOR')) {
  47.             return true;
  48.         }
  49.         $user $token->getUser();
  50.         // Only authenticated UserIdentity can proceed
  51.         if (!$user instanceof UserIdentity) {
  52.             return false;
  53.         }
  54.         $this->profile $this->profileFetcher->find($user->getProfileId());
  55.         $role = (new RoleConstants($user->getRole()));
  56.         if ($role->isOrganizerUser()) {
  57.             if ($this->checkPermissionEmployee($user$attribute) === false) {
  58.                 return $this->handleException();
  59.             }
  60.         }
  61.         //is not owner object
  62.         if ($this->isOwnerObject($subject$user) === false) {
  63.             if ($subject->getStatus()->isNew() or $subject->getStatus()->isArchive()) {
  64.                 return $this->handleException();
  65.             }
  66.         }
  67.         if ($this->checkClosedPurchase($subject) === false) {
  68.             return $this->handleException();
  69.         }
  70.         return true;
  71.     }
  72.     private function checkClosedPurchase(DetailView $lot): bool
  73.     {
  74.         //закрытая закупка не виден не приглашенным
  75.         if ($lot->closed_purchase && $lot->is_hide_closed_purchase) {
  76.             $inn $this->profile->getInn();
  77.             //заказчик
  78.             if ($lot->organizer_profile_id === $this->profile->id) {
  79.                 return true;
  80.             }
  81.             if (!$this->invitedMemberFetcher->isInvitedByInnOrProfile($inn$lot->procedure_id$this->profile->id)) {
  82.                 return false;
  83.             }
  84.         }
  85.         return true;
  86.     }
  87.     /**
  88.      * Проверка разрешений сотрудника
  89.      * @param UserIdentity $user
  90.      * @param string $attribute
  91.      * @return bool
  92.      */
  93.     private function checkPermissionEmployee(UserIdentity $userstring $attribute): bool
  94.     {
  95.         switch ($attribute) {
  96.             case self::CONTRACTS_SHOW_TO_LOT:
  97.                 return $user->isPermission(Permission::CONTRACTS_SHOW_TO_LOT);
  98.                 break;
  99.             case self::PROCEDURE_SHOW:
  100.                 return true;
  101.                 break;
  102.         }
  103.         return false;
  104.     }
  105.     private function isOwnerObject(DetailView $subjectUserIdentity $user): bool
  106.     {
  107.         if ($subject->organizer_profile_id === $user->getProfileId()) {
  108.             return true;
  109.         }
  110.         return false;
  111.     }
  112.     private function handleException()
  113.     {
  114.         throw new AccessDeniedException('Доступ запрещен. У вас недостаточно прав для совершения этого действия.');
  115.     }
  116. }