src/Security/PlanningVoter.php line 63

Open in your IDE?
  1. <?php
  2. //------------------------------------------------------------------------------
  3. // src/Security/PlanningVoter.php
  4. // OK #4453 : VoterCache
  5. //------------------------------------------------------------------------------
  6. namespace App\Security;
  7. use Doctrine\Persistence\ManagerRegistry;
  8. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  9. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  10. use App\Entity\Access;
  11. use App\Entity\Config\Module;
  12. use App\Entity\Config\OptionConfig;
  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. use App\Services\LogTools;
  18. class PlanningVoter extends Voter
  19. {
  20.     //--------------------------------------------------------------------------------
  21.     // is_granted constants
  22.     const IS_ACTIVE "planning_is_active";
  23.     const LOAD_GLOBAL_PLANNING "planning_global_view";
  24.     const LOAD_INDIVIDUAL_PLANNING "planning_individual_view";
  25.     const DECLARE_AVAILABILITIES "planning_declare_availabilities";
  26.     const VIEW_NUMBER_GLOBAL_PLANNING "planning_global_view_number";
  27.     const ORGANIZE_PLANNING_RESOURCES "planning_global_organize_planning_resources";
  28.     const PLANNING_OPTIMISATION_IS_ACTIVE "planning_optimisation_is_active";
  29.     const OPTIMISE_PLANNING "optimise_planning";
  30.     //--------------------------------------------------------------------------------
  31.     const IS_GRANTED_CONSTANTS = array(
  32.         self::IS_ACTIVE,
  33.         self::LOAD_GLOBAL_PLANNING,
  34.         self::LOAD_INDIVIDUAL_PLANNING,
  35.         self::DECLARE_AVAILABILITIES,
  36.         self::VIEW_NUMBER_GLOBAL_PLANNING,
  37.         self::ORGANIZE_PLANNING_RESOURCES,
  38.         self::PLANNING_OPTIMISATION_IS_ACTIVE,
  39.         self::OPTIMISE_PLANNING,
  40.     );
  41.     //--------------------------------------------------------------------------------
  42.     // acl constants
  43.     const ACL_PERM_LOAD_GLOBAL_PLANNING "planning_global_view";
  44.     const ACL_PERM_LOAD_INDIVIDUAL_PLANNING "planning_individual_view";
  45.     const ACL_PERM_DECLARE_AVAILABILITIES "planning_declare_availabilities";
  46.     const ACL_PERM_VIEW_NUMBER_GLOBAL_PLANNING "planning_global_view_number";
  47.     const ACL_PERM_ORGANIZE_PLANNING_RESOURCES "planning_global_organize_planning_resources";
  48.     const ACL_PERM_OPTIMISE_PLANNING "optimise_planning";
  49.     //--------------------------------------------------------------------------------
  50.     public function __construct(ManagerRegistry $doctrineModuleTools $moduleToolsLogTools $logTools)
  51.     {
  52.         $this->em $doctrine->getManager();
  53.         $this->moduleTools $moduleTools;
  54.         $this->logTools $logTools;
  55.         $this->aclRepository $this->em->getRepository(Acl::class);
  56.         $this->aclPermissionRepository $this->em->getRepository(AclPermission::class);
  57.     }
  58.     // Plan.io Task #4453 [See AccessVoter for details]
  59.     public function supportsAttribute(string $attribute): bool
  60.     {
  61.         return in_array($attributeself::IS_GRANTED_CONSTANTStrue);
  62.     }
  63.     
  64.     protected function supports(string $attribute$subject null): bool
  65.     {
  66.         // if the attribute isn't one we support, return false
  67.         if (!in_array($attributeself::IS_GRANTED_CONSTANTS))
  68.         {
  69.             return false;
  70.         }
  71.         // No object here
  72.         return true;
  73.     }
  74.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  75.     {
  76.         $user $token->getUser();
  77.         if (!$user instanceof Access)
  78.         {
  79.             // the user must be logged in; if not, deny access
  80.             return false;
  81.         }
  82.         // The user must have a function; if not deny access
  83.         $function $user->getFunction();
  84.         if ($function === null)        return false;
  85.         // Plan.io Task #3710 : Get current group
  86.         $currentGroup $user->getSocietyGroup();
  87.         if ($currentGroup === null)
  88.             return false;
  89.         // This is needed to check HumanResource Module in canLoadGlobalPlanning
  90.         $this->currentGroup $currentGroup;
  91.         // Module activated ?
  92.         if ($this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_PLANNING))
  93.         {
  94.             return false;
  95.         }
  96.         switch ($attribute)
  97.         {
  98.             case self::IS_ACTIVE:
  99.                 return true;
  100.             case self::LOAD_GLOBAL_PLANNING:
  101.                 return $this->canLoadGlobalPlanning($user$function);
  102.             case self::LOAD_INDIVIDUAL_PLANNING:
  103.                 return $this->canLoadIndividualPlanning($user$function);
  104.             case self::DECLARE_AVAILABILITIES:
  105.                 return $this->canDeclareAvailabilities($user$function);
  106.             case self::VIEW_NUMBER_GLOBAL_PLANNING:
  107.                 return $this->canViewNumberGlobalPlanning($user$function);
  108.             case self::ORGANIZE_PLANNING_RESOURCES:
  109.                 return $this->canOrganizePlanningResources($user$function);
  110.             case self::PLANNING_OPTIMISATION_IS_ACTIVE:
  111.                 return $this->planningOptimisationIsActive($user$function);
  112.             case self::OPTIMISE_PLANNING:
  113.                 return $this->canOptimisePlanning($user$function);
  114.         }
  115.         throw new \LogicException('This code should not be reached!');
  116.     }
  117.     private function canLoadGlobalPlanning(Access $accessAccessFunction $function)
  118.     {
  119.         // Si le module Ressources humaines n'est pas activé, accès au planning individuel uniquement
  120.         if ($this->moduleTools->isInactiveByCode($this->currentGroupModule::MODULE_HUMAN_RESOURCE))
  121.         {
  122.             return false;
  123.         }
  124.         // Get Acl_Permission
  125.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LOAD_GLOBAL_PLANNING);
  126.         if ($aclPerm === null)        return false;
  127.         // Get Acl
  128.         $acl $this->aclRepository->findOneBy(array(
  129.             'function'        =>    $function,
  130.             'permission'    =>    $aclPerm
  131.         ));
  132.         if ($acl === null)        return false;
  133.         return $acl->getValue();
  134.     }
  135.     private function canLoadIndividualPlanning(Access $accessAccessFunction $function)
  136.     {
  137.         // Get Acl_Permission
  138.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LOAD_INDIVIDUAL_PLANNING);
  139.         if ($aclPerm === null)        return false;
  140.         // Get Acl
  141.         $acl $this->aclRepository->findOneBy(array(
  142.             'function'        =>    $function,
  143.             'permission'    =>    $aclPerm
  144.         ));
  145.         if ($acl === null)        return false;
  146.         return $acl->getValue();
  147.     }
  148.     private function canDeclareAvailabilities(Access $accessAccessFunction $function)
  149.     {
  150.         // Get Acl_Permission
  151.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_DECLARE_AVAILABILITIES);
  152.         if ($aclPerm === null)        return false;
  153.         // Get Acl
  154.         $acl $this->aclRepository->findOneBy(array(
  155.             'function'        =>    $function,
  156.             'permission'    =>    $aclPerm
  157.         ));
  158.         if ($acl === null)        return false;
  159.         return $acl->getValue();
  160.     }
  161.     private function canViewNumberGlobalPlanning(Access $accessAccessFunction $function)
  162.     {
  163.         // Get Acl_Permission
  164.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_NUMBER_GLOBAL_PLANNING);
  165.         if ($aclPerm === null)        return false;
  166.         // Get Acl
  167.         $acl $this->aclRepository->findOneBy(array(
  168.             'function'        =>    $function,
  169.             'permission'    =>    $aclPerm
  170.         ));
  171.         if ($acl === null)        return false;
  172.         return $acl->getValue();
  173.     }
  174.     private function canOrganizePlanningResources(Access $accessAccessFunction $function)
  175.     {
  176.         // Si le module Ressources humaines n'est pas activé, accès au planning individuel uniquement
  177.         if ($this->moduleTools->isInactiveByCode($this->currentGroupModule::MODULE_HUMAN_RESOURCE))
  178.         {
  179.             return false;
  180.         }
  181.         // Get Acl_Permission
  182.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ORGANIZE_PLANNING_RESOURCES);
  183.         if ($aclPerm === null)        return false;
  184.         // Get Acl
  185.         $acl $this->aclRepository->findOneBy(array(
  186.             'function'        =>    $function,
  187.             'permission'    =>    $aclPerm
  188.         ));
  189.         if ($acl === null)        return false;
  190.         return $acl->getValue();
  191.     }
  192.     private function planningOptimisationIsActive()
  193.     {
  194.         // Check if option "planning_optimisation" is active in module planning
  195.         $planningOptimisationConfig $this->em->getRepository(OptionConfig::class)
  196.             ->findOneBy(array(
  197.                 'code'                =>    OptionConfig::PLANNING_OPTIMISATION_CODE,
  198.                 'societyGroup'        =>    $this->currentGroup,
  199.             ));
  200.         if ($planningOptimisationConfig !== null)
  201.         {
  202.             return $planningOptimisationConfig->getValue();
  203.         }
  204.         return false;
  205.     }
  206.     private function canOptimisePlanning(Access $accessAccessFunction $function)
  207.     {
  208.         // Check if option "planning_optimisation" is active in module planning
  209.         if (!$this->planningOptimisationIsActive())
  210.         {
  211.             return false;
  212.         }
  213.         // Get Acl_Permission
  214.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_OPTIMISE_PLANNING);
  215.         if ($aclPerm === null)        return false;
  216.         // Get Acl
  217.         $acl $this->aclRepository->findOneBy(array(
  218.             'function'        =>    $function,
  219.             'permission'    =>    $aclPerm
  220.         ));
  221.         if ($acl === null)        return false;
  222.         return $acl->getValue();
  223.     }
  224. }