From ec41b17ef4f56c733f57732395e8a108846facb2 Mon Sep 17 00:00:00 2001
From: Guillaume Heurtier <guillaume.heurtier@maarch.org>
Date: Fri, 8 Nov 2019 14:39:58 +0100
Subject: [PATCH] FIX #11691 TIME 1:00 added attachment management privilege

---
 migration/19.12/1912.sql                      | 11 +++++++++++
 .../controllers/AttachmentController.php      | 19 +++++++++++++++----
 .../models/AttachmentModelAbstract.php        |  8 ++++----
 src/frontend/lang/lang-en.ts                  |  2 ++
 src/frontend/lang/lang-fr.ts                  |  2 ++
 src/frontend/lang/lang-nl.ts                  |  2 ++
 src/frontend/service/privileges.service.ts    | 12 ++++++++++++
 7 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/migration/19.12/1912.sql b/migration/19.12/1912.sql
index cae5ab468b7..94b2b009501 100644
--- a/migration/19.12/1912.sql
+++ b/migration/19.12/1912.sql
@@ -417,6 +417,17 @@ WHERE service_id = 'edit_recipient_outside_process' OR service_id = 'update_diff
 DELETE FROM usergroups_services WHERE service_id = 'edit_recipient_outside_process';
 DELETE FROM usergroups_services WHERE service_id = 'update_list_diff_in_details';
 DELETE FROM usergroups_services WHERE service_id = 'edit_recipient_in_process';
+
+UPDATE usergroups_services SET service_id = 'manage_own_attachments_in_details' WHERE service_id = 'edit_attachments_from_detail';
+INSERT INTO usergroups_services (group_id, service_id)
+SELECT distinct(group_id), 'manage_attachments'
+FROM usergroups_services WHERE group_id IN (
+    SELECT group_id FROM usergroups_services
+    WHERE service_id = 'modify_attachments' OR service_id = 'delete_attachments'
+);
+DELETE FROM usergroups_services WHERE service_id = 'modify_attachments';
+DELETE FROM usergroups_services WHERE service_id = 'delete_attachments';
+
 UPDATE listmodels SET title = object_id WHERE title IS NULL;
 UPDATE baskets SET basket_clause = REGEXP_REPLACE(basket_clause, 'coll_id(\s*)=(\s*)''letterbox_coll''(\s*)AND', '', 'gmi') WHERE basket_id in ('CopyMailBasket', 'DdeAvisBasket');
 UPDATE baskets SET basket_clause = REGEXP_REPLACE(basket_clause, 'coll_id(\s*)=(\s*)''letterbox_coll''(\s*)and', '', 'gmi') WHERE basket_id in ('CopyMailBasket', 'DdeAvisBasket');
diff --git a/src/app/attachment/controllers/AttachmentController.php b/src/app/attachment/controllers/AttachmentController.php
index 2ae994d021d..e3121042b60 100755
--- a/src/app/attachment/controllers/AttachmentController.php
+++ b/src/app/attachment/controllers/AttachmentController.php
@@ -452,25 +452,36 @@ class AttachmentController
             return $response->withStatus(400)->withJson(['errors' => 'Route id must be an integer val']);
         }
 
-        $attachment = AttachmentModel::getById(['id' => $args['id'], 'select' => ['origin_id', 'res_id_master', 'attachment_type', 'res_id', 'title']]);
+        $attachment = AttachmentModel::getById(['id' => $args['id'], 'select' => ['origin_id', 'res_id_master', 'attachment_type', 'res_id', 'title', 'typist']]);
         if (empty($attachment)) {
             return $response->withStatus(400)->withJson(['errors' => 'Attachment not found']);
         }
 
