소스 검색

documents and bring minor fixes

Olivier Massot 3 년 전
부모
커밋
15a7ab6f3a

+ 1 - 1
.env

@@ -82,5 +82,5 @@ MAILER_DSN=smtp://localhost
 ###< symfony/mailer ###
 
 ###> bindfile populate buffer file
-BINDFILE_BUFFER_FILE=/env/subdomain.txt
+BIND_FILE_BUFFER_FILE=/env/subdomain.txt
 ###< bindfile populate buffer file

+ 1 - 1
.env.ci

@@ -36,5 +36,5 @@ DOLIBARR_API_BASE_URI='https://dev-erp.2iopenservice.com/api/index.php/'
 ###< dolibarr client ###
 
 ###> bindfile populate buffer file
-BINDFILE_BUFFER_FILE=var/subdomain.txt
+BIND_FILE_BUFFER_FILE=var/subdomain.txt
 ###< bindfile populate buffer file

+ 1 - 1
.env.preprod

@@ -36,5 +36,5 @@ DOLIBARR_API_BASE_URI=https://dev-erp.2iopenservice.com/api/index.php/
 ###< dolibarr client ###
 
 ###> bindfile populate buffer file
-BINDFILE_BUFFER_FILE=var/subdomain.txt
+BIND_FILE_BUFFER_FILE=var/subdomain.txt
 ###< bindfile populate buffer file

+ 1 - 1
.env.prod

@@ -32,5 +32,5 @@ DATABASE_ADMINASSOS_URL=mysql://root:mysql2iopenservice369566@prod-back:3306/adm
 ###< AdminAssos configuration ###
 
 ###> bindfile populate buffer file
-BINDFILE_BUFFER_FILE=/env/subdomain.txt
+BIND_FILE_BUFFER_FILE=/env/subdomain.txt
 ###< bindfile populate buffer file

+ 1 - 1
.env.test

@@ -13,5 +13,5 @@ DOLIBARR_API_BASE_URI='https://dev-erp.2iopenservice.com/api/index.php/'
 ###< dolibarr client ###
 
 ###> bindfile populate buffer file
-BINDFILE_BUFFER_FILE=var/subdomain.txt
+BIND_FILE_BUFFER_FILE=var/subdomain.txt
 ###< bindfile populate buffer file

+ 4 - 1
config/packages/dev/messenger.yaml

@@ -1,6 +1,9 @@
+# Désactive le fonctionnement asynchrone de messenger en mode dev
+# > commenter pour tester avec un fonctionnement asynchrone
+#   (dans ce cas, la commande `messenger:consume async` doit être en cours d'exécution)
 framework:
     messenger:
         transports:
             # https://symfony.com/doc/current/messenger.html#transport-configuration
             async: 'sync://'
-            failed: 'sync://'
+            failed: 'sync://'

+ 1 - 1
config/services.yaml

@@ -10,7 +10,7 @@ services:
         bind:
             $opentalentConfig: '%kernel.project_dir%%env(OPENTALENT_CONFIG)%'
             $internalFilesUploadUri: '%env(INTERNAL_FILES_DOWNLOAD_URI)%'
-            $bindfileBufferFile: '%env(BINDFILE_BUFFER_FILE)'
+            $bindfileBufferFile: '%env(BIND_FILE_BUFFER_FILE)%'
             $contextAwareDataPersister: '@api_platform.doctrine.orm.data_persister'
 
     # Logging: a shorter version of the default monolog line formatter

+ 25 - 0
doc/bindfile.md

