mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-10-04 12:29:43 +00:00
Partage d'export enregistré et génération asynchrone des exports
This commit is contained in:
@@ -11,12 +11,21 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Security\Authorization;
|
||||
|
||||
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
|
||||
class ChillExportVoter extends Voter
|
||||
class ChillExportVoter extends Voter implements ProvideRoleHierarchyInterface
|
||||
{
|
||||
final public const EXPORT = 'chill_export';
|
||||
/**
|
||||
* Role which give access to the creation of new export from the export itself.
|
||||
*/
|
||||
final public const COMPOSE_EXPORT = 'CHILL_MAIN_COMPOSE_EXPORT';
|
||||
|
||||
/**
|
||||
* Role which give access to the execution and edition to the saved exports, but not for creating new ones.
|
||||
*/
|
||||
final public const GENERATE_SAVED_EXPORT = 'CHILL_MAIN_GENERATE_SAVED_EXPORT';
|
||||
|
||||
private readonly VoterHelperInterface $helper;
|
||||
|
||||
@@ -24,7 +33,7 @@ class ChillExportVoter extends Voter
|
||||
{
|
||||
$this->helper = $voterHelperFactory
|
||||
->generate(self::class)
|
||||
->addCheckFor(null, [self::EXPORT])
|
||||
->addCheckFor(null, [self::COMPOSE_EXPORT, self::GENERATE_SAVED_EXPORT])
|
||||
->build();
|
||||
}
|
||||
|
||||
@@ -37,4 +46,21 @@ class ChillExportVoter extends Voter
|
||||
{
|
||||
return $this->helper->voteOnAttribute($attribute, $subject, $token);
|
||||
}
|
||||
|
||||
public function getRolesWithHierarchy(): array
|
||||
{
|
||||
return ['export.role.export_role' => [
|
||||
self::COMPOSE_EXPORT, self::GENERATE_SAVED_EXPORT,
|
||||
]];
|
||||
}
|
||||
|
||||
public function getRoles(): array
|
||||
{
|
||||
return [self::COMPOSE_EXPORT, self::GENERATE_SAVED_EXPORT];
|
||||
}
|
||||
|
||||
public function getRolesWithoutScope(): array
|
||||
{
|
||||
return $this->getRoles();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,32 @@
|
||||
<?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;
|
||||
|
||||
use Chill\MainBundle\Entity\ExportGeneration;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
|
||||
class ExportGenerationVoter extends Voter
|
||||
{
|
||||
public const VIEW = 'view';
|
||||
|
||||
protected function supports(string $attribute, $subject)
|
||||
{
|
||||
return self::VIEW === $attribute && $subject instanceof ExportGeneration;
|
||||
}
|
||||
|
||||
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token)
|
||||
{
|
||||
/* @var ExportGeneration $subject */
|
||||
return $token->getUser()->getUserIdentifier() === $subject->getCreatedBy()->getUserIdentifier();
|
||||
}
|
||||
}
|
@@ -12,23 +12,37 @@ declare(strict_types=1);
|
||||
namespace Chill\MainBundle\Security\Authorization;
|
||||
|
||||
use Chill\MainBundle\Entity\SavedExport;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Export\ExportManager;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
|
||||
class SavedExportVoter extends Voter
|
||||
final class SavedExportVoter extends Voter
|
||||
{
|
||||
final public const DELETE = 'CHLL_MAIN_EXPORT_SAVED_DELETE';
|
||||
final public const DELETE = 'CHILL_MAIN_EXPORT_SAVED_DELETE';
|
||||
|
||||
final public const EDIT = 'CHLL_MAIN_EXPORT_SAVED_EDIT';
|
||||
final public const EDIT = 'CHILL_MAIN_EXPORT_SAVED_EDIT';
|
||||
|
||||
final public const GENERATE = 'CHLL_MAIN_EXPORT_SAVED_GENERATE';
|
||||
final public const GENERATE = 'CHILL_MAIN_EXPORT_SAVED_GENERATE';
|
||||
|
||||
final public const DUPLICATE = 'CHILL_MAIN_EXPORT_SAVED_DUPLICATE';
|
||||
|
||||
final public const SHARE = 'CHILL_MAIN_EXPORT_SAVED_SHARE';
|
||||
|
||||
private const ALL = [
|
||||
self::DELETE,
|
||||
self::EDIT,
|
||||
self::GENERATE,
|
||||
self::SHARE,
|
||||
self::DUPLICATE,
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
private readonly ExportManager $exportManager,
|
||||
private readonly AccessDecisionManagerInterface $accessDecisionManager,
|
||||
) {}
|
||||
|
||||
protected function supports($attribute, $subject): bool
|
||||
{
|
||||
return $subject instanceof SavedExport && \in_array($attribute, self::ALL, true);
|
||||
@@ -36,9 +50,30 @@ class SavedExportVoter extends Voter
|
||||
|
||||
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
|
||||
{
|
||||
/* @var SavedExport $subject */
|
||||
$user = $token->getUser();
|
||||
|
||||
if (!$user instanceof User) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return match ($attribute) {
|
||||
self::DELETE, self::EDIT, self::GENERATE => $subject->getUser() === $token->getUser(),
|
||||
self::DELETE, self::EDIT => $subject->getUser() === $token->getUser(),
|
||||
self::SHARE => $subject->getUser() === $token->getUser() && $this->accessDecisionManager->decide($token, [ChillExportVoter::COMPOSE_EXPORT]),
|
||||
self::DUPLICATE => $this->accessDecisionManager->decide($token, [ChillExportVoter::COMPOSE_EXPORT]) && $this->accessDecisionManager->decide($token, [self::EDIT], $subject) ,
|
||||
self::GENERATE => $this->canUserGenerate($user, $subject),
|
||||
default => throw new \UnexpectedValueException('attribute not supported: '.$attribute),
|
||||
};
|
||||
}
|
||||
|
||||
private function canUserGenerate(User $user, SavedExport $savedExport): bool
|
||||
{
|
||||
if (!($savedExport->getUser() === $user || $savedExport->isSharedWithUser($user))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$export = $this->exportManager->getExport($savedExport->getExportAlias());
|
||||
|
||||
return $this->exportManager->isGrantedForElement($export);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,43 @@
|
||||
<?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 Chill\MainBundle\Security\Authorization\ExportGenerationVoter;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
|
||||
final readonly class ExportGenerationStoredObjectVoter implements StoredObjectVoterInterface
|
||||
{
|
||||
public function __construct(private ExportGenerationRepository $repository, private Security $security) {}
|
||||
|
||||
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 $this->security->isGranted(ExportGenerationVoter::VIEW, $generation);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user