From ad65ba3e87a032898e90950b650291e0b26a7fa2 Mon Sep 17 00:00:00 2001
From: Quentin RIBAC <quentin.ribac@xelians.fr>
Date: Thu, 28 Oct 2021 17:53:14 +0200
Subject: [PATCH] FEAT #14837 TIME 2:45 better checks in multigest preprocess

---
 .../PreProcessActionController.php            | 17 +++-
 .../controllers/MultigestController.php       | 77 ++++++++++++-------
 src/lang/lang-en.json                         |  4 +-
 src/lang/lang-fr.json                         |  4 +-
 src/lang/lang-nl.json                         |  4 +-
 5 files changed, 70 insertions(+), 36 deletions(-)

diff --git a/src/app/action/controllers/PreProcessActionController.php b/src/app/action/controllers/PreProcessActionController.php
index 7a236541a43..a6918994fde 100755
--- a/src/app/action/controllers/PreProcessActionController.php
+++ b/src/app/action/controllers/PreProcessActionController.php
@@ -55,6 +55,8 @@ use Template\models\TemplateModel;
 use User\models\UserEntityModel;
 use User\models\UserModel;
 use ExportSeda\controllers\PreProcessActionSEDATrait;
+use Multigest\controllers\MultigestController;
+use SrcCore\models\PasswordModel;
 
 class PreProcessActionController
 {
@@ -1729,17 +1731,17 @@ class PreProcessActionController
 
         $body['resources'] = array_slice($body['resources'], 0, 500);
         if (!ResController::hasRightByResId(['resId' => $body['resources'], 'userId' => $GLOBALS['id']])) {
-            return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
+            return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter', 'lang' => 'documentOutOfPerimeter']);
         }
         $body['resources'] = PreProcessActionController::getNonLockedResources(['resources' => $body['resources'], 'userId' => $GLOBALS['id']]);
 
         $configuration = ConfigurationModel::getByPrivilege(['privilege' => 'admin_multigest']);
         if (empty($configuration)) {
-            return $response->withStatus(400)->withJson(['errors' => 'Multigest configuration is not enabled']);
+            return $response->withStatus(400)->withJson(['errors' => 'Multigest configuration is not enabled', 'lang' => 'multigestIsNotEnabled']);
         }
         $configuration = json_decode($configuration['value'], true);
         if (empty($configuration['uri'])) {
-            return $response->withStatus(400)->withJson(['errors' => 'Multigest configuration URI is empty']);
+            return $response->withStatus(400)->withJson(['errors' => 'Multigest configuration URI is empty', 'lang' => 'multigestUriIsEmpty']);
         }
 
         $entity = UserModel::getPrimaryEntityById(['id' => $args['userId'], 'select' => ['entities.external_id']]);
@@ -1751,6 +1753,15 @@ class PreProcessActionController
             return $response->withStatus(400)->withJson(['errors' => 'User primary entity has no Multigest account', 'lang' => 'noMultigestAccount']);
         }
 
+        $accountCheck = MultigestController::checkAccountWithCredentials([
+            'sasId' => $entityInformations['multigest']['sasId'],
+            'login' => $entityInformations['multigest']['login'],
+            'password' => PasswordModel::decrypt(['cryptedPassword' => $entityInformations['multigest']['password']])
+        ]);
+        if (!empty($accountCheck['errors'])) {
+            return $response->withStatus(400)->withJson(['errors' => $accountCheck['errors'], 'lang' => ($accountCheck['lang'] ?? null)]);
+        }
+
         $resourcesInformations = [];
         foreach ($body['resources'] as $resId) {
             $resource = ResModel::getById(['select' => ['filename', 'alt_identifier', 'external_id'], 'resId' => $resId]);
diff --git a/src/app/external/multigest/controllers/MultigestController.php b/src/app/external/multigest/controllers/MultigestController.php
index 5045c498ced..776b7282c1b 100644
--- a/src/app/external/multigest/controllers/MultigestController.php
+++ b/src/app/external/multigest/controllers/MultigestController.php
@@ -294,57 +294,78 @@ class MultigestController
         }
 
         $body = $request->getParsedBody();
+        if (!empty($body['password'])) {
+            $body['password'] = PasswordModel::decrypt(['cryptedPassword' => $body['password']]);
+        }
+        $result = MultigestController::checkAccountWithCredentials($body);
 
