From f39b0ee0029324fd2a8614b6aac61187c4c7ba23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 27 Sep 2022 16:09:09 +0200 Subject: [PATCH] [task] Feature: use the resolution of center with person's center history --- .../SingleTaskAclAwareRepository.php | 32 ++- .../SingleTaskACLAwareRepositoryTest.php | 211 ++++++++++++++++++ 2 files changed, 231 insertions(+), 12 deletions(-) create mode 100644 src/Bundle/ChillTaskBundle/Tests/Repository/SingleTaskACLAwareRepositoryTest.php diff --git a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php index d2dd7fc18..dca83eb71 100644 --- a/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php +++ b/src/Bundle/ChillTaskBundle/Repository/SingleTaskAclAwareRepository.php @@ -13,6 +13,7 @@ namespace Chill\TaskBundle\Repository; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; +use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Person; use Chill\TaskBundle\Entity\SingleTask; @@ -31,14 +32,14 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository { private AuthorizationHelperInterface $authorizationHelper; - private CenterResolverDispatcherInterface $centerResolverDispatcher; + private CenterResolverManagerInterface $centerResolverDispatcher; private EntityManagerInterface $em; private Security $security; public function __construct( - CenterResolverDispatcherInterface $centerResolverDispatcher, + CenterResolverManagerInterface $centerResolverDispatcher, EntityManagerInterface $em, Security $security, AuthorizationHelperInterface $authorizationHelper @@ -304,14 +305,18 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository QueryBuilder $qb, $entity ): QueryBuilder { - $scopes = $this->authorizationHelper->getReachableScopes( - $this->security->getUser(), - TaskVoter::SHOW, - $this->centerResolverDispatcher->resolveCenter($entity) - ); + foreach ($this->centerResolverDispatcher->resolveCenters($entity) as $center) { + $scopes = $this->authorizationHelper->getReachableScopes( + $this->security->getUser(), + TaskVoter::SHOW, + $center + ); - return $qb->andWhere($qb->expr()->in('t.circle', ':scopes')) - ->setParameter('scopes', $scopes); + $qb->andWhere($qb->expr()->in('t.circle', ':scopes')) + ->setParameter('scopes', $scopes); + } + + return $qb; } private function addACLGlobal( @@ -329,7 +334,10 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository $qb->leftJoin('t.person', 'person') ->leftJoin('t.course', 'course') ->leftJoin('course.participations', 'participation') - ->leftJoin('participation.person', 'person_p'); + ->leftJoin('participation.person', 'person_p') + ->leftJoin('person.centerCurrent', 'center_current_person') + ->leftJoin('person_p.centerCurrent', 'center_current_participation') + ; $qb->distinct(true); $k = 0; @@ -344,8 +352,8 @@ final class SingleTaskAclAwareRepository implements SingleTaskAclAwareRepository $and = $qb->expr()->andX( $qb->expr()->orX( - $qb->expr()->eq('person.center', ':center_' . $k), - $qb->expr()->eq('person_p.center', ':center_' . $k) + $qb->expr()->eq('center_current_person.center', ':center_' . $k), + $qb->expr()->eq('center_current_participation.center', ':center_' . $k) ), $qb->expr()->in('t.circle', ':scopes_' . $k) ); diff --git a/src/Bundle/ChillTaskBundle/Tests/Repository/SingleTaskACLAwareRepositoryTest.php b/src/Bundle/ChillTaskBundle/Tests/Repository/SingleTaskACLAwareRepositoryTest.php new file mode 100644 index 000000000..f4c54b6cc --- /dev/null +++ b/src/Bundle/ChillTaskBundle/Tests/Repository/SingleTaskACLAwareRepositoryTest.php @@ -0,0 +1,211 @@ +em = self::$container->get(EntityManagerInterface::class); + $this->userRepository = self::$container->get(UserRepository::class); + $this->centerRepository = self::$container->get(CenterRepositoryInterface::class); + $this->scopeRepository = self::$container->get(ScopeRepository::class); + $this->personRepository = self::$container->get(PersonRepository::class); + } + + public function testCountByPerson(): void + { + $centerA = $this->centerRepository->findOneBy(['name' => 'Center A']); + $user = new User(); + $scopes = $this->scopeRepository->findAll(); + $person = $this->getRandomPerson($this->em); + + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn($user); + + $centerResolverDispatcher = $this->prophesize(CenterResolverManagerInterface::class); + $centerResolverDispatcher->resolveCenters(Argument::type(Person::class), Argument::any()) + ->willReturn([$centerA]); + + $authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class); + $authorizationHelper->getReachableScopes(Argument::exact($user), Argument::exact(TaskVoter::SHOW), Argument::exact($centerA)) + ->willReturn($scopes); + + $repository = new SingleTaskAclAwareRepository( + $centerResolverDispatcher->reveal(), + $this->em, + $security->reveal(), + $authorizationHelper->reveal() + ); + + $nb = $repository->countByPerson($person, null, []); + + $this->assertGreaterThanOrEqual(0, $nb); + } + + public function testFindByPerson(): void + { + $centerA = $this->centerRepository->findOneBy(['name' => 'Center A']); + $user = new User(); + $scopes = $this->scopeRepository->findAll(); + $person = $this->getRandomPerson($this->em); + + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn($user); + + $centerResolverDispatcher = $this->prophesize(CenterResolverManagerInterface::class); + $centerResolverDispatcher->resolveCenters(Argument::type(Person::class), Argument::any()) + ->willReturn([$centerA]); + + $authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class); + $authorizationHelper->getReachableScopes(Argument::exact($user), Argument::exact(TaskVoter::SHOW), Argument::exact($centerA)) + ->willReturn($scopes); + + $repository = new SingleTaskAclAwareRepository( + $centerResolverDispatcher->reveal(), + $this->em, + $security->reveal(), + $authorizationHelper->reveal() + ); + + $tasks = $repository->findByPerson($person, null, []); + + $this->assertGreaterThanOrEqual(0, count($tasks)); + } + + public function testFindByAllViewable(): void + { + $centerA = $this->centerRepository->findOneBy(['name' => 'Center A']); + $user = new User(); + $scopes = $this->scopeRepository->findAll(); + + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn($user); + + $centerResolverDispatcher = $this->prophesize(CenterResolverManagerInterface::class); + $centerResolverDispatcher->resolveCenters(Argument::type(Person::class), Argument::any()) + ->willReturn([$centerA]); + + $authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class); + $authorizationHelper->getReachableCenters(Argument::exact($user), Argument::exact(TaskVoter::SHOW)) + ->willReturn([$centerA]); + $authorizationHelper->getReachableScopes(Argument::exact($user), Argument::exact(TaskVoter::SHOW), Argument::exact($centerA)) + ->willReturn($scopes); + + $repository = new SingleTaskAclAwareRepository( + $centerResolverDispatcher->reveal(), + $this->em, + $security->reveal(), + $authorizationHelper->reveal() + ); + + $tasks = $repository->findByAllViewable(null, []); + + $this->assertGreaterThanOrEqual(0, count($tasks)); + } + + public function testCountByAllViewable(): void + { + $centerA = $this->centerRepository->findOneBy(['name' => 'Center A']); + $user = new User(); + $scopes = $this->scopeRepository->findAll(); + + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn($user); + + $centerResolverDispatcher = $this->prophesize(CenterResolverManagerInterface::class); + $centerResolverDispatcher->resolveCenters(Argument::type(Person::class), Argument::any()) + ->willReturn([$centerA]); + + $authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class); + $authorizationHelper->getReachableCenters(Argument::exact($user), Argument::exact(TaskVoter::SHOW)) + ->willReturn([$centerA]); + $authorizationHelper->getReachableScopes(Argument::exact($user), Argument::exact(TaskVoter::SHOW), Argument::exact($centerA)) + ->willReturn($scopes); + + $repository = new SingleTaskAclAwareRepository( + $centerResolverDispatcher->reveal(), + $this->em, + $security->reveal(), + $authorizationHelper->reveal() + ); + + $nb = $repository->countByAllViewable(null, []); + + $this->assertGreaterThanOrEqual(0, $nb); + } + + public function testFindByCourse(): void + { + $centerA = $this->centerRepository->findOneBy(['name' => 'Center A']); + $user = new User(); + $scopes = $this->scopeRepository->findAll(); + /** @var Person $person */ + $person = $this->em->createQuery( + 'SELECT p FROM '.Person::class.' p JOIN p.centerCurrent cc + WHERE SIZE(p.accompanyingPeriodParticipations) > 0 + AND cc.center = :center' + ) + ->setParameter('center', $centerA) + ->setMaxResults(1) + ->getSingleResult() + ; + $period = $person->getAccompanyingPeriodParticipations()->first()->getAccompanyingPeriod(); + + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn($user); + + $centerResolverDispatcher = $this->prophesize(CenterResolverManagerInterface::class); + $centerResolverDispatcher->resolveCenters(Argument::type(AccompanyingPeriod::class), Argument::any()) + ->willReturn([$centerA]); + + $authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class); + $authorizationHelper->getReachableScopes(Argument::exact($user), Argument::exact(TaskVoter::SHOW), Argument::any()) + ->willReturn($scopes); + + $repository = new SingleTaskAclAwareRepository( + $centerResolverDispatcher->reveal(), + $this->em, + $security->reveal(), + $authorizationHelper->reveal() + ); + + $tasks = $repository->findByCourse($period); + + $this->assertGreaterThanOrEqual(0, count($tasks)); + } +} \ No newline at end of file