src/Security/BugVoter.php line 50

Open in your IDE?
  1. <?php
  2. //------------------------------------------------------------------------------
  3. // src/Security/BugVoter.php
  4. //------------------------------------------------------------------------------
  5. namespace App\Security;
  6. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  7. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  8. use Doctrine\Persistence\ManagerRegistry;
  9. use App\Entity\Access;
  10. use App\Entity\Config\Config;
  11. use App\Entity\Config\Module;
  12. use App\Entity\HR\AccessFunction;
  13. use App\Entity\Platform\Bug\Bug;
  14. use App\Entity\Security\Acl;
  15. use App\Entity\Security\AclPermission;
  16. use App\Services\Config\ModuleTools;
  17. class BugVoter extends Voter
  18. {
  19.     //--------------------------------------------------------------------------------
  20.     // is_granted constants
  21.     const ADD "add_bug";
  22.     const LISTING "list_bugs";
  23.     const VIEW "view_bug";
  24.     const EDIT "edit_bug";
  25.     const IS_GRANTED_CONSTANTS = array(
  26.         self::ADD,
  27.         self::LISTING,
  28.         self::VIEW,
  29.         self::EDIT,
  30.     );
  31.     //--------------------------------------------------------------------------------
  32.     // acl constants
  33.     const ACL_PERM_ADD "bug_add";
  34.     const ACL_PERM_LISTING "bug_list";
  35.     const ACL_PERM_VIEW "bug_view";
  36.     const ACL_PERM_EDIT "bug_edit";
  37.     //--------------------------------------------------------------------------------
  38.     public function __construct(ManagerRegistry $doctrineModuleTools $moduleTools)
  39.     {
  40.         $this->em $doctrine->getManager();
  41.         $this->moduleTools $moduleTools;
  42.         $this->aclRepository $this->em->getRepository(Acl::class);
  43.         $this->aclPermissionRepository $this->em->getRepository(AclPermission::class);
  44.     }
  45.     // Plan.io Task #4453 [See AccessVoter for details]
  46.     public function supportsAttribute(string $attribute): bool
  47.     {
  48.         return in_array($attributeself::IS_GRANTED_CONSTANTStrue);
  49.     }
  50.     protected function supports(string $attribute$subject): bool
  51.     {
  52.         // if the attribute isn't one we support, return false
  53.         if (!in_array($attributeself::IS_GRANTED_CONSTANTS))
  54.         {
  55.             return false;
  56.         }
  57.         // only vote on Bug objects inside this voter
  58.         if ($subject !== null && !$subject instanceof Bug)
  59.         {
  60.             return false;
  61.         }
  62.         return true;
  63.     }
  64.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  65.     {
  66.         $user $token->getUser();
  67.         if (!$user instanceof Access)
  68.         {
  69.             // the user must be logged in; if not, deny access
  70.             return false;
  71.         }
  72.         // The user must have a function; if not deny access
  73.         $function $user->getFunction();
  74.         if ($function === null)        return false;
  75.         // Plan.io Task #3710 : Get current group
  76.         $currentGroup $user->getSocietyGroup();
  77.         if ($currentGroup === null)
  78.             return false;
  79.         // you know $subject is a Bug object, thanks to supports
  80.         /** @var Bug $bug */
  81.         $bug $subject;
  82.         // Check current group affectation
  83.         if ($subject !== null)
  84.         {
  85.             $subjectSociety $subject->getSociety();
  86.             if ($subjectSociety === null)
  87.                 return false;
  88.             $subjectGroup $subjectSociety->getGroup();
  89.             if ($subjectGroup === null)
  90.                 return false;
  91.             if (!$currentGroup->equals($subjectGroup))
  92.                 return false;
  93.         }
  94.         switch ($attribute)
  95.         {
  96.             case self::ADD:
  97.                 return $this->canAdd($user$function);
  98.             case self::LISTING:
  99.                 return $this->canList($user$function);
  100.             case self::VIEW:
  101.                 return $this->canView($bug$user$function);
  102.             case self::EDIT:
  103.                 return $this->canEdit($bug$user$function);
  104.         }
  105.         throw new \LogicException('This code should not be reached!');
  106.     }
  107.     // $access is the user trying to load the resource
  108.     // $bug is the resource being loaded
  109.     // Check if the Society of the resource
  110.     // belongs to the societies of the $access
  111.     private function checkSociety(Bug $bugAccess $access)
  112.     {
  113.         // Get all the societies of the access
  114.         $societies $access->getSocieties();
  115.         // Get the Society of the Bug
  116.         $bugSociety $bug->getSociety();
  117.         if ($bugSociety === null)
  118.             return false;
  119.         $found false;
  120.         foreach ($societies as $society)
  121.         {
  122.             if ($society->getId() == $bugSociety->getId())
  123.             {
  124.                 $found true;
  125.                 break;
  126.             }
  127.         }
  128.         return $found;
  129.     }
  130.     private function canAdd(Access $userAccessFunction $function)
  131.     {
  132.         // Get AclPermission
  133.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ADD);
  134.         if ($aclPerm === null)        return false;
  135.         // Get Acl
  136.         $acl $this->aclRepository->findOneBy(array(
  137.             'function'        =>    $function,
  138.             'permission'    =>    $aclPerm
  139.         ));
  140.         if ($acl === null)        return false;
  141.         // Since only one acl type can exist
  142.         // we can return the result of the acl_permission
  143.         return $acl->getValue();
  144.     }
  145.     private function canList(Access $userAccessFunction $function)
  146.     {
  147.         // Get AclPermission
  148.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  149.         if ($aclPerm === null)        return false;
  150.         // Get Acl
  151.         $acl $this->aclRepository->findOneBy(array(
  152.             'function'        =>    $function,
  153.             'permission'    =>    $aclPerm
  154.         ));
  155.         if ($acl === null)        return false;
  156.         // Since only one acl type can exist
  157.         // we can return the result of the acl_permission
  158.         return $acl->getValue();
  159.     }
  160.     private function canView(Bug $bugAccess $userAccessFunction $function)
  161.     {
  162.         // Two AclPermission may exist
  163.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW);
  164.         // If both are null, exit
  165.         if ($aclPerm === null)
  166.             return false;
  167.         // Get First one
  168.         if ($aclPerm !== null)
  169.         {
  170.             $acl $this->aclRepository->findOneBy(array(
  171.                 'function'        =>    $function,
  172.                 'permission'    =>    $aclPerm
  173.             ));
  174.             if ($acl !== null)
  175.             {
  176.                 if ($acl->getValue())
  177.                 {
  178.                     // A single positive answer is enough
  179.                     return true;
  180.                 }
  181.             }
  182.         }
  183.         // If we are here, all hope is lost
  184.         return false;
  185.     }
  186.     private function canEdit(Bug $bugAccess $userAccessFunction $function)
  187.     {
  188.         // Two AclPermission may exist
  189.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT);
  190.         // If both are null, exit
  191.         if ($aclPerm === null)
  192.             return false;
  193.         // Get First one
  194.         if ($aclPerm !== null)
  195.         {
  196.             $acl $this->aclRepository->findOneBy(array(
  197.                 'function'        =>    $function,
  198.                 'permission'    =>    $aclPerm
  199.             ));
  200.             if ($acl !== null)
  201.             {
  202.                 if ($acl->getValue())
  203.                 {
  204.                     // A single positive answer is enough
  205.                     return true;
  206.                 }
  207.             }
  208.         }
  209.         // If we are here, all hope is lost
  210.         return false;
  211.     }
  212. }