src/Security/WebappMakerVoter.php line 57

Open in your IDE?
  1. <?php
  2. //------------------------------------------------------------------------------
  3. // src/Security/WebappMakerVoter.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\Config\OptionConfig;
  13. use App\Entity\HR\AccessFunction;
  14. use App\Entity\Security\Acl;
  15. use App\Entity\Security\AclPermission;
  16. use App\Entity\WebappMaker\Template as WebappTemplate;
  17. use App\Services\Config\ModuleTools;
  18. use App\Services\Config\OptionConfigTools;
  19. class WebappMakerVoter extends Voter
  20. {
  21.     // Allow authors as managers
  22.     //--------------------------------------------------------------------------------
  23.     // is_granted constants
  24.     const IS_ACTIVE "webapp_maker_is_active";
  25.     const ADD "add_webapp_template";
  26.     const EDIT "edit_webapp_template";
  27.     const DELETE "delete_webapp_template";
  28.     const DO_ANY "do_any_webapp_template";
  29.     const IS_GRANTED_CONSTANTS = array(
  30.         self::IS_ACTIVE,
  31.         self::ADD,
  32.         self::EDIT,
  33.         self::DELETE,
  34.         self::DO_ANY,
  35.     );
  36.     //--------------------------------------------------------------------------------
  37.     // acl constants
  38.     const ACL_PERM_ADD "webapp_maker_template_add";
  39.     const ACL_PERM_EDIT "webapp_maker_template_edit";
  40.     const ACL_PERM_DELETE "webapp_maker_template_delete";
  41.     //--------------------------------------------------------------------------------
  42.     public function __construct(ManagerRegistry $doctrineModuleTools $moduleToolsOptionConfigTools $optionConfigTools)
  43.     {
  44.         $this->em $doctrine->getManager();
  45.         $this->moduleTools $moduleTools;
  46.         $this->optionConfigTools $optionConfigTools;
  47.         $this->aclRepository $this->em->getRepository(Acl::class);
  48.         $this->aclPermissionRepository $this->em->getRepository(AclPermission::class);
  49.     }
  50.     // Plan.io Task #4453 [See AccessVoter for details]
  51.     public function supportsAttribute(string $attribute): bool
  52.     {
  53.         return in_array($attributeself::IS_GRANTED_CONSTANTStrue);
  54.     }
  55.     protected function supports(string $attribute$subject null): bool
  56.     {
  57.         // if the attribute isn't one we support, return false
  58.         if (!in_array($attributeself::IS_GRANTED_CONSTANTS))
  59.         {
  60.             return false;
  61.         }
  62.         // only vote on WebappTemplate or Task objects inside this voter
  63.         if ($subject !== null && !($subject instanceof WebappTemplate))
  64.         {
  65.             return false;
  66.         }
  67.         return true;
  68.     }
  69.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  70.     {
  71.         $user $token->getUser();
  72.         if (!$user instanceof Access)
  73.         {
  74.             // the user must be logged in; if not, deny access
  75.             return false;
  76.         }
  77.         // The user must have a function; if not deny access
  78.         $function $user->getFunction();
  79.         if ($function === null)        return false;
  80.         // Plan.io Task #3710 : Get current group
  81.         $currentGroup $user->getSocietyGroup();
  82.         if ($currentGroup === null)
  83.             return false;
  84.         $this->currentGroup $currentGroup;
  85.         // Module activated ?
  86.         if ($this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_DOCUMENT))
  87.         {
  88.             return false;
  89.         }
  90.         // Option activated for this SocietyGroup ?
  91.         $userSocietyGroup $user->getSocietyGroup();
  92.         if ($userSocietyGroup === null)
  93.         {
  94.             return false;
  95.         }
  96.         if (!$this->optionConfigTools->isActive_WebappMaker($userSocietyGroup))
  97.         {
  98.             return false;
  99.         }
  100.         // you know $subject is a WebappTemplate object, thanks to supports
  101.         /** @var WebappTemplate $template */
  102.         $template $subject;
  103.         // Check current group affectation
  104.         if ($subject !== null && $subject instanceof WebappTemplate)
  105.         {
  106.             $subjectGroup $subject->getSocietyGroup();
  107.             if ($subjectGroup === null)
  108.                 return false;
  109.             if (!$currentGroup->equals($subjectGroup))
  110.                 return false;
  111.         }
  112.         switch ($attribute)
  113.         {
  114.             case self::IS_ACTIVE:
  115.                 return true;
  116.             case self::ADD:
  117.             {
  118.                 return $this->canAdd($user$function);
  119.             }
  120.             case self::EDIT:
  121.             {
  122.                 return $this->canEdit($template$user$function);
  123.             }
  124.             case self::DELETE:
  125.             {
  126.                 return $this->canDelete($template$user$function);
  127.             }
  128.             case self::DO_ANY:
  129.             {
  130.                 return $this->canDoAny($user$function);
  131.             }
  132.         }
  133.         throw new \LogicException('This code should not be reached!');
  134.     }
  135.     private function canDoAny(Access $userAccessFunction $function)
  136.     {
  137.         // Several AclPermission may exist
  138.         $aclPermAdd $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ADD);
  139.         $aclPermEdit $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT);
  140.         $aclPermDelete $this->aclPermissionRepository->findOneByName(self::ACL_PERM_DELETE);
  141.         // If both are null, exit
  142.         if ($aclPermAdd === null && $aclPermEdit === null && $aclPermDelete === null)
  143.             return false;
  144.         // Get First one
  145.         if ($aclPermAdd !== null)
  146.         {
  147.             $acl $this->aclRepository->findOneBy(array(
  148.                 'function'        =>    $function,
  149.                 'permission'    =>    $aclPermAdd
  150.             ));
  151.             if ($acl !== null)
  152.             {
  153.                 if ($acl->getValue())
  154.                 {
  155.                     // A single positive answer is enough
  156.                     return true;
  157.                 }
  158.             }
  159.         }
  160.         // If we are here it means that nothing good has been found
  161.         // Load second permission
  162.         if ($aclPermEdit !== null)
  163.         {
  164.             $acl $this->aclRepository->findOneBy(array(
  165.                 'function'        =>    $function,
  166.                 'permission'    =>    $aclPermEdit
  167.             ));
  168.             if ($acl !== null)
  169.             {
  170.                 if ($acl->getValue())
  171.                 {
  172.                     // A single positive answer is enough
  173.                     return true;
  174.                 }
  175.             }
  176.         }
  177.         // If we are here it means that nothing good has been found
  178.         // Load third permission
  179.         if ($aclPermDelete !== null)
  180.         {
  181.             $acl $this->aclRepository->findOneBy(array(
  182.                 'function'        =>    $function,
  183.                 'permission'    =>    $aclPermDelete
  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.     private function canAdd(Access $userAccessFunction $function)
  198.     {
  199.         // Get Acl_Permission
  200.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ADD);
  201.         if ($aclPerm === null)        return false;
  202.         // Get Acl
  203.         $acl $this->aclRepository->findOneBy(array(
  204.             'function'        =>    $function,
  205.             'permission'    =>    $aclPerm
  206.         ));
  207.         if ($acl === null)        return false;
  208.         // Since only one acl type can exist
  209.         // we can return the result of the acl_permission
  210.         return $acl->getValue();
  211.     }
  212.     private function canEdit(WebappTemplate $templateAccess $userAccessFunction $function)
  213.     {
  214.         // Allow authors to edit their own templates
  215.         if ($template->getAuthor() !== null && $template->getAuthor()->equals($user))
  216.         {
  217.             return true;
  218.         }
  219.         // Get Acl_Permission
  220.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT);
  221.         if ($aclPerm === null)        return false;
  222.         // Get Acl
  223.         $acl $this->aclRepository->findOneBy(array(
  224.             'function'        =>    $function,
  225.             'permission'    =>    $aclPerm
  226.         ));
  227.         if ($acl === null)        return false;
  228.         // Since only one acl type can exist
  229.         // we can return the result of the acl_permission
  230.         return $acl->getValue();
  231.     }
  232.     private function canDelete(WebappTemplate $templateAccess $userAccessFunction $function)
  233.     {
  234.         // Allow authors to delete their own templates
  235.         if ($template->getAuthor() !== null && $template->getAuthor()->equals($user))
  236.         {
  237.             return true;
  238.         }
  239.         // Get Acl_Permission
  240.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_DELETE);
  241.         if ($aclPerm === null)        return false;
  242.         // Get Acl
  243.         $acl $this->aclRepository->findOneBy(array(
  244.             'function'        =>    $function,
  245.             'permission'    =>    $aclPerm
  246.         ));
  247.         if ($acl === null)        return false;
  248.         // Since only one acl type can exist
  249.         // we can return the result of the acl_permission
  250.         return $acl->getValue();
  251.     }
  252. }