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`.
This commit is contained in:
Julien Fastré 2025-03-13 17:23:05 +01:00
parent bd61eedfbb
commit 70ca4acafb
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
2 changed files with 55 additions and 1 deletions

View File

@ -11,17 +11,30 @@ declare(strict_types=1);
namespace Chill\MainBundle\Repository; namespace Chill\MainBundle\Repository;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
use Chill\MainBundle\Entity\ExportGeneration; use Chill\MainBundle\Entity\ExportGeneration;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
/** /**
* @extends ServiceEntityRepository<ExportGeneration> * @extends ServiceEntityRepository<ExportGeneration>
*
* @implements AssociatedEntityToStoredObjectInterface<ExportGeneration>
*/ */
class ExportGenerationRepository extends ServiceEntityRepository class ExportGenerationRepository extends ServiceEntityRepository implements AssociatedEntityToStoredObjectInterface
{ {
public function __construct(ManagerRegistry $registry) public function __construct(ManagerRegistry $registry)
{ {
parent::__construct($registry, ExportGeneration::class); parent::__construct($registry, ExportGeneration::class);
} }
public function findAssociatedEntityToStoredObject(StoredObject $storedObject): ?ExportGeneration
{
return $this->createQueryBuilder('e')
->where('e.storedObject = :storedObject')
->setParameter('storedObject', $storedObject)
->getQuery()
->getOneOrNullResult();
}
} }

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Security\Authorization\StoredObject;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoterInterface;
use Chill\MainBundle\Repository\ExportGenerationRepository;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
final readonly class ExportGenerationStoredObjectVoter implements StoredObjectVoterInterface
{
public function __construct(private ExportGenerationRepository $repository) {}
public function supports(StoredObjectRoleEnum $attribute, StoredObject $subject): bool
{
return null !== $this->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();
}
}