@@ -0,0 +1,25 @@
+# Fichier Bind
+
+Le fichier "bind" rend possible la résolution des sous-domaines au niveau du serveur DNS (situé sur prod-back).
+Chaque fois qu'un nouveau sous-domaine est enregistré, ce fichier doit être mis à jour. Cependant, pour des questions de 
+droits, c'est l'utilisateur root qui doit procéder à cette mise à jour. 
+
+Voilà ce qu'il se passe lorsqu'une structure enregistre un nouveau sous-domaine depuis `prod-back`:
+
+1. Le logiciel ajoute le sous-domaine en question dans une nouvelle ligne du fichier tampon `/env/subdomain.txt`
+2. Un cron tourne toutes les 5 minutes et consomme le contenu de ce fichier avant de le vider
+3. Ce cron exécute le script `/env/add-subdomain`, qui met à jour le fichier bind `/etc/bind/zones/opentalent.fr.db`
+4. Une fois mis à jour le fichier bind, le cron exécuté sur prod-back (le serveur DNS) envoie par ssh le contenu du 
+   fichier subdomain.txt sur un même fichier `/env/subdomain.txt` situé sur le serveur `vpn` 
+5. Le même cron tourne toutes les 5 minutes sur le serveur vpn procède à son tour à la mise à jour de son fichier bind
+
+La mise à jour des deux fichiers bind est nécessaire, pour permettre la prise en compte des sous-domaines depuis
+l'intérieur ou l'extérieur du VPN.
+
+Lorsqu'un nouveau sous-domaine est enregistré depuis `prod-v2`:
+
+1. Le logiciel remplit de la même façon un fichier `/env/subdomain.txt`
+2. Un cron lit ce fichier et ajoute les sous-domaines listés au subdomain.txt sur `prod-back`
+3. La suite se déroule comme dans le premier scénario
+
+

+ 54 - 5
src/DataPersister/BaseDataPersister.php

@@ -6,11 +6,15 @@ use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
 use Doctrine\ORM\EntityManagerInterface;
 use Symfony\Contracts\Service\Attribute\Required;
 
+/**
+ * Classe de base pour les DataPersister classiques, proposant des hook pre et post persist,
+ * ainsi que certaines méthodes liées au contexte de la mise à jour.
+ */
 class BaseDataPersister implements ContextAwareDataPersisterInterface
 {
     protected array $context = [];
 
-    // dependencies injections
+    // <-- dependencies injections
     protected EntityManagerInterface $entityManager;
     protected ContextAwareDataPersisterInterface $contextAwareDataPersister;
 
@@ -18,6 +22,7 @@ class BaseDataPersister implements ContextAwareDataPersisterInterface
     public function setContextAwareDataPersister(ContextAwareDataPersisterInterface $contextAwareDataPersister): void {$this->contextAwareDataPersister = $contextAwareDataPersister;}
     #[Required]
     public function setEntityManager(EntityManagerInterface $entityManager): void {$this->entityManager = $entityManager;}
+    // dependencies injections -->
 
     public function supports($data, array $context = []): bool
     {
@@ -28,6 +33,8 @@ class BaseDataPersister implements ContextAwareDataPersisterInterface
     {
         $this->context = $context;
 
+        $this->validate($data);
+
         $data = $this->preProcess($data);
 
         $this->prePersist($data);
@@ -39,32 +46,74 @@ class BaseDataPersister implements ContextAwareDataPersisterInterface
         return $result;
     }
 
+    /**
+     * Validation de la nouvelle donnée
+     *
+     * @param $data
+     */
+    protected function validate($data): void {
+    }
+
+    /**
+     * Transformation de la donnée en entrée
+     *
+     * @param $data
+     * @return mixed
+     */
     protected function preProcess($data) {
         return $data;
     }
 
+    /**
+     * Opérations avant mise à jour
+     *
+     * @param $data
+     */
     protected function prePersist($data): void {
     }
 
+    /**
+     * Opérations après mise à jour
+     *
+     * @param $data
+     */
     protected function postPersist($data): void {
     }
 
+    /**
+     * La fonction native 'remove' n'est pas supportée par défaut, la réimplémenter au besoin
+     *
+     * @param mixed $data
+     * @param array $context
+     */
     public function remove($data, array $context = []): void {
         throw new \RuntimeException('not supported', 500);
     }
 
+    /**
+     * La requête traitée est de type POST
+     *
+     * @return bool
+     */
     protected function isPostRequest(): bool {
         return $this->context['collection_operation_name'] ?? null === 'post';
     }
 
+    /**
+     * La requête traitée est de type PUT
+     *
+     * @return bool
+     */
     protected function isPutRequest(): bool {
         return $this->context['item_operation_name'] ?? null === 'put';
     }
 
+    /**
+     * Retourne l'entité existante (avant mise à jour) si elle existe, null sinon
+     *
+     * @return mixed|null
+     */
     protected function previousData() {
-        if (!$this->isPutRequest()) {
-            return null;
-        }
-        return $this->context['previous_data'];
+        return $this->context['previous_data'] ?? null;
     }
 }

+ 12 - 12
src/DataPersister/Organization/ParametersDataPersister.php

@@ -10,7 +10,6 @@ use App\Message\Command\Typo3\Typo3DeleteCommand;
 use App\Message\Command\Typo3\Typo3UndeleteCommand;
 use App\Message\Command\Typo3\Typo3UpdateCommand;
 use App\Service\OnChange\Organization\OnParametersChange;
-use App\Service\Typo3\Typo3Service;
 use Exception;
 use Symfony\Component\Messenger\MessageBusInterface;
 
@@ -22,9 +21,7 @@ class ParametersDataPersister extends BaseDataPersister
     public function __construct(
         private MessageBusInterface $messageBus,
         private OnParametersChange $onParametersChange,
-        private Typo3Service $typo3Service,
         private \App\Service\Network\Utils $networkUtils
-
     )
     {}
 
@@ -33,6 +30,17 @@ class ParametersDataPersister extends BaseDataPersister
         return $data instanceof Parameters;
     }
 
