From 208898a202a6aac6727511af50673284c1893193 Mon Sep 17 00:00:00 2001 From: Zacharias Zacharodimos Date: Mon, 16 Dec 2024 15:11:43 +0100 Subject: [PATCH] pids: add manage permission to be able to skip doi transitions checks --- .../services/components/pids.py | 8 +++- invenio_rdm_records/services/permissions.py | 1 + tests/services/test_rdm_service.py | 40 +++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/invenio_rdm_records/services/components/pids.py b/invenio_rdm_records/services/components/pids.py index 20d50fed7..cb0401d05 100644 --- a/invenio_rdm_records/services/components/pids.py +++ b/invenio_rdm_records/services/components/pids.py @@ -107,7 +107,9 @@ def update_draft(self, identity, data=None, record=None, errors=None): # if DOI is not required in an instance check validate allowed providers # for each record version - if "doi" not in required_schemes: + if "doi" not in required_schemes and not self.service.check_permission( + identity, "pid_manage" + ): previous_published = self.service.record_cls.get_latest_published_by_parent( record.parent ) @@ -149,7 +151,9 @@ def publish(self, identity, draft=None, record=None): # if DOI is not required in an instance check validate allowed providers # for each record version - if "doi" not in required_schemes: + if "doi" not in required_schemes and not self.service.check_permission( + identity, "pid_manage" + ): # if a doi was ever minted for the parent record then we always require one # for any version of the record that will be published if draft.parent.get("pids", {}).get("doi"): diff --git a/invenio_rdm_records/services/permissions.py b/invenio_rdm_records/services/permissions.py index 8d6f06477..6c89de5e2 100644 --- a/invenio_rdm_records/services/permissions.py +++ b/invenio_rdm_records/services/permissions.py @@ -188,6 +188,7 @@ class RDMRecordPermissionPolicy(RecordPermissionPolicy): can_pid_update = can_review can_pid_discard = can_review can_pid_delete = can_review + can_pid_manage = [SystemProcess()] # # Actions diff --git a/tests/services/test_rdm_service.py b/tests/services/test_rdm_service.py index daf7aedb2..48351bc0d 100644 --- a/tests/services/test_rdm_service.py +++ b/tests/services/test_rdm_service.py @@ -14,6 +14,8 @@ import pytest +from invenio_access.permissions import system_identity + from invenio_rdm_records.proxies import current_rdm_records from invenio_rdm_records.services.errors import ( EmbargoNotLiftedError, @@ -172,6 +174,44 @@ def test_publish_public_record_versions_managed_doi_no_doi( running_app.app.config["RDM_PERSISTENT_IDENTIFIERS"]["doi"]["required"] = True +def test_edit_published_record_change_doi_when_optional( + running_app, search_clear, minimal_record, verified_user +): + running_app.app.config["RDM_PERSISTENT_IDENTIFIERS"]["doi"]["required"] = False + verified_user_identity = verified_user.identity + service = current_rdm_records.records_service + # Publish without DOI + draft = service.create(verified_user_identity, minimal_record) + record = service.publish(id_=draft.id, identity=verified_user_identity) + assert "doi" not in record._record.pids + assert "doi" not in record._record.parent.pids + + # create a new version with no DOI + draft = service.new_version(verified_user_identity, record.id) + draft_data = deepcopy(draft.data) + draft_data["metadata"]["publication_date"] = "2023-01-01" + + draft = service.update_draft(verified_user_identity, draft.id, data=draft_data) + record = service.publish(id_=draft.id, identity=verified_user_identity) + assert "doi" not in record._record.pids + assert "doi" not in record._record.parent.pids + + # edit the new published version and change the DOI to locally managed with + # system user + draft = service.edit(system_identity, record.id) + draft = service.pids.create(system_identity, draft.id, "doi") + draft_data = deepcopy(draft.data) + draft_data["metadata"]["publication_date"] = "2023-01-01" + draft = service.update_draft(system_identity, draft.id, data=draft_data) + + record = service.publish(id_=draft.id, identity=system_identity) + assert "doi" in record._record.pids + assert "doi" in record._record.parent.pids + + # Reset the running_app config for next tests + running_app.app.config["RDM_PERSISTENT_IDENTIFIERS"]["doi"]["required"] = True + + def test_publish_public_record_with_default_doi( running_app, search_clear, minimal_record, uploader ):