mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-10-31 01:08:26 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			create-adm
			...
			signature-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7aa63a25a7 | 
| @@ -0,0 +1,45 @@ | ||||
| <?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\Entity\StoredObject; | ||||
| 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 Symfony\Component\HttpFoundation\Response; | ||||
| use Symfony\Component\Messenger\MessageBusInterface; | ||||
| use Symfony\Component\Routing\Annotation\Route; | ||||
|  | ||||
| class SignatureRequestController | ||||
| { | ||||
|     public function __construct( | ||||
|         private MessageBusInterface $messageBus, | ||||
|         private StoredObjectManagerInterface $storedObjectManager, | ||||
|     ) {} | ||||
|  | ||||
|     #[Route('/api/1.0/document/workflow/{id}/signature-request', name: 'chill_docstore_signature_request')] | ||||
|     public function processSignature(StoredObject $storedObject): Response | ||||
|     { | ||||
|         $content = $this->storedObjectManager->read($storedObject); | ||||
|  | ||||
|         $this->messageBus->dispatch(new RequestPdfSignMessage( | ||||
|             0, | ||||
|             new PDFSignatureZone(10.0, 10.0, 180.0, 180.0, new PDFPage(0, 500.0, 800.0)), | ||||
|             0, | ||||
|             'test signature', | ||||
|             $content | ||||
|         )); | ||||
|  | ||||
|         return new Response('<html><head><title>test</title></head><body><p>ok</p></body></html>'); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| <?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\Service\Signature\Driver\BaseSigner; | ||||
|  | ||||
| use Chill\DocStoreBundle\Service\Signature\PDFSignatureZone; | ||||
|  | ||||
| final readonly class RequestPdfSignMessage | ||||
| { | ||||
|     public function __construct( | ||||
|         public int $signatureId, | ||||
|         public PDFSignatureZone $PDFSignatureZone, | ||||
|         public int $signatureZoneIndex, | ||||
|         public string $reason, | ||||
|         public string $content, | ||||
|     ) {} | ||||
| } | ||||
| @@ -0,0 +1,94 @@ | ||||
| <?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\Service\Signature\Driver\BaseSigner; | ||||
|  | ||||
| use Chill\DocStoreBundle\Service\Signature\PDFSignatureZone; | ||||
| use Symfony\Component\Messenger\Envelope; | ||||
| use Symfony\Component\Messenger\Exception\MessageDecodingFailedException; | ||||
| use Symfony\Component\Messenger\Stamp\NonSendableStampInterface; | ||||
| use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface; | ||||
| use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; | ||||
| use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; | ||||
| use Symfony\Component\Serializer\Normalizer\NormalizerInterface; | ||||
|  | ||||
| final readonly class RequestPdfSignMessageSerializer implements SerializerInterface | ||||
| { | ||||
|     public function __construct( | ||||
|         private NormalizerInterface $normalizer, | ||||
|         private DenormalizerInterface $denormalizer, | ||||
|     ) {} | ||||
|  | ||||
|     public function decode(array $encodedEnvelope): Envelope | ||||
|     { | ||||
|         $body = $encodedEnvelope['body']; | ||||
|         $headers = $encodedEnvelope['headers']; | ||||
|  | ||||
|         if (RequestPdfSignMessage::class !== ($headers['Message'] ?? null)) { | ||||
|             throw new MessageDecodingFailedException('serializer does not support this message'); | ||||
|         } | ||||
|  | ||||
|         $data = json_decode($body, true); | ||||
|  | ||||
|         $zoneSignature = $this->denormalizer->denormalize($data['signatureZone'], PDFSignatureZone::class, 'json', [ | ||||
|             AbstractNormalizer::GROUPS => ['write'], | ||||
|         ]); | ||||
|  | ||||
|         $message = new RequestPdfSignMessage( | ||||
|             $data['signatureId'], | ||||
|             $zoneSignature, | ||||
|             $data['signatureZoneIndex'], | ||||
|             $data['reason'], | ||||
|             base64_decode($data['content']), | ||||
|         ); | ||||
|  | ||||
|         // in case of redelivery, unserialize any stamps | ||||
|         $stamps = []; | ||||
|         if (isset($headers['stamps'])) { | ||||
|             $stamps = unserialize($headers['stamps']); | ||||
|         } | ||||
|  | ||||
|         return new Envelope($message, $stamps); | ||||
|     } | ||||
|  | ||||
|     public function encode(Envelope $envelope): array | ||||
|     { | ||||
|         $message = $envelope->getMessage(); | ||||
|  | ||||
|         if (!$message instanceof RequestPdfSignMessage) { | ||||
|             throw new MessageDecodingFailedException('Message is not a RequestPdfSignMessage'); | ||||
|         } | ||||
|  | ||||
|         $data = [ | ||||
|             'signatureId' => $message->signatureId, | ||||
|             'signatureZoneIndex' => $message->signatureZoneIndex, | ||||
|             'signatureZone' => $this->normalizer->normalize($message->PDFSignatureZone, 'json', [AbstractNormalizer::GROUPS => ['read']]), | ||||
|             'reason' => $message->reason, | ||||
|             'content' => base64_encode($message->content), | ||||
|         ]; | ||||
|  | ||||
|         $allStamps = []; | ||||
|         foreach ($envelope->all() as $stamp) { | ||||
|             if ($stamp instanceof NonSendableStampInterface) { | ||||
|                 continue; | ||||
|             } | ||||
|             $allStamps = [...$allStamps, ...$stamp]; | ||||
|         } | ||||
|  | ||||
|         return [ | ||||
|             'body' => json_encode($data, JSON_THROW_ON_ERROR, 512), | ||||
|             'headers' => [ | ||||
|                 'stamps' => serialize($allStamps), | ||||
|                 'Message' => RequestPdfSignMessage::class, | ||||
|             ], | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,132 @@ | ||||
| <?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\Tests\Service\Signature\Driver\BaseSigner; | ||||
|  | ||||
| use Chill\DocStoreBundle\Service\Signature\PDFPage; | ||||
| use Chill\DocStoreBundle\Service\Signature\PDFSignatureZone; | ||||
| use Chill\DocStoreBundle\Service\Signature\Driver\BaseSigner\RequestPdfSignMessage; | ||||
| use Chill\DocStoreBundle\Service\Signature\Driver\BaseSigner\RequestPdfSignMessageSerializer; | ||||
| use PHPUnit\Framework\TestCase; | ||||
| use Symfony\Component\Messenger\Envelope; | ||||
| use Symfony\Component\Serializer\Exception\UnexpectedValueException; | ||||
| use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; | ||||
| use Symfony\Component\Serializer\Normalizer\NormalizerInterface; | ||||
| use Symfony\Component\Serializer\Serializer; | ||||
|  | ||||
| /** | ||||
|  * @internal | ||||
|  * | ||||
|  * @coversNothing | ||||
|  */ | ||||
| class RequestPdfSignMessageSerializerTest extends TestCase | ||||
| { | ||||
|     public function testEncode(): void | ||||
|     { | ||||
|         $serializer = $this->buildSerializer(); | ||||
|  | ||||
|         $envelope = new Envelope( | ||||
|             $request = new RequestPdfSignMessage( | ||||
|                 0, | ||||
|                 new PDFSignatureZone(10.0, 10.0, 180.0, 180.0, new PDFPage(0, 500.0, 800.0)), | ||||
|                 0, | ||||
|                 'metadata to add to the signature', | ||||
|                 'abc' | ||||
|             ), | ||||
|         ); | ||||
|  | ||||
|         $actual = $serializer->encode($envelope); | ||||
|         $expectedBody = json_encode([ | ||||
|             'signatureId' => $request->signatureId, | ||||
|             'signatureZoneIndex' => $request->signatureZoneIndex, | ||||
|             'signatureZone' => ['x' => 10.0], | ||||
|             'reason' => $request->reason, | ||||
|             'content' => base64_encode($request->content), | ||||
|         ]); | ||||
|  | ||||
|         self::assertIsArray($actual); | ||||
|         self::assertArrayHasKey('body', $actual); | ||||
|         self::assertArrayHasKey('headers', $actual); | ||||
|         self::assertEquals($expectedBody, $actual['body']); | ||||
|     } | ||||
|  | ||||
|     public function testDecode(): void | ||||
|     { | ||||
|         $serializer = $this->buildSerializer(); | ||||
|  | ||||
|         $request = new RequestPdfSignMessage( | ||||
|             0, | ||||
|             new PDFSignatureZone(10.0, 10.0, 180.0, 180.0, new PDFPage(0, 500.0, 800.0)), | ||||
|             0, | ||||
|             'metadata to add to the signature', | ||||
|             'abc' | ||||
|         ); | ||||
|  | ||||
|         $bodyAsString = json_encode([ | ||||
|             'signatureId' => $request->signatureId, | ||||
|             'signatureZoneIndex' => $request->signatureZoneIndex, | ||||
|             'signatureZone' => ['x' => 10.0], | ||||
|             'reason' => $request->reason, | ||||
|             'content' => base64_encode($request->content), | ||||
|         ], JSON_THROW_ON_ERROR); | ||||
|  | ||||
|         $actual = $serializer->decode([ | ||||
|             'body' => $bodyAsString, | ||||
|             'headers' => [ | ||||
|                 'Message' => RequestPdfSignMessage::class, | ||||
|             ], | ||||
|         ]); | ||||
|  | ||||
|         self::assertInstanceOf(RequestPdfSignMessage::class, $actual->getMessage()); | ||||
|         self::assertEquals($request->signatureId, $actual->getMessage()->signatureId); | ||||
|         self::assertEquals($request->signatureZoneIndex, $actual->getMessage()->signatureZoneIndex); | ||||
|         self::assertEquals($request->reason, $actual->getMessage()->reason); | ||||
|         self::assertEquals($request->content, $actual->getMessage()->content); | ||||
|         self::assertNotNull($actual->getMessage()->PDFSignatureZone); | ||||
|     } | ||||
|  | ||||
|     private function buildSerializer(): RequestPdfSignMessageSerializer | ||||
|     { | ||||
|         $normalizer = | ||||
|             new class () implements NormalizerInterface { | ||||
|                 public function normalize($object, ?string $format = null, array $context = []): array | ||||
|                 { | ||||
|                     if (!$object instanceof PDFSignatureZone) { | ||||
|                         throw new UnexpectedValueException('expected RequestPdfSignMessage'); | ||||
|                     } | ||||
|  | ||||
|                     return [ | ||||
|                         'x' => $object->x, | ||||
|                     ]; | ||||
|                 } | ||||
|  | ||||
|                 public function supportsNormalization($data, ?string $format = null): bool | ||||
|                 { | ||||
|                     return $data instanceof PDFSignatureZone; | ||||
|                 } | ||||
|             }; | ||||
|         $denormalizer = new class () implements DenormalizerInterface { | ||||
|             public function denormalize($data, string $type, ?string $format = null, array $context = []) | ||||
|             { | ||||
|                 return new PDFSignatureZone(10.0, 10.0, 180.0, 180.0, new PDFPage(0, 500.0, 800.0)); | ||||
|             } | ||||
|  | ||||
|             public function supportsDenormalization($data, string $type, ?string $format = null) | ||||
|             { | ||||
|                 return PDFSignatureZone::class === $type; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         $serializer = new Serializer([$normalizer, $denormalizer]); | ||||
|  | ||||
|         return new RequestPdfSignMessageSerializer($serializer, $serializer); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user