diff --git a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php index c45ccfbad..ab8739ce9 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php +++ b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php @@ -20,29 +20,47 @@ use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Serializer\Model\Collection; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument; -use Chill\PersonBundle\Entity\SocialWork\Evaluation; -use Exception; + use GuzzleHttp\Client; + use GuzzleHttp\Exception\TransferException; use PhpOffice\PhpWord\TemplateProcessor; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\HeaderUtils; +use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlOpenstackGenerator; +use Jose\Component\Core\JWK; +use Base64Url\Base64Url; + +use Symfony\Component\HttpKernel\KernelInterface; // TODO à mettre dans services use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; -class DocGeneratorTemplateController extends AbstractController +use Symfony\Contracts\HttpClient\HttpClientInterface; + +final class DocGeneratorTemplateController extends AbstractController { private DocGeneratorTemplateRepository $docGeneratorTemplateRepository; private PaginatorFactory $paginatorFactory; - public function __construct(DocGeneratorTemplateRepository $docGeneratorTemplateRepository, PaginatorFactory $paginatorFactory) - { + private KernelInterface $kernel; + + private HttpClientInterface $client; + + public function __construct( + DocGeneratorTemplateRepository $docGeneratorTemplateRepository, + PaginatorFactory $paginatorFactory, + KernelInterface $kernel, + HttpClientInterface $client + ) { $this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository; $this->paginatorFactory = $paginatorFactory; + $this->kernel = $kernel; + $this->client = $client; } /** @@ -60,11 +78,39 @@ class DocGeneratorTemplateController extends AbstractController ): Response { $getUrlGen = $tempUrlGenerator->generate( 'GET', - $template->getFile() - ); + $template->getFile()->getFilename()); - $tmpfname = tempnam(sys_get_temp_dir(), 'DOC_TEMPLATE'); - file_put_contents($tmpfname, file_get_contents($getUrlGen->url)); + $data = $this->client->request('GET', $getUrlGen->url); + + $iv = $template->getFile()->getIv(); // iv as an Array + $ivGoodFormat = pack('C*', ...$iv); // iv as a String (ok for openssl_decrypt) + + $method = 'AES-256-CBC'; + + $key = $template->getFile()->getKeyInfos()['k']; + $keyGoodFormat = Base64Url::decode($key); + + $dataDecrypted = openssl_decrypt($data->getContent(), $method, $keyGoodFormat, 1, $ivGoodFormat); + + if ($dataDecrypted === FALSE) { + throw new \Exception("Error during Decrypt ", 1); + } + + $tmpfnameDeCrypted = tempnam($this->kernel->getCacheDir(), 'DECRYPT_DOC_TEMPLATE'); // plus ou moins + + if (!$handle = fopen($tmpfnameDeCrypted, 'a')) { + echo "Cannot open file ($tmpfnameDeCrypted)"; + exit; + } + + if (fwrite($handle, $dataDecrypted) === FALSE) { + echo "Cannot write to file ($tmpfnameDeCrypted)"; + exit; + } + + dump("Success, wrote ($dataDecrypted) to file ($tmpfnameDeCrypted)"); + + fclose($handle); $entity = $this->getDoctrine()->getRepository($entityClassName)->find($entityId); @@ -72,10 +118,10 @@ class DocGeneratorTemplateController extends AbstractController $context = new HouseholdMemberSelectionContext(); $datas = $context->getData($entity); } else { - throw new Exception('Not implemented', 1); + throw new \Exception('Not implemented', 1); } - $templateProcessor = new TemplateProcessor($tmpfname); + $templateProcessor = new TemplateProcessor($tmpfnameDeCrypted); foreach ($datas['setValues'] as $setValuesConf) { $templateProcessor->setValues($setValuesConf); @@ -85,12 +131,10 @@ class DocGeneratorTemplateController extends AbstractController $templateProcessor->cloneRowAndSetValues($cloneRowAndSetValues[0], $cloneRowAndSetValues[1]); } - $tmpfname2 = tempnam(sys_get_temp_dir(), 'DOC_GENERATED'); - $templateProcessor->saveAs($tmpfname2); + $tmpfnameGenerated = tempnam($this->kernel->getCacheDir(), 'DOC_GENERATED'); + $templateProcessor->saveAs($tmpfnameGenerated); - unlink($tmpfname); - - $fileContent = fopen($tmpfname2, 'rb'); // the generated file content + $fileContent = fopen($tmpfnameGenerated, 'rb'); // the generated file content $genDocName = 'doc_' . sprintf('%010d', mt_rand()) . '.docx'; @@ -99,7 +143,8 @@ class DocGeneratorTemplateController extends AbstractController $genDocName ); - unlink($tmpfname2); + unlink($tmpfnameDeCrypted); + unlink($tmpfnameGenerated); $client = new Client(); @@ -140,7 +185,7 @@ class DocGeneratorTemplateController extends AbstractController } throw new Exception('Unable to generate document.'); - } + } /** * @Route( diff --git a/src/Bundle/ChillDocGeneratorBundle/DataFixtures/ORM/LoadDocGeneratorTemplate.php b/src/Bundle/ChillDocGeneratorBundle/DataFixtures/ORM/LoadDocGeneratorTemplate.php index 082605fd7..af8915df7 100644 --- a/src/Bundle/ChillDocGeneratorBundle/DataFixtures/ORM/LoadDocGeneratorTemplate.php +++ b/src/Bundle/ChillDocGeneratorBundle/DataFixtures/ORM/LoadDocGeneratorTemplate.php @@ -14,8 +14,8 @@ namespace Chill\DocGeneratorBundle\DataFixtures\ORM; use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate; use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation; use Doctrine\Common\DataFixtures\AbstractFixture; - use Doctrine\Persistence\ObjectManager; +use Chill\DocStoreBundle\Entity\StoredObject; /** * Load DocGeneratorTemplate. @@ -28,13 +28,23 @@ class LoadDocGeneratorTemplate extends AbstractFixture [ 'name' => ['fr' => 'FORMULAIRE AEB'], 'desc' => 'stocké sur openstack comedienbe', - 'file' => 'FORMULAIRE_AEB_WITH_DATA_INJ.docx', + 'file' => [ + 'filename' => 'pKNlhCrQDCRsAuC8vYHDKa', + 'key' => '{"alg":"A256CBC","ext":true,"k":"_VihnD41-VDHlpS-ouwtbMPnu-OXVdtA7ENQWWtAQYM","key_ops":["encrypt","decrypt"],"kty":"oct"}', + 'iv' => '[86,231,83,148,117,107,149,173,130,19,105,194,224,145,8,48]', + 'type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + ], 'context' => 'Chill\DocGeneratorBundle\Context\HouseholdMemberSelectionContext', 'entities' => [AccompanyingPeriodWorkEvaluation::class], ], [ 'name' => ['fr' => 'AIDE ALIMENTAIRE'], 'desc' => 'stocké sur openstack comedienbe', - 'file' => 'AIDE_ALIMENTAIRE.docx', + 'file' => [ + 'filename' => 'pKNlhCrQDCRsAuC8vYHDKa', + 'key' => '{"alg":"A256CBC","ext":true,"k":"_VihnD41-VDHlpS-ouwtbMPnu-OXVdtA7ENQWWtAQYM","key_ops":["encrypt","decrypt"],"kty":"oct"}', + 'iv' => '[86,231,83,148,117,107,149,173,130,19,105,194,224,145,8,48]', + 'type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + ], 'context' => 'Chill\DocGeneratorBundle\Context\HouseholdMemberSelectionContext', 'entities' => ['Chill\PersonBundle\Entity\AccompanyingPeriod', 'Chill\PersonBundle\Entity\SocialWork\SocialAction', AccompanyingPeriodWorkEvaluation::class], ], @@ -43,10 +53,19 @@ class LoadDocGeneratorTemplate extends AbstractFixture foreach ($templates as $template) { echo 'Adding doc generator templates ' . $template['file'] . ")\n"; + $newStoredObj = (new StoredObject()) + ->setFilename($template['file']['filename']) + ->setKeyInfos(json_decode($template['file']['key'], true)) + ->setIv(json_decode($template['file']['iv'], true)) + ->setCreationDate(new \DateTime('today')) + ->setType($template['file']['type']); + + $manager->persist($newStoredObj); + $newTemplate = (new DocGeneratorTemplate()) ->setName($template['name']) ->setDescription($template['desc']) - ->setFile($template['file']) + ->setFile($newStoredObj) ->setContext($template['context']) ->setEntities($template['entities']); diff --git a/src/Bundle/ChillDocGeneratorBundle/Entity/DocGeneratorTemplate.php b/src/Bundle/ChillDocGeneratorBundle/Entity/DocGeneratorTemplate.php index e5e3e41a1..751fd75cb 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Entity/DocGeneratorTemplate.php +++ b/src/Bundle/ChillDocGeneratorBundle/Entity/DocGeneratorTemplate.php @@ -13,6 +13,7 @@ namespace Chill\DocGeneratorBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Serializer\Annotation as Serializer; +use Chill\DocStoreBundle\Entity\StoredObject; /** * @ORM\Entity @@ -50,9 +51,9 @@ class DocGeneratorTemplate private array $entities = []; /** - * @ORM\Column(type="string", length=255) + * @ORM\ManyToOne(targetEntity=StoredObject::class, cascade={"persist"}).) */ - private string $file; + private ?StoredObject $file = null; /** * @ORM\Id @@ -61,6 +62,7 @@ class DocGeneratorTemplate * @Serializer\Groups({"read"}) */ private int $id; + /** * @ORM\Column(type="json") @@ -83,7 +85,7 @@ class DocGeneratorTemplate return $this->entities; } - public function getFile(): ?string + public function getFile(): ?StoredObject { return $this->file; } @@ -93,10 +95,11 @@ class DocGeneratorTemplate return $this->id; } - public function getName(): ?array + public function getName(): ?array { return $this->name; } + public function setContext(string $context): self { @@ -119,7 +122,7 @@ class DocGeneratorTemplate return $this; } - public function setFile(string $file): self + public function setFile(StoredObject $file): self { $this->file = $file; diff --git a/src/Bundle/ChillDocGeneratorBundle/Form/DocGeneratorTemplateType.php b/src/Bundle/ChillDocGeneratorBundle/Form/DocGeneratorTemplateType.php index 75d33d0e5..6323d8ebf 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Form/DocGeneratorTemplateType.php +++ b/src/Bundle/ChillDocGeneratorBundle/Form/DocGeneratorTemplateType.php @@ -14,8 +14,12 @@ namespace Chill\DocGeneratorBundle\Form; use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate; use Chill\MainBundle\Form\Type\TranslatableStringFormType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use Chill\DocStoreBundle\Form\StoredObjectType; +use Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation; +use Chill\MainBundle\Form\Type\TranslatableStringFormType; class DocGeneratorTemplateType extends AbstractType { @@ -25,8 +29,19 @@ class DocGeneratorTemplateType extends AbstractType ->add('name', TranslatableStringFormType::class, [ 'label' => 'Nom', ]) + ->add('context') + ->add('entities', ChoiceType::class, [ + 'multiple' => true, + 'choices' => [ + 'AccompanyingPeriod' => 'Chill\PersonBundle\Entity\AccompanyingPeriod', + 'SocialWork\SocialAction' => 'Chill\PersonBundle\Entity\SocialWork\SocialAction', + 'AccompanyingPeriod\AccompanyingPeriodWorkEvaluation' => AccompanyingPeriodWorkEvaluation::class + ]]) ->add('description') - ->add('file'); + ->add('file', StoredObjectType::class, [ + 'error_bubbling' => true + ]) + ; } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/edit.html.twig b/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/edit.html.twig index f1ab64888..77c9f3e10 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/edit.html.twig +++ b/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/edit.html.twig @@ -10,3 +10,12 @@ {% block content_form_actions_save_and_show %}{% endblock %} {% endembed %} {% endblock %} + +{% block js %} + {{ parent() }} + {{ encore_entry_script_tags('mod_async_upload') }} +{% endblock %} + +{% block css %} + {{ encore_entry_link_tags('mod_async_upload') }} +{% endblock %} diff --git a/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/index.html.twig b/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/index.html.twig index 8d28c5a05..d98bd4811 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/index.html.twig +++ b/src/Bundle/ChillDocGeneratorBundle/Resources/views/Admin/DocGeneratorTemplate/index.html.twig @@ -5,7 +5,7 @@ {% block table_entities_thead_tr %}