From 0294a8911bb704888e56730b1d1d5d4d30998e04 Mon Sep 17 00:00:00 2001
From: "florian.azizian" <florian.azizian@maarch.org>
Date: Wed, 19 Jun 2019 12:45:03 +0100
Subject: [PATCH] FEAT #10771 TIME 2:30 link user to MP

---
 rest/index.php                                |   6 +-
 .../controllers/MaarchParapheurController.php | 274 ++++++++++++++++++
 src/app/user/controllers/UserController.php   | 225 +++-----------
 src/core/lang/lang-en.php                     |   2 +
 src/core/lang/lang-fr.php                     |   2 +
 src/core/lang/lang-nl.php                     |   2 +
 6 files changed, 319 insertions(+), 192 deletions(-)

diff --git a/rest/index.php b/rest/index.php
index 21452b1e0e9..2485db9ed0f 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -338,8 +338,10 @@ $app->post('/users/{id}/password', \User\controllers\UserController::class . ':r
 $app->put('/users/{id}/password', \User\controllers\UserController::class . ':updatePassword');
 $app->get('/users/{userId}/status', \User\controllers\UserController::class . ':getStatusByUserId');
 $app->put('/users/{id}/status', \User\controllers\UserController::class . ':updateStatus');
-$app->put('/users/{id}/maarchParapheur', \User\controllers\UserController::class . ':sendToMaarchParapheur');
-$app->put('/users/{id}/externalSignatures', \User\controllers\UserController::class . ':sendSignaturesToMaarchParapheur');
+$app->put('/users/{id}/createInMaarchParapheur', \ExternalSignatoryBook\controllers\MaarchParapheurController::class . ':sendUserToMaarchParapheur');
+$app->put('/users/{id}/linkToMaarchParapheur', \ExternalSignatoryBook\controllers\MaarchParapheurController::class . ':linkUserToMaarchParapheur');
+$app->put('/users/{id}/unlinkToMaarchParapheur', \ExternalSignatoryBook\controllers\MaarchParapheurController::class . ':unlinkUserToMaarchParapheur');
+$app->put('/users/{id}/externalSignatures', \ExternalSignatoryBook\controllers\MaarchParapheurController::class . ':sendSignaturesToMaarchParapheur');
 $app->post('/users/{id}/groups', \User\controllers\UserController::class . ':addGroup');
 $app->put('/users/{id}/groups/{groupId}', \User\controllers\UserController::class . ':updateGroup');
 $app->delete('/users/{id}/groups/{groupId}', \User\controllers\UserController::class . ':deleteGroup');
diff --git a/src/app/external/externalSignatoryBook/controllers/MaarchParapheurController.php b/src/app/external/externalSignatoryBook/controllers/MaarchParapheurController.php
index f5aa770f209..b4beb088e69 100755
--- a/src/app/external/externalSignatoryBook/controllers/MaarchParapheurController.php
+++ b/src/app/external/externalSignatoryBook/controllers/MaarchParapheurController.php
@@ -19,6 +19,7 @@ use Convert\controllers\ConvertPdfController;
 use Docserver\models\DocserverModel;
 use Entity\models\EntityModel;
 use Entity\models\ListInstanceModel;
+use History\controllers\HistoryController;
 use Note\models\NoteModel;
 use Priority\models\PriorityModel;
 use Resource\controllers\SummarySheetController;
@@ -29,6 +30,7 @@ use Slim\Http\Request;
 use Slim\Http\Response;
 use SrcCore\models\CoreConfigModel;
 use SrcCore\models\CurlModel;
+use User\controllers\UserController;
 use User\models\UserModel;
 
 class MaarchParapheurController
@@ -507,4 +509,276 @@ class MaarchParapheurController
 
         return $response->withJson(['picture' => $curlResponse['response']['picture']]);
     }
