From ba4d51bfd8931e98bfaebb7e4f64d1cf3cfdbb4c Mon Sep 17 00:00:00 2001
From: "florian.azizian" <florian.azizian@maarch.org>
Date: Fri, 17 Apr 2020 14:00:34 +0100
Subject: [PATCH] FEAT #13779 TIME 1 Add token in onlyOffice Configuration

---
 .../xml/documentEditorsConfig.xml             |  1 +
 rest/index.php                                |  1 +
 .../controllers/OnlyOfficeController.php      | 48 +++++++++++++++++--
 3 files changed, 47 insertions(+), 3 deletions(-)

diff --git a/apps/maarch_entreprise/xml/documentEditorsConfig.xml b/apps/maarch_entreprise/xml/documentEditorsConfig.xml
index 3d625f1c741..52fddb28f46 100644
--- a/apps/maarch_entreprise/xml/documentEditorsConfig.xml
+++ b/apps/maarch_entreprise/xml/documentEditorsConfig.xml
@@ -8,5 +8,6 @@
         <server_uri>onlyoffice.maarchcourrier.com</server_uri>
         <server_port>80</server_port>
         <server_ssl>false</server_ssl>
+        <server_token></server_token>
     </onlyoffice>
 </ROOT>
diff --git a/rest/index.php b/rest/index.php
index 5c424d0a68c..763c7235f6a 100755
--- a/rest/index.php
+++ b/rest/index.php
@@ -167,6 +167,7 @@ $app->post('/jnlp/{jnlpUniqueId}', \ContentManagement\controllers\JnlpController
 $app->get('/jnlp/lock/{jnlpUniqueId}', \ContentManagement\controllers\JnlpController::class . ':isLockFileExisting');
 $app->get('/documentEditors', \ContentManagement\controllers\DocumentEditorController::class . ':get');
 $app->get('/onlyOffice/configuration', \ContentManagement\controllers\OnlyOfficeController::class . ':getConfiguration');
+$app->post('/onlyOffice/token', \ContentManagement\controllers\OnlyOfficeController::class . ':getToken');
 $app->post('/onlyOffice/mergedFile', \ContentManagement\controllers\OnlyOfficeController::class . ':saveMergedFile');
 $app->get('/onlyOffice/mergedFile', \ContentManagement\controllers\OnlyOfficeController::class . ':getMergedFile');
 $app->get('/onlyOffice/encodedFile', \ContentManagement\controllers\OnlyOfficeController::class . ':getEncodedFileFromUrl');
diff --git a/src/app/contentManagement/controllers/OnlyOfficeController.php b/src/app/contentManagement/controllers/OnlyOfficeController.php
index 97fa04ac849..a2e0bb96962 100644
--- a/src/app/contentManagement/controllers/OnlyOfficeController.php
+++ b/src/app/contentManagement/controllers/OnlyOfficeController.php
@@ -48,14 +48,55 @@ class OnlyOfficeController
         return $response->withJson($configurations);
     }
 
+    public static function getToken(Request $request, Response $response)
+    {
+        $body = $request->getParsedBody();
+        if (!Validator::notEmpty()->validate($body['config'])) {
+            return $response->withStatus(400)->withJson(['errors' => 'Body params config is empty']);
+        }
+
+        $loadedXml = CoreConfigModel::getXmlLoaded(['path' => 'apps/maarch_entreprise/xml/documentEditorsConfig.xml']);
+
+        if (empty($loadedXml) || empty($loadedXml->onlyoffice->enabled) || $loadedXml->onlyoffice->enabled == 'false' || empty($loadedXml->onlyoffice->server_uri)) {
+            return $response->withStatus(400)->withJson(['errors' => 'OnlyOffice server is disabled']);
+        }
+
+        $token = null;
+        $serverToken = (string)$loadedXml->onlyoffice->server_token;
+        if (!empty($serverToken)) {
+            $header = [
+                "alg" => "HS256",
+                "typ" => "JWT"
+            ];
+
+            $encHeader  = OnlyOfficeController::base64UrlEncode(json_encode($header));
+            $encPayload = OnlyOfficeController::base64UrlEncode(json_encode($body['config']));
+            $hash       = OnlyOfficeController::base64UrlEncode(OnlyOfficeController::calculateHash(['header' => $encHeader, 'payload' => $encPayload, 'serverToken' => $serverToken]));
+        
+            $token = "$encHeader.$encPayload.$hash";
+        }
+
+        return $response->withJson($token);
+    }
+
+    public static function calculateHash($args = [])
+    {
+        return hash_hmac("sha256", $args['header'] . "." . $args['payload'], $args['serverToken'], true);
+    }
+    
+    public static function base64UrlEncode($str)
+    {
+        return str_replace("/", "_", str_replace("+", "-", trim(base64_encode($str), "=")));
+    }
+
     public static function saveMergedFile(Request $request, Response $response)
     {
         $body = $request->getParsedBody();
 
         if (!Validator::stringType()->notEmpty()->validate($body['onlyOfficeKey'])) {
-            return $response->withStatus(400)->withJson(['errors' => 'Query params onlyOfficeKey is empty']);
+            return $response->withStatus(400)->withJson(['errors' => 'Body params onlyOfficeKey is empty']);
         } elseif (!preg_match('/[A-Za-z0-9]/i', $body['onlyOfficeKey'])) {
-            return $response->withStatus(400)->withJson(['errors' => 'Query params onlyOfficeKey is forbidden']);
+            return $response->withStatus(400)->withJson(['errors' => 'Body params onlyOfficeKey is forbidden']);
         }
 
         if ($body['objectType'] == 'templateCreation') {
@@ -233,7 +274,8 @@ class OnlyOfficeController
         $uri = (string)$loadedXml->onlyoffice->server_uri;
         $port = (string)$loadedXml->onlyoffice->server_port;
 
-        $exec = shell_exec("nc -vz -w 5 {$uri} {$port} 2>&1");
+        $aUri = explode("/", $uri);
+        $exec = shell_exec("nc -vz -w 5 {$aUri[0]} {$port} 2>&1");
 
         if (strpos($exec, 'not found') !== false) {
             return $response->withStatus(400)->withJson(['errors' => 'Netcat command not found', 'lang' => 'preRequisiteMissing']);
-- 
GitLab