-        if (!Validator::stringType()->notEmpty()->validate($body['login'])) {
-            return $response->withStatus(400)->withJson(['errors' => 'Body login is empty or not a string']);
-        } elseif (!Validator::stringType()->notEmpty()->validate($body['sasId'])) {
-            return $response->withStatus(400)->withJson(['errors' => 'Body sasId is empty or not a string']);
+        if (!empty($result['errors'])) {
+            $return = ['errors' => $result['errors']];
+            if (!empty($result['lang'])) {
+                $return['lang'] = $result['lang'];
+            }
+            return $response->withStatus(400)->withJson($return);
+        }
+
+        return $response->withStatus(204);
+    }
+
+    public static function checkAccountWithCredentials(array $args)
+    {
+        if (!Validator::stringType()->notEmpty()->validate($args['login'])) {
+            return ['errors' => 'Body login is empty or not a string'];
+        } elseif (!Validator::stringType()->notEmpty()->validate($args['sasId'])) {
+            return ['errors' => 'Body sasId is empty or not a string'];
         }
 
         $configuration = ConfigurationModel::getByPrivilege(['privilege' => 'admin_multigest']);
         if (empty($configuration)) {
-            return $response->withStatus(400)->withJson(['errors' => 'Multigest configuration is not enabled', 'lang' => 'multigestIsNotEnabled']);
+            return ['errors' => 'Multigest configuration is not enabled', 'lang' => 'multigestIsNotEnabled'];
         }
         $configuration = json_decode($configuration['value'], true);
         if (empty($configuration['uri'])) {
-            return $response->withStatus(400)->withJson(['errors' => 'Multigest configuration URI is empty', 'lang' => 'multigestUriIsEmpty']);
+            return ['errors' => 'Multigest configuration URI is empty', 'lang' => 'multigestUriIsEmpty'];
         }
         $multigestUri = rtrim($configuration['uri'], '/');
 
-        $soapClient = new \SoapClient($multigestUri, [
-            'login'          => $body['login'],
-            'password'       => $body['password'] ?? '',
-            'authentication' => SOAP_AUTHENTICATION_BASIC
-        ]);
+        try {
+            $soapClient = new \SoapClient($multigestUri, [
+                'login'          => $args['login'],
+                'password'       => $args['password'] ?? '',
+                'authentication' => SOAP_AUTHENTICATION_BASIC
+            ]);
+        } catch (\SoapFault $e) {
+            return ['errors' => (string) $e, 'lang' => 'soapClientCreationError'];
+        }
 
         $multigestParameters = CoreConfigModel::getJsonLoaded(['path' => 'config/multigest.json']);
         if (empty($multigestParameters)) {
-            return $response->withStatus(400)->withJson(['errors' => 'Multigest mapping file does not exist', 'lang' => 'multigestMappingDoesNotExist']);
+            return ['errors' => 'Multigest mapping file does not exist', 'lang' => 'multigestMappingDoesNotExist'];
         }
         if (empty($multigestParameters['mapping']['document'])) {
-            return $response->withStatus(400)->withJson(['errors' => 'Multigest mapping for document is empty', 'lang' => 'multigestMappingForDocumentIsEmpty']);
+            return ['errors' => 'Multigest mapping for document is empty', 'lang' => 'multigestMappingForDocumentIsEmpty'];
         }
 
         $keyMetadataField = key($multigestParameters['mapping']['document']);
         $result = $soapClient->GedChampReset();
         if (is_soap_fault($result)) {
-            return $response->withStatus(400)->withJson(['errors' => 'MultiGest SoapFault: ' . $result]);
+            return ['errors' => 'MultiGest SoapFault: ' . $result];
         }
         $result = $soapClient->GedAddChampRecherche($keyMetadataField, 'FAKEDATA');
         if (is_soap_fault($result)) {
-            return $response->withStatus(400)->withJson(['errors' => 'MultiGest SoapFault: ' . $result]);
+            return ['errors' => 'MultiGest SoapFault: ' . $result];
         }
-        $result = $soapClient->GedDossierExist($body['sasId'], $body['login']);
+        $result = $soapClient->GedDossierExist($args['sasId'], $args['login']);
         if (is_soap_fault($result)) {
-            return $response->withStatus(400)->withJson(['errors' => 'MultiGest SoapFault: ' . $result]);
+            return ['errors' => 'MultiGest SoapFault: ' . $result];
         }
         $result = (int) $result;
 
         if ($result < 0 && $result != -7) { // -7 -> "Dossier inexistant"
-            return $response->withStatus(400)->withJson(['errors' => 'MultiGest connection failed for user ' . $body['login'] . ' in sas ' . $body['sasId'], 'lang' => 'multigestAccountTestFailed']);
+            return ['errors' => 'MultiGest connection failed for user ' . $args['login'] . ' in sas ' . $args['sasId'], 'lang' => 'multigestAccountTestFailed'];
         }
 
-        return $response->withStatus(204);
+        return true;
     }
 
     public static function sendResource(array $args)