+
+    public static function sendUserToMaarchParapheur(Request $request, Response $response, array $aArgs)
+    {
+
+        $body = $request->getParsedBody();
+        $check = Validator::stringType()->notEmpty()->validate($body['login']) && preg_match("/^[\w.@-]*$/", $body['login']);
+        if (!$check) {
+            return $response->withStatus(400)->withJson(['errors' => 'login is empty or wrong format']);
+        }
+        
+        $error = UserController::hasUsersRights(['id' => $aArgs['id']]);
+        if (!empty($error['error'])) {
+            return $response->withStatus($error['status'])->withJson(['errors' => $error['error']]);
+        }
+
+        $loadedXml = CoreConfigModel::getXmlLoaded(['path' => 'modules/visa/xml/remoteSignatoryBooks.xml']);
+
+        if ($loadedXml->signatoryBookEnabled == 'maarchParapheur') {
+            $userInfo = UserModel::getById(['select' => ['firstname', 'lastname', 'mail', 'external_id'], 'id' => $aArgs['id']]);
+
+            $bodyData = [
+                "lastname"  => $userInfo['lastname'],
+                "firstname" => $userInfo['firstname'],
+                "login"     => $body['login'],
+                "email"     => $userInfo['mail']
+            ];
+
+            foreach ($loadedXml->signatoryBook as $value) {
+                if ($value->id == "maarchParapheur") {
+                    $url      = $value->url;
+                    $userId   = $value->userId;
+                    $password = $value->password;
+                    break;
+                }
+            }
+
+            $curlResponse = CurlModel::execSimple([
+                'url'           => rtrim($url, '/') . '/rest/users',
+                'basicAuth'     => ['user' => $userId, 'password' => $password],
+                'headers'       => ['content-type:application/json'],
+                'method'        => 'POST',
+                'body'          => json_encode($bodyData)
+            ]);
+
+            if ($curlResponse['code'] != '200') {
+                if (!empty($curlResponse['response']['errors'])) {
+                    $errors =  $curlResponse['response']['errors'];
+                } else {
+                    $errors =  $curlResponse['errors'];
+                }
+                if (empty($errors)) {
+                    $errors = 'An error occured. Please check your configuration file.';
+                }
+                return $response->withStatus(400)->withJson(['errors' => $errors]);
+            }
+        } else {
+            return $response->withStatus(403)->withJson(['errors' => 'maarchParapheur is not enabled']);
+        }
+
+        $externalId = json_decode($userInfo['external_id'], true);
+        $externalId['maarchParapheur'] = $curlResponse['response']['id'];
+
+        UserModel::updateExternalId(['id' => $aArgs['id'], 'externalId' => json_encode($externalId)]);
+
+        HistoryController::add([
+            'tableName'    => 'users',
+            'recordId'     => $GLOBALS['userId'],
+            'eventType'    => 'ADD',
+            'eventId'      => 'userCreation',
+            'info'         => _USER_CREATED_IN_MAARCHPARAPHEUR . " {$userInfo['firstname']} {$userInfo['lastname']}"
+        ]);
+
+        return $response->withJson(['externalId' => $curlResponse['response']['id']]);
+    }
+
+    public static function linkUserToMaarchParapheur(Request $request, Response $response, array $aArgs)
+    {
+        $body = $request->getParsedBody();
+        $check = Validator::intType()->notEmpty()->validate($body['maarchParapheurUserId']);
+        if (!$check) {
+            return $response->withStatus(400)->withJson(['errors' => 'maarchParapheurUserId is empty or not an integer']);
+        }
+        
+        $error = UserController::hasUsersRights(['id' => $aArgs['id']]);
+        if (!empty($error['error'])) {
+            return $response->withStatus($error['status'])->withJson(['errors' => $error['error']]);
+        }
+
+        $loadedXml = CoreConfigModel::getXmlLoaded(['path' => 'modules/visa/xml/remoteSignatoryBooks.xml']);
+
+        if ($loadedXml->signatoryBookEnabled == 'maarchParapheur') {
+
+            foreach ($loadedXml->signatoryBook as $value) {
+                if ($value->id == "maarchParapheur") {
+                    $url      = $value->url;
+                    $userId   = $value->userId;
+                    $password = $value->password;
+                    break;
+                }
+            }
+
+            $curlResponse = CurlModel::execSimple([
+                'url'           => rtrim($url, '/') . '/rest/users/'.$body['maarchParapheurUserId'],
+                'basicAuth'     => ['user' => $userId, 'password' => $password],
+                'headers'       => ['content-type:application/json'],
+                'method'        => 'GET'
+            ]);
+
+            if ($curlResponse['code'] != '200') {
+                if (!empty($curlResponse['response']['errors'])) {
+                    $errors =  $curlResponse['response']['errors'];
+                } else {
+                    $errors =  $curlResponse['errors'];
+                }
+                if (empty($errors)) {
+                    $errors = 'An error occured. Please check your configuration file.';
+                }
+                return $response->withStatus(400)->withJson(['errors' => $errors]);
+            }
+
+            if (empty($curlResponse['response']['user'])) {
+                return $response->withStatus(400)->withJson(['errors' => 'User does not exist in Maarch Parapheur']);
+            }
+        } else {
+            return $response->withStatus(403)->withJson(['errors' => 'maarchParapheur is not enabled']);
+        }
+
+        $userInfos = UserModel::getByExternalId([
+            'select'            => ['user_id'],
+            'externalId'        => $body['maarchParapheurUserId'],
+            'externalName'      => 'maarchParapheur'
+        ]);
+
+        if (!empty($userInfos)) {
+            return $response->withStatus(403)->withJson(['errors' => 'This maarch parapheur user is already linked to someone. Choose another one.']);
+        }
+
+        $userInfo = UserModel::getById(['select' => ['external_id', 'firstname', 'lastname'], 'id' => $aArgs['id']]);
+
+        $externalId = json_decode($userInfo['external_id'], true);
+        $externalId['maarchParapheur'] = $body['maarchParapheurUserId'];
+
+        UserModel::updateExternalId(['id' => $aArgs['id'], 'externalId' => json_encode($externalId)]);
+
+        HistoryController::add([
+            'tableName'    => 'users',
+            'recordId'     => $GLOBALS['userId'],
+            'eventType'    => 'ADD',
+            'eventId'      => 'userCreation',
+            'info'         => _USER_LINKED_TO_MAARCHPARAPHEUR . " {$userInfo['firstname']} {$userInfo['lastname']}"
+        ]);
+
+        return $response->withJson(['success' => 'success']);
+    }
+
+    public static function unlinkUserToMaarchParapheur(Request $request, Response $response, array $aArgs)
+    {
+        $error = UserController::hasUsersRights(['id' => $aArgs['id']]);
+        if (!empty($error['error'])) {
+            return $response->withStatus($error['status'])->withJson(['errors' => $error['error']]);
+        }
+
+        $userInfo = UserModel::getById(['select' => ['external_id', 'firstname', 'lastname'], 'id' => $aArgs['id']]);
+
+        $externalId = json_decode($userInfo['external_id'], true);
+        unset($externalId['maarchParapheur']);
+
+        UserModel::updateExternalId(['id' => $aArgs['id'], 'externalId' => json_encode($externalId)]);
+
+        HistoryController::add([
+            'tableName'    => 'users',
+            'recordId'     => $GLOBALS['userId'],
+            'eventType'    => 'ADD',
+            'eventId'      => 'userCreation',
+            'info'         => _USER_UNLINKED_TO_MAARCHPARAPHEUR . " {$userInfo['firstname']} {$userInfo['lastname']}"
+        ]);
+
+        return $response->withJson(['success' => 'success']);
+    }
+
+    public static function sendSignaturesToMaarchParapheur(Request $request, Response $response, array $aArgs)
+    {
+        $error = UserController::hasUsersRights(['id' => $aArgs['id'], 'himself' => true]);
+        if (!empty($error['error'])) {
+            return $response->withStatus($error['status'])->withJson(['errors' => $error['error']]);
+        }
+
+        $loadedXml = CoreConfigModel::getXmlLoaded(['path' => 'modules/visa/xml/remoteSignatoryBooks.xml']);
+
+        if ($loadedXml->signatoryBookEnabled == 'maarchParapheur') {
+            $userInfo   = UserModel::getById(['select' => ['external_id', 'user_id'], 'id' => $aArgs['id']]);
+            $externalId = json_decode($userInfo['external_id'], true);
+
+            if (!empty($externalId['maarchParapheur'])) {
+                $userSignatures = UserSignatureModel::get([
+                    'select'    => ['signature_path', 'signature_file_name', 'id'],
+                    'where'     => ['user_serial_id = ?'],
+                    'data'      => [$aArgs['id']]
+                ]);
+                if (empty($userSignatures)) {
+                    return $response->withStatus(400)->withJson(['errors' => 'User has no signature']);
+                }
+        
+                $docserver = DocserverModel::getCurrentDocserver(['typeId' => 'TEMPLATES', 'collId' => 'templates', 'select' => ['path_template']]);
+                if (empty($docserver['path_template']) || !file_exists($docserver['path_template'])) {
+                    return $response->withStatus(400)->withJson(['errors' => 'Path for signature docserver does not exists']);
+                }
+
+                $signatures = [];
+                $signaturesId = [];
+                foreach ($userSignatures as $value) {
+                    $pathToSignature = $docserver['path_template'] . str_replace('#', '/', $value['signature_path']) . $value['signature_file_name'];
+                    if (is_file($pathToSignature)) {
+                        $base64          = base64_encode(file_get_contents($pathToSignature));
+                        $format          = pathinfo($pathToSignature, PATHINFO_EXTENSION);
+                        $signatures[]    = ['encodedSignature' => $base64, 'format' => $format];
+                        $signaturesId[]   = $value['id'];
+                    } else {
+                        return $response->withStatus(403)->withJson(['errors' => 'File does not exists : ' . $pathToSignature]);
+                    }
+                }
+
+                $bodyData = [
+                    "signatures"          => $signatures,
+                    "externalApplication" => 'maarchCourrier'
+                ];
+    
+                foreach ($loadedXml->signatoryBook as $value) {
+                    if ($value->id == "maarchParapheur") {
+                        $url      = $value->url;
+                        $userId   = $value->userId;
+                        $password = $value->password;
+                        break;
+                    }
+                }
+
+                $curlResponse = CurlModel::execSimple([
+                    'url'           => rtrim($url, '/') . '/rest/users/' . $externalId['maarchParapheur'] . '/externalSignatures',
+                    'basicAuth'     => ['user' => $userId, 'password' => $password],
+                    'headers'       => ['content-type:application/json'],
+                    'method'        => 'PUT',
+                    'body'          => json_encode($bodyData)
+                ]);
+            } else {
+                return $response->withStatus(403)->withJson(['errors' => 'user does not exists in maarch Parapheur']);
+            }
+
+            if ($curlResponse['code'] != '204') {
+                if (!empty($curlResponse['response']['errors'])) {
+                    $errors =  $curlResponse['response']['errors'];
+                } else {
+                    $errors =  $curlResponse['errors'];
+                }
+                if (empty($errors)) {
+                    $errors = 'An error occured. Please check your configuration file.';
+                }
+                return $response->withStatus(400)->withJson(['errors' => $errors]);
+            }
+        } else {
+            return $response->withStatus(403)->withJson(['errors' => 'maarchParapheur is not enabled']);
+        }
+
+        HistoryController::add([
+            'tableName'    => 'users',
+            'recordId'     => $userInfo['user_id'],
+            'eventType'    => 'UP',
+            'eventId'      => 'signatureSync',
+            'info'         => _SIGNATURES_SEND_TO_MAARCHPARAPHEUR . " : " . implode(", ", $signaturesId)
+        ]);
+
+        return $response->withJson(['success' => 'success']);
+    }
 }
