src/Security/SupplierVoter.php line 73

Open in your IDE?
  1. <?php
  2. //------------------------------------------------------------------------------
  3. // src/Security/SupplierVoter.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\Supplier;
  14. use App\Entity\Security\Acl;
  15. use App\Entity\Security\AclPermission;
  16. use App\Entity\SocietyGroup;
  17. use App\Services\Config\ModuleTools;
  18. class SupplierVoter extends Voter
  19. {
  20.     //--------------------------------------------------------------------------------
  21.     // is_granted constants
  22.     const IS_ACTIVE "supplier_is_active";
  23.     const ADD "add_supplier";
  24.     const LISTING "list_suppliers";
  25.     const LISTING_SOCIETY "list_suppliers_society";
  26.     const LISTING_ANY "list_suppliers_any";
  27.     const VIEW "view_supplier";
  28.     const EDIT "edit_supplier";
  29.     // Task plan.io #3879
  30.     const LINK_TO_HUMAN_RESOURCE "link_supplier_human_resource";
  31.     const IS_GRANTED_CONSTANTS = array(
  32.         self::IS_ACTIVE,
  33.         self::ADD,
  34.         self::LISTING,
  35.         self::LISTING_SOCIETY,
  36.         self::LISTING_ANY,
  37.         self::VIEW,
  38.         self::EDIT,
  39.         self::LINK_TO_HUMAN_RESOURCE,
  40.     );
  41.     //--------------------------------------------------------------------------------
  42.     // acl constants
  43.     const ACL_PERM_ADD "supplier_add";
  44.     const ACL_PERM_LISTING "supplier_list";
  45.     const ACL_PERM_LISTING_SOCIETY "supplier_list_society";
  46.     const ACL_PERM_VIEW "supplier_view";
  47.     const ACL_PERM_VIEW_SOCIETY "supplier_view_society";
  48.     const ACL_PERM_EDIT "supplier_edit";
  49.     const ACL_PERM_EDIT_SOCIETY "supplier_edit_society";
  50.     const ACL_PERM_LINK "supplier_link_human_resource";
  51.     //--------------------------------------------------------------------------------
  52.     public function __construct(ManagerRegistry $doctrineModuleTools $moduleTools)
  53.     {
  54.         $this->em $doctrine->getManager();
  55.         $this->moduleTools $moduleTools;
  56.         $this->aclRepository $this->em->getRepository(Acl::class);
  57.         $this->aclPermissionRepository $this->em->getRepository(AclPermission::class);
  58.     }
  59.     // Plan.io Task #4453 [See AccessVoter for details]
  60.     public function supportsAttribute(string $attribute): bool
  61.     {
  62.         return in_array($attributeself::IS_GRANTED_CONSTANTStrue);
  63.     }
  64.     
  65.     protected function supports(string $attribute$subject null): bool
  66.     {
  67.         // if the attribute isn't one we support, return false
  68.         if (!in_array($attributeself::IS_GRANTED_CONSTANTS))
  69.         {
  70.             return false;
  71.         }
  72.         // only vote on Supplier objects inside this voter
  73.         if ($subject !== null && !$subject instanceof Supplier)
  74.         {
  75.             return false;
  76.         }
  77.         return true;
  78.     }
  79.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  80.     {
  81.         $user $token->getUser();
  82.         if (!$user instanceof Access)
  83.         {
  84.             // the user must be logged in; if not, deny access
  85.             return false;
  86.         }
  87.         // The user must have a function; if not deny access
  88.         $function $user->getFunction();
  89.         if ($function === null)        return false;
  90.         // Plan.io Task #3710 : Get current group
  91.         $currentGroup $user->getSocietyGroup();
  92.         if ($currentGroup === null)
  93.             return false;
  94.         // Module activated ?
  95.         if ($this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_SUPPLIER))
  96.         {
  97.             return false;
  98.         }
  99.         // you know $subject is a Supplier object, thanks to supports
  100.         /** @var Supplier $supplier */
  101.         $supplier $subject;
  102.         // Check current group affectation
  103.         if ($subject !== null)
  104.         {
  105.             $subjectSociety $subject->getSociety();
  106.             if ($subjectSociety === null)
  107.                 return false;
  108.             $subjectGroup $subjectSociety->getGroup();
  109.             if ($subjectGroup === null)
  110.                 return false;
  111.             if (!$currentGroup->equals($subjectGroup))
  112.                 return false;
  113.         }
  114.         switch ($attribute)
  115.         {
  116.             case self::IS_ACTIVE:
  117.                 return true;
  118.             case self::ADD:
  119.                 return $this->canAdd($user$function);
  120.             case self::LISTING:
  121.                 return $this->canList($user$function);
  122.             case self::LISTING_SOCIETY:
  123.                 return $this->canListSociety($user$function);
  124.             case self::LISTING_ANY:
  125.                 return $this->canListAny($user$function);
  126.             case self::VIEW:
  127.                 return $this->canView($supplier$user$function);
  128.             case self::EDIT:
  129.                 return $this->canEdit($supplier$user$function);
  130.             case self::LINK_TO_HUMAN_RESOURCE:
  131.                 return $this->canLinkToHumanResource($currentGroup$user$function);
  132.         }
  133.         throw new \LogicException('This code should not be reached!');
  134.     }
  135.     // $access is the user trying to load the resource
  136.     // $supplier is the resource being loaded
  137.     // Check if the Society of the resource
  138.     // belongs to the societies of the $access
  139.     private function checkSociety(Supplier $supplierAccess $access)
  140.     {
  141.         // Get all the societies of the access
  142.         $societies $access->getSocieties();
  143.         // Get the Society of the Supplier
  144.         $supplierSociety $supplier->getSociety();
  145.         if ($supplierSociety === null)
  146.             return false;
  147.         $found false;
  148.         foreach ($societies as $society)
  149.         {
  150.             if ($society->getId() == $supplierSociety->getId())
  151.             {
  152.                 $found true;
  153.                 break;
  154.             }
  155.         }
  156.         return $found;
  157.     }
  158.     private function canAdd(Access $userAccessFunction $function)
  159.     {
  160.         // Get Acl_Permission
  161.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ADD);
  162.         if ($aclPerm === null)        return false;
  163.         // Get Acl
  164.         $acl $this->aclRepository->findOneBy(array(
  165.             'function'        =>    $function,
  166.             'permission'    =>    $aclPerm
  167.         ));
  168.         if ($acl === null)        return false;
  169.         // Since only one acl type can exist
  170.         // we can return the result of the acl_permission
  171.         return $acl->getValue();
  172.     }
  173.     private function canList(Access $userAccessFunction $function)
  174.     {
  175.         // Get Acl_Permission
  176.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  177.         if ($aclPerm === null)        return false;
  178.         // Get Acl
  179.         $acl $this->aclRepository->findOneBy(array(
  180.             'function'        =>    $function,
  181.             'permission'    =>    $aclPerm
  182.         ));
  183.         if ($acl === null)        return false;
  184.         // Since only one acl type can exist
  185.         // we can return the result of the acl_permission
  186.         return $acl->getValue();
  187.     }
  188.     private function canListSociety(Access $userAccessFunction $function)
  189.     {
  190.         // Get Acl_Permission
  191.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  192.         if ($aclPerm === null)        return false;
  193.         // Get Acl
  194.         $acl $this->aclRepository->findOneBy(array(
  195.             'function'        =>    $function,
  196.             'permission'    =>    $aclPerm
  197.         ));
  198.         if ($acl === null)        return false;
  199.         // Since only one acl type can exist
  200.         // we can return the result of the acl_permission
  201.         // Further filtering is done in the Controller
  202.         return $acl->getValue();
  203.     }
  204.     private function canListAny(Access $userAccessFunction $function)
  205.     {
  206.         // Two Acl_Permission may exist
  207.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  208.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  209.         // If all are null, exit
  210.         if ($aclPerm === null && $aclPermSociety === null)
  211.             return false;
  212.         // Get First one
  213.         if ($aclPerm !== null)
  214.         {
  215.             $acl $this->aclRepository->findOneBy(array(
  216.                 'function'        =>    $function,
  217.                 'permission'    =>    $aclPerm
  218.             ));
  219.             if ($acl !== null)
  220.             {
  221.                 if ($acl->getValue())
  222.                 {
  223.                     // A single positive answer is enough
  224.                     return true;
  225.                 }
  226.             }
  227.         }
  228.         // If we are here it means that nothing good has been found
  229.         // Load second permission
  230.         if ($aclPermSociety !== null)
  231.         {
  232.             $acl $this->aclRepository->findOneBy(array(
  233.                 'function'        =>    $function,
  234.                 'permission'    =>    $aclPermSociety
  235.             ));
  236.             if ($acl !== null)
  237.             {
  238.                 if ($acl->getValue())
  239.                 {
  240.                     // A single positive answer is enough
  241.                     return true;
  242.                 }
  243.             }
  244.         }
  245.         // If we are here, all hope is lost
  246.         return false;
  247.     }
  248.     private function canView(Supplier $supplierAccess $userAccessFunction $function)
  249.     {
  250.         // Get Acl_Permissions
  251.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW);
  252.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_SOCIETY);
  253.         // If all are null, exit
  254.         if ($aclPerm === null && $aclPermSociety === null)
  255.             return false;
  256.         // Get First one
  257.         if ($aclPerm !== null)
  258.         {
  259.             $acl $this->aclRepository->findOneBy(array(
  260.                 'function'        =>    $function,
  261.                 'permission'    =>    $aclPerm
  262.             ));
  263.             if ($acl !== null)
  264.             {
  265.                 if ($acl->getValue())
  266.                 {
  267.                     // A single positive answer is enough
  268.                     return true;
  269.                 }
  270.             }
  271.         }
  272.         // If we are here it means that nothing good has been found
  273.         // Load second permission
  274.         if ($aclPermSociety !== null)
  275.         {
  276.             $acl $this->aclRepository->findOneBy(array(
  277.                 'function'        =>    $function,
  278.                 'permission'    =>    $aclPermSociety
  279.             ));
  280.             if ($acl !== null)
  281.             {
  282.                 if ($acl->getValue())
  283.                 {
  284.                     // A single positive answer is enough
  285.                     // In this case the good answer will be provided by the checkSociety
  286.                     return $this->checkSociety($supplier$user);
  287.                 }
  288.             }
  289.         }
  290.         // If we are here, all hope is lost
  291.         return false;
  292.     }
  293.     private function canEdit(Supplier $supplierAccess $userAccessFunction $function)
  294.     {
  295.         // Three Acl_Permission may exist
  296.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT);
  297.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT_SOCIETY);
  298.         // If all are null, exit
  299.         if ($aclPerm === null && $aclPermSociety === null)
  300.             return false;
  301.         // Get First one
  302.         if ($aclPerm !== null)
  303.         {
  304.             $acl $this->aclRepository->findOneBy(array(
  305.                 'function'        =>    $function,
  306.                 'permission'    =>    $aclPerm
  307.             ));
  308.             if ($acl !== null)
  309.             {
  310.                 if ($acl->getValue())
  311.                 {
  312.                     // A single positive answer is enough
  313.                     return true;
  314.                 }
  315.             }
  316.         }
  317.         // If we are here it means that nothing good has been found
  318.         // Load second permission
  319.         if ($aclPermSociety !== null)
  320.         {
  321.             $acl $this->aclRepository->findOneBy(array(
  322.                 'function'        =>    $function,
  323.                 'permission'    =>    $aclPermSociety
  324.             ));
  325.             if ($acl !== null)
  326.             {
  327.                 if ($acl->getValue())
  328.                 {
  329.                     // A single positive answer is enough
  330.                     // In this case the good answer will be provided by the checkSociety
  331.                     return $this->checkSociety($supplier$user);
  332.                 }
  333.             }
  334.         }
  335.         // If we are here, all hope is lost
  336.         return false;
  337.     }
  338.     // Task plan.io #3879
  339.     private function canLinkToHumanResource(SocietyGroup $societyGroupAccess $userAccessFunction $function)
  340.     {
  341.         // Check module humanResource is active
  342.         if ($this->moduleTools->isInactiveByCode($societyGroupModule::MODULE_HUMAN_RESOURCE))
  343.         {
  344.             return false;
  345.         }
  346.         // Get Acl_Permission
  347.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LINK);
  348.         if ($aclPerm === null)        return false;
  349.         // Get Acl
  350.         $acl $this->aclRepository->findOneBy(array(
  351.             'function'        =>    $function,
  352.             'permission'    =>    $aclPerm
  353.         ));
  354.         if ($acl === null)        return false;
  355.         // Since only one acl type can exist
  356.         // we can return the result of the acl_permission
  357.         return $acl->getValue();
  358.     }
  359. }