From b65d39d3be1e248d28d901843c2a8ac73058b44b Mon Sep 17 00:00:00 2001 From: Pierre Narcisi Date: Wed, 27 Sep 2023 14:46:05 +0200 Subject: [PATCH] fix(permissions) fix for import case --- backend/geonature/core/gn_meta/models.py | 10 ++++++---- backend/geonature/core/gn_meta/routes.py | 9 +++++++-- backend/geonature/tests/test_gn_meta.py | 25 ++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/backend/geonature/core/gn_meta/models.py b/backend/geonature/core/gn_meta/models.py index ad9b11efb6..5b2c8f646e 100644 --- a/backend/geonature/core/gn_meta/models.py +++ b/backend/geonature/core/gn_meta/models.py @@ -253,10 +253,12 @@ def _get_read_scope(self, user=None): cruved = get_scopes_by_action(id_role=user.id_role, module_code="METADATA") return cruved["R"] - def _get_create_scope(self, module_code, user=None): + def _get_create_scope(self, module_code, user=None, object_code=None): if user is None: user = g.current_user - cruved = get_scopes_by_action(id_role=user.id_role, module_code=module_code) + cruved = get_scopes_by_action( + id_role=user.id_role, module_code=module_code, object_code=object_code + ) return cruved["C"] def filter_by_scope(self, scope, user=None): @@ -366,14 +368,14 @@ def filter_by_readable(self, user=None): """ return self.filter_by_scope(self._get_read_scope(user)) - def filter_by_creatable(self, module_code, user=None): + def filter_by_creatable(self, module_code, user=None, object_code=None): """ Return all dataset where user have read rights minus those who user to not have create rigth """ query = self.filter(TDatasets.modules.any(module_code=module_code)) scope = self._get_read_scope(user) - create_scope = self._get_create_scope(module_code, user=user) + create_scope = self._get_create_scope(module_code, user=user, object_code=object_code) if create_scope < scope: scope = create_scope return query.filter_by_scope(scope) diff --git a/backend/geonature/core/gn_meta/routes.py b/backend/geonature/core/gn_meta/routes.py index 51d7dd250c..91ad14f03d 100644 --- a/backend/geonature/core/gn_meta/routes.py +++ b/backend/geonature/core/gn_meta/routes.py @@ -65,6 +65,7 @@ from werkzeug.datastructures import Headers from geonature.core.gn_permissions import decorators as permissions from geonature.core.gn_permissions.tools import get_scopes_by_action +from geonature.core.gn_permissions.models import TObjects from geonature.core.gn_meta.mtd import mtd_utils import geonature.utils.filemanager as fm import geonature.utils.utilsmails as mail @@ -104,12 +105,16 @@ def get_datasets(): """ params = MultiDict(request.args) if request.is_json: - params.update(MultiDict(request.json)) + params.update(request.json) fields = params.get("fields", type=str, default=[]) if fields: fields = fields.split(",") if "create" in params: - query = TDatasets.query.filter_by_creatable(params.pop("create")) + create = params.pop("create").split(".") + if len(create) > 1: + query = TDatasets.query.filter_by_creatable(create[0], object_code=create[1]) + else: + query = TDatasets.query.filter_by_creatable(create[0]) else: query = TDatasets.query.filter_by_readable() diff --git a/backend/geonature/tests/test_gn_meta.py b/backend/geonature/tests/test_gn_meta.py index a8fca40ad6..02c9a5a524 100644 --- a/backend/geonature/tests/test_gn_meta.py +++ b/backend/geonature/tests/test_gn_meta.py @@ -679,6 +679,31 @@ def test_get_dataset_filter_module_code(self, users, datasets, module): assert expected_ds.issubset(filtered_ds) assert datasets["own_dataset"].id_dataset not in filtered_ds + def test_get_dataset_filter_create(self, users, datasets, module): + set_logged_user_cookie(self.client, users["admin_user"]) + + response = self.client.get( + url_for("gn_meta.get_datasets"), + json={ + "module_code": module.module_code, + "create": module.module_code + ".ALL" + }, + ) + + response_with_object = self.client.get( + url_for("gn_meta.get_datasets"), + json={ + "module_code": module.module_code, + "create": module.module_code + ".ALL" + }, + ) + + expected_ds = {datasets["with_module_1"].id_dataset} + filtered_ds = {ds["id_dataset"] for ds in response.json} + assert response.json == response_with_object.json + assert expected_ds.issubset(filtered_ds) + assert datasets["own_dataset"].id_dataset not in filtered_ds + def test_get_dataset_search(self, users, datasets, module): set_logged_user_cookie(self.client, users["admin_user"]) ds = datasets["with_module_1"]