src/Security/HumanResourceVoter.php line 79

Open in your IDE?
  1. <?php
  2. //------------------------------------------------------------------------------
  3. // src/Security/HumanResourceVoter.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\HR\HumanResource;
  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 HumanResourceVoter extends Voter
  19. {
  20.     //--------------------------------------------------------------------------------
  21.     // is_granted constants
  22.     const IS_ACTIVE "human_resource_is_active";
  23.     const ADD "add_human_resource";
  24.     const LISTING "list_human_resources";
  25.     const LISTING_SOCIETY "list_human_resources_society";
  26.     const LISTING_ANY "list_human_resources_any";
  27.     const VIEW "view_human_resource";
  28.     const EDIT "edit_human_resource";
  29.     const ANONYMIZE "anonymize_human_resource";
  30.     const IMPORT "import_human_resources";
  31.     const LISTING_ATTACHMENTS "list_human_resource_attachments";
  32.     const IS_GRANTED_CONSTANTS = array(
  33.         self::IS_ACTIVE,
  34.         self::ADD,
  35.         self::LISTING,
  36.         self::LISTING_SOCIETY,
  37.         self::LISTING_ANY,
  38.         self::VIEW,
  39.         self::EDIT,
  40.         self::ANONYMIZE,
  41.         self::IMPORT,
  42.         self::LISTING_ATTACHMENTS,
  43.     );
  44.     //--------------------------------------------------------------------------------
  45.     // acl constants
  46.     const ACL_PERM_IMPORT "human_resource_import";
  47.     const ACL_PERM_ADD "human_resource_add";
  48.     const ACL_PERM_LISTING "human_resource_list";
  49.     const ACL_PERM_LISTING_SOCIETY "human_resource_list_society";
  50.     const ACL_PERM_VIEW "human_resource_view";
  51.     const ACL_PERM_VIEW_SOCIETY "human_resource_view_society";
  52.     const ACL_PERM_EDIT "human_resource_edit";
  53.     const ACL_PERM_EDIT_SOCIETY "human_resource_edit_society";
  54.     const ACL_PERM_ANONYMIZE "human_resource_anonymize";
  55.     const ACL_PERM_ANONYMIZE_SOCIETY "human_resource_anonymize_society";
  56.     const ACL_PERM_ATTACHMENT_LIST "rh_attachment_list";
  57.     const ACL_PERM_ATTACHMENT_LIST_SOCIETY "rh_attachment_list_society";
  58.     const ACL_PERM_ATTACHMENT_LIST_BASE_SOCIETY "rh_attachment_list_base_society";
  59.     //--------------------------------------------------------------------------------
  60.     public function __construct(ManagerRegistry $doctrineLogTools $logToolsModuleTools $moduleTools)
  61.     {
  62.         $this->em $doctrine->getManager();
  63.         $this->logTools $logTools;
  64.         $this->moduleTools $moduleTools;
  65.         $this->aclRepository $this->em->getRepository(Acl::class);
  66.         $this->aclPermissionRepository $this->em->getRepository(AclPermission::class);
  67.     }
  68.     // Plan.io Task #4453 [See AccessVoter for details]
  69.     public function supportsAttribute(string $attribute): bool
  70.     {
  71.         return in_array($attributeself::IS_GRANTED_CONSTANTStrue);
  72.     }
  73.     protected function supports(string $attribute$subject): bool
  74.     {
  75.         // $this->logTools->ploopLog("[HumanResourceVoter][supports] attribute = $attribute");
  76.         // if the attribute isn't one we support, return false
  77.         if (!in_array($attributeself::IS_GRANTED_CONSTANTS))
  78.         {
  79.             return false;
  80.         }
  81.         // only vote on HumanResource objects inside this voter
  82.         if ($subject !== null && !$subject instanceof HumanResource)
  83.         {
  84.             return false;
  85.         }
  86.         return true;
  87.     }
  88.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  89.     {
  90.         $user $token->getUser();
  91.         if (!$user instanceof Access)
  92.         {
  93.             // the user must be logged in; if not, deny access
  94.             return false;
  95.         }
  96.         // The user must have a function; if not deny access
  97.         $function $user->getFunction();
  98.         if ($function === null)        return false;
  99.         // Plan.io Task #3710 : Get current group
  100.         $currentGroup $user->getSocietyGroup();
  101.         if ($currentGroup === null)
  102.             return false;
  103.         // Module activated ?
  104.         if ($this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_HUMAN_RESOURCE))
  105.         {
  106.             return false;
  107.         }
  108.         if ($attribute == self::EDIT)
  109.         {
  110.             if ($subject->getAnonymized())
  111.             {
  112.                 return false;
  113.             }
  114.         }
  115.         // you know $subject is a HumanResource object, thanks to supports
  116.         /** @var HumanResource $rh */
  117.         $rh $subject;
  118.         // Check current group affectation
  119.         if ($subject !== null)
  120.         {
  121.             $subjectSociety $subject->getSociety();
  122.             if ($subjectSociety === null)
  123.                 return false;
  124.             $subjectGroup $subjectSociety->getGroup();
  125.             if ($subjectGroup === null)
  126.                 return false;
  127.             if (!$currentGroup->equals($subjectGroup))
  128.                 return false;
  129.         }
  130.         switch ($attribute)
  131.         {
  132.             case self::IS_ACTIVE:
  133.                 return true;
  134.             case self::IMPORT:
  135.                 return $this->canImport($user$function);
  136.             case self::ADD:
  137.                 return $this->canAdd($rh$user$function);
  138.             case self::LISTING:
  139.                 return $this->canList($rh$user$function);
  140.             case self::LISTING_SOCIETY:
  141.                 return $this->canListSociety($rh$user$function);
  142.             case self::LISTING_ANY:
  143.                 return $this->canListAny($rh$user$function);
  144.             case self::VIEW:
  145.                 return $this->canView($rh$user$function);
  146.             case self::EDIT:
  147.                 return $this->canEdit($rh$user$function);
  148.             case self::ANONYMIZE:
  149.                 return $this->canAnonymize($rh$user$function);
  150.             case self::LISTING_ATTACHMENTS:
  151.                 return $this->canListAttachments($rh$user$function);
  152.         }
  153.         throw new \LogicException('This code should not be reached!');
  154.     }
  155.     // $access is the user trying to load the resource
  156.     // $rh is the resource being loaded
  157.     // Check if the Society of the resource
  158.     // belongs to the societies of the $access
  159.     private function checkSociety(HumanResource $rhAccess $access)
  160.     {
  161.         // Get all the societies of the access
  162.         $societies $access->getSocieties();
  163.         // Get the Society of the HumanResource
  164.         $rhSociety $rh->getSociety();
  165.         if ($rhSociety === null)
  166.             return false;
  167.         $found false;
  168.         foreach ($societies as $society)
  169.         {
  170.             if ($society->getId() == $rhSociety->getId())
  171.             {
  172.                 $found true;
  173.                 break;
  174.             }
  175.         }
  176.         return $found;
  177.     }
  178.     // $access is the user trying to load the resource
  179.     // $rh is the resource being loaded
  180.     private function checkBaseSociety(HumanResource $rhAccess $access)
  181.     {
  182.         // Get the base society of the access
  183.         $baseSociety $access->getSociety();
  184.         if ($baseSociety === null)
  185.         {
  186.             return false;
  187.         }
  188.         // Get the Society of the Human_Resource
  189.         $rhSociety $rh->getSociety();
  190.         if ($rhSociety === null)
  191.         {
  192.             return false;
  193.         }
  194.         if ($baseSociety->equals($rhSociety))
  195.         {
  196.             return true;
  197.         }
  198.         return false;
  199.     }
  200.     private function canImport(Access $accessAccessFunction $function)
  201.     {
  202.         // Get Acl_Permission
  203.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_IMPORT);
  204.         if ($aclPerm === null)        return false;
  205.         // Get Acl
  206.         $acl $this->aclRepository->findOneBy(array(
  207.             'function'        =>    $function,
  208.             'permission'    =>    $aclPerm
  209.         ));
  210.         if ($acl === null)        return false;
  211.         return $acl->getValue();
  212.     }
  213.     private function canAdd(HumanResource $rh nullAccess $userAccessFunction $function)
  214.     {
  215.         // Get AclPermission
  216.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ADD);
  217.         if ($aclPerm === null)        return false;
  218.         // Get Acl
  219.         $acl $this->aclRepository->findOneBy(array(
  220.             'function'        =>    $function,
  221.             'permission'    =>    $aclPerm
  222.         ));
  223.         if ($acl === null)        return false;
  224.         // Since only one acl type can exist
  225.         // we can return the result of the acl_permission
  226.         return $acl->getValue();
  227.     }
  228.     private function canList(HumanResource $rh nullAccess $userAccessFunction $function)
  229.     {
  230.         // Get AclPermission
  231.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  232.         if ($aclPerm === null)        return false;
  233.         // Get Acl
  234.         $acl $this->aclRepository->findOneBy(array(
  235.             'function'        =>    $function,
  236.             'permission'    =>    $aclPerm
  237.         ));
  238.         if ($acl === null)        return false;
  239.         // Since only one acl type can exist
  240.         // we can return the result of the acl_permission
  241.         return $acl->getValue();
  242.     }
  243.     private function canListSociety(HumanResource $rh nullAccess $userAccessFunction $function)
  244.     {
  245.         // Get AclPermission
  246.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  247.         if ($aclPerm === null)        return false;
  248.         // Get Acl
  249.         $acl $this->aclRepository->findOneBy(array(
  250.             'function'        =>    $function,
  251.             'permission'    =>    $aclPerm
  252.         ));
  253.         if ($acl === null)        return false;
  254.         // Since only one acl type can exist
  255.         // we can return the result of the acl_permission
  256.         // Further filtering is done in the Controller
  257.         return $acl->getValue();
  258.     }
  259.     private function canListAny(HumanResource $rh nullAccess $userAccessFunction $function)
  260.     {
  261.         // Two AclPermission may exist
  262.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  263.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  264.         // If both are null, exit
  265.         if ($aclPerm === null && $aclPermSociety === null)
  266.             return false;
  267.         // Get First one
  268.         if ($aclPerm !== null)
  269.         {
  270.             $acl $this->aclRepository->findOneBy(array(
  271.                 'function'        =>    $function,
  272.                 'permission'    =>    $aclPerm
  273.             ));
  274.             if ($acl !== null)
  275.             {
  276.                 if ($acl->getValue())
  277.                 {
  278.                     // A single positive answer is enough
  279.                     return true;
  280.                 }
  281.             }
  282.         }
  283.         // If we are here it means that nothing good has been found
  284.         // Load second permission
  285.         if ($aclPermSociety !== null)
  286.         {
  287.             $acl $this->aclRepository->findOneBy(array(
  288.                 'function'        =>    $function,
  289.                 'permission'    =>    $aclPermSociety
  290.             ));
  291.             if ($acl !== null)
  292.             {
  293.                 if ($acl->getValue())
  294.                 {
  295.                     // A single positive answer is enough
  296.                     return true;
  297.                 }
  298.             }
  299.         }
  300.         // If we are here, all hope is lost
  301.         return false;
  302.     }
  303.     private function canView(HumanResource $rh nullAccess $userAccessFunction $function)
  304.     {
  305.         // Two AclPermission may exist
  306.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW);
  307.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_SOCIETY);
  308.         // If both are null, exit
  309.         if ($aclPerm === null && $aclPermSociety === null)
  310.             return false;
  311.         // Get First one
  312.         if ($aclPerm !== null)
  313.         {
  314.             $acl $this->aclRepository->findOneBy(array(
  315.                 'function'        =>    $function,
  316.                 'permission'    =>    $aclPerm
  317.             ));
  318.             if ($acl !== null)
  319.             {
  320.                 if ($acl->getValue())
  321.                 {
  322.                     // A single positive answer is enough
  323.                     return true;
  324.                 }
  325.             }
  326.         }
  327.         // If we are here it means that nothing good has been found
  328.         // Load second permission
  329.         if ($aclPermSociety !== null)
  330.         {
  331.             $acl $this->aclRepository->findOneBy(array(
  332.                 'function'        =>    $function,
  333.                 'permission'    =>    $aclPermSociety
  334.             ));
  335.             if ($acl !== null)
  336.             {
  337.                 if ($acl->getValue())
  338.                 {
  339.                     // A single positive answer is enough
  340.                     // In this case the good answer will be provided by the checkSociety
  341.                     return $this->checkSociety($rh$user);
  342.                 }
  343.             }
  344.         }
  345.         // If we are here, all hope is lost
  346.         return false;
  347.     }
  348.     private function canEdit(HumanResource $rh nullAccess $userAccessFunction $function)
  349.     {
  350.         if($rh->getAnonymized())
  351.         {
  352.             return false;
  353.         }
  354.         // Two AclPermission may exist
  355.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT);
  356.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT_SOCIETY);
  357.         // If both are null, exit
  358.         if ($aclPerm === null && $aclPermSociety === null)
  359.             return false;
  360.         // Get First one
  361.         if ($aclPerm !== null)
  362.         {
  363.             $acl $this->aclRepository->findOneBy(array(
  364.                 'function'        =>    $function,
  365.                 'permission'    =>    $aclPerm
  366.             ));
  367.             if ($acl !== null)
  368.             {
  369.                 if ($acl->getValue())
  370.                 {
  371.                     // A single positive answer is enough
  372.                     return true;
  373.                 }
  374.             }
  375.         }
  376.         // If we are here it means that nothing good has been found
  377.         // Load second permission
  378.         if ($aclPermSociety !== null)
  379.         {
  380.             $acl $this->aclRepository->findOneBy(array(
  381.                 'function'        =>    $function,
  382.                 'permission'    =>    $aclPermSociety
  383.             ));
  384.             if ($acl !== null)
  385.             {
  386.                 if ($acl->getValue())
  387.                 {
  388.                     // A single positive answer is enough
  389.                     // In this case the good answer will be provided by the checkSociety
  390.                     return $this->checkSociety($rh$user);
  391.                 }
  392.             }
  393.         }
  394.         // If we are here, all hope is lost
  395.         return false;
  396.     }
  397.     private function canAnonymize(HumanResource $rh nullAccess $userAccessFunction $function)
  398.     {
  399.         // Two AclPermission may exist
  400.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ANONYMIZE);
  401.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ANONYMIZE_SOCIETY);
  402.         // If both are null, exit
  403.         if ($aclPerm === null && $aclPermSociety === null)
  404.             return false;
  405.         // Get First one
  406.         if ($aclPerm !== null)
  407.         {
  408.             $acl $this->aclRepository->findOneBy(array(
  409.                 'function'        =>    $function,
  410.                 'permission'    =>    $aclPerm
  411.             ));
  412.             if ($acl !== null)
  413.             {
  414.                 if ($acl->getValue())
  415.                 {
  416.                     // A single positive answer is enough
  417.                     return true;
  418.                 }
  419.             }
  420.         }
  421.         // If we are here it means that nothing good has been found
  422.         // Load second permission
  423.         if ($aclPermSociety !== null)
  424.         {
  425.             $acl $this->aclRepository->findOneBy(array(
  426.                 'function'        =>    $function,
  427.                 'permission'    =>    $aclPermSociety
  428.             ));
  429.             if ($acl !== null)
  430.             {
  431.                 if ($acl->getValue())
  432.                 {
  433.                     // A single positive answer is enough
  434.                     // In this case the good answer will be provided by the checkSociety
  435.                     return $this->checkSociety($rh$user);
  436.                 }
  437.             }
  438.         }
  439.         // If we are here, all hope is lost
  440.         return false;
  441.     }
  442.     private function canListAttachments(HumanResource $rhAccess $userAccessFunction $function)
  443.     {
  444.         // Several Acl_Permission may exist
  445.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ATTACHMENT_LIST);
  446.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ATTACHMENT_LIST_SOCIETY);
  447.         $aclPermBaseSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ATTACHMENT_LIST_BASE_SOCIETY);
  448.         // If all are null, exit
  449.         if ($aclPerm === null && $aclPermSociety === null && $aclPermBaseSociety === null)
  450.             return false;
  451.         // Get First one
  452.         if ($aclPerm !== null)
  453.         {
  454.             $acl $this->aclRepository->findOneBy(array(
  455.                 'function'        =>    $function,
  456.                 'permission'    =>    $aclPerm
  457.             ));
  458.             if ($acl !== null)
  459.             {
  460.                 if ($acl->getValue())
  461.                 {
  462.                     // A single positive answer is enough
  463.                     return true;
  464.                 }
  465.             }
  466.         }
  467.         // If we are here it means that nothing good has been found
  468.         // Load second permission
  469.         if ($aclPermSociety !== null)
  470.         {
  471.             $acl $this->aclRepository->findOneBy(array(
  472.                 'function'        =>    $function,
  473.                 'permission'    =>    $aclPermSociety
  474.             ));
  475.             if ($acl !== null)
  476.             {
  477.                 if ($acl->getValue())
  478.                 {
  479.                     // A single positive answer is enough
  480.                     // In this case the good answer will be provided by the checkSociety
  481.                     return $this->checkSociety($rh$user);
  482.                 }
  483.             }
  484.         }
  485.         // If we are here it means that nothing good has been found
  486.         // Load third permission
  487.         if ($aclPermBaseSociety !== null)
  488.         {
  489.             $acl $this->aclRepository->findOneBy(array(
  490.                 'function'        =>    $function,
  491.                 'permission'    =>    $aclPermBaseSociety
  492.             ));
  493.             if ($acl !== null)
  494.             {
  495.                 if ($acl->getValue())
  496.                 {
  497.                     // A single positive answer is enough
  498.                     // In this case the good answer will be provided by the checkBaseSociety
  499.                     return $this->checkBaseSociety($rh$user);
  500.                 }
  501.             }
  502.         }
  503.         // If we are here, all hope is lost
  504.         return false;
  505.     }
  506. }