From b211086dc3c881643e320fb645286a72228c0613 Mon Sep 17 00:00:00 2001
From: kobros-tech
Date: Tue, 25 Mar 2025 01:59:49 +0300
Subject: [PATCH 1/2] [FIX] dms: fix access rules for beter security
---
dms/README.rst | 3 +
dms/__manifest__.py | 6 +-
dms/controllers/portal.py | 15 +++-
dms/readme/USAGE.md | 2 +
dms/security/ir.model.access.csv | 3 -
dms/security/security.xml | 145 +++++++++++++-----------------
dms/static/description/index.html | 2 +
dms/tests/test_portal.py | 11 +++
dms/views/dms_directory.xml | 10 ++-
dms/views/dms_file.xml | 9 ++
10 files changed, 114 insertions(+), 92 deletions(-)
diff --git a/dms/README.rst b/dms/README.rst
index c9bc69d61..8a1a245c4 100644
--- a/dms/README.rst
+++ b/dms/README.rst
@@ -148,6 +148,9 @@ and their files. Another possibility is to click on "Share" button
inside a directory or a file for obtaining a tokenized link for single
access to that resource, no matter if logged or not.
+For any file if you add the portal user or the internal user to
+followers mixin, they can read that file.
+
Known issues / Roadmap
======================
diff --git a/dms/__manifest__.py b/dms/__manifest__.py
index 595254d23..13146bcdc 100644
--- a/dms/__manifest__.py
+++ b/dms/__manifest__.py
@@ -28,6 +28,9 @@
"template/portal.xml",
# Data
"data/onboarding_data.xml",
+ # Wizard
+ "wizards/wizard_dms_file_move_views.xml",
+ "wizards/wizard_dms_share_views.xml",
# Views
"views/dms_tag.xml",
"views/dms_category.xml",
@@ -37,9 +40,6 @@
"views/dms_access_groups_views.xml",
"views/res_config_settings.xml",
"views/menu.xml",
- # Wizard
- "wizards/wizard_dms_file_move_views.xml",
- "wizards/wizard_dms_share_views.xml",
],
"assets": {
"web.assets_backend": [
diff --git a/dms/controllers/portal.py b/dms/controllers/portal.py
index e1eaa7d64..dab3d88c7 100644
--- a/dms/controllers/portal.py
+++ b/dms/controllers/portal.py
@@ -177,6 +177,11 @@ def _get_files(self, access_token, dms_directory_id, search, search_in, sort_br)
file_domain = [
("is_hidden", "=", False),
("directory_id", "=", dms_directory_id),
+ (
+ "message_partner_ids",
+ "child_of",
+ [request.env.user.commercial_partner_id.id],
+ ),
]
# search
if search and search_in == "name":
@@ -206,7 +211,15 @@ def _get_directories(
:rtype: tuple[odoo.model.dms_directory, bool|odoo.model.dms_directory]
"""
# domain
- domain = [("is_hidden", "=", False), ("parent_id", "=", dms_directory_id)]
+ domain = [
+ ("is_hidden", "=", False),
+ ("parent_id", "=", dms_directory_id),
+ (
+ "file_ids.message_partner_ids",
+ "child_of",
+ [request.env.user.commercial_partner_id.id],
+ ),
+ ]
# search
if search and search_in:
domain.append(("name", "ilike", search))
diff --git a/dms/readme/USAGE.md b/dms/readme/USAGE.md
index 115fee86e..41480ab6d 100644
--- a/dms/readme/USAGE.md
+++ b/dms/readme/USAGE.md
@@ -9,3 +9,5 @@ group in directories, so they will see in the portal such directories
and their files. Another possibility is to click on "Share" button
inside a directory or a file for obtaining a tokenized link for single
access to that resource, no matter if logged or not.
+
+For any file if you add the portal user or the internal user to followers mixin, they can read that file.
diff --git a/dms/security/ir.model.access.csv b/dms/security/ir.model.access.csv
index f192f9808..f998a2025 100644
--- a/dms/security/ir.model.access.csv
+++ b/dms/security/ir.model.access.csv
@@ -8,17 +8,14 @@ access_dms_storage_portal,dms_storage_portal,model_dms_storage,base.group_portal
access_dms_storage_user,dms_storage_user,model_dms_storage,group_dms_user,1,0,0,0
access_dms_storage_manager,dms_storage_manager,model_dms_storage,group_dms_manager,1,1,1,1
-access_dms_directory_public,dms_directory_public,model_dms_directory,base.group_public,1,0,0,0
access_dms_directory_portal,dms_directory_portal,model_dms_directory,base.group_portal,1,0,0,0
access_dms_directory_base_user,dms_directory_base_user,model_dms_directory,base.group_user,1,0,0,0
access_dms_directory_user,dms_directory_user,model_dms_directory,group_dms_user,1,1,1,1
-access_dms_file_public,dms_file_public,model_dms_file,base.group_public,1,0,0,0
access_dms_file_portal,dms_file_portal,model_dms_file,base.group_portal,1,0,0,0
access_dms_file_base_user,dms_file_base_user,model_dms_file,base.group_user,1,0,0,0
access_dms_file_user,dms_file_user,model_dms_file,group_dms_user,1,1,1,1
-access_dms_access_group_public,access_dms_access_group_public,model_dms_access_group,base.group_public,1,0,0,0
access_dms_access_group_portal,access_dms_access_group_portal,model_dms_access_group,base.group_portal,1,0,0,0
access_security_access_groups_user,access_security_access_groups_user,model_dms_access_group,base.group_user,1,0,0,0
access_security_access_groups_dms_user,access_security_access_groups_dms_user,model_dms_access_group,group_dms_user,1,1,1,1
diff --git a/dms/security/security.xml b/dms/security/security.xml
index 463f914c3..7c0343c8c 100644
--- a/dms/security/security.xml
+++ b/dms/security/security.xml
@@ -15,7 +15,7 @@
User
-
+
Manager
@@ -29,7 +29,12 @@
DMS Storage multi-company
-
+
+
+
+
+
+
['|',('company_id','=',False),('company_id','in',company_ids)]
@@ -37,7 +42,12 @@
DMS Directory multi-company
-
+
+
+
+
+
+
['|',('company_id','=',False),('company_id','in',company_ids)]
@@ -45,7 +55,12 @@
File multi-company
-
+
+
+
+
+
+
['|',('company_id','=',False),('company_id','in',company_ids)]
@@ -53,16 +68,26 @@
Locked files are only modified by locker user.
-
+
-
+
['|', ('locked_by', '=', False), ('locked_by', '=', user.id)]
+
+ DMS Managers can edit and delete locked files.
+
+
+
+
+
+
+ [(1 ,'=', 1)]
+
DMS users can only edit and delete their own groups.
@@ -107,85 +132,37 @@
[('is_hidden', '=', True)]
-
-
- Apply computed create permissions.
-
-
-
-
-
-
- [('permission_create', '=', user.id)]
-
-
- Apply computed read permissions.
+
+
+ Portal Personal Directories Read
-
-
-
-
-
- [('permission_read', '=', user.id)]
-
-
- Apply computed unlink permissions.
-
-
-
-
-
-
- [('permission_unlink', '=', user.id)]
-
-
- Apply computed write permissions.
-
-
-
-
-
-
- [('permission_write', '=', user.id)]
-
-
- Apply computed create permissions.
-
-
-
-
-
-
- [('permission_create', '=', user.id)]
-
-
- Apply computed read permissions.
-
-
-
-
-
-
- [('permission_read', '=', user.id)]
-
-
- Apply computed unlink permissions.
-
-
-
-
-
-
- [('permission_unlink', '=', user.id)]
-
-
- Apply computed write permissions.
+ [('file_ids.message_partner_ids','child_of',[user.commercial_partner_id.id])]
+
+
+
+
+
+
+
+
+ Portal Personal Files Read
-
-
-
-
-
- [('permission_write', '=', user.id)]
+
+ [('message_partner_ids','child_of',[user.commercial_partner_id.id])]
+
+
+
+
+
diff --git a/dms/static/description/index.html b/dms/static/description/index.html
index 0a97bebff..3d97eecf1 100644
--- a/dms/static/description/index.html
+++ b/dms/static/description/index.html
@@ -510,6 +510,8 @@
and their files. Another possibility is to click on “Share” button
inside a directory or a file for obtaining a tokenized link for single
access to that resource, no matter if logged or not.
+For any file if you add the portal user or the internal user to
+followers mixin, they can read that file.
diff --git a/dms/tests/test_portal.py b/dms/tests/test_portal.py
index dbc321ae6..96a9f51de 100644
--- a/dms/tests/test_portal.py
+++ b/dms/tests/test_portal.py
@@ -44,6 +44,17 @@ def test_access_portal(self):
)
def test_tour(self):
+ file_id = self.env.ref("dms.file_11_demo")
+ follower = self.env["mail.followers"].create(
+ {
+ "res_model": "dms.file",
+ "res_id": file_id.id,
+ "partner_id": self.portal_user.partner_id.id,
+ "is_active": True,
+ }
+ )
+
+ file_id.message_follower_ids = follower
for tour in ("dms_portal_mail_tour", "dms_portal_partners_tour"):
with self.subTest(tour=tour):
self.start_tour("/my", tour, login="portal")
diff --git a/dms/views/dms_directory.xml b/dms/views/dms_directory.xml
index 5f9e6d212..c7f6fb80b 100644
--- a/dms/views/dms_directory.xml
+++ b/dms/views/dms_directory.xml
@@ -386,7 +386,15 @@
dms.directory