app/Service/Security/Voter/User/UserVoter.php line 11

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Sq\Service\Security\Voter\User;
  3. use Sq\Entity\Schema\ORM\User;
  4. use Sq\Service\Security\Voter\SecurityAttributes;
  5. use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
  6. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  7. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  8. class UserVoter extends Voter
  9. {
  10.     protected function supports($attribute$subject): bool
  11.     {
  12.         $attributes = [
  13.             SecurityAttributes::VIEW,
  14.             // SecurityAttributes::CREATE is only allowed by an anonymous user that is not logged in.
  15.             SecurityAttributes::EDIT,
  16.             SecurityAttributes::DELETE,
  17.         ];
  18.         return in_array($attribute$attributestrue)
  19.             && $subject instanceof User;
  20.     }
  21.     protected function voteOnAttribute($attribute$subjectTokenInterface $token): bool
  22.     {
  23.         /** @var \Sq\Entity\Schema\ORM\User $subject */
  24.         $user $token->getUser();
  25.         if (!$user instanceof User)
  26.         {
  27.             return false;
  28.         }
  29.         // A user can view another user if they share an organization.
  30.         if ($attribute === SecurityAttributes::VIEW)
  31.         {
  32.             return $user->getRole() === User::ROLE_ADMIN || $this->doUsersBelongToSameOrganization($user$subject);
  33.         }
  34.         // Other users cannot edit or delete a user that is not themselves.
  35.         if ($token instanceof SwitchUserToken)
  36.         {
  37.             return false;
  38.         }
  39.         return $subject->getId() === $user->getId()
  40.             || $user->getRole() === User::ROLE_ADMIN;
  41.     }
  42.     private function doUsersBelongToSameOrganization(User $userUser $subject): bool
  43.     {
  44.         foreach ($user->getOrganizations() as $organization)
  45.         {
  46.             if ($subject->getOrganizations()->contains($organization))
  47.             {
  48.                 return true;
  49.             }
  50.         }
  51.         return false;
  52.     }
  53. }