src/Security/StoreVoter.php line 20

Open in your IDE?
  1. <?php
  2. //------------------------------------------------------------------------------
  3. // src/Security/StoreVoter.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\Client\Store;
  11. use App\Entity\Config\Config;
  12. use App\Entity\Config\Module;
  13. use App\Entity\HR\AccessFunction;
  14. use App\Entity\Security\Acl;
  15. use App\Entity\Security\AclPermission;
  16. use App\Services\Config\ModuleTools;
  17. class StoreVoter extends Voter
  18. {
  19.     const ADD "add_store";
  20.     const LISTING "list_stores";
  21.     const VIEW "view_store";
  22.     const EDIT "edit_store";
  23.     const IS_GRANTED_CONSTANTS = array(
  24.         self::ADD,
  25.         self::LISTING,
  26.         self::VIEW,
  27.         self::EDIT,
  28.     );
  29.     //--------------------------------------------------------------------------------
  30.     // acl constants
  31.     const ACL_PERM_ADD "store_add";
  32.     const ACL_PERM_LISTING "store_list";
  33.     const ACL_PERM_VIEW "store_view";
  34.     const ACL_PERM_EDIT "store_edit";
  35.     //--------------------------------------------------------------------------------
  36.     public function __construct(ManagerRegistry $doctrineModuleTools $moduleTools)
  37.     {
  38.         $this->em $doctrine->getManager();
  39.         $this->moduleTools $moduleTools;
  40.         $this->aclRepository $this->em->getRepository(Acl::class);
  41.         $this->aclPermissionRepository $this->em->getRepository(AclPermission::class);
  42.     }
  43.     // Plan.io Task #4453 [See AccessVoter for details]
  44.     public function supportsAttribute(string $attribute): bool
  45.     {
  46.         return in_array($attributeself::IS_GRANTED_CONSTANTStrue);
  47.     }
  48.     protected function supports(string $attribute$subject): bool
  49.     {
  50.         // if the attribute isn't one we support, return false
  51.         if (!in_array($attributeself::IS_GRANTED_CONSTANTS))
  52.         {
  53.             return false;
  54.         }
  55.         // only vote on Store objects inside this voter
  56.         if ($subject !== null && !$subject instanceof Store)
  57.         {
  58.             return false;
  59.         }
  60.         return true;
  61.     }
  62.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  63.     {
  64.         $user $token->getUser();
  65.         if (!$user instanceof Access)
  66.         {
  67.             // the user must be logged in; if not, deny access
  68.             return false;
  69.         }
  70.         // The user must have a function; if not deny access
  71.         $function $user->getFunction();
  72.         if ($function === null)        return false;
  73.         // Plan.io Task #3710 : Get current group
  74.         $currentGroup $user->getSocietyGroup();
  75.         if ($currentGroup === null)
  76.             return false;
  77.         $this->currentGroup $currentGroup;
  78.         // Module activated ?
  79.         if ($this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_CLIENT) && $this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_CLIENT_LIGHT))
  80.         {
  81.             return false;
  82.         }
  83.         // you know $subject is a Store object, thanks to supports
  84.         /** @var Store $store */
  85.         $store $subject;
  86.         // Check current group affectation
  87.         if ($subject !== null)
  88.         {
  89.             $subjectGroup $subject->getSocietyGroup();
  90.             if ($subjectGroup === null)
  91.                 return false;
  92.             if (!$currentGroup->equals($subjectGroup))
  93.                 return false;
  94.         }
  95.         switch ($attribute)
  96.         {
  97.             case self::ADD:
  98.                 return $this->canAdd($user$function);
  99.             case self::LISTING:
  100.                 return $this->canList($user$function);
  101.             case self::VIEW:
  102.                 return $this->canView($store$user$function);
  103.             case self::EDIT:
  104.                 return $this->canEdit($store$user$function);
  105.         }
  106.         throw new \LogicException('This code should not be reached!');
  107.     }
  108.     private function canAdd(Access $accessAccessFunction $function)
  109.     {
  110.         // Module activated ?
  111.         // CLIENT_LIGHT cannot add Clients / Stores
  112.         if ($this->moduleTools->isInactiveByCode($this->currentGroupModule::MODULE_CLIENT))
  113.         {
  114.             return false;
  115.         }
  116.         // Get Acl_Permission
  117.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ADD);
  118.         if ($aclPerm === null)        return false;
  119.         // Get Acl
  120.         $acl $this->aclRepository->findOneBy(array(
  121.             'function'        =>    $function,
  122.             'permission'    =>    $aclPerm
  123.         ));
  124.         if ($acl === null)        return false;
  125.         return $acl->getValue();
  126.     }
  127.     private function canList(Access $accessAccessFunction $function)
  128.     {
  129.         // Restrictions are also applied in the Controller
  130.         // But this helps speeding page loading if the access is not even allowed to load the page
  131.         // (ie. if it has no list privileges whatsoever)
  132.         // Get Acl_Permission
  133.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  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 list type can exist for the Stores,
  142.         // we can return the result of the acl_permission
  143.         return $acl->getValue();
  144.     }
  145.     private function canView(Store $storeAccess $accessAccessFunction $function)
  146.     {
  147.         // Several Acl_Permission exist
  148.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW);
  149.         // If all are null, exit
  150.         if ($aclPerm === null)
  151.             return false;
  152.         // Get First one (view all)
  153.         if ($aclPerm !== null)
  154.         {
  155.             $acl $this->aclRepository->findOneBy(array(
  156.                 'function'        =>    $function,
  157.                 'permission'    =>    $aclPerm
  158.             ));
  159.             if ($acl !== null)
  160.             {
  161.                 if ($acl->getValue())
  162.                 {
  163.                     // A single positive answer is enough
  164.                     return true;
  165.                 }
  166.             }
  167.         }
  168.         // If we are here, all hope is lost
  169.         return false;
  170.     }
  171.     private function canEdit(Store $storeAccess $accessAccessFunction $function)
  172.     {
  173.         // Several Acl_Permission exist
  174.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT);
  175.         // If all are null, exit
  176.         if ($aclPerm === null)
  177.             return false;
  178.         // Get First one (view all)
  179.         if ($aclPerm !== null)
  180.         {
  181.             $acl $this->aclRepository->findOneBy(array(
  182.                 'function'        =>    $function,
  183.                 'permission'    =>    $aclPerm
  184.             ));
  185.             if ($acl !== null)
  186.             {
  187.                 if ($acl->getValue())
  188.                 {
  189.                     // A single positive answer is enough
  190.                     return true;
  191.                 }
  192.             }
  193.         }
  194.         // If we are here, all hope is lost
  195.         return false;
  196.     }
  197. }