+    protected function validate($parameters): void
+    {
+        // Une structure CMF n'a pas le droit de désactiver son site typo3
+        if (
+            $parameters->getDesactivateOpentalentSiteWeb() === true &&
+            $this->networkUtils->isCMFAndActiveNow($parameters->getOrganization())
+        ) {
+            throw new \RuntimeException('This structure is currently active in the CMF network, the website can not be disabled.');
+        }
+    }
+
     /**
      * @param Parameters $parameters
      * @throws Exception
@@ -40,7 +48,7 @@ class ParametersDataPersister extends BaseDataPersister
     public function prePersist($parameters): void{
         if(
             $this->previousData() &&
-            $this->previousData()->getAdvancedEducationNotationType() != $parameters->getAdvancedEducationNotationType()
+            $this->previousData()->getAdvancedEducationNotationType() !== $parameters->getAdvancedEducationNotationType()
         ){
             $this->onParametersChange->onAdvancedEducationNotationTypeChange($parameters);
         }
@@ -55,14 +63,6 @@ class ParametersDataPersister extends BaseDataPersister
                 $this->previousData()->getMusicalDate()
             );
         }
-
-        // Une structure CMF n'a pas le droit de désactiver son site typo3
-        if (
-            $parameters->getDesactivateOpentalentSiteWeb() === true &&
-            $this->networkUtils->isCMFAndActiveNow($parameters->getOrganization())
-        ) {
-            throw new \RuntimeException('This structure is currently active in the CMF network, the website can not be disabled.');
-        }
     }
 
     /**

+ 3 - 17
src/DataPersister/Organization/SubdomainDataPersister.php

@@ -5,36 +5,28 @@ namespace App\DataPersister\Organization;
 
 use App\DataPersister\BaseDataPersister;
 use App\Entity\Organization\Subdomain;
-use App\Message\Command\Export;
 use App\Message\Command\Typo3\Typo3UpdateCommand;
 use App\Service\Organization\Utils;
 use App\Service\Typo3\BindFileService;
-use App\Service\Typo3\Typo3Service;
 use Exception;
 use Symfony\Component\Messenger\MessageBusInterface;
 
 /**
- * Classe ParametersDataPersister qui est un custom dataPersister gérant la resource Parameters
+ * Ccustom dataPersister gérant la resource Subdomain
  */
 class SubdomainDataPersister extends BaseDataPersister
 {
     public function __construct(
         private BindFileService $bindFileService,
         private MessageBusInterface $messageBus,
-    )
-    {
-    }
+    ) {}
 
     public function supports($data, array $context = []): bool
     {
         return $data instanceof Subdomain;
     }
 
