src/EspaceDocBundle/Security/CategoryVoter.php line 24

Open in your IDE?
  1. <?php
  2. namespace App\EspaceDocBundle\Security;
  3. use App\Entity\Contacts;
  4. use App\Entity\User;
  5. use App\EspaceDocBundle\Entity\Acl;
  6. use App\EspaceDocBundle\Entity\Category;
  7. use App\EspaceDocBundle\Entity\Document;
  8. use App\EspaceDocBundle\Entity\UserGroup;
  9. use App\EspaceDocBundle\Repository\AclRepository;
  10. use App\EspaceDocBundle\Repository\DocumentRepository;
  11. use App\EspaceDocBundle\Repository\UserGroupRepository;
  12. use App\Repository\ContactsRepository;
  13. use Doctrine\ORM\EntityManager;
  14. use PhpParser\Comment\Doc;
  15. use Psr\Log\LoggerInterface;
  16. use Symfony\Component\DependencyInjection\ContainerAwareInterface;
  17. use Symfony\Component\DependencyInjection\ContainerInterface;
  18. use Symfony\Component\HttpFoundation\RequestStack;
  19. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  20. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  21. class CategoryVoter extends Voter implements ContainerAwareInterface
  22. {
  23.     const VIEW                          'view';
  24.     const EDIT                          'edit';
  25.     const DELETE                        'delete';
  26.     const EDIT_DOCUMENTS                'edit_documents';
  27.     const EDIT_DOCUMENTS_LIKE           'edit_documents_like';
  28.     const VIEW_DOCUMENTS_LIKE           'view_documents_like';
  29.     const BULK_DELETE_DOCUMENTS_POST    'bulk_delete_documents_post';
  30.     private $container;
  31.     /**
  32.      * @var RequestStack
  33.      */
  34.     private $requestStack;
  35.     /**
  36.      * @var EntityManager L'EM de l'ED
  37.      */
  38.     private $edEntityManager;
  39.     /**
  40.      * @var EntityManager L'EM du site
  41.      */
  42.     private $entityManager;
  43.     public function setContainer(ContainerInterface $container null)
  44.     {
  45.         $this->setContainer($container);
  46.     }
  47.     public function __construct(RequestStack $requestStackLoggerInterface $loggerContainerInterface $container)
  48.     {
  49.         $this->container $container;
  50.         $this->logger $logger;
  51.         $this->requestStack $requestStack;
  52.         $doctrine $this->container->get('doctrine');
  53.         $this->edEntityManager $doctrine->getManager('espacedoc');
  54.         $this->entityManager $doctrine->getManager();
  55.     }
  56.     protected function supports($attribute$subject)
  57.     {
  58.         // Voter seulement sur ce qui me concerne
  59.         if(!in_array($attribute, [
  60.             self::VIEW,
  61.             self::EDIT,
  62.             self::DELETE,
  63.             self::EDIT_DOCUMENTS,
  64.             self::EDIT_DOCUMENTS_LIKE,
  65.             self::VIEW_DOCUMENTS_LIKE,
  66.             self::BULK_DELETE_DOCUMENTS_POST,
  67.         ])) {
  68.             return false;
  69.         }
  70.         if(
  71.             !$subject instanceof Category &&                    // Si on ne me donne pas une catégorie
  72.             !($subject instanceof Document && (                 // Ni un document
  73.                 $attribute === self::EDIT_DOCUMENTS_LIKE ||
  74.                 $attribute === self::VIEW_DOCUMENTS_LIKE ||
  75.                 $attribute === self::VIEW
  76.             )) && (
  77.                 $attribute !== self::BULK_DELETE_DOCUMENTS_POST // S'il ne s'agit pas d'un bulk delete (dans ce cas, le subjectest dans $_POST
  78.             )
  79.         ) {
  80.             return false;
  81.         }
  82.         return true;
  83.     }
  84.     /**
  85.      * @param string $attribute
  86.      * @param mixed $subject
  87.      * @param TokenInterface $token
  88.      * @return bool
  89.      * @throws \Doctrine\ORM\NonUniqueResultException
  90.      */
  91.     protected function voteOnAttribute($attribute$subjectTokenInterface $token)
  92.     {
  93.         $user $token->getUser();
  94.         if($attribute !== self::EDIT_DOCUMENTS_LIKE) {
  95.             /** @var Category $category */
  96.             $category $subject;
  97.         } else {
  98.             /** @var Document $document */
  99.             $document $subject;
  100.         }
  101.         // Si utilisateur pas connecté, dehors
  102.         if (!$user instanceof User) {
  103.             return false;
  104.         }
  105.         // Superadmin peut tout faire
  106.         if($user->getIsSuper()) {
  107.             return true;
  108.         }
  109.         switch ($attribute) {
  110.             case self::VIEW:
  111.                 return $this->canView($category$user);
  112.             case self::EDIT:
  113.                 return $this->canEdit($category$user);
  114.             case self::EDIT_DOCUMENTS:
  115.                 return $this->canEditDocuments($category$user);
  116.             case self::EDIT_DOCUMENTS_LIKE:
  117.                 return $this->canEditDocuments($document->getCategory(), $user);
  118.             case self::VIEW_DOCUMENTS_LIKE:
  119.                 return $this->canViewDocuments($document->getCategory(), $user);
  120.             case self::DELETE:
  121.                 return $this->canDelete($category$user);
  122.             case self::BULK_DELETE_DOCUMENTS_POST:
  123.                 return $this->canBulkDeleteFromRequest($user);
  124.         }
  125.         throw new \LogicException('Unhandled attribute. Please check supports() method.');
  126.     }
  127.     private function canView($objectUser $user)
  128.     {
  129.         if($object instanceof Document) {
  130.             $category $object->getCategory();
  131.         } else {
  132.             $category $object;
  133.         }
  134.         // Est-ce que j'ai l'ACL 'éditer les documents' ?
  135.         // Récupération de l'ID du groupe ED
  136.         /** @var ContactsRepository $contactsRepository */
  137.         $contactsRepository $this->entityManager->getRepository(Contacts::class);
  138.         $contact $contactsRepository->findOneBy(['xutilisateur' => $user->getId()]);
  139.         if(!$contact) {
  140.             return false;
  141.         }
  142.         $groupId $contact->getGroup();
  143.         // Si je suis dans un groupe ED
  144.         if($groupId) {
  145.             // Récupération du groupe ED
  146.             /** @var UserGroupRepository $userGroupsRepository */
  147.             $userGroupsRepository $this->edEntityManager->getRepository(UserGroup::class);
  148.             $userGroup $userGroupsRepository->find($groupId);
  149.             // Si je suis dans le groupe 'admin', dans tous les cas, j'ai le droit d'éditer
  150.             if('admins' === $userGroup->getSlug()) {
  151.                 return true;
  152.             }
  153.             /** @var AclRepository $aclsRepository */
  154.             $aclsRepository $this->edEntityManager->getRepository(Acl::class);
  155.             return (
  156.                 $aclsRepository->groupHasAclForCategory($userGroup$categoryAcl::EDIT_CATEGORY) || // Si j'ai le droit d'éditer la catégorie, j'ai aussi le droit d'éditer les documents
  157.                 $aclsRepository->groupHasAclForCategory($userGroup$categoryAcl::EDIT_DOCUMENTS) ||
  158.                 $aclsRepository->groupHasAclForCategory($userGroup$categoryAcl::VIEW)
  159.             );
  160.         }
  161.         return false;
  162.     }
  163.     /**
  164.      * @param Category $category
  165.      * @param User $user
  166.      * @return bool
  167.      * @throws \Doctrine\ORM\NonUniqueResultException
  168.      */
  169.     private function canEdit(Category $categoryUser $user)
  170.     {
  171.         // Est-ce que j'ai l'ACL 'éditer' ?
  172.         // Récupération de l'ID du groupe ED
  173.         /** @var ContactsRepository $contactsRepository */
  174.         $contactsRepository $this->entityManager->getRepository(Contacts::class);
  175.         $contact $contactsRepository->findOneBy(['xutilisateur' => $user->getId()]);
  176.         $groupId $contact->getGroup();
  177.         // Si je suis dans un groupe ED
  178.         if($groupId) {
  179.             // Récupération du groupe ED
  180.             /** @var UserGroupRepository $userGroupsRepository */
  181.             $userGroupsRepository $this->edEntityManager->getRepository(UserGroup::class);
  182.             $userGroup $userGroupsRepository->find($groupId);
  183.             // Si je suis dans le groupe 'admin', dans tous les cas, j'ai le droit d'éditer
  184.             if('admins' === $userGroup->getSlug()) {
  185.                 return true;
  186.             }
  187.             /** @var AclRepository $aclsRepository */
  188.             $aclsRepository $this->edEntityManager->getRepository(Acl::class);
  189.             return $aclsRepository->groupHasAclForCategory($userGroup$categoryAcl::EDIT_CATEGORY);
  190.         }
  191.         return false;
  192.     }
  193.     /**
  194.      * @param Category $category
  195.      * @param User $user
  196.      * @return bool
  197.      * @throws \Doctrine\ORM\NonUniqueResultException
  198.      */
  199.     private function canEditDocuments(Category $categoryUser $user)
  200.     {
  201.         // Est-ce que j'ai l'ACL 'éditer les documents' ?
  202.         // Récupération de l'ID du groupe ED
  203.         /** @var ContactsRepository $contactsRepository */
  204.         $contactsRepository $this->entityManager->getRepository(Contacts::class);
  205.         $contact $contactsRepository->findOneBy(['xutilisateur' => $user->getId()]);
  206.         if(!$contact) {
  207.             return false;
  208.         }
  209.         $groupId $contact->getGroup();
  210.         // Si je suis dans un groupe ED
  211.         if($groupId) {
  212.             // Récupération du groupe ED
  213.             /** @var UserGroupRepository $userGroupsRepository */
  214.             $userGroupsRepository $this->edEntityManager->getRepository(UserGroup::class);
  215.             $userGroup $userGroupsRepository->find($groupId);
  216.             // Si je suis dans le groupe 'admin', dans tous les cas, j'ai le droit d'éditer
  217.             if('admins' === $userGroup->getSlug()) {
  218.                 return true;
  219.             }
  220.             /** @var AclRepository $aclsRepository */
  221.             $aclsRepository $this->edEntityManager->getRepository(Acl::class);
  222.             return (
  223.                 $aclsRepository->groupHasAclForCategory($userGroup$categoryAcl::EDIT_CATEGORY) || // Si j'ai le droit d'éditer la catégorie, j'ai aussi le droit d'éditer les documents
  224.                 $aclsRepository->groupHasAclForCategory($userGroup$categoryAcl::EDIT_DOCUMENTS)
  225.             );
  226.         }
  227.         return false;
  228.     }
  229.     /**
  230.      * @param Category $category
  231.      * @param User $user
  232.      * @return bool
  233.      * @throws \Doctrine\ORM\NonUniqueResultException
  234.      */
  235.     private function canViewDocuments(Category $categoryUser $user)
  236.     {
  237.         // Est-ce que j'ai l'ACL 'Voir les documents' ?
  238.         // Récupération de l'ID du groupe ED
  239.         /** @var ContactsRepository $contactsRepository */
  240.         $contactsRepository $this->entityManager->getRepository(Contacts::class);
  241.         $contact $contactsRepository->findOneBy(['xutilisateur' => $user->getId()]);
  242.         $groupId $contact->getGroup();
  243.         // Si je suis dans un groupe ED
  244.         if($groupId) {
  245.             // Récupération du groupe ED
  246.             /** @var UserGroupRepository $userGroupsRepository */
  247.             $userGroupsRepository $this->edEntityManager->getRepository(UserGroup::class);
  248.             $userGroup $userGroupsRepository->find($groupId);
  249.             // Si je suis dans le groupe 'admin', dans tous les cas, j'ai le droit d'éditer
  250.             if('admins' === $userGroup->getSlug()) {
  251.                 return true;
  252.             }
  253.             /** @var AclRepository $aclsRepository */
  254.             $aclsRepository $this->edEntityManager->getRepository(Acl::class);
  255.             return (
  256.                 $aclsRepository->groupHasAclForCategory($userGroup$categoryAcl::EDIT_CATEGORY) || // Si j'ai le droit d'éditer la catégorie, j'ai aussi le droit d'éditer les documents
  257.                 $aclsRepository->groupHasAclForCategory($userGroup$categoryAcl::EDIT_DOCUMENTS) ||
  258.                 $aclsRepository->groupHasAclForCategory($userGroup$categoryAcl::VIEW)
  259.             );
  260.         }
  261.         return false;
  262.     }
  263.     /**
  264.      * @param Category $category
  265.      * @param User $user
  266.      * @return bool
  267.      * @throws \Doctrine\ORM\NonUniqueResultException
  268.      */
  269.     private function canDelete(Category $categoryUser $user)
  270.     {
  271.         return $this->canEdit($category$user);
  272.     }
  273.     /**
  274.      * Vérifier si j'ai le droit de supprimer les documents dont les ID sont passés en POST, dans `delete_documents`
  275.      *
  276.      * @param $user
  277.      * @return bool
  278.      */
  279.     private function canBulkDeleteFromRequest($user)
  280.     {
  281.         try {
  282.         /** @var DocumentRepository $documentRepository */
  283.         $documentRepository $this->entityManager->getRepository(Document::class);
  284.         $documentsToDelete $this->requestStack->getMasterRequest()->get('delete_documents');
  285.         foreach ($documentsToDelete as $key => $documentId) {
  286.             $document $documentRepository->find($documentId);
  287.             if(!$this->canEditDocuments($document->getCategory(), $user)) {
  288.                 return false;
  289.             }
  290.         }
  291.         return true;
  292.         } catch (\Exception $exception) {
  293.             return false;
  294.         }
  295.     }
  296. }