src/Security/DocumentVoter.php line 139

Open in your IDE?
  1. <?php
  2. //------------------------------------------------------------------------------
  3. // src/Security/DocumentVoter.php
  4. // OK #4453 : VoterCache (isActive, listings)
  5. //------------------------------------------------------------------------------
  6. namespace App\Security;
  7. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  8. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  9. use Doctrine\Persistence\ManagerRegistry;
  10. use App\Entity\Access;
  11. use App\Entity\APIRest\AccessAPI;
  12. use App\Entity\Config\Config;
  13. use App\Entity\Config\Module;
  14. use App\Entity\Config\OptionConfig;
  15. use App\Entity\HR\AccessFunction;
  16. use App\Entity\Mission\MissionTarget;
  17. use App\Entity\Planning\Task;
  18. use App\Entity\Security\AccessCacheAcl;
  19. use App\Entity\Security\Acl;
  20. use App\Entity\Security\AclPermission;
  21. use App\Entity\Webapp\Document;
  22. use App\Entity\Webapp\Components\DocumentRule;
  23. use App\Entity\Webapp\Components\DocumentTargetRule;
  24. use App\Entity\Webapp\Components\DocumentType;
  25. use App\Services\Config\ModuleTools;
  26. use App\Services\Config\OptionConfigTools;
  27. class DocumentVoter extends Voter
  28. {
  29.     // Allow authors as managers
  30.     //--------------------------------------------------------------------------------
  31.     // is_granted constants
  32.     const IS_ACTIVE "document_is_active";
  33.     const ADD "add_document";
  34.     const ADD_RFI "add_document_rfi";
  35.     const ADD_RFI_GC "add_document_rfi_gc";
  36.     const ADD_ANOMALY "add_document_anomaly";
  37.     const ADD_ANOMALY_GC "add_document_anomaly_gc";
  38.     const ADD_REPORT "add_document_report";
  39.     const ADD_KVISIT "add_document_kvisit";
  40.     const ADD_CUSTOM_REPORT "add_document_custom_report";
  41.     const LISTING "list_documents";
  42.     const LISTING_SOCIETY "list_documents_society";
  43.     const LISTING_MANAGER "list_documents_manager";
  44.     const LISTING_ANY "list_documents_any";
  45.     const LISTING_ARCHIVED "list_archived_documents";
  46.     const LISTING_ARCHIVED_SOCIETY "list_archived_documents_society";
  47.     const LISTING_ARCHIVED_MANAGER "list_archived_documents_manager";
  48.     const LISTING_ARCHIVED_ANY "list_archived_documents_any";
  49.     const VIEW_PDF "view_pdf_document";
  50.     const ARCHIVE "archive_document";
  51.     const IS_GRANTED_CONSTANTS = array(
  52.         self::IS_ACTIVE,
  53.         self::ADD,
  54.         self::ADD_RFI,
  55.         self::ADD_RFI_GC,
  56.         self::ADD_ANOMALY,
  57.         self::ADD_ANOMALY_GC,
  58.         self::ADD_REPORT,
  59.         self::ADD_KVISIT,
  60.         self::ADD_CUSTOM_REPORT,
  61.         self::LISTING,
  62.         self::LISTING_SOCIETY,
  63.         self::LISTING_MANAGER,
  64.         self::LISTING_ANY,
  65.         self::LISTING_ARCHIVED,
  66.         self::LISTING_ARCHIVED_SOCIETY,
  67.         self::LISTING_ARCHIVED_MANAGER,
  68.         self::LISTING_ARCHIVED_ANY,
  69.         self::VIEW_PDF,
  70.         self::ARCHIVE,
  71.     );
  72.     const IS_GRANTED_CONSTANTS_SHARING_EXCEPTION = array(
  73.         self::VIEW_PDF,
  74.     );
  75.     // Plan.io Task #4453
  76.     const IS_GRANTED_FROM_CACHE = [
  77.         self::IS_ACTIVE,
  78.         self::LISTING,
  79.         self::LISTING_SOCIETY,
  80.         self::LISTING_MANAGER,
  81.         self::LISTING_ANY,
  82.         self::LISTING_ARCHIVED,
  83.         self::LISTING_ARCHIVED_SOCIETY,
  84.         self::LISTING_ARCHIVED_MANAGER,
  85.         self::LISTING_ARCHIVED_ANY,
  86.     ];
  87.     //--------------------------------------------------------------------------------
  88.     // acl constants
  89.     const ACL_PERM_ADD "webapp_doc_add";
  90.     const ACL_PERM_LISTING "webapp_doc_list";
  91.     const ACL_PERM_LISTING_SOCIETY "webapp_doc_list_society";
  92.     const ACL_PERM_LISTING_MANAGER "webapp_doc_list_manager";
  93.     const ACL_PERM_VIEW_PDF "webapp_doc_pdf_view";
  94.     const ACL_PERM_VIEW_PDF_SOCIETY "webapp_doc_pdf_view_society";
  95.     const ACL_PERM_VIEW_PDF_MANAGER "webapp_doc_pdf_view_manager";
  96.     const ACL_PERM_VIEW_PDF_CLIENT_MANAGER "webapp_doc_pdf_view_ind_manager";
  97.     // Archive
  98.     const ACL_PERM_ARCHIVE "webapp_doc_archive";
  99.     const ACL_PERM_ARCHIVE_SOCIETY "webapp_doc_archive_society";
  100.     const ACL_PERM_ARCHIVE_MANAGER "webapp_doc_archive_manager";
  101.     // Archived : List
  102.     const ACL_PERM_LISTING_ARCHIVED "webapp_doc_list_archived";
  103.     const ACL_PERM_LISTING_ARCHIVED_SOCIETY "webapp_doc_list_archived_society";
  104.     const ACL_PERM_LISTING_ARCHIVED_MANAGER "webapp_doc_list_archived_manager";
  105.     // Archived : View
  106.     const ACL_PERM_VIEW_PDF_ARCHIVED "webapp_doc_pdf_view_archived";
  107.     const ACL_PERM_VIEW_PDF_ARCHIVED_SOCIETY "webapp_doc_pdf_view_archived_society";
  108.     const ACL_PERM_VIEW_PDF_ARCHIVED_MANAGER "webapp_doc_pdf_view_archived_manager";
  109.     const ACL_PERM_VIEW_PDF_ARCHIVED_CLIENT_MANAGER "webapp_doc_pdf_view_archived_ind_manager";
  110.     //--------------------------------------------------------------------------------
  111.     public function __construct(ManagerRegistry $doctrineModuleTools $moduleToolsOptionConfigTools $optionConfigTools)
  112.     {
  113.         $this->em $doctrine->getManager();
  114.         $this->moduleTools $moduleTools;
  115.         $this->optionConfigTools $optionConfigTools;
  116.         $this->aclRepository $this->em->getRepository(Acl::class);
  117.         $this->aclPermissionRepository $this->em->getRepository(AclPermission::class);
  118.     }
  119.     // Plan.io Task #4453 [See AccessVoter for details]
  120.     public function supportsAttribute(string $attribute): bool
  121.     {
  122.         return in_array($attributeself::IS_GRANTED_CONSTANTStrue);
  123.     }
  124.     
  125.     protected function supports(string $attribute$subject null): bool
  126.     {
  127.         // if the attribute isn't one we support, return false
  128.         if (!in_array($attributeself::IS_GRANTED_CONSTANTS))
  129.         {
  130.             return false;
  131.         }
  132.         // only vote on Document or Task objects inside this voter
  133.         if ($subject !== null && !($subject instanceof Document || $subject instanceof Task))
  134.         {
  135.             return false;
  136.         }
  137.         return true;
  138.     }
  139.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  140.     {
  141.         $user $token->getUser();
  142.         $originalUserIsAccess true;
  143.         // Plan.io Task #3707
  144.         if ($user instanceof AccessAPI)
  145.         {
  146.             if ($user->getAccess() === null)
  147.             {
  148.                 return false;
  149.             }
  150.             $user $user->getAccess();
  151.             $originalUserIsAccess false;
  152.         }
  153.         // Plan.io Task #4453 : Bypass everything, but only for Access users
  154.         // if ($originalUserIsAccess && AccessCacheAcl::voterCacheIsActive())
  155.         // {
  156.         //     if (in_array($attribute, self::IS_GRANTED_FROM_CACHE))
  157.         //     {
  158.         //         $accessCacheAcl = $this->em->getRepository(AccessCacheAcl::class)->findOneBy(array(
  159.         //             'access'    =>  $user,
  160.         //             'aclKey'    =>  $attribute,
  161.         //         ));
  162.         //         if ($accessCacheAcl !== null)
  163.         //         {
  164.         //             return $accessCacheAcl->isActive();
  165.         //         }
  166.         //     }
  167.         // }
  168.         // Plan.io Task #3707
  169.         // At this point $user is an object of Access type
  170.         // even if the $token->getUser() is AccessAPI
  171.         if (!$user instanceof Access)
  172.         {
  173.             // the user must be logged in; if not, deny access
  174.             return false;
  175.         }
  176.         // The user must have a function; if not deny access
  177.         $function $user->getFunction();
  178.         if ($function === null)        return false;
  179.         // Plan.io Task #3710 : Get current group
  180.         $currentGroup $user->getSocietyGroup();
  181.         if ($currentGroup === null)
  182.             return false;
  183.         $this->currentGroup $currentGroup;
  184.         // Module activated ?
  185.         if ($this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_DOCUMENT))
  186.         {
  187.             return false;
  188.         }
  189.         // This one also needs the planning
  190.         if ($this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_PLANNING))
  191.         {
  192.             return false;
  193.         }
  194.         // This one also needs clients or clients light
  195.         if ($this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_CLIENT) && $this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_CLIENT_LIGHT))
  196.         {
  197.             return false;
  198.         }
  199.         // you know $subject is a Document object, thanks to supports
  200.         /** @var Document $doc */
  201.         $doc $subject;
  202.         // Check current group affectation
  203.         if ($subject !== null && $subject instanceof Document)
  204.         {
  205.             $docSociety $subject->getSociety();
  206.             if ($docSociety === null)
  207.                 return false;
  208.             $docSocietyGroup $docSociety->getGroup();
  209.             if ($docSocietyGroup === null)
  210.                 return false;
  211.             // if (!$currentGroup->equals($docSocietyGroup))
  212.             //     return false;
  213.             if (!in_array($attributeself::IS_GRANTED_CONSTANTS_SHARING_EXCEPTION))
  214.             {
  215.                 // Just check currentGroup
  216.                 if (!$currentGroup->equals($docSocietyGroup))
  217.                     return false;
  218.             }
  219.             else
  220.             {
  221.                 // Take sharing into account
  222.                 // If the document belongs to a mission that was created by the currentGroup
  223.                 // (document.mission.societyGroupAuthor == currentGroup)
  224.                 // Then it can see the document
  225.                 if (!$currentGroup->equals($docSocietyGroup))
  226.                 {
  227.                     if ($doc->getMission() !== null)
  228.                     {
  229.                         $missionSocietyGroupAuthor $doc->getMission()->getSocietyGroupAuthor();
  230.                         if (!$currentGroup->equals($missionSocietyGroupAuthor))
  231.                         {
  232.                             return false;
  233.                         }
  234.                     }
  235.                 }
  236.             }
  237.         }
  238.         switch ($attribute)
  239.         {
  240.             case self::IS_ACTIVE:
  241.                 return true;
  242.             case self::ADD:
  243.             {
  244.                 if ($subject !== null && $subject instanceof Task)
  245.                 {
  246.                     $task $subject;
  247.                     return $this->canAdd($user$function$task);
  248.                 }
  249.                 return $this->canAdd($user$function);
  250.             }
  251.             case self::ADD_RFI:
  252.             {
  253.                 if ($subject !== null && $subject instanceof Task)
  254.                 {
  255.                     $task $subject;
  256.                     if ($this->canAdd($user$function$task))
  257.                     {
  258.                         return $this->canAddDocumentType($user$function$taskDocumentType::CODE_RFI);
  259.                     }
  260.                 }
  261.                 return false;
  262.             }
  263.             case self::ADD_RFI_GC:
  264.             {
  265.                 if ($subject !== null && $subject instanceof Task)
  266.                 {
  267.                     $task $subject;
  268.                     if ($this->canAdd($user$function$task))
  269.                     {
  270.                         return $this->canAddDocumentType($user$function$taskDocumentType::CODE_RFI_GC);
  271.                     }
  272.                 }
  273.                 return false;
  274.             }
  275.             case self::ADD_ANOMALY:
  276.             {
  277.                 if ($subject !== null && $subject instanceof Task)
  278.                 {
  279.                     $task $subject;
  280.                     if ($this->canAdd($user$function$task))
  281.                     {
  282.                         return $this->canAddDocumentType($user$function$taskDocumentType::CODE_ANOMALY);
  283.                     }
  284.                 }
  285.                 return false;
  286.             }
  287.             case self::ADD_ANOMALY_GC:
  288.             {
  289.                 if ($subject !== null && $subject instanceof Task)
  290.                 {
  291.                     $task $subject;
  292.                     if ($this->canAdd($user$function$task))
  293.                     {
  294.                         return $this->canAddDocumentType($user$function$taskDocumentType::CODE_ANOMALY_GC);
  295.                     }
  296.                 }
  297.                 return false;
  298.             }
  299.             case self::ADD_REPORT:
  300.             {
  301.                 if ($subject !== null && $subject instanceof Task)
  302.                 {
  303.                     $task $subject;
  304.                     if ($this->canAdd($user$function$task))
  305.                     {
  306.                         return $this->canAddDocumentType($user$function$taskDocumentType::CODE_REPORT);
  307.                     }
  308.                 }
  309.                 return false;
  310.             }
  311.             case self::ADD_KVISIT:
  312.             {
  313.                 if ($this->optionConfigTools->isActive_webappKvisitReport($this->currentGroup))
  314.                 {
  315.                     if ($subject !== null && $subject instanceof Task)
  316.                     {
  317.                         $task $subject;
  318.                         if ($this->canAdd($user$function$task))
  319.                         {
  320.                             return $this->canAddDocumentType($user$function$taskDocumentType::CODE_KVISIT_REPORT);
  321.                         }
  322.                     }
  323.                 }
  324.                 return false;
  325.             }
  326.             case self::ADD_CUSTOM_REPORT:
  327.             {
  328.                 if ($subject !== null && $subject instanceof Task)
  329.                 {
  330.                     $task $subject;
  331.                     if ($this->canAdd($user$function$task))
  332.                     {
  333.                         return $this->canAddCustomReport($user$function$task);
  334.                     }
  335.                 }
  336.                 return false;
  337.             }
  338.             case self::LISTING:
  339.                 return $this->canList($user$function);
  340.             case self::LISTING_SOCIETY:
  341.                 return $this->canListSociety($user$function);
  342.             case self::LISTING_MANAGER:
  343.                 return $this->canListManager($user$function);
  344.             case self::LISTING_ANY:
  345.                 return $this->canListAny($user$function);
  346.             case self::VIEW_PDF:
  347.                 return $this->canViewPdf($doc$user$function);
  348.             case self::ARCHIVE:
  349.                 return $this->canArchive($doc$user$function);
  350.             case self::LISTING_ARCHIVED:
  351.                 return $this->canListArchived($user$function);
  352.             case self::LISTING_ARCHIVED_SOCIETY:
  353.                 return $this->canListArchivedSociety($user$function);
  354.             case self::LISTING_ARCHIVED_MANAGER:
  355.                 return $this->canListArchivedManager($user$function);
  356.             case self::LISTING_ARCHIVED_ANY:
  357.                 return $this->canListArchivedAny($user$function);
  358.         }
  359.         throw new \LogicException('This code should not be reached!');
  360.     }
  361.     // $access is the user trying to load the resource
  362.     // $doc is the resource being loaded
  363.     // Check if the Society of the resource
  364.     // belongs to the societies of the $access
  365.     private function checkSociety(Document $docAccess $access)
  366.     {
  367.         // Get all the societies of the access
  368.         $societies $access->getSocieties();
  369.         // Get the Society of the Document
  370.         $docSociety $doc->getSociety();
  371.         if ($docSociety === null)
  372.             return false;
  373.         $found false;
  374.         foreach ($societies as $society)
  375.         {
  376.             if ($society->getId() == $docSociety->getId())
  377.             {
  378.                 $found true;
  379.                 break;
  380.             }
  381.         }
  382.         return $found;
  383.     }
  384.     // Check if the $access is the manager of the $doc
  385.     private function checkManager(Document $docAccess $access)
  386.     {
  387.         // Get manager
  388.         $manager $doc->getManager();
  389.         $author $doc->getAuthor();
  390.         if ($manager === null)
  391.             return false;
  392.         if ($manager === null && $author === null)
  393.             return false;
  394.         if ($manager !== null)
  395.             if ($manager->getId() === $access->getId())
  396.                 return true;
  397.         if ($author !== null)
  398.             if ($author->getId() === $access->getId())
  399.                 return true;
  400.         return false;
  401.     }
  402.     // Check if the $access is the manager of the client of the $doc
  403.     private function checkClientManager(Document $docAccess $access)
  404.     {
  405.         // Get manager
  406.         if ($doc->getReceiver() === null)
  407.             return null;
  408.         $client $doc->getReceiver();
  409.         if ($client->getIndividual() !== null)
  410.         {
  411.             // Only Individuals have managers
  412.             // Get manager
  413.             $manager $client->getIndividual()->getManager();
  414.             if ($manager === null)
  415.                 return false;
  416.             if ($manager->getId() === $access->getId())
  417.                 return true;
  418.         }
  419.         return false;
  420.     }
  421.     private function canAdd(Access $userAccessFunction $function$task null)
  422.     {
  423.         // Plan.io Task #3323 + #4302
  424.         if ($task !== null)
  425.         {
  426.             if ($task->isArchivedRefused())
  427.             {
  428.                 return false;
  429.             }
  430.             if ($task->isHelp())
  431.             {
  432.                 return false;
  433.             }
  434.             if ($task->isAbsence())
  435.             {
  436.                 return false;
  437.             }
  438.             // It's child recurrence
  439.             if ($task->getRecurrenceParent() !== null)
  440.             {
  441.                 return false;
  442.             }
  443.         }
  444.         // Get Acl_Permission
  445.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ADD);
  446.         if ($aclPerm === null)        return false;
  447.         // Get Acl
  448.         $acl $this->aclRepository->findOneBy(array(
  449.             'function'        =>    $function,
  450.             'permission'    =>    $aclPerm
  451.         ));
  452.         if ($acl === null)        return false;
  453.         // Since only one acl type can exist
  454.         // we can return the result of the acl_permission
  455.         return $acl->getValue();
  456.     }
  457.     // Updated by Plan.io Task #4224 : Added DocumentTargetRule logic
  458.     private function canAddDocumentType(Access $userAccessFunction $functionTask $task$docCode)
  459.     {
  460.         // Get DocumentType
  461.         $docType $this->em->getRepository(DocumentType::class)
  462.             ->findOneByCode($docCode);
  463.         if ($docType === null)
  464.         {
  465.             return false;
  466.         }
  467.         // Get TaskType
  468.         $taskType $task->getType();
  469.         if ($taskType === null)
  470.         {
  471.             return false;
  472.         }
  473.         // Do we need to take the MissionTarget into account ?
  474.         if (!$taskType->getHasDocTargetRule())
  475.         {
  476.             // Nope
  477.             // Just do the DocumentRule check
  478.             $docRule $this->em->getRepository(DocumentRule::class)
  479.                 ->findOneBy(array(
  480.                     'documentType'        =>    $docType,
  481.                     'taskType'            =>    $taskType,
  482.                     'state'                =>    1,
  483.                 ));
  484.             if ($docRule !== null)
  485.             {
  486.                 return true;
  487.             }
  488.             return false;
  489.         }
  490.         // If we are here it means that we have DocumentTargetRules for this TaskType
  491.         // Get MissionTarget, if any
  492.         $missionTarget null;
  493.         $mission $task->getMission();
  494.         if ($mission !== null)
  495.         {
  496.             $missionTarget $mission->getTarget();
  497.         }
  498.         if ($missionTarget === null)
  499.         {
  500.             // Simplest case : No Target, everything is possible ;)
  501.             return true;
  502.         }
  503.         // Apply both MissionTarget and TaskType rule
  504.         $docRule $this->em->getRepository(DocumentTargetRule::class)
  505.             ->findOneBy(array(
  506.                 'documentType'        =>    $docType,
  507.                 'taskType'            =>    $taskType,
  508.                 'missionTarget'        =>    $missionTarget,
  509.                 'state'                =>    1,
  510.             ));
  511.         if ($docRule !== null)
  512.         {
  513.             return true;
  514.         }
  515.         // If we are here, all hope is lost
  516.         return false;
  517.     }
  518.     // We need to pass two arguments to the Security :: DocumentVoter
  519.     // So add the second argument as a property of the first
  520.     // https://stackoverflow.com/questions/39999301/symfony2-pass-a-second-object-to-a-voter
  521.     private function canAddCustomReport(Access $userAccessFunction $functionTask $task)
  522.     {
  523.         // Get DocumentType
  524.         $docType $task->getDocType();
  525.         if ($docType === null)
  526.         {
  527.             return false;
  528.         }
  529.         // Get TaskType
  530.         $taskType $task->getType();
  531.         if ($taskType === null)
  532.         {
  533.             return false;
  534.         }
  535.         // Do we need to take the MissionTarget into account ?
  536.         if (!$taskType->getHasDocTargetRule())
  537.         {
  538.             // Nope
  539.             // Just do the DocumentRule check
  540.             $docRule $this->em->getRepository(DocumentRule::class)
  541.                 ->findOneBy(array(
  542.                     'documentType'        =>    $docType,
  543.                     'taskType'            =>    $taskType,
  544.                     'state'                =>    1,
  545.                 ));
  546.             if ($docRule !== null)
  547.             {
  548.                 return true;
  549.             }
  550.             return false;
  551.         }
  552.         // If we are here it means that we have DocumentTargetRules for this TaskType
  553.         // Get MissionTarget, if any
  554.         $missionTarget null;
  555.         $mission $task->getMission();
  556.         if ($mission !== null)
  557.         {
  558.             $missionTarget $mission->getTarget();
  559.         }
  560.         if ($missionTarget === null)
  561.         {
  562.             // Simplest case : No Target, everything is possible ;)
  563.             return true;
  564.         }
  565.         // Apply both MissionTarget and TaskType rule
  566.         $docRule $this->em->getRepository(DocumentTargetRule::class)
  567.             ->findOneBy(array(
  568.                 'documentType'        =>    $docType,
  569.                 'taskType'            =>    $taskType,
  570.                 'missionTarget'        =>    $missionTarget,
  571.                 'state'                =>    1,
  572.             ));
  573.         if ($docRule !== null)
  574.         {
  575.             return true;
  576.         }
  577.         // If we are here, all hope is lost
  578.         return false;
  579.     }
  580.     private function canList(Access $userAccessFunction $function)
  581.     {
  582.         // Get Acl_Permission
  583.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  584.         if ($aclPerm === null)        return false;
  585.         // Get Acl
  586.         $acl $this->aclRepository->findOneBy(array(
  587.             'function'        =>    $function,
  588.             'permission'    =>    $aclPerm
  589.         ));
  590.         if ($acl === null)        return false;
  591.         // Since only one acl type can exist
  592.         // we can return the result of the acl_permission
  593.         return $acl->getValue();
  594.     }
  595.     private function canListSociety(Access $userAccessFunction $function)
  596.     {
  597.         // Get Acl_Permission
  598.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  599.         if ($aclPerm === null)        return false;
  600.         // Get Acl
  601.         $acl $this->aclRepository->findOneBy(array(
  602.             'function'        =>    $function,
  603.             'permission'    =>    $aclPerm
  604.         ));
  605.         if ($acl === null)        return false;
  606.         // Since only one acl type can exist
  607.         // we can return the result of the acl_permission
  608.         // Further filtering is done in the Controller
  609.         return $acl->getValue();
  610.     }
  611.     private function canListManager(Access $userAccessFunction $function)
  612.     {
  613.         // Get Acl_Permission
  614.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_MANAGER);
  615.         if ($aclPerm === null)        return false;
  616.         // Get Acl
  617.         $acl $this->aclRepository->findOneBy(array(
  618.             'function'        =>    $function,
  619.             'permission'    =>    $aclPerm
  620.         ));
  621.         if ($acl === null)        return false;
  622.         // Since only one acl type can exist
  623.         // we can return the result of the acl_permission
  624.         // Further filtering is done in the Controller
  625.         return $acl->getValue();
  626.     }
  627.     private function canListAny(Access $userAccessFunction $function)
  628.     {
  629.         // Two Acl_Permission may exist
  630.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  631.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  632.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_MANAGER);
  633.         // If both are null, exit
  634.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null)
  635.             return false;
  636.         // Get First one
  637.         if ($aclPerm !== null)
  638.         {
  639.             $acl $this->aclRepository->findOneBy(array(
  640.                 'function'        =>    $function,
  641.                 'permission'    =>    $aclPerm
  642.             ));
  643.             if ($acl !== null)
  644.             {
  645.                 if ($acl->getValue())
  646.                 {
  647.                     // A single positive answer is enough
  648.                     return true;
  649.                 }
  650.             }
  651.         }
  652.         // If we are here it means that nothing good has been found
  653.         // Load second permission
  654.         if ($aclPermSociety !== null)
  655.         {
  656.             $acl $this->aclRepository->findOneBy(array(
  657.                 'function'        =>    $function,
  658.                 'permission'    =>    $aclPermSociety
  659.             ));
  660.             if ($acl !== null)
  661.             {
  662.                 if ($acl->getValue())
  663.                 {
  664.                     // A single positive answer is enough
  665.                     return true;
  666.                 }
  667.             }
  668.         }
  669.         // If we are here it means that nothing good has been found
  670.         // Load third permission
  671.         if ($aclPermManager !== null)
  672.         {
  673.             $acl $this->aclRepository->findOneBy(array(
  674.                 'function'        =>    $function,
  675.                 'permission'    =>    $aclPermManager
  676.             ));
  677.             if ($acl !== null)
  678.             {
  679.                 if ($acl->getValue())
  680.                 {
  681.                     // A single positive answer is enough
  682.                     return true;
  683.                 }
  684.             }
  685.         }
  686.         // If we are here, all hope is lost
  687.         return false;
  688.     }
  689.     private function canViewPdf(Document $docAccess $userAccessFunction $function)
  690.     {
  691.         if ($doc->isArchived())
  692.         {
  693.             return $this->canViewArchivedPdf($doc$user$function);
  694.         }
  695.         // Many Acl_Permission may exist
  696.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_PDF);
  697.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_PDF_SOCIETY);
  698.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_PDF_MANAGER);
  699.         $aclPermClientManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_PDF_CLIENT_MANAGER);
  700.         // If all are null, exit
  701.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null && $aclPermClientManager === null)
  702.             return false;
  703.         // Get First one
  704.         if ($aclPerm !== null)
  705.         {
  706.             $acl $this->aclRepository->findOneBy(array(
  707.                 'function'        =>    $function,
  708.                 'permission'    =>    $aclPerm
  709.             ));
  710.             if ($acl !== null)
  711.             {
  712.                 if ($acl->getValue())
  713.                 {
  714.                     // A single positive answer is enough
  715.                     return true;
  716.                 }
  717.             }
  718.         }
  719.         // If we are here it means that nothing good has been found
  720.         // Load second permission
  721.         if ($aclPermSociety !== null)
  722.         {
  723.             $acl $this->aclRepository->findOneBy(array(
  724.                 'function'        =>    $function,
  725.                 'permission'    =>    $aclPermSociety
  726.             ));
  727.             if ($acl !== null)
  728.             {
  729.                 if ($acl->getValue())
  730.                 {
  731.                     // A single positive answer is enough
  732.                     // In this case the good answer will be provided by the checkSociety
  733.                     // However, we don't want to stop if the answer is no, but look further
  734.                     // This is the case when the client is in society A and the document is in society B
  735.                     if ($this->checkSociety($doc$user))
  736.                         return true;
  737.                 }
  738.             }
  739.         }
  740.         // If we are here it means that nothing good has been found
  741.         // Load third permission
  742.         if ($aclPermManager !== null)
  743.         {
  744.             $acl $this->aclRepository->findOneBy(array(
  745.                 'function'        =>    $function,
  746.                 'permission'    =>    $aclPermManager
  747.             ));
  748.             if ($acl !== null)
  749.             {
  750.                 if ($acl->getValue())
  751.                 {
  752.                     // A single positive answer is enough
  753.                     // In this case the good answer will be provided by the checkSociety
  754.                     if ($this->checkManager($doc$user))
  755.                         return true;
  756.                 }
  757.             }
  758.         }
  759.         // If we are here it means that nothing good has been found
  760.         // Load third permission
  761.         if ($aclPermClientManager !== null)
  762.         {
  763.             $acl $this->aclRepository->findOneBy(array(
  764.                 'function'        =>    $function,
  765.                 'permission'    =>    $aclPermClientManager
  766.             ));
  767.             if ($acl !== null)
  768.             {
  769.                 if ($acl->getValue())
  770.                 {
  771.                     // A single positive answer is enough
  772.                     // In this case the good answer will be provided by the checkSociety
  773.                     if ($this->checkClientManager($doc$user))
  774.                         return true;
  775.                 }
  776.             }
  777.         }
  778.         // If we are here, all hope is lost
  779.         return false;
  780.     }
  781.     private function canArchive(Document $docAccess $userAccessFunction $function)
  782.     {
  783.         // Many Acl_Permission may exist
  784.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ARCHIVE);
  785.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ARCHIVE_SOCIETY);
  786.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ARCHIVE_MANAGER);
  787.         // If all are null, exit
  788.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null)
  789.             return false;
  790.         // Get First one
  791.         if ($aclPerm !== null)
  792.         {
  793.             $acl $this->aclRepository->findOneBy(array(
  794.                 'function'        =>    $function,
  795.                 'permission'    =>    $aclPerm
  796.             ));
  797.             if ($acl !== null)
  798.             {
  799.                 if ($acl->getValue())
  800.                 {
  801.                     // A single positive answer is enough
  802.                     return true;
  803.                 }
  804.             }
  805.         }
  806.         // If we are here it means that nothing good has been found
  807.         // Load second permission
  808.         if ($aclPermSociety !== null)
  809.         {
  810.             $acl $this->aclRepository->findOneBy(array(
  811.                 'function'        =>    $function,
  812.                 'permission'    =>    $aclPermSociety
  813.             ));
  814.             if ($acl !== null)
  815.             {
  816.                 if ($acl->getValue())
  817.                 {
  818.                     // A single positive answer is enough
  819.                     // In this case the good answer will be provided by the checkSociety
  820.                     // However, we don't want to stop if the answer is no, but look further
  821.                     // This is the case when the client is in society A and the document is in society B
  822.                     if ($this->checkSociety($doc$user))
  823.                         return true;
  824.                 }
  825.             }
  826.         }
  827.         // If we are here it means that nothing good has been found
  828.         // Load third permission
  829.         if ($aclPermManager !== null)
  830.         {
  831.             $acl $this->aclRepository->findOneBy(array(
  832.                 'function'        =>    $function,
  833.                 'permission'    =>    $aclPermManager
  834.             ));
  835.             if ($acl !== null)
  836.             {
  837.                 if ($acl->getValue())
  838.                 {
  839.                     // A single positive answer is enough
  840.                     // In this case the good answer will be provided by the checkSociety
  841.                     if ($this->checkManager($doc$user))
  842.                         return true;
  843.                 }
  844.             }
  845.         }
  846.         // If we are here, all hope is lost
  847.         return false;
  848.     }
  849.     private function canViewArchivedPdf(Document $docAccess $userAccessFunction $function)
  850.     {
  851.         if ($doc->isNotArchived())
  852.         {
  853.             return $this->canViewPdf($doc$user$function);
  854.         }
  855.         // Many Acl_Permission may exist
  856.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_PDF_ARCHIVED);
  857.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_PDF_ARCHIVED_SOCIETY);
  858.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_PDF_ARCHIVED_MANAGER);
  859.         $aclPermClientManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_PDF_ARCHIVED_CLIENT_MANAGER);
  860.         // If all are null, exit
  861.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null && $aclPermClientManager === null)
  862.             return false;
  863.         // Get First one
  864.         if ($aclPerm !== null)
  865.         {
  866.             $acl $this->aclRepository->findOneBy(array(
  867.                 'function'        =>    $function,
  868.                 'permission'    =>    $aclPerm
  869.             ));
  870.             if ($acl !== null)
  871.             {
  872.                 if ($acl->getValue())
  873.                 {
  874.                     // A single positive answer is enough
  875.                     return true;
  876.                 }
  877.             }
  878.         }
  879.         // If we are here it means that nothing good has been found
  880.         // Load second permission
  881.         if ($aclPermSociety !== null)
  882.         {
  883.             $acl $this->aclRepository->findOneBy(array(
  884.                 'function'        =>    $function,
  885.                 'permission'    =>    $aclPermSociety
  886.             ));
  887.             if ($acl !== null)
  888.             {
  889.                 if ($acl->getValue())
  890.                 {
  891.                     // A single positive answer is enough
  892.                     // In this case the good answer will be provided by the checkSociety
  893.                     // However, we don't want to stop if the answer is no, but look further
  894.                     // This is the case when the client is in society A and the document is in society B
  895.                     if ($this->checkSociety($doc$user))
  896.                         return true;
  897.                 }
  898.             }
  899.         }
  900.         // If we are here it means that nothing good has been found
  901.         // Load third permission
  902.         if ($aclPermManager !== null)
  903.         {
  904.             $acl $this->aclRepository->findOneBy(array(
  905.                 'function'        =>    $function,
  906.                 'permission'    =>    $aclPermManager
  907.             ));
  908.             if ($acl !== null)
  909.             {
  910.                 if ($acl->getValue())
  911.                 {
  912.                     // A single positive answer is enough
  913.                     // In this case the good answer will be provided by the checkSociety
  914.                     if ($this->checkManager($doc$user))
  915.                         return true;
  916.                 }
  917.             }
  918.         }
  919.         // If we are here it means that nothing good has been found
  920.         // Load third permission
  921.         if ($aclPermClientManager !== null)
  922.         {
  923.             $acl $this->aclRepository->findOneBy(array(
  924.                 'function'        =>    $function,
  925.                 'permission'    =>    $aclPermClientManager
  926.             ));
  927.             if ($acl !== null)
  928.             {
  929.                 if ($acl->getValue())
  930.                 {
  931.                     // A single positive answer is enough
  932.                     if ($this->checkClientManager($doc$user))
  933.                         return true;
  934.                     // "Voir les PDF de tous les documents archivés des clients dont il est le gestionnaire et tous les documents archivés dont il est l'auteur"
  935.                     // Also check if author / manager of this particular document
  936.                     if ($this->checkManager($doc$user))
  937.                         return true;
  938.                 }
  939.             }
  940.         }
  941.         // If we are here, all hope is lost
  942.         return false;
  943.     }
  944.     private function canListArchived(Access $userAccessFunction $function)
  945.     {
  946.         // Get Acl_Permission
  947.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_ARCHIVED);
  948.         if ($aclPerm === null)        return false;
  949.         // Get Acl
  950.         $acl $this->aclRepository->findOneBy(array(
  951.             'function'        =>    $function,
  952.             'permission'    =>    $aclPerm
  953.         ));
  954.         if ($acl === null)        return false;
  955.         // Since only one acl type can exist
  956.         // we can return the result of the acl_permission
  957.         return $acl->getValue();
  958.     }
  959.     private function canListArchivedSociety(Access $userAccessFunction $function)
  960.     {
  961.         // Get Acl_Permission
  962.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_ARCHIVED_SOCIETY);
  963.         if ($aclPerm === null)        return false;
  964.         // Get Acl
  965.         $acl $this->aclRepository->findOneBy(array(
  966.             'function'        =>    $function,
  967.             'permission'    =>    $aclPerm
  968.         ));
  969.         if ($acl === null)        return false;
  970.         // Since only one acl type can exist
  971.         // we can return the result of the acl_permission
  972.         // Further filtering is done in the Controller
  973.         return $acl->getValue();
  974.     }
  975.     private function canListArchivedManager(Access $userAccessFunction $function)
  976.     {
  977.         // Get Acl_Permission
  978.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_ARCHIVED_MANAGER);
  979.         if ($aclPerm === null)        return false;
  980.         // Get Acl
  981.         $acl $this->aclRepository->findOneBy(array(
  982.             'function'        =>    $function,
  983.             'permission'    =>    $aclPerm
  984.         ));
  985.         if ($acl === null)        return false;
  986.         // Since only one acl type can exist
  987.         // we can return the result of the acl_permission
  988.         // Further filtering is done in the Controller
  989.         return $acl->getValue();
  990.     }
  991.     private function canListArchivedAny(Access $userAccessFunction $function)
  992.     {
  993.         // Two Acl_Permission may exist
  994.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_ARCHIVED);
  995.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_ARCHIVED_SOCIETY);
  996.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_ARCHIVED_MANAGER);
  997.         // If both are null, exit
  998.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null)
  999.             return false;
  1000.         // Get First one
  1001.         if ($aclPerm !== null)
  1002.         {
  1003.             $acl $this->aclRepository->findOneBy(array(
  1004.                 'function'        =>    $function,
  1005.                 'permission'    =>    $aclPerm
  1006.             ));
  1007.             if ($acl !== null)
  1008.             {
  1009.                 if ($acl->getValue())
  1010.                 {
  1011.                     // A single positive answer is enough
  1012.                     return true;
  1013.                 }
  1014.             }
  1015.         }
  1016.         // If we are here it means that nothing good has been found
  1017.         // Load second permission
  1018.         if ($aclPermSociety !== null)
  1019.         {
  1020.             $acl $this->aclRepository->findOneBy(array(
  1021.                 'function'        =>    $function,
  1022.                 'permission'    =>    $aclPermSociety
  1023.             ));
  1024.             if ($acl !== null)
  1025.             {
  1026.                 if ($acl->getValue())
  1027.                 {
  1028.                     // A single positive answer is enough
  1029.                     return true;
  1030.                 }
  1031.             }
  1032.         }
  1033.         // If we are here it means that nothing good has been found
  1034.         // Load third permission
  1035.         if ($aclPermManager !== null)
  1036.         {
  1037.             $acl $this->aclRepository->findOneBy(array(
  1038.                 'function'        =>    $function,
  1039.                 'permission'    =>    $aclPermManager
  1040.             ));
  1041.             if ($acl !== null)
  1042.             {
  1043.                 if ($acl->getValue())
  1044.                 {
  1045.                     // A single positive answer is enough
  1046.                     return true;
  1047.                 }
  1048.             }
  1049.         }
  1050.         // If we are here, all hope is lost
  1051.         return false;
  1052.     }
  1053. }