-    /**
-     * @param Subdomain $subdomain
-     */
-    protected function prePersist($subdomain): void
-    {
+    protected function validate($subdomain): void {
         if ($this->isPostRequest()) {
             // Ensure we do not exceed the limit of 3 subdomains per organization
             if (count($subdomain->getOrganization()->getSubdomains()) >= 3) {
@@ -45,7 +37,6 @@ class SubdomainDataPersister extends BaseDataPersister
 
     /**
      * @param Subdomain $subdomain
-     * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
      */
     protected function postPersist($subdomain): void
     {
@@ -88,9 +79,4 @@ class SubdomainDataPersister extends BaseDataPersister
             }
         }
     }
-
-    public function remove($data, array $context = []): void
-    {
-        throw new Exception('not supported', 500);
-    }
 }

+ 1 - 3
src/Entity/Organization/Subdomain.php

@@ -16,9 +16,7 @@ use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
  */
 #[ApiResource(
     collectionOperations: [
-        'get' => [
-            'security' => '(is_granted("ROLE_ORGANIZATION_VIEW") or is_granted("ROLE_ORGANIZATION"))' // TODO: Comment je teste l'organisation sur une collection?
-        ],
+        'get',  // TODO: Comment je teste l'organisation et les droits sur une collection?
         'post'
     ],
     itemOperations: [

+ 1 - 1
src/Message/Command/Typo3/Typo3DeleteCommand.php

@@ -4,7 +4,7 @@ declare(strict_types=1);
 namespace App\Message\Command\Typo3;
 
 /**
- * Envoi d'une requête à l'api Typo3
+ * Envoi d'une requête Delete à l'api Typo3
  */
 class Typo3DeleteCommand
 {

+ 1 - 1
src/Message/Command/Typo3/Typo3UndeleteCommand.php

@@ -4,7 +4,7 @@ declare(strict_types=1);
 namespace App\Message\Command\Typo3;
 
 /**
- * Envoi d'une requête à l'api Typo3
+ * Envoi d'une requête Undelete à l'api Typo3
  */
 class Typo3UndeleteCommand
 {

+ 1 - 1
src/Message/Command/Typo3/Typo3UpdateCommand.php

@@ -4,7 +4,7 @@ declare(strict_types=1);
 namespace App\Message\Command\Typo3;
 
 /**
- * Envoi d'une requête à l'api Typo3
+ * Envoi d'une requête Update à l'api Typo3
  */
 class Typo3UpdateCommand
 {

+ 4 - 2
src/Service/Typo3/BindFileService.php

@@ -2,6 +2,9 @@
 
 namespace App\Service\Typo3;
 
+/**
+ * Opérations sur le fichier Bind, qui gère entre autres l'adressage DNS lié aux sous-domaines
+ */
 class BindFileService
 {
     public function __construct(
@@ -17,8 +20,7 @@ class BindFileService
      */
     public function registerSubdomain(string $subdomain): void
     {
-        var_dump($this->bindfileBufferFile);
-        $fsd = @fopen($this->bindfileBufferFile, 'ab+');
+        $fsd = fopen($this->bindfileBufferFile, 'ab+');
         fwrite($fsd, $subdomain);
         fwrite($fsd, "\n");
         fclose($fsd);

+ 3 - 0
src/Service/Typo3/Typo3Service.php

@@ -7,6 +7,9 @@ use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
 use Symfony\Contracts\HttpClient\HttpClientInterface;
 use Symfony\Contracts\HttpClient\ResponseInterface;
 
+/**
+ * Service d'appel à l'API de l'instance Typo3
+ */
 class Typo3Service
 {
     public function __construct(