@@ -373,7 +394,7 @@ class MultigestController
         }
         $entityConfiguration = json_decode($userPrimaryEntity['external_id'], true);
         if (empty($entityConfiguration['multigest'])) {
-            return ['errors' => 'Entity has no associated Multigest account', 'lang' => 'entityHasNoMultigestAccount'];
+            return ['errors' => 'Entity has no associated Multigest account', 'lang' => 'noMultigestAccount'];
         }
         $entityConfiguration = [
             'login' => $entityConfiguration['multigest']['login'] ?? '',
@@ -498,14 +519,16 @@ class MultigestController
         if (empty($metadataFields) || empty($metadataValues)) {
             return ['errors' => 'No valid metadata from Multigest mapping', 'lang' => 'multigestInvalidMapping'];
         }
-        $metadataFields = utf8_decode($metadataFields);
-        $metadataValues = utf8_decode($metadataValues);
 
-        $soapClient = new \SoapClient($multigestUri, [
-            'login'    => $configuration['login'],
-            'password' => $configuration['password'],
-            'authentication' => SOAP_AUTHENTICATION_BASIC
-        ]);
+        try {
+            $soapClient = new \SoapClient($multigestUri, [
+                'login'          => $configuration['login'],
+                'password'       => empty($configuration['password']) ? '' : PasswordModel::decrypt(['cryptedPassword' => $configuration['password']]),
+                'authentication' => SOAP_AUTHENTICATION_BASIC
+            ]);
+        } catch (\SoapFault $e) {
+            return ['errors' => (string) $e, 'lang' => 'soapClientCreationError'];
+        }
 
         $result = $soapClient->GedSetModeUid(1);
         if (is_soap_fault($result)) {
diff --git a/src/lang/lang-en.json b/src/lang/lang-en.json
index 0de34cc8e12..af6f1606543 100644
--- a/src/lang/lang-en.json
+++ b/src/lang/lang-en.json
@@ -2555,12 +2555,12 @@
     "multigestMappingForDocumentIsEmpty": "Multigest mapping for document is empty",
     "multigestInvalidMapping": "Multigest mapping for document is invalid",
     "multigestAccountTestFailed": "Multigest account test failed",
-    "entityHasNoMultigestAccount": "This entity has no associated Multigest account",
     "documentAlreadyInMultigest": "This document is already in Multigest",
     "multigestFolderCreationError": "An error occured while creating Multigest folder",
     "documentNotExist": "This document does not exist",
     "documentHasNoFile": "This document has no file",
     "documentHasNoChrono": "This document has no chrono identifier",
     "documentNotFoundOnDocserver": "Document not found on document server",
-    "docserverDocumentNotReadable": "Document could not be read from document server"
+    "docserverDocumentNotReadable": "Document could not be read from document server",
+    "soapClientCreationError": "Error while initiating SOAP client"
 }
diff --git a/src/lang/lang-fr.json b/src/lang/lang-fr.json
index 0bd256e999f..af7db35a754 100644
--- a/src/lang/lang-fr.json
+++ b/src/lang/lang-fr.json
@@ -2560,12 +2560,12 @@
     "multigestMappingForDocumentIsEmpty": "Mapping Multigest vide pour la section document",
     "multigestInvalidMapping": "Mapping Multigest invalide",
     "multigestAccountTestFailed": "Échec du test de connexion Multigest",
-    "entityHasNoMultigestAccount": "Cette entité n’a aucun compte Multigest associé",
     "documentAlreadyInMultigest": "Ce document est déjà dans Multigest",
     "multigestFolderCreationError": "Échec de la création du dossier Multigest",
     "documentNotExist": "Ce courrier n’existe pas",
     "documentHasNoFile": "Ce courrier n’a pas de fichier",
     "documentHasNoChrono": "Ce courrier n’a pas de numéro chrono",
     "documentNotFoundOnDocserver": "Fichier introuvable dans l’espace de stockage",
-    "docserverDocumentNotReadable": "Fichier illisible sur l’espace de stockage"
+    "docserverDocumentNotReadable": "Fichier illisible sur l’espace de stockage",
+    "soapClientCreationError": "Erreur de lancement de la communication SOAP"
 }
diff --git a/src/lang/lang-nl.json b/src/lang/lang-nl.json
index ba74cc6bc17..fe7b084acbc 100644
--- a/src/lang/lang-nl.json
+++ b/src/lang/lang-nl.json
@@ -2202,12 +2202,12 @@
     "multigestMappingForDocumentIsEmpty": "Mapping Multigest vide pour la section document__TO_TRANSLATE",
     "multigestInvalidMapping": "Mapping Multigest invalide__TO_TRANSLATE",
     "multigestAccountTestFailed": "Échec du test de connexion Multigest__TO_TRANSLATE",
-    "entityHasNoMultigestAccount": "Cette entité n’a aucun compte Multigest associé__TO_TRANSLATE",
     "documentAlreadyInMultigest": "Ce document est déjà dans Multigest__TO_TRANSLATE",
     "multigestFolderCreationError": "Échec de la création du dossier Multigest__TO_TRANSLATE",
     "documentNotExist": "Ce courrier n’existe pas__TO_TRANSLATE",
     "documentHasNoFile": "Ce courrier n’a pas de fichier__TO_TRANSLATE",
     "documentHasNoChrono": "Ce courrier n’a pas de numéro chrono__TO_TRANSLATE",
     "documentNotFoundOnDocserver": "Fichier introuvable dans l’espace de stockage__TO_TRANSLATE",
-    "docserverDocumentNotReadable": "Fichier illisible sur l’espace de stockage__TO_TRANSLATE"
+    "docserverDocumentNotReadable": "Fichier illisible sur l’espace de stockage__TO_TRANSLATE",
+    "soapClientCreationError": "Erreur de lancement de la communication SOAP__TO_TRANSLATE"
 }
-- 
GitLab