From 70ca4acafb9ac518fc22f1c7a414b0a2bf54bfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 13 Mar 2025 17:23:05 +0100 Subject: [PATCH] Add voter for ExportGeneration stored object authorization Introduces `ExportGenerationStoredObjectVoter` to handle permissions for stored objects linked to export generations. Implements entity association retrieval in `ExportGenerationRepository` by adhering to `AssociatedEntityToStoredObjectInterface`. --- .../Repository/ExportGenerationRepository.php | 15 ++++++- .../ExportGenerationStoredObjectVoter.php | 41 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/Bundle/ChillMainBundle/Security/Authorization/StoredObject/ExportGenerationStoredObjectVoter.php diff --git a/src/Bundle/ChillMainBundle/Repository/ExportGenerationRepository.php b/src/Bundle/ChillMainBundle/Repository/ExportGenerationRepository.php index e23407e9a..4482f2972 100644 --- a/src/Bundle/ChillMainBundle/Repository/ExportGenerationRepository.php +++ b/src/Bundle/ChillMainBundle/Repository/ExportGenerationRepository.php @@ -11,17 +11,30 @@ declare(strict_types=1); namespace Chill\MainBundle\Repository; +use Chill\DocStoreBundle\Entity\StoredObject; +use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface; use Chill\MainBundle\Entity\ExportGeneration; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; /** * @extends ServiceEntityRepository + * + * @implements AssociatedEntityToStoredObjectInterface */ -class ExportGenerationRepository extends ServiceEntityRepository +class ExportGenerationRepository extends ServiceEntityRepository implements AssociatedEntityToStoredObjectInterface { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, ExportGeneration::class); } + + public function findAssociatedEntityToStoredObject(StoredObject $storedObject): ?ExportGeneration + { + return $this->createQueryBuilder('e') + ->where('e.storedObject = :storedObject') + ->setParameter('storedObject', $storedObject) + ->getQuery() + ->getOneOrNullResult(); + } } diff --git a/src/Bundle/ChillMainBundle/Security/Authorization/StoredObject/ExportGenerationStoredObjectVoter.php b/src/Bundle/ChillMainBundle/Security/Authorization/StoredObject/ExportGenerationStoredObjectVoter.php new file mode 100644 index 000000000..5dd1ecac8 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Security/Authorization/StoredObject/ExportGenerationStoredObjectVoter.php @@ -0,0 +1,41 @@ +repository->findAssociatedEntityToStoredObject($subject); + } + + public function voteOnAttribute(StoredObjectRoleEnum $attribute, StoredObject $subject, TokenInterface $token): bool + { + if (StoredObjectRoleEnum::EDIT === $attribute) { + return false; + } + + if (null === $generation = $this->repository->findAssociatedEntityToStoredObject($subject)) { + throw new \UnexpectedValueException('generation not found'); + } + + return $token->getUser()->getUserIdentifier() === $generation->getCreatedBy()->getUserIdentifier(); + } +}