From 6fa99655b2af04ec23c58e20a2bb9e3ab48d9569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 10 Feb 2022 00:37:24 +0100 Subject: [PATCH] delegates the acl for fetching person documents to an ACLAwareREpository --- .../Controller/DocumentPersonController.php | 24 ++---- .../PersonDocumentACLAwareRepository.php | 85 +++++++++++++++++++ ...sonDocumentACLAwareRepositoryInterface.php | 12 +++ .../ChillDocStoreBundle/config/services.yaml | 1 - 4 files changed, 106 insertions(+), 16 deletions(-) create mode 100644 src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php create mode 100644 src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php diff --git a/src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php b/src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php index 994a5d70f..b20772d29 100644 --- a/src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php +++ b/src/Bundle/ChillDocStoreBundle/Controller/DocumentPersonController.php @@ -13,6 +13,7 @@ namespace Chill\DocStoreBundle\Controller; use Chill\DocStoreBundle\Entity\PersonDocument; use Chill\DocStoreBundle\Form\PersonDocumentType; +use Chill\DocStoreBundle\Repository\PersonDocumentACLAwareRepositoryInterface; use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; @@ -44,6 +45,8 @@ class DocumentPersonController extends AbstractController private PaginatorFactory $paginatorFactory; + private PersonDocumentACLAwareRepositoryInterface $personDocumentACLAwareRepository; + /** * DocumentPersonController constructor. */ @@ -51,12 +54,14 @@ class DocumentPersonController extends AbstractController TranslatorInterface $translator, EventDispatcherInterface $eventDispatcher, AuthorizationHelper $authorizationHelper, - PaginatorFactory $paginatorFactory + PaginatorFactory $paginatorFactory, + PersonDocumentACLAwareRepositoryInterface $personDocumentACLAwareRepository ) { $this->translator = $translator; $this->eventDispatcher = $eventDispatcher; $this->authorizationHelper = $authorizationHelper; $this->paginatorFactory = $paginatorFactory; + $this->personDocumentACLAwareRepository = $personDocumentACLAwareRepository; } /** @@ -152,21 +157,10 @@ class DocumentPersonController extends AbstractController $this->denyAccessUnlessGranted(PersonVoter::SEE, $person); - $reachableScopes = $this->authorizationHelper - ->getReachableScopes( - $this->getUser(), - PersonDocumentVoter::SEE, - $person->getCenter() - ); + $documents = $this->personDocumentACLAwareRepository->findByPerson($person); - $documents = $em - ->getRepository('ChillDocStoreBundle:PersonDocument') - ->findBy( - ['person' => $person, 'scope' => $reachableScopes], - ['date' => 'DESC'] - ); - - $total = count($documents); + // wrong: count documents in database and retrieve document for this page. + $total = $this->personDocumentACLAwareRepository->countByPerson($person); $pagination = $this->paginatorFactory->create($total); $event = new PrivacyEvent($person, [ diff --git a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php new file mode 100644 index 000000000..010da47a3 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepository.php @@ -0,0 +1,85 @@ +em = $em; + $this->authorizationHelper = $authorizationHelper; + $this->centerResolverDispatcher = $centerResolverDispatcher; + $this->security = $security; + } + + public function findByPerson(Person $person, array $orderBy = [], int $limit = 20, int $offset = 0): array + { + $qb = $this->buildQueryByPerson($person)->select('d'); + + $this->addACL($qb, $person); + + foreach ($orderBy as list($field, $order)) { + $qb->addOrderBy($field, $order); + } + + $qb->setFirstResult($offset)->setMaxResults($limit); + + return $qb->getQuery()->getResult(); + } + + public function countByPerson(Person $person): int + { + $qb = $this->buildQueryByPerson($person)->select('COUNT(d)'); + + $this->addACL($qb, $person); + + return $qb->getQuery()->getSingleScalarResult(); + } + + public function buildQueryByPerson(Person $person): QueryBuilder + { + $qb = $this->em->getRepository(PersonDocument::class)->createQueryBuilder('d'); + + $qb + ->where($qb->expr()->eq('d.person', ':person')) + ->setParameter('person', $person) + ; + + return $qb; + } + + private function addACL(QueryBuilder $qb, Person $person): void + { + + $center = $this->centerResolverDispatcher->resolveCenter($person); + + $reachableScopes = $this->authorizationHelper + ->getReachableScopes( + $this->security->getUser(), + PersonDocumentVoter::SEE, + $center + ); + + $qb->andWhere($qb->expr()->in('d.scope', ':scopes')) + ->setParameter('scopes', $reachableScopes) + ; + } + +} diff --git a/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php new file mode 100644 index 000000000..f4f654b18 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Repository/PersonDocumentACLAwareRepositoryInterface.php @@ -0,0 +1,12 @@ +