src/Security/Voter/UserVoter.php line 9

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter;
  3. use App\Entity\User;
  4. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  5. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  6. class UserVoter extends Voter
  7. {
  8.     // these strings are just invented: you can use anything
  9.     const LIST = 'list';
  10.     const VIEW 'view';
  11.     const EDIT 'edit';
  12.     const ADD 'add';
  13.     const DELETE 'delete';
  14.     protected function supports($attribute$subject)
  15.     {
  16.         // if the attribute isn't one we support, return false
  17.         if (!in_array($attribute, [self::LIST, self::VIEWself::EDITself::ADDself::DELETE])) {
  18.             return false;
  19.         }
  20.         // list and add have no subject, so subject cannot be passed
  21.         if ($attribute === self::LIST || $attribute === self::ADD) {
  22.             return true;
  23.         }
  24.         // only vote on User objects inside this voter
  25.         if (!$subject instanceof User) {
  26.             return false;
  27.         }
  28.         return true;
  29.     }
  30.     protected function voteOnAttribute($attribute$subjectTokenInterface $token)
  31.     {
  32.         $user $token->getUser();
  33.         if (!$user instanceof User) {
  34.             // the user must be logged in; if not, deny access
  35.             return false;
  36.         }
  37.         // you know $subject is a User object, thanks to supports
  38.         /** @var User $user */
  39.         $userSubject $subject;
  40.         switch ($attribute) {
  41.             case self::LIST:
  42.                 return $this->canList($user);
  43.             case self::VIEW:
  44.                 return $this->canView($userSubject$user);
  45.             case self::ADD:
  46.                 return $this->canAdd($user);
  47.             case self::EDIT:
  48.                 return $this->canEdit($userSubject$user);
  49.             case self::DELETE:
  50.                 return $this->canDelete($userSubject$user);
  51.         }
  52.         throw new \LogicException('This code should not be reached!');
  53.     }
  54.     private function canView(User $userSubjectUser $user)
  55.     {
  56.         // if they can edit, they can view
  57.         if ($this->canEdit($userSubject$user)) {
  58.             return true;
  59.         }
  60.         // user can edit self
  61.         if ($userSubject->getId() === $user->getId()) {
  62.             return true;
  63.         }
  64.         // admin can edit
  65.         if ($user->getIsAdmin() === true) {
  66.             return true;
  67.         }
  68.         return false;
  69.     }
  70.     private function canEdit(User $userSubjectUser $user)
  71.     {
  72.         // user can edit self
  73.         if ($userSubject->getId() === $user->getId()) {
  74.             return true;
  75.         }
  76.         // admin can edit
  77.         if ($user->getIsAdmin() === true) {
  78.             return true;
  79.         }
  80.         return false;
  81.     }
  82.     private function canAdd(User $user)
  83.     {
  84.         // for now only an Admin can create users
  85.         return $user->getIsAdmin();
  86.     }
  87.     private function canDelete(User $userSubjectUser $user)
  88.     {
  89.         // for now deleting is the same as editing with the exception that a user cannot delete self
  90.         if ($userSubject->getId() === $user->getId()) {
  91.             return false;
  92.         }
  93.         return $this->canEdit($userSubject$user);
  94.     }
  95.     private function canList(User $user)
  96.     {
  97.         // only users with isViewer rights can list users
  98.         return $user->getIsViewer();
  99.     }
  100. }