vendor/datenwerk/ginger-bundle/Security/TagVoter.php line 12

Open in your IDE?
  1. <?php
  2. namespace DW\GingerBundle\Security;
  3. use DW\GingerBundle\Entity\GroupInterface;
  4. use DW\GingerBundle\Entity\TagInterface;
  5. use DW\GingerBundle\Entity\User;
  6. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  7. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  8. use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
  9. class TagVoter extends Voter
  10. {
  11.     const VIEW 'view';
  12.     const EDIT 'edit';
  13.     const CREATE 'create';
  14.     const DELETE 'delete';
  15.     const USE = 'use';
  16.     private AccessDecisionManagerInterface $decisionManager;
  17.     public function __construct(AccessDecisionManagerInterface $decisionManager)
  18.     {
  19.         $this->decisionManager $decisionManager;
  20.     }
  21.     protected function supports($attribute$subject): bool
  22.     {
  23.         // if the attribute isn't one we support, return false
  24.         if (!in_array($attribute, array(self::VIEWself::EDITself::CREATEself::DELETEself::USE))) {
  25.             return false;
  26.         }
  27.         // only vote on tag objects inside this voter
  28.         if (!$subject instanceof TagInterface) {
  29.             return false;
  30.         }
  31.         return true;
  32.     }
  33.     protected function voteOnAttribute($attribute$subjectTokenInterface $token): bool
  34.     {
  35.         $user $token->getUser();
  36.         if (!$user instanceof User) {
  37.             // the user must be logged in; if not, deny access
  38.             return false;
  39.         }
  40.         /** @var Tag $tag */
  41.         $tag $subject;
  42.         switch ($attribute) {
  43.             case self::VIEW:
  44.                 return $this->canView($tag$token);
  45.             case self::EDIT:
  46.                 return $this->canEdit($tag$token);
  47.             case self::CREATE:
  48.                 return $this->canCreate($tag$token);
  49.             case self::DELETE:
  50.                 return $this->canDelete($tag$token);
  51.             case self::USE:
  52.                 return $this->canUse($tag$token);
  53.         }
  54.         throw new \LogicException('This code should not be reached!');
  55.     }
  56.     private function canCreate(TagInterface $tagTokenInterface $token): bool
  57.     {
  58.         if ($this->decisionManager->decide($token, ['ROLE_GINGER_TAG_CREATE'])) {
  59.             return true;
  60.         }
  61.         return false;
  62.     }
  63.     private function canView(TagInterface $tagTokenInterface $token): bool
  64.     {
  65.        // Everyone can view tags
  66.         return true;
  67.     }
  68.     private function canEdit(TagInterface $tagTokenInterface $token): bool
  69.     {
  70.         if (!$this->decisionManager->decide($token, ['ROLE_GINGER_TAG_EDIT'])) {
  71.             return false;
  72.         }
  73.         $user $token->getUser();
  74.         // "God users" have no groups
  75.         if ($user->getGroups()->isEmpty()) {
  76.             return true;
  77.         }
  78.         // Users groups must have the tag
  79.         /**@var GroupInterface $group */
  80.         foreach ($user->getGroups() as $group) {
  81.             if ($group->getTags()->contains($tag)) {
  82.                 return true;
  83.             }
  84.         }
  85.         return false;
  86.     }
  87.     private function canDelete(TagInterface $tagTokenInterface $token): bool
  88.     {
  89.         if ($this->canEdit($tag$token) && $this->decisionManager->decide($token, ['ROLE_GINGER_TAG_DELETE'])) {
  90.             return true;
  91.         }
  92.         return false;
  93.     }
  94.     private function canUse(TagInterface $tagTokenInterface $token): bool
  95.     {
  96.         // everyone may use general tags
  97.         if ($tag->getType() === TagInterface::TYPE_GENERAL) {
  98.             return true;
  99.         }
  100.         $user $token->getUser();
  101.         // "God users" have no groups
  102.         if ($user->getGroups()->isEmpty()) {
  103.             return true;
  104.         }
  105.         // Special usecase: Editors may use special tags when merging duplicates.
  106.         // https://mantis.dwerk.at/view.php?id=29636
  107.         if ($this->decisionManager->decide($token, ['ROLE_GINGER_DUPLICATE_CONTROLLER'])) {
  108.             return true;
  109.         }
  110.         // Users groups must have the tag
  111.         /**@var GroupInterface $group */
  112.         foreach ($user->getGroups() as $group) {
  113.             if ($group->getTags()->contains($tag)) {
  114.                 return true;
  115.             }
  116.         }
  117.         return false;
  118.     }
  119. }