From 5b13aa558481d5abaffb78d697dd2582ebec2828 Mon Sep 17 00:00:00 2001 From: Damien <damien.burel@maarch.org> Date: Wed, 12 May 2021 14:34:46 +0200 Subject: [PATCH] FEAT #16982 TIME 4:30 WIP External yousign workflow + fix workflow without userId + take care of security --- .../controllers/DocumentController.php | 58 ++++++++++-------- .../search/controllers/SearchController.php | 15 ++++- .../controllers/YousignController.php | 59 +++++++++++++++---- .../WorkflowExternalInformationModel.php | 20 +++++++ 4 files changed, 116 insertions(+), 36 deletions(-) diff --git a/src/app/document/controllers/DocumentController.php b/src/app/document/controllers/DocumentController.php index 18ed05c39f..1b851314ab 100755 --- a/src/app/document/controllers/DocumentController.php +++ b/src/app/document/controllers/DocumentController.php @@ -177,7 +177,7 @@ class DocumentController } } - $workflow = WorkflowModel::getByDocumentId(['select' => ['user_id', 'mode', 'process_date', 'signature_mode', 'status', 'note', 'signature_positions', 'date_positions'], 'documentId' => $args['id'], 'orderBy' => ['"order"']]); + $workflow = WorkflowModel::getByDocumentId(['select' => ['id', 'user_id', 'mode', 'process_date', 'signature_mode', 'status', 'note', 'signature_positions', 'date_positions'], 'documentId' => $args['id'], 'orderBy' => ['"order"']]); $currentFound = false; $currentId = null; foreach ($workflow as $value) { @@ -185,18 +185,26 @@ class DocumentController $date = new \DateTime($value['process_date']); $value['process_date'] = $date->format('d-m-Y H:i'); } - $userSignaturesModes = UserModel::getById(['id' => $value['user_id'], 'select' => ['signature_modes']]); - + $userLabel = ''; + if (!empty($value['user_id'])) { + $userSignaturesModes = UserModel::getById(['id' => $value['user_id'], 'select' => ['signature_modes']]); + $userLabel = UserModel::getLabelledUserById(['id' => $value['user_id']]); + } else { + $workflowExternalInformations = WorkflowExternalInformationModel::get(['select' => ['*'], 'where' => ['workflow_id = ?'], 'data' => [$value['id']]]); + if (!empty($workflowExternalInformations[0])) { + $userLabel = "{$workflowExternalInformations[0]['firstname']} {$workflowExternalInformations[0]['lastname']}"; + } + } $formattedDocument['workflow'][] = [ 'userId' => $value['user_id'], - 'userDisplay' => UserModel::getLabelledUserById(['id' => $value['user_id']]), + 'userDisplay' => $userLabel, 'mode' => $value['mode'], 'processDate' => $value['process_date'], 'current' => !$currentFound && empty($value['status']), 'signatureMode' => $value['signature_mode'], 'signaturePositions' => json_decode($value['signature_positions'], true), 'datePositions' => json_decode($value['date_positions'], true), - 'userSignatureModes' => json_decode($userSignaturesModes['signature_modes'], true) ?? [], + 'userSignatureModes' => !empty($userSignaturesModes['signature_modes']) ? json_decode($userSignaturesModes['signature_modes'], true) : [], 'note' => $value['note'], 'status' => $value['status'] ]; @@ -325,6 +333,7 @@ class DocumentController $hasEidas = false; $hasElectronicSignature = false; foreach ($body['workflow'] as $key => $workflow) { + $processingUser = null; if (empty($workflow['processingUser']) && empty($workflow['userId']) && !empty($workflow['externalInformations'])) { if (!Validator::stringType()->notEmpty()->validate($workflow['externalInformations']['firstname'] ?? null)) { return $response->withStatus(400)->withJson(['errors' => "Body workflow[{$key}][externalInformations] firstname is empty or not a string"]); @@ -509,13 +518,17 @@ class DocumentController $firstWorkflowId = $workflowId; } if (empty($workflow['userId'])) { + $informations = []; + if ($workflow['externalInformations']['type'] == 'yousign') { + $informations = YousignController::formatExternalInformations($workflow['externalInformations']); + } WorkflowExternalInformationModel::create([ 'workflow_id' => $workflowId, 'firstname' => $workflow['externalInformations']['firstname'], 'lastname' => $workflow['externalInformations']['lastname'], 'email' => $workflow['externalInformations']['email'], 'phone' => $workflow['externalInformations']['phone'], - 'informations' => empty($workflow['externalInformations']['informations']) ? '{}' : json_encode($workflow['externalInformations']['informations']) + 'informations' => json_encode($informations) ]); } } @@ -567,17 +580,19 @@ class DocumentController } if (empty($body['workflow'][0]['userId'])) { - YousignController::createProcedure([ - 'encodedDocument' => $encodedDocument['encodedDocument'], - 'name' => $body['title'], - 'description' => $body['description'], - 'firstname' => $body['workflow'][0]['externalInformations']['firstname'], - 'lastname' => $body['workflow'][0]['externalInformations']['lastname'], - 'email' => $body['workflow'][0]['externalInformations']['email'], - 'phone' => $body['workflow'][0]['externalInformations']['phone'], - 'position' => "364,105,462,145", - 'workflowId' => $firstWorkflowId - ]); + if ($body['workflow'][0]['externalInformations']['type'] == 'yousign') { + $procedureCreated = YousignController::createProcedure([ + 'documentId' => $id, + 'encodedDocument' => $encodedDocument['encodedDocument'], + 'name' => $body['title'], + 'description' => $body['description'], + 'position' => "364,105,462,145", + 'workflowId' => $firstWorkflowId + ]); + if (!empty($procedureCreated['errors'])) { + return $response->withStatus(500)->withJson(['errors' => 'Yousign procedure creation failed : ' . $procedureCreated['errors']]); + } + } } else { EmailController::sendNotification(['documentId' => $id, 'userId' => $GLOBALS['id']]); } @@ -1012,8 +1027,8 @@ class DocumentController public static function endAction(array $args) { - ValidatorModel::notEmpty($args, ['id', 'status', 'workflowId', 'userId']); - ValidatorModel::intVal($args, ['id', 'workflowId', 'userId']); + ValidatorModel::notEmpty($args, ['id', 'status', 'workflowId']); + ValidatorModel::intVal($args, ['id', 'workflowId']); ValidatorModel::stringType($args, ['status', 'note']); $set = ['process_date' => 'CURRENT_TIMESTAMP', 'status' => $args['status']]; @@ -1043,13 +1058,10 @@ class DocumentController $document = DocumentModel::getById(['select' => ['title', 'description'], 'id' => $args['id']]); YousignController::createProcedure([ + 'documentId' => $args['id'], 'encodedDocument' => base64_encode($content), 'name' => $document['title'], 'description' => $document['description'], - 'firstname' => $workflowExternalInformations[0]['firstname'], - 'lastname' => $workflowExternalInformations[0]['lastname'], - 'email' => $workflowExternalInformations[0]['email'], - 'phone' => $workflowExternalInformations[0]['phone'], 'position' => "364,105,462,145", 'workflowId' => $nextWorkflow['id'] ]); diff --git a/src/app/search/controllers/SearchController.php b/src/app/search/controllers/SearchController.php index 30632ff0d5..d824c1aef8 100755 --- a/src/app/search/controllers/SearchController.php +++ b/src/app/search/controllers/SearchController.php @@ -21,6 +21,7 @@ use Slim\Http\Request; use Slim\Http\Response; use SrcCore\models\ValidatorModel; use User\models\UserModel; +use Workflow\models\WorkflowExternalInformationModel; use Workflow\models\WorkflowModel; class SearchController @@ -123,7 +124,7 @@ class SearchController $count = empty($documents[0]['count']) ? 0 : $documents[0]['count']; $hasIndexation = PrivilegeController::hasPrivilege(['userId' => $GLOBALS['id'], 'privilege' => 'indexation']); foreach ($documents as $key => $document) { - $workflow = WorkflowModel::getByDocumentId(['select' => ['user_id', 'mode', 'process_date', 'signature_mode', 'note', 'status'], 'documentId' => $document['id'], 'orderBy' => ['"order"']]); + $workflow = WorkflowModel::getByDocumentId(['select' => ['id', 'user_id', 'mode', 'process_date', 'signature_mode', 'note', 'status'], 'documentId' => $document['id'], 'orderBy' => ['"order"']]); $currentFound = false; $formattedWorkflow = []; $state = null; @@ -133,9 +134,19 @@ class SearchController $value['process_date'] = $date->format('d-m-Y H:i'); } + $userLabel = ''; + if (!empty($value['user_id'])) { + $userLabel = UserModel::getLabelledUserById(['id' => $value['user_id']]); + } else { + $workflowExternalInformations = WorkflowExternalInformationModel::getByWorkflowId(['select' => ['firstname', 'lastname'], 'workflowId' => $value['id']]); + if (!empty($workflowExternalInformations[0])) { + $userLabel = "{$workflowExternalInformations[0]['firstname']} {$workflowExternalInformations[0]['lastname']}"; + } + } + $formattedWorkflow[] = [ 'userId' => $value['user_id'], - 'userDisplay' => UserModel::getLabelledUserById(['id' => $value['user_id']]), + 'userDisplay' => $userLabel, 'mode' => $value['mode'], 'processDate' => $value['process_date'], 'current' => !$currentFound && empty($value['status']), diff --git a/src/app/workflow/controllers/YousignController.php b/src/app/workflow/controllers/YousignController.php index 4878321579..50988af6c6 100755 --- a/src/app/workflow/controllers/YousignController.php +++ b/src/app/workflow/controllers/YousignController.php @@ -19,7 +19,9 @@ use Docserver\models\AdrModel; use Document\controllers\DocumentController; use Slim\Http\Request; use Slim\Http\Response; +use SrcCore\controllers\UrlController; use SrcCore\models\CurlModel; +use SrcCore\models\ValidatorModel; use Workflow\models\WorkflowExternalInformationModel; use Workflow\models\WorkflowModel; @@ -30,6 +32,13 @@ class YousignController $url = 'https://staging-api.yousign.com'; $token = ''; + $workflowExternalInformations = WorkflowExternalInformationModel::getByWorkflowId(['select' => ['*'], 'workflowId' => $args['workflowId']]); + if (empty($workflowExternalInformations)) { + return ['errors' => 'No external informations found']; + } + + $workflowExternalInformations['informations'] = json_decode($workflowExternalInformations['informations'], true); + $fileResponse = CurlModel::exec([ 'url' => "{$url}/files", 'bearerAuth' => ['token' => $token], @@ -46,6 +55,7 @@ class YousignController } $fileId = $fileResponse['response']['id']; + $trunkedFileId = str_replace('/files/', '', $fileId); $procedureResponse = CurlModel::exec([ 'url' => "{$url}/procedures", @@ -57,10 +67,12 @@ class YousignController 'description' => $args['description'], 'members' => [ [ - 'firstname' => $args['firstname'], - 'lastname' => $args['lastname'], - 'email' => $args['email'], - 'phone' => $args['phone'], + 'firstname' => $workflowExternalInformations['firstname'], + 'lastname' => $workflowExternalInformations['lastname'], + 'email' => $workflowExternalInformations['email'], + 'phone' => $workflowExternalInformations['phone'], + 'operationLevel' => 'custom', + 'operationCustomModes' => [$workflowExternalInformations['informations']['security']], 'fileObjects' => [ [ 'file' => $fileId, @@ -79,16 +91,25 @@ class YousignController "to" => ["@member"] ] ] - ] + ], +// 'webhook' => [ +// 'member.finished' => [ +// [ +// 'url' => UrlController::getCoreUrl() . "/rest/documents/{$args['documentId']}/workflows/{$args['workflowId']}/files/{$trunkedFileId}", +// 'method' => 'GET', +// ] +// ] +// ] ] ]) ]); - if ($procedureResponse['code'] != 201) { return ['errors' => json_encode($procedureResponse['reponse'])]; } - $informations = json_encode(['yousignFileId' => $fileId]); + + $workflowExternalInformations['informations']['yousignFileId'] = $fileId; + $informations = json_encode($workflowExternalInformations['informations']); WorkflowExternalInformationModel::update(['set' => ['informations' => $informations], 'where' => ['workflow_id = ?'], 'data' => [$args['workflowId']]]); return true; @@ -129,7 +150,7 @@ class YousignController } $storeInfos = DocserverController::storeResourceOnDocServer([ - 'encodedFile' => $fileResponse['reponse'], + 'encodedFile' => $fileResponse['response'], 'format' => 'pdf', 'docserverType' => 'DOC' ]); @@ -151,11 +172,27 @@ class YousignController DocumentController::endAction([ 'id' => $args['id'], - 'workflowId' => $workflow['id'], - 'status' => DocumentController::ACTIONS[$args['actionId']], - 'note' => $body['note'] ?? null + 'workflowId' => $args['workflowId'], + 'status' => 'VAL', + 'note' => null ]); return true; } + + public static function formatExternalInformations(array $args) + { + ValidatorModel::stringType($args, ['security']); + + $informations = [ + 'type' => 'yousign', + 'security' => 'sms' + ]; + + if (!empty($args['security']) && $args['security'] == 'email') { + $informations['security'] = 'email'; + } + + return $informations; + } } diff --git a/src/app/workflow/models/WorkflowExternalInformationModel.php b/src/app/workflow/models/WorkflowExternalInformationModel.php index 176f345757..fc0a48f64a 100755 --- a/src/app/workflow/models/WorkflowExternalInformationModel.php +++ b/src/app/workflow/models/WorkflowExternalInformationModel.php @@ -39,6 +39,26 @@ class WorkflowExternalInformationModel return $workflows; } + public static function getByWorkflowId(array $args) + { + ValidatorModel::notEmpty($args, ['select', 'workflowId']); + ValidatorModel::intVal($args, ['workflowId']); + ValidatorModel::arrayType($args, ['select']); + + $workflow = DatabaseModel::select([ + 'select' => $args['select'], + 'table' => ['workflows_external_informations'], + 'where' => ['workflow_id = ?'], + 'data' => [$args['workflowId']] + ]); + + if (empty($workflow[0])) { + return []; + } + + return $workflow[0]; + } + public static function create(array $args) { ValidatorModel::notEmpty($args, ['workflow_id', 'firstname', 'lastname']); -- GitLab