src/Security/LogVoter.php line 39

Open in your IDE?
  1. <?php
  2. //------------------------------------------------------------------------------
  3. // src/Security/LogVoter.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\Common\Collections\ArrayCollection;
  9. use Doctrine\Persistence\ManagerRegistry;
  10. use App\Entity\Access;
  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. // use Icod\PlatformBundle\Entity\Log;
  18. class LogVoter extends Voter
  19. {
  20.     const LISTING "list_logs";
  21.     const LISTING_SOCIETY "list_logs_society";
  22.     const LISTING_ANY "list_logs_any";
  23.     const IS_GRANTED_CONSTANTS = array(
  24.         self::LISTING,
  25.         self::LISTING_SOCIETY,
  26.         self::LISTING_ANY,
  27.     );
  28.     //--------------------------------------------------------------------------------
  29.     // acl constants
  30.     const ACL_PERM_LISTING "log_list";
  31.     const ACL_PERM_LISTING_SOCIETY "log_list_society";
  32.     public function __construct(ManagerRegistry $doctrineModuleTools $moduleTools)
  33.     {
  34.         $this->em $doctrine->getManager();
  35.         $this->moduleTools $moduleTools;
  36.         $this->aclRepository $this->em->getRepository(Acl::class);
  37.         $this->aclPermissionRepository $this->em->getRepository(AclPermission::class);
  38.     }
  39.     // Plan.io Task #4453 [See AccessVoter for details]
  40.     public function supportsAttribute(string $attribute): bool
  41.     {
  42.         return in_array($attributeself::IS_GRANTED_CONSTANTStrue);
  43.     }
  44.     protected function supports(string $attribute$subject): bool
  45.     {
  46.         // if the attribute isn't one we support, return false
  47.         if (!in_array($attributeself::IS_GRANTED_CONSTANTS))
  48.         {
  49.             return false;
  50.         }
  51.         return true;
  52.     }
  53.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  54.     {
  55.         $user $token->getUser();
  56.         if (!$user instanceof Access)
  57.         {
  58.             // the user must be logged in; if not, deny access
  59.             return false;
  60.         }
  61.         // The user must have a function; if not deny access
  62.         $function $user->getFunction();
  63.         if ($function === null)        return false;
  64.         // Plan.io Task #3710 : Get current group
  65.         $currentGroup $user->getSocietyGroup();
  66.         if ($currentGroup === null)
  67.             return false;
  68.         // you know $subject is a Log object, thanks to supports
  69.         /** @var Log $log */
  70.         $log $subject;
  71.         switch ($attribute)
  72.         {
  73.             case self::LISTING:
  74.                 return $this->canList($user$function);
  75.             case self::LISTING_SOCIETY:
  76.                 return $this->canListSociety($user$function);
  77.             case self::LISTING_ANY:
  78.                 return $this->canListAny($user$function);
  79.         }
  80.         throw new \LogicException('This code should not be reached!');
  81.     }
  82.     // Check if one of the societies of the access
  83.     // belongs to the societies of the action's group
  84.     private function checkSociety(Log $logAccess $access)
  85.     {
  86.         // Get all the societies of the access
  87.         $accessSocieties $access->getSocieties();
  88.         if (count($accessSocieties) < 1)
  89.             return false;
  90.         // Get the corresponding groups
  91.         $accessGroups = new \Doctrine\Common\Collections\ArrayCollection();
  92.         foreach ($accessSocieties as $s)
  93.              if ($s->getGroup() !== null)
  94.                 if ($accessGroups->contains($s->getGroup()) == false)
  95.                     $accessGroups[] = $s->getGroup();
  96.         $logAccess $log->getAccess();
  97.         if ($logAccess !== null)
  98.         {
  99.             // Logs from PLATFORM
  100.             // Get the societies for the action's access
  101.             $logAccessSocieties $logAccess->getSocieties();
  102.             if (count($logAccessSocieties) < 1)
  103.                 return false;
  104.             // Get the corresponding groups
  105.             $logAccessGroups = new \Doctrine\Common\Collections\ArrayCollection();
  106.             foreach ($logAccessSocieties as $s)
  107.                  if ($s->getGroup() !== null)
  108.                     if ($logAccessGroups->contains($s->getGroup()) == false)
  109.                         $logAccessGroups[] = $s->getGroup();
  110.             foreach ($accessGroups as $as)
  111.             {
  112.                 foreach ($logAccessGroups as $ps)
  113.                 {
  114.                     if ($as->getId() == $ps->getId())
  115.                     {
  116.                         return true;
  117.                     }
  118.                 }
  119.             }
  120.             return false;
  121.         }
  122.         return false;
  123.     }
  124.     private function canList(Access $accessAccessFunction $function)
  125.     {
  126.         // Restrictions are also applied in the Controller
  127.         // But this helps speeding page loading if the access is not even allowed to load the page
  128.         // (ie. if it has no list privileges whatsoever)
  129.         // Get Acl_Permission
  130.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  131.         if ($aclPerm === null)        return false;
  132.         // Get Acl
  133.         $acl $this->aclRepository->findOneBy(array(
  134.             'function'        =>    $function,
  135.             'permission'    =>    $aclPerm
  136.         ));
  137.         if ($acl === null)        return false;
  138.         // Since only one list type can exist for the Logs,
  139.         // we can return the result of the acl_permission
  140.         return $acl->getValue();
  141.     }
  142.     private function canListSociety(Access $accessAccessFunction $function)
  143.     {
  144.         // Get Acl_Permission
  145.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  146.         if ($aclPerm === null)        return false;
  147.         // Get Acl
  148.         $acl $this->aclRepository->findOneBy(array(
  149.             'function'        =>    $function,
  150.             'permission'    =>    $aclPerm
  151.         ));
  152.         if ($acl === null)        return false;
  153.         // Since only one acl type can exist
  154.         // we can return the result of the acl_permission
  155.         // Further filtering is done in the Controller
  156.         return $acl->getValue();
  157.     }
  158.     private function canListAny(Access $accessAccessFunction $function)
  159.     {
  160.         // Several Acl_Permission may exist
  161.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  162.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  163.         // If all are null, exit
  164.         if ($aclPerm === null && $aclPermSociety === null)
  165.             return false;
  166.         // Get First one
  167.         if ($aclPerm !== null)
  168.         {
  169.             $acl $this->aclRepository->findOneBy(array(
  170.                 'function'        =>    $function,
  171.                 'permission'    =>    $aclPerm
  172.             ));
  173.             if ($acl !== null)
  174.             {
  175.                 if ($acl->getValue())
  176.                 {
  177.                     // A single positive answer is enough
  178.                     return true;
  179.                 }
  180.             }
  181.         }
  182.         // If we are here it means that nothing good has been found
  183.         // Load second permission
  184.         if ($aclPermSociety !== null)
  185.         {
  186.             $acl $this->aclRepository->findOneBy(array(
  187.                 'function'        =>    $function,
  188.                 'permission'    =>    $aclPermSociety
  189.             ));
  190.             if ($acl !== null)
  191.             {
  192.                 if ($acl->getValue())
  193.                 {
  194.                     // A single positive answer is enough
  195.                     return true;
  196.                 }
  197.             }
  198.         }
  199.         // If we are here, all hope is lost
  200.         return false;
  201.     }
  202. }