chill-bundles/src/Bundle/ChillDocStoreBundle/Controller/SignatureRequestController.php

115 lines
4.9 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\DocStoreBundle\Controller;
use Chill\DocStoreBundle\Service\Signature\Driver\BaseSigner\RequestPdfSignMessage;
use Chill\DocStoreBundle\Service\Signature\PDFPage;
use Chill\DocStoreBundle\Service\Signature\PDFSignatureZone;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
use Chill\DocStoreBundle\Service\StoredObjectToPdfConverter;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSignatureStateEnum;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowStepSignature;
use Chill\MainBundle\Templating\Entity\ChillEntityRenderManagerInterface;
use Chill\MainBundle\Security\Authorization\EntityWorkflowStepSignatureVoter;
use Chill\MainBundle\Templating\Entity\UserRender;
use Chill\MainBundle\Workflow\EntityWorkflowManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
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 Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class SignatureRequestController
{
public function __construct(
private readonly MessageBusInterface $messageBus,
private readonly StoredObjectManagerInterface $storedObjectManager,
private readonly EntityWorkflowManager $entityWorkflowManager,
private readonly ChillEntityRenderManagerInterface $entityRender,
private readonly NormalizerInterface $normalizer,
private readonly Security $security,
private readonly StoredObjectToPdfConverter $converter,
private readonly EntityManagerInterface $entityManager,
) {}
#[Route('/api/1.0/document/workflow/{id}/signature-request', name: 'chill_docstore_signature_request')]
public function processSignature(EntityWorkflowStepSignature $signature, Request $request): JsonResponse
{
if (!$this->security->isGranted(EntityWorkflowStepSignatureVoter::SIGN, $signature)) {
throw new AccessDeniedHttpException('not authorized to sign this step');
}
$entityWorkflow = $signature->getStep()->getEntityWorkflow();
if (EntityWorkflowSignatureStateEnum::PENDING !== $signature->getState()) {
return new JsonResponse([], status: Response::HTTP_CONFLICT);
}
$storedObject = $this->entityWorkflowManager->getAssociatedStoredObject($entityWorkflow);
if ('application/pdf' !== $storedObject->getType()) {
[$storedObject, $storedObjectVersion, $content] = $this->converter->addConvertedVersion($storedObject, $request->getLocale(), includeConvertedContent: true);
$this->entityManager->persist($storedObjectVersion);
$this->entityManager->flush();
} else {
$content = $this->storedObjectManager->read($storedObject);
}
$data = \json_decode((string) $request->getContent(), true, 512, JSON_THROW_ON_ERROR);
$zone = new PDFSignatureZone(
$data['zone']['index'],
$data['zone']['x'],
$data['zone']['y'],
$data['zone']['height'],
$data['zone']['width'],
new PDFPage($data['zone']['PDFPage']['index'], $data['zone']['PDFPage']['width'], $data['zone']['PDFPage']['height'])
);
$this->messageBus->dispatch(new RequestPdfSignMessage(
$signature->getId(),
$zone,
$data['zone']['index'],
'Signed by IP: '.(string) $request->getClientIp().', authenticated user: '.$this->entityRender->renderString($this->security->getUser(), []),
$this->entityRender->renderString($signature->getSigner(), [
// options for user render
'absence' => false,
'main_scope' => false,
UserRender::SPLIT_LINE_BEFORE_CHARACTER => 30,
// options for person render
'addAge' => false,
]),
$content
));
return new JsonResponse(null, JsonResponse::HTTP_OK, []);
}
#[Route('/api/1.0/document/workflow/{id}/check-signature', name: 'chill_docstore_check_signature')]
public function checkSignature(EntityWorkflowStepSignature $signature): JsonResponse
{
$entityWorkflow = $signature->getStep()->getEntityWorkflow();
$storedObject = $this->entityWorkflowManager->getAssociatedStoredObject($entityWorkflow);
return new JsonResponse(
[
'state' => $signature->getState(),
'storedObject' => $this->normalizer->normalize($storedObject, 'json'),
],
JsonResponse::HTTP_OK,
[]
);
}
}