mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-10-07 05:49:42 +00:00
Introduce `PostPublicViewMessage` and `PostPublicViewMessageHandler` to handle external user views on public links by applying workflow transitions. Integrate with `WorkflowViewSendPublicController` and add relevant tests.
90 lines
3.6 KiB
PHP
90 lines
3.6 KiB
PHP
<?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\Controller;
|
|
|
|
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSend;
|
|
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSendView;
|
|
use Chill\MainBundle\Workflow\EntityWorkflowManager;
|
|
use Chill\MainBundle\Workflow\Exception\HandlerWithPublicViewNotFoundException;
|
|
use Chill\MainBundle\Workflow\Messenger\PostPublicViewMessage;
|
|
use Chill\MainBundle\Workflow\Templating\EntityWorkflowViewMetadataDTO;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\Clock\ClockInterface;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
|
use Symfony\Component\Messenger\MessageBusInterface;
|
|
use Symfony\Component\Routing\Annotation\Route;
|
|
use Twig\Environment;
|
|
|
|
final readonly class WorkflowViewSendPublicController
|
|
{
|
|
public const LOG_PREFIX = '[workflow-view-send-public-controller] ';
|
|
|
|
public function __construct(
|
|
private EntityManagerInterface $entityManager,
|
|
private LoggerInterface $chillLogger,
|
|
private EntityWorkflowManager $entityWorkflowManager,
|
|
private ClockInterface $clock,
|
|
private Environment $environment,
|
|
private MessageBusInterface $messageBus,
|
|
) {}
|
|
|
|
#[Route('/public/main/workflow/send/{uuid}/view/{verificationKey}', name: 'chill_main_workflow_send_view_public', methods: ['GET'])]
|
|
public function __invoke(EntityWorkflowSend $workflowSend, string $verificationKey, Request $request): Response
|
|
{
|
|
if (50 < $workflowSend->getNumberOfErrorTrials()) {
|
|
throw new AccessDeniedHttpException('number of trials exceeded, no more access allowed');
|
|
}
|
|
|
|
if ($verificationKey !== $workflowSend->getPrivateToken()) {
|
|
$this->chillLogger->info(self::LOG_PREFIX.'Invalid trial for this send', ['client_ip' => $request->getClientIp()]);
|
|
$workflowSend->increaseErrorTrials();
|
|
$this->entityManager->flush();
|
|
|
|
throw new AccessDeniedHttpException('invalid verification key');
|
|
}
|
|
|
|
if ($this->clock->now() > $workflowSend->getExpireAt()) {
|
|
return new Response(
|
|
$this->environment->render('@ChillMain/Workflow/workflow_view_send_public_expired.html.twig'),
|
|
409
|
|
);
|
|
}
|
|
|
|
if (100 < $workflowSend->getViews()->count()) {
|
|
$this->chillLogger->info(self::LOG_PREFIX.'100 view reached, not allowed to see it again');
|
|
throw new AccessDeniedHttpException('100 views reached, not allowed to see it again');
|
|
}
|
|
|
|
try {
|
|
$metadata = new EntityWorkflowViewMetadataDTO(
|
|
$workflowSend->getViews()->count(),
|
|
100 - $workflowSend->getViews()->count(),
|
|
);
|
|
$response = new Response(
|
|
$this->entityWorkflowManager->renderPublicView($workflowSend, $metadata),
|
|
);
|
|
|
|
$view = new EntityWorkflowSendView($workflowSend, $this->clock->now(), $request->getClientIp());
|
|
$this->entityManager->persist($view);
|
|
$this->messageBus->dispatch(new PostPublicViewMessage($view->getId()));
|
|
$this->entityManager->flush();
|
|
|
|
return $response;
|
|
} catch (HandlerWithPublicViewNotFoundException $e) {
|
|
throw new \RuntimeException('Could not render the public view', previous: $e);
|
|
}
|
|
}
|
|
}
|