+        $user = UserModel::getById(['id' => $GLOBALS['id']]);
+        if ($user['user_id'] != $attachment['typist']
+            && !PrivilegeController::hasPrivilege(['privilegeId' => 'manage_attachments', 'userId' => $GLOBALS['id']])) {
+            return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter2']);
+        }
+
         if (!ResController::hasRightByResId(['resId' => [$attachment['res_id_master']], 'userId' => $GLOBALS['id']])) {
             return $response->withStatus(403)->withJson(['errors' => 'Document out of perimeter']);
         }
 
         if ($attachment['attachment_type'] == 'signed_response') {
-            AttachmentModel::delete(['id' => $attachment['res_id']]);
+            AttachmentModel::delete([
+                'where' => ['res_id = ?'],
+                'data'  => [$attachment['res_id']]
+            ]);
         } else {
             if (empty($attachment['origin_id'])) {
                 $idToDelete = $attachment['res_id'];
             } else {
                 $idToDelete = $attachment['origin_id'];
             }
-
-            AttachmentModel::delete(['id' => $idToDelete]);
+            AttachmentModel::delete([
+                'where' => ['res_id = ? or origin_id = ?'],
+                'data'  => [$idToDelete, $idToDelete]
+            ]);
         }
         HistoryController::add([
             'tableName' => 'res_attachments',
diff --git a/src/app/attachment/models/AttachmentModelAbstract.php b/src/app/attachment/models/AttachmentModelAbstract.php
index 316259a7aa0..f5e65821d9c 100755
--- a/src/app/attachment/models/AttachmentModelAbstract.php
+++ b/src/app/attachment/models/AttachmentModelAbstract.php
@@ -287,16 +287,16 @@ abstract class AttachmentModelAbstract
 
     public static function delete(array $args)
     {
-        ValidatorModel::notEmpty($args, ['id']);
-        ValidatorModel::intVal($args, ['id']);
+        ValidatorModel::notEmpty($args, ['where', 'data']);
+        ValidatorModel::arrayType($args, ['where', 'data']);
 
         DatabaseModel::update([
             'table' => 'res_attachments',
             'set'   => [
                 'status'    => 'DEL'
             ],
-            'where' => ['res_id = ? or origin_id = ?'],
-            'data'  => [$args['id'], $args['id']]
+            'where' => $args['where'],
+            'data'  => $args['data']
         ]);
 
         return true;
diff --git a/src/frontend/lang/lang-en.ts b/src/frontend/lang/lang-en.ts
index f2be4195e08..53e461fa8fa 100755
--- a/src/frontend/lang/lang-en.ts
+++ b/src/frontend/lang/lang-en.ts
@@ -1266,4 +1266,6 @@ export const LANG_EN = {
     "diffListPrivilegeMsgProcess" : "in process page.",
     "recordMail" : "Record a mail",
     "closed" : "Closed",
+    "manageAttachments": "Update or delete attachments",
+    "manageOwnAttachmentsInDetails": "Update or delete user's own attachments in the details page",
 };
diff --git a/src/frontend/lang/lang-fr.ts b/src/frontend/lang/lang-fr.ts
index 3d0137abb24..a5fd1e4d913 100755
--- a/src/frontend/lang/lang-fr.ts
+++ b/src/frontend/lang/lang-fr.ts
@@ -1303,4 +1303,6 @@ export const LANG_FR = {
     "diffListPrivilegeMsgProcess" : "lors du traitement du courrier.",
     "recordMail" : "Enregistrer un courrier",
     "closed" : "Clôturé",
+    "manageAttachments": "Modifier ou supprimer des pièces jointes",
+    "manageOwnAttachmentsInDetails": "Modifier ou supprimer ses propres pièces jointes dans la fiche détaillée",
 };
diff --git a/src/frontend/lang/lang-nl.ts b/src/frontend/lang/lang-nl.ts
index b36708e5239..6d46f46fb59 100755
--- a/src/frontend/lang/lang-nl.ts
+++ b/src/frontend/lang/lang-nl.ts
@@ -1291,4 +1291,6 @@ export const LANG_NL = {
     "diffListPrivilegeMsgProcess" : "in process page.", //_TO_TRANSLATE
     "recordMail" : "Record a mail", //_TO_TRANSLATE
     "closed" : "Closed", //_TO_TRANSLATE
+    "manageAttachments": "Update or delete attachments", //_TO_TRANSLATE
+    "manageOwnAttachmentsInDetails": "Update or delete user's own attachments in the details page", //_TO_TRANSLATE
 };
diff --git a/src/frontend/service/privileges.service.ts b/src/frontend/service/privileges.service.ts
index 1d22f0c5bee..803546dfd4c 100644
--- a/src/frontend/service/privileges.service.ts
+++ b/src/frontend/service/privileges.service.ts
@@ -401,6 +401,18 @@ export class PrivilegeService {
             "label": this.lang.printFolderDoc,
             "comment": this.lang.printFolderDoc,
             "unit": 'application'
+        },
+        {
+            "id": "manage_attachments",
+            "label": this.lang.manageAttachments,
+            "comment": this.lang.manageAttachments,
+            "unit": 'application'
+        },
+        {
+            "id": "manage_own_attachments_in_details",
+            "label": this.lang.manageOwnAttachmentsInDetails,
+            "comment": this.lang.manageOwnAttachmentsInDetails,
+            "unit": 'application'
         }
     ];
 
-- 
GitLab