mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Allow users to edit a document if they were added to the previous step of a workflow.
OP#826 Workflow - les utilisateurs des étapes précédentes sur un workflow doivent aussi avoir la main sur les étapes en cours du workflow (Vendee/accent-suivi-developpement/1289) https://champs-libres.openproject.com/work_packages/826
This commit is contained in:
parent
5339d4f5d9
commit
64d91e2afe
@ -16,6 +16,9 @@ use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
|||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Component\Workflow\Registry;
|
use Symfony\Component\Workflow\Registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an object, associated with a workflow, is blocked, or not, by this workflow.
|
||||||
|
*/
|
||||||
class WorkflowStoredObjectPermissionHelper
|
class WorkflowStoredObjectPermissionHelper
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@ -24,28 +27,19 @@ class WorkflowStoredObjectPermissionHelper
|
|||||||
private readonly Registry $registry,
|
private readonly Registry $registry,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the user is allowed to update the given object.
|
||||||
|
*
|
||||||
|
* Return false if some workflow block the edition of the object.
|
||||||
|
*/
|
||||||
public function notBlockedByWorkflow(object $entity): bool
|
public function notBlockedByWorkflow(object $entity): bool
|
||||||
{
|
{
|
||||||
$entityWorkflows = $this->entityWorkflowManager->findByRelatedEntity($entity);
|
$entityWorkflows = $this->entityWorkflowManager->findByRelatedEntity($entity);
|
||||||
$currentUser = $this->security->getUser();
|
$currentUser = $this->security->getUser();
|
||||||
|
|
||||||
|
$usersInvolved = [];
|
||||||
|
$entityWorkflowsNotFinalizedPositive = [];
|
||||||
foreach ($entityWorkflows as $entityWorkflow) {
|
foreach ($entityWorkflows as $entityWorkflow) {
|
||||||
if ($entityWorkflow->isFinal()) {
|
|
||||||
|
|
||||||
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
|
|
||||||
$marking = $workflow->getMarkingStore()->getMarking($entityWorkflow);
|
|
||||||
foreach ($marking->getPlaces() as $place => $active) {
|
|
||||||
$metadata = $workflow->getMetadataStore()->getPlaceMetadata($place);
|
|
||||||
if ($metadata['isFinalPositive'] ?? true) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!$entityWorkflow->getCurrentStep()->getAllDestUser()->contains($currentUser)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// as soon as there is one signatured applyied, we are not able to
|
// as soon as there is one signatured applyied, we are not able to
|
||||||
// edit the document any more
|
// edit the document any more
|
||||||
foreach ($entityWorkflow->getSteps() as $step) {
|
foreach ($entityWorkflow->getSteps() as $step) {
|
||||||
@ -55,6 +49,33 @@ class WorkflowStoredObjectPermissionHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($entityWorkflow->isFinal()) {
|
||||||
|
$workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName());
|
||||||
|
$marking = $workflow->getMarkingStore()->getMarking($entityWorkflow);
|
||||||
|
foreach ($marking->getPlaces() as $place => $active) {
|
||||||
|
$metadata = $workflow->getMetadataStore()->getPlaceMetadata($place);
|
||||||
|
if ($metadata['isFinalPositive'] ?? true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$entityWorkflowsNotFinalizedPositive[] = $entityWorkflow;
|
||||||
|
foreach ($entityWorkflow->getSteps() as $step) {
|
||||||
|
foreach ($step->getAllDestUser()->toArray() as $user) {
|
||||||
|
$usersInvolved[] = $user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there isn't any user, but a workflow, blocked
|
||||||
|
if ([] !== $entityWorkflowsNotFinalizedPositive) {
|
||||||
|
if ([] === $usersInvolved) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return in_array($currentUser, $usersInvolved, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -53,13 +53,24 @@ class WorkflowStoredObjectPermissionHelperTest extends TestCase
|
|||||||
self::assertEquals($expected, $helper->notBlockedByWorkflow($entityWorkflow), $message);
|
self::assertEquals($expected, $helper->notBlockedByWorkflow($entityWorkflow), $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildHelper(object $relatedEntity, EntityWorkflow $entityWorkflow, User $user): WorkflowStoredObjectPermissionHelper
|
public function testNoWorkflow(): void
|
||||||
|
{
|
||||||
|
$object = new \stdClass();
|
||||||
|
$helper = $this->buildHelper($object, null, $user = new User());
|
||||||
|
self::assertTrue($helper->notBlockedByWorkflow($object), "the user is not blocked by the user, as there aren't any user inside");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildHelper(object $relatedEntity, ?EntityWorkflow $entityWorkflow, User $user): WorkflowStoredObjectPermissionHelper
|
||||||
{
|
{
|
||||||
$security = $this->prophesize(Security::class);
|
$security = $this->prophesize(Security::class);
|
||||||
$security->getUser()->willReturn($user);
|
$security->getUser()->willReturn($user);
|
||||||
|
|
||||||
$entityWorkflowManager = $this->prophesize(EntityWorkflowManager::class);
|
$entityWorkflowManager = $this->prophesize(EntityWorkflowManager::class);
|
||||||
$entityWorkflowManager->findByRelatedEntity(Argument::type('object'))->willReturn([$entityWorkflow]);
|
if (null !== $entityWorkflow) {
|
||||||
|
$entityWorkflowManager->findByRelatedEntity(Argument::type('object'))->willReturn([$entityWorkflow]);
|
||||||
|
} else {
|
||||||
|
$entityWorkflowManager->findByRelatedEntity(Argument::type('object'))->willReturn([]);
|
||||||
|
}
|
||||||
|
|
||||||
return new WorkflowStoredObjectPermissionHelper($security->reveal(), $entityWorkflowManager->reveal(), $this->buildRegistry());
|
return new WorkflowStoredObjectPermissionHelper($security->reveal(), $entityWorkflowManager->reveal(), $this->buildRegistry());
|
||||||
}
|
}
|
||||||
@ -79,6 +90,16 @@ class WorkflowStoredObjectPermissionHelperTest extends TestCase
|
|||||||
|
|
||||||
yield [$entityWorkflow, $user, true, 'allowed because the user is present as a dest user'];
|
yield [$entityWorkflow, $user, true, 'allowed because the user is present as a dest user'];
|
||||||
|
|
||||||
|
$entityWorkflow = new EntityWorkflow();
|
||||||
|
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||||
|
$dto->futureDestUsers[] = $user = new User();
|
||||||
|
$entityWorkflow->setStep('test', $dto, 'to_test', new \DateTimeImmutable(), $user);
|
||||||
|
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||||
|
$dto->futureDestUsers[] = new User();
|
||||||
|
$entityWorkflow->setStep('test', $dto, 'to_test', new \DateTimeImmutable(), $user);
|
||||||
|
|
||||||
|
yield [$entityWorkflow, $user, true, 'allowed because the user is present as a **previous** dest user'];
|
||||||
|
|
||||||
$entityWorkflow = new EntityWorkflow();
|
$entityWorkflow = new EntityWorkflow();
|
||||||
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
$dto = new WorkflowTransitionContextDTO($entityWorkflow);
|
||||||
$dto->futureDestUsers[] = $user = new User();
|
$dto->futureDestUsers[] = $user = new User();
|
||||||
|
@ -243,6 +243,9 @@ class EntityWorkflow implements TrackCreationInterface, TrackUpdateInterface
|
|||||||
throw new \RuntimeException();
|
throw new \RuntimeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Selectable<int, EntityWorkflowStep>&Collection<int, EntityWorkflowStep>
|
||||||
|
*/
|
||||||
public function getSteps(): Collection&Selectable
|
public function getSteps(): Collection&Selectable
|
||||||
{
|
{
|
||||||
return $this->steps;
|
return $this->steps;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user