From 4c328684c5d01fccfdcda2e93937c4e35fc122f3 Mon Sep 17 00:00:00 2001 From: Maximilian Moser Date: Wed, 2 Nov 2022 13:19:52 +0100 Subject: [PATCH 1/2] permissions: disable write operations when read-only mode is on --- invenio_vocabularies/services/permissions.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/invenio_vocabularies/services/permissions.py b/invenio_vocabularies/services/permissions.py index 6a8c7d57..4cb500ed 100644 --- a/invenio_vocabularies/services/permissions.py +++ b/invenio_vocabularies/services/permissions.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # # Copyright (C) 2020-2021 CERN. +# Copyright (C) 2022 TU Wien. # # Invenio-Vocabularies is free software; you can redistribute it and/or # modify it under the terms of the MIT License; see LICENSE file for more @@ -9,7 +10,11 @@ """Vocabulary permissions.""" from invenio_records_permissions import RecordPermissionPolicy -from invenio_records_permissions.generators import AnyUser, SystemProcess +from invenio_records_permissions.generators import ( + AnyUser, + DisableIfReadOnly, + SystemProcess, +) class PermissionPolicy(RecordPermissionPolicy): @@ -17,7 +22,7 @@ class PermissionPolicy(RecordPermissionPolicy): can_search = [SystemProcess(), AnyUser()] can_read = [SystemProcess(), AnyUser()] - can_create = [SystemProcess()] - can_update = [SystemProcess()] - can_delete = [SystemProcess()] - can_manage = [SystemProcess()] + can_create = [SystemProcess(), DisableIfReadOnly()] + can_update = [SystemProcess(), DisableIfReadOnly()] + can_delete = [SystemProcess(), DisableIfReadOnly()] + can_manage = [SystemProcess(), DisableIfReadOnly()] From 83d308d2065f9726a255d3247f25dcb972982e4e Mon Sep 17 00:00:00 2001 From: Maximilian Moser Date: Tue, 15 Nov 2022 13:29:11 +0100 Subject: [PATCH 2/2] tests: add tests for read-only mode * the tests use the service rather than the resource because there are no write operations for vocabularies exposed in the REST API --- tests/services/test_service.py | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/services/test_service.py b/tests/services/test_service.py index 811a1d0f..1165204a 100644 --- a/tests/services/test_service.py +++ b/tests/services/test_service.py @@ -2,6 +2,7 @@ # # This file is part of Invenio. # Copyright (C) 2020-2021 CERN. +# Copyright (C) 2022 TU Wien. # # Invenio-Vocabularies is free software; you can redistribute it and/or # modify it under the terms of the MIT License; see LICENSE file for more @@ -13,6 +14,7 @@ import pytest from invenio_cache import current_cache from invenio_pidstore.errors import PIDAlreadyExists, PIDDeletedError +from invenio_records_resources.services.errors import PermissionDeniedError from marshmallow.exceptions import ValidationError from sqlalchemy.exc import IntegrityError @@ -181,3 +183,44 @@ def test_indexed_at_query(app, db, service, identity, lang_type, lang_data): type="languages", ) assert res.total == 1 + + +# +# Read-only mode +# + + +def test_create_ro(app, service, identity, lang_type, lang_data): + """Try to create a vocabulary in read-only mode.""" + app.config["RECORDS_PERMISSIONS_READ_ONLY"] = True + + pytest.raises(PermissionDeniedError, service.create, identity, lang_data) + + +def test_update_ro(app, service, identity, lang_type, lang_data): + """Try to update a vocabulary in read-only mode.""" + app.config["RECORDS_PERMISSIONS_READ_ONLY"] = False + item = service.create(identity, lang_data) + + app.config["RECORDS_PERMISSIONS_READ_ONLY"] = True + pytest.raises( + PermissionDeniedError, service.update, identity, ("languages", "eng"), lang_data + ) + + +def test_delete_ro(app, service, identity, lang_type, lang_data): + """Try to delete a vocabulary in read-only mode.""" + app.config["RECORDS_PERMISSIONS_READ_ONLY"] = False + item = service.create(identity, lang_data) + + app.config["RECORDS_PERMISSIONS_READ_ONLY"] = True + pytest.raises(PermissionDeniedError, service.delete, identity, ("languages", "eng")) + + +def test_create_type_ro(app, service, identity): + """Try to create a vocabulary type in read-only mode.""" + app.config["RECORDS_PERMISSIONS_READ_ONLY"] = True + + pytest.raises( + PermissionDeniedError, service.create_type, identity, "newtype", "new" + )