diff --git a/src/app/user/controllers/UserController.php b/src/app/user/controllers/UserController.php
index 29ac34dbe2e..3de534acb24 100755
--- a/src/app/user/controllers/UserController.php
+++ b/src/app/user/controllers/UserController.php
@@ -42,7 +42,6 @@ use User\models\UserBasketPreferenceModel;
 use User\models\UserEntityModel;
 use User\models\UserModel;
 use User\models\UserSignatureModel;
-use SrcCore\models\CurlModel;
 
 class UserController
 {
@@ -1335,209 +1334,55 @@ class UserController
         ]);
     }
 
-    public function sendToMaarchParapheur(Request $request, Response $response, array $aArgs)
-    {
-        $error = $this->hasUsersRights(['id' => $aArgs['id']]);
-        if (!empty($error['error'])) {
-            return $response->withStatus($error['status'])->withJson(['errors' => $error['error']]);
-        }
-
-        $loadedXml = CoreConfigModel::getXmlLoaded(['path' => 'modules/visa/xml/remoteSignatoryBooks.xml']);
-
-        if ($loadedXml->signatoryBookEnabled == 'maarchParapheur') {
-            $userInfo = UserModel::getById(['select' => ['firstname', 'lastname', 'mail', 'external_id', 'user_id'], 'id' => $aArgs['id']]);
-
-            $bodyData = [
-                "lastname"  => $userInfo['lastname'],
-                "firstname" => $userInfo['firstname'],
-                "login"     => $userInfo['user_id'],
-                "email"     => $userInfo['mail']
-            ];
-
-            foreach ($loadedXml->signatoryBook as $value) {
-                if ($value->id == "maarchParapheur") {
-                    $url      = $value->url;
-                    $userId   = $value->userId;
-                    $password = $value->password;
-                    break;
-                }
-            }
-
-            $curlResponse = CurlModel::execSimple([
-                'url'           => rtrim($url, '/') . '/rest/users',
-                'basicAuth'     => ['user' => $userId, 'password' => $password],
-                'headers'       => ['content-type:application/json'],
-                'method'        => 'POST',
-                'body'          => json_encode($bodyData)
-            ]);
-
-            if ($curlResponse['code'] != '200') {
-                if (!empty($curlResponse['response']['errors'])) {
-                    $errors =  $curlResponse['response']['errors'];
-                } else {
-                    $errors =  $curlResponse['errors'];
-                }
-                if (empty($errors)) {
-                    $errors = 'An error occured. Please check your configuration file.';
-                }
-                return $response->withStatus(400)->withJson(['errors' => $errors]);
-            }
-        } else {
-            return $response->withStatus(403)->withJson(['errors' => 'maarchParapheur is not enabled']);
-        }
-
-        $externalId = json_decode($userInfo['external_id'], true);
-        $externalId['maarchParapheur'] = $curlResponse['response']['id'];
-
-        UserModel::updateExternalId(['id' => $aArgs['id'], 'externalId' => json_encode($externalId)]);
-
-        HistoryController::add([
-            'tableName'    => 'users',
-            'recordId'     => $GLOBALS['userId'],
-            'eventType'    => 'ADD',
-            'eventId'      => 'userCreation',
-            'info'         => _USER_CREATED_IN_MAARCHPARAPHEUR . " {$userInfo['firstname']} {$userInfo['lastname']}"
-        ]);
-
-        return $response->withJson(['externalId' => $curlResponse['response']['id']]);
-    }
-
-    public function sendSignaturesToMaarchParapheur(Request $request, Response $response, array $aArgs)
-    {
-        $error = $this->hasUsersRights(['id' => $aArgs['id'], 'himself' => true]);
-        if (!empty($error['error'])) {
-            return $response->withStatus($error['status'])->withJson(['errors' => $error['error']]);
-        }
-
-        $loadedXml = CoreConfigModel::getXmlLoaded(['path' => 'modules/visa/xml/remoteSignatoryBooks.xml']);
-
-        if ($loadedXml->signatoryBookEnabled == 'maarchParapheur') {
-            $userInfo   = UserModel::getById(['select' => ['external_id', 'user_id'], 'id' => $aArgs['id']]);
-            $externalId = json_decode($userInfo['external_id'], true);
-
-            if (!empty($externalId['maarchParapheur'])) {
-                $userSignatures = UserSignatureModel::get([
-                    'select'    => ['signature_path', 'signature_file_name', 'id'],
-                    'where'     => ['user_serial_id = ?'],
-                    'data'      => [$aArgs['id']]
-                ]);
-                if (empty($userSignatures)) {
-                    return $response->withStatus(400)->withJson(['errors' => 'User has no signature']);
-                }
-        
-                $docserver = DocserverModel::getCurrentDocserver(['typeId' => 'TEMPLATES', 'collId' => 'templates', 'select' => ['path_template']]);
-                if (empty($docserver['path_template']) || !file_exists($docserver['path_template'])) {
-                    return $response->withStatus(400)->withJson(['errors' => 'Path for signature docserver does not exists']);
-                }
-
-                $signatures = [];
-                $signaturesId = [];
-                foreach ($userSignatures as $value) {
-                    $pathToSignature = $docserver['path_template'] . str_replace('#', '/', $value['signature_path']) . $value['signature_file_name'];
-                    if (is_file($pathToSignature)) {
-                        $base64          = base64_encode(file_get_contents($pathToSignature));
-                        $format          = pathinfo($pathToSignature, PATHINFO_EXTENSION);
-                        $signatures[]    = ['encodedSignature' => $base64, 'format' => $format];
-                        $signaturesId[]   = $value['id'];
-                    } else {
-                        return $response->withStatus(403)->withJson(['errors' => 'File does not exists : ' . $pathToSignature]);
-                    }
-                }
-
-                $bodyData = [
-                    "signatures"          => $signatures,
-                    "externalApplication" => 'maarchCourrier'
-                ];
-    
-                foreach ($loadedXml->signatoryBook as $value) {
-                    if ($value->id == "maarchParapheur") {
-                        $url      = $value->url;
-                        $userId   = $value->userId;
-                        $password = $value->password;
-                        break;
-                    }
-                }
-
-                $curlResponse = CurlModel::execSimple([
-                    'url'           => rtrim($url, '/') . '/rest/users/' . $externalId['maarchParapheur'] . '/externalSignatures',
-                    'basicAuth'     => ['user' => $userId, 'password' => $password],
-                    'headers'       => ['content-type:application/json'],
-                    'method'        => 'PUT',
-                    'body'          => json_encode($bodyData)
-                ]);
-            } else {
-                return $response->withStatus(403)->withJson(['errors' => 'user does not exists in maarch Parapheur']);
-            }
-
-            if ($curlResponse['code'] != '204') {
-                if (!empty($curlResponse['response']['errors'])) {
-                    $errors =  $curlResponse['response']['errors'];
-                } else {
-                    $errors =  $curlResponse['errors'];
-                }
-                if (empty($errors)) {
-                    $errors = 'An error occured. Please check your configuration file.';
-                }
-                return $response->withStatus(400)->withJson(['errors' => $errors]);
-            }
-        } else {
-            return $response->withStatus(403)->withJson(['errors' => 'maarchParapheur is not enabled']);
-        }
-
-        HistoryController::add([
-            'tableName'    => 'users',
-            'recordId'     => $userInfo['user_id'],
-            'eventType'    => 'UP',
-            'eventId'      => 'signatureSync',
-            'info'         => _SIGNATURES_SEND_TO_MAARCHPARAPHEUR . " : " . implode(", ", $signaturesId)
-        ]);
-
-        return $response->withJson(['success' => 'success']);
-    }
-
-    private function hasUsersRights(array $aArgs)
+    public function hasUsersRights(array $aArgs)
     {
         $error = [
             'status'    => 200,
             'error'     => ''
         ];
 
-        $user = UserModel::getById(['id' => $aArgs['id'], 'select' => ['user_id']]);
-        if (empty($user['user_id'])) {
+        if (!is_numeric($aArgs['id'])) {
             $error['status'] = 400;
-            $error['error'] = 'User not found';
+            $error['error'] = 'id must be an integer';
         } else {
-            if (empty($aArgs['himself']) || $GLOBALS['userId'] != $user['user_id']) {
-                if (!ServiceModel::hasService(['id' => 'admin_users', 'userId' => $GLOBALS['userId'], 'location' => 'apps', 'type' => 'admin'])) {
-                    $error['status'] = 403;
-                    $error['error'] = 'Service forbidden';
-                }
-                if ($GLOBALS['userId'] != 'superadmin') {
-                    $entities = EntityModel::getAllEntitiesByUserId(['userId' => $GLOBALS['userId']]);
-                    $users = UserEntityModel::getWithUsers([
-                        'select'    => ['users.id'],
-                        'where'     => ['users_entities.entity_id in (?)', 'status != ?'],
-                        'data'      => [$entities, 'DEL']
-                    ]);
-                    $usersNoEntities = UserEntityModel::getUsersWithoutEntities(['select' => ['id']]);
-                    $users = array_merge($users, $usersNoEntities);
-                    $allowed = false;
-                    foreach ($users as $value) {
-                        if ($value['id'] == $aArgs['id']) {
-                            $allowed = true;
-                        }
-                    }
-                    if (!$allowed) {
+            $user = UserModel::getById(['id' => $aArgs['id'], 'select' => ['user_id']]);
+            if (empty($user['user_id'])) {
+                $error['status'] = 400;
+                $error['error'] = 'User not found';
+            } else {
+                if (empty($aArgs['himself']) || $GLOBALS['userId'] != $user['user_id']) {
+                    if (!ServiceModel::hasService(['id' => 'admin_users', 'userId' => $GLOBALS['userId'], 'location' => 'apps', 'type' => 'admin'])) {
                         $error['status'] = 403;
-                        $error['error'] = 'UserId out of perimeter';
+                        $error['error'] = 'Service forbidden';
+                    }
+                    if ($GLOBALS['userId'] != 'superadmin') {
+                        $entities = EntityModel::getAllEntitiesByUserId(['userId' => $GLOBALS['userId']]);
+                        $users = UserEntityModel::getWithUsers([
+                            'select'    => ['users.id'],
+                            'where'     => ['users_entities.entity_id in (?)', 'status != ?'],
+                            'data'      => [$entities, 'DEL']
+                        ]);
+                        $usersNoEntities = UserEntityModel::getUsersWithoutEntities(['select' => ['id']]);
+                        $users = array_merge($users, $usersNoEntities);
+                        $allowed = false;
+                        foreach ($users as $value) {
+                            if ($value['id'] == $aArgs['id']) {
+                                $allowed = true;
+                            }
+                        }
+                        if (!$allowed) {
+                            $error['status'] = 403;
+                            $error['error'] = 'UserId out of perimeter';
+                        }
                     }
+                } elseif ($aArgs['delete'] && $GLOBALS['userId'] == $user['user_id']) {
+                    $error['status'] = 403;
+                    $error['error'] = 'Can not delete yourself';
                 }
-            } elseif ($aArgs['delete'] && $GLOBALS['userId'] == $user['user_id']) {
-                $error['status'] = 403;
-                $error['error'] = 'Can not delete yourself';
             }
         }
 
+
         return $error;
     }
 
diff --git a/src/core/lang/lang-en.php b/src/core/lang/lang-en.php
index e6d0a36410b..deeed9cf4fe 100755
--- a/src/core/lang/lang-en.php
+++ b/src/core/lang/lang-en.php
@@ -455,6 +455,8 @@ define('_CLOSING_DATE', 'Closing date');
 define('_ACTION_DATE', 'Action date');
 
 define('_USER_CREATED_IN_MAARCHPARAPHEUR', 'User created in Maarch Parapheur');
+define('_USER_LINKED_TO_MAARCHPARAPHEUR', 'User link to Maarch Parapheur');
+define('_USER_UNLINKED_TO_MAARCHPARAPHEUR', 'User unlink to Maarch Parapheur');
 define('_SIGNATURES_SEND_TO_MAARCHPARAPHEUR', 'Signatures sent to Maarch Parapheur');
 
 define('_CREATE_ACKNOWLEDGEMENT_RECEIPT', 'Generate and send acknowledgement receipt');
diff --git a/src/core/lang/lang-fr.php b/src/core/lang/lang-fr.php
index d64b0dccfb9..14cff98edd1 100755
--- a/src/core/lang/lang-fr.php
+++ b/src/core/lang/lang-fr.php
@@ -455,6 +455,8 @@ define('_CLOSING_DATE', 'Date de clôture');
 define('_ACTION_DATE', 'Date d\'action');
 
 define('_USER_CREATED_IN_MAARCHPARAPHEUR', 'Utilisateur créé dans Maarch Parapheur');
+define('_USER_LINKED_TO_MAARCHPARAPHEUR', 'Utilisateur associé à un compte Maarch Parapheur');
+define('_USER_UNLINKED_TO_MAARCHPARAPHEUR', 'Utilisateur dissocié d\'un Maarch Parapheur');
 define('_SIGNATURES_SEND_TO_MAARCHPARAPHEUR', 'Signature(s) envoyée(s) à Maarch Parapheur');
 
 define('_CREATE_ACKNOWLEDGEMENT_RECEIPT', 'Générer et envoyer les accusés de réception');
diff --git a/src/core/lang/lang-nl.php b/src/core/lang/lang-nl.php
index 1191c3418ba..c4b09fbf963 100755
--- a/src/core/lang/lang-nl.php
+++ b/src/core/lang/lang-nl.php
@@ -454,6 +454,8 @@ define('_CLOSING_DATE', 'Closing date_TO_TRANSLATE');
 define('_ACTION_DATE', 'Action date_TO_TRANSLATE');
 
 define('_USER_CREATED_IN_MAARCHPARAPHEUR', 'User created in Maarch Parapheur_TO_TRANSLATE');
+define('_USER_LINKED_TO_MAARCHPARAPHEUR', 'User link to Maarch Parapheur_TO_TRANSLATE');
+define('_USER_UNLINKED_TO_MAARCHPARAPHEUR', 'User unlink to Maarch Parapheur_TO_TRANSLATE');
 define('_SIGNATURES_SEND_TO_MAARCHPARAPHEUR', 'Signatures send to Maarch Parapheur_TO_TRANSLATE');
 
 define('_CREATE_ACKNOWLEDGEMENT_RECEIPT', 'Generate and send acknowledgement receipt_TO_TRANSLATE');
-- 
GitLab