src/Security/Voter/Profile/ProfileVoter.php line 16

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Security\Voter\Profile;
  4. use App\Model\User\Entity\User\Role\Permission;
  5. use App\Model\User\Entity\User\Role\RoleConstants;
  6. use App\ReadModel\Profile\DetailView;
  7. use App\Security\UserIdentity;
  8. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  9. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  10. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  11. use Symfony\Component\Security\Core\Security;
  12. class ProfileVoter extends Voter
  13. {
  14.     public const PROFILE_CREATE 'profile_create';
  15.     public const PROFILE_EDIT 'profile_edit';
  16.     public const PROFILE_INDEX 'profile_index';
  17.     public const PROFILE_RECALL 'profile_recall';
  18.     public const ORGANIZATION_USERS_LIST 'organization_users_list';
  19.     public const ORGANIZATION_POSITION_LIST 'organization_position_list';
  20.     public const ORGANIZATION_USERS_CREATE 'organization_users_create';
  21.     public const ORGANIZATION_USERS_DELETE 'organization_users_delete';
  22.     public const CONTRACTS_LIST 'contracts_list';
  23.     public const PROCEDURE_MY_LIST 'procedure_my_list';
  24.     private Security $security;
  25.     public function __construct(Security $security)
  26.     {
  27.         $this->security $security;
  28.     }
  29.     protected function supports(string $attribute$subject): bool
  30.     {
  31.         return in_array($attribute, [
  32.                 self::PROFILE_CREATE,
  33.                 self::PROFILE_EDIT,
  34.                 self::PROFILE_INDEX,
  35.                 self::PROFILE_RECALL,
  36.                 self::ORGANIZATION_USERS_LIST,
  37.                 self::ORGANIZATION_POSITION_LIST,
  38.                 self::ORGANIZATION_USERS_CREATE,
  39.                 self::ORGANIZATION_USERS_DELETE,
  40.                 self::CONTRACTS_LIST,
  41.                 self::PROCEDURE_MY_LIST
  42.             ], true);
  43.     }
  44.     /**
  45.      * @param string $attribute
  46.      * @param $subject
  47.      * @param TokenInterface $token
  48.      * @return bool
  49.      */
  50.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  51.     {
  52.         // Moderators have full access
  53.         if ($this->security->isGranted('ROLE_MODERATOR')) {
  54.             return true;
  55.         }
  56.         $user $token->getUser();
  57.         // Only authenticated UserIdentity can proceed
  58.         if (!$user instanceof UserIdentity) {
  59.             return false;
  60.         }
  61.         $role = (new RoleConstants($user->getRole()));
  62.         if ($role->isOrganizerUser()) {
  63.             if ($this->checkPermissionEmployee($user$attribute$subject) === false) {
  64.                 return $this->handleException();
  65.             }
  66.         }
  67.         // Check specific permissions
  68.         switch ($attribute) {
  69.             case self::PROFILE_INDEX:
  70.                 if (!$this->isOwnerProfile($subject$user)) {
  71.                     return $this->handleException();
  72.                 }
  73.                 break;
  74.             case self::PROFILE_EDIT:
  75.                 // Only profile owner can proceed
  76.                 if (!$this->isOwnerProfile($subject$user)) {
  77.                     return $this->handleException();
  78.                 }
  79.                 return $user->isPermission(Permission::PROFILE_EDIT);
  80.                 break;
  81.             case self::CONTRACTS_LIST:
  82.                 // Only profile owner can proceed
  83.                 if (!$this->isOwnerProfile($subject$user)) {
  84.                     return $this->handleException();
  85.                 }
  86.                 return $user->isPermission(Permission::CONTRACTS_LIST);
  87.                 break;
  88.             case self::PROCEDURE_MY_LIST:
  89.                 if ($subject->id !== $user->getProfileId()) {
  90.                     return $this->handleException();
  91.                 }
  92.                 break;
  93.         }
  94.         return true;
  95.     }
  96.     private function handleException()
  97.     {
  98.         throw new AccessDeniedException('Доступ запрещен. У вас недостаточно прав для совершения этого действия.');
  99.     }
  100.     /**
  101.      * Проверка разрешений сотрудника
  102.      * @param UserIdentity $user
  103.      * @param string $attribute
  104.      * @param DetailView $subject
  105.      * @return bool
  106.      */
  107.     private function checkPermissionEmployee(UserIdentity $userstring $attributeDetailView $subject): bool
  108.     {
  109.         switch ($attribute) {
  110.             case self::PROFILE_INDEX:
  111.                 if (!$this->isOwnerProfile($subject$user)) {
  112.                     return false;
  113.                 }
  114.                 return true;
  115.                 break;
  116.             case self::PROFILE_EDIT:
  117.                 if (!$this->isOwnerProfile($subject$user)) {
  118.                     return false;
  119.                 }
  120.                 return $user->isPermission(Permission::PROFILE_EDIT);
  121.                 break;
  122.             case self::ORGANIZATION_USERS_LIST:
  123.                 // Only profile owner can proceed
  124.                 if (!$this->isOwnerProfile($subject$user)) {
  125.                     return false;
  126.                 }
  127.                 return $user->isPermission(Permission::ORGANIZATION_USERS_LIST);
  128.                 break;
  129.             case self::ORGANIZATION_POSITION_LIST:
  130.                 if (!$this->isOwnerProfile($subject$user)) {
  131.                     return false;
  132.                 }
  133.                 return $user->isPermission(Permission::ORGANIZATION_POSITION_LIST);
  134.                 break;
  135.             case self::ORGANIZATION_USERS_CREATE:
  136.                 if (!$this->isOwnerProfile($subject$user)) {
  137.                     return false;
  138.                 }
  139.                 return $user->isPermission(Permission::ORGANIZATION_USERS_CREATE);
  140.                 break;
  141.             case self::ORGANIZATION_USERS_DELETE:
  142.                 if (!$this->isOwnerProfile($subject$user)) {
  143.                     return false;
  144.                 }
  145.                 return $user->isPermission(Permission::ORGANIZATION_USERS_DELETE);
  146.                 break;
  147.             case self::CONTRACTS_LIST:
  148.                 if (!$this->isOwnerProfile($subject$user)) {
  149.                     return false;
  150.                 }
  151.                 return $user->isPermission(Permission::CONTRACTS_LIST);
  152.                 break;
  153.             case self::PROCEDURE_MY_LIST:
  154.                 if ($subject->id !== $user->getProfileId()) {
  155.                     return $this->handleException();
  156.                 }
  157.                 return true;
  158.                 break;
  159.             default:
  160.                 return false;
  161.         }
  162.     }
  163.     private function isOwnerProfile(DetailView $subjectUserIdentity $user): bool
  164.     {
  165.         // Only profile owner can proceed
  166.         if ($subject->id !== $user->getProfileId()) {
  167.             return false;
  168.         }
  169.         return true;
  170.     }
  171. }