diff --git a/tests/test_state.py b/tests/test_state.py index eee4b1dad6485ab9e2c238a0cc87398eab1dbafa..0b2c510d5c78609e9f9797336687446a7b20e2d6 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -1,3 +1,25 @@ +# encoding: utf-8 +# +# This file is a part of the CaosDB Project. +# +# Copyright (C) 2020-2022 IndiScale GmbH <info@indiscale.com> +# Copyright (C) 2020-2022 Timm Fitschen <t.fitschen@indiscale.com> +# +# This program is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along +# with this program. If not, see <https://www.gnu.org/licenses/>. +# +# ** end header +# import pytest import caosdb as db from caosdb import administration as admin @@ -111,6 +133,7 @@ def setup_module(): "ACL": None}) state_acl = db.ACL() state_acl.grant(role="role1", permission="UPDATE:DESCRIPTION") + state_acl.deny(role="anonymous", permission="RETRIEVE:ENTITY") state_acl = db.State.create_state_acl(state_acl) st1.acl = state_acl.combine(st1.acl) st1.update_acl() @@ -146,6 +169,8 @@ def setup_module(): def teardown_function(function): switch_to_admin_user() + # deactivate anonymous user + db.administration.set_server_property("AUTH_OPTIONAL", "FALSE") d = db.execute_query("FIND TestRT") if len(d) > 0: d.delete(flags={"forceFinalState": "true"}) @@ -480,10 +505,16 @@ def test_transfer_state_acl(): rec.state = db.State(model="Model1", name="State1") insert_rec = rec.insert(flags={"ACL": None}) - state_acl = db.ACL().combine(db.get_global_acl()) + state_acl = db.ACL() state_acl.grant(role="role1", permission="UPDATE:DESCRIPTION") + state_acl.deny(role="anonymous", permission="RETRIEVE:ENTITY") + state_acl = state_acl.combine(db.get_global_acl()) # the acl has been transfered from the state record + assert insert_rec.acl.get_permissions_for_role("role1") == { + "UPDATE:DESCRIPTION"} + assert "RETRIEVE:ENTITY" not in insert_rec.acl.get_permissions_for_role( + "anonymous") assert insert_rec.acl == state_acl @@ -806,3 +837,29 @@ def test_transitions_included_after_empty_update(): db.Transition(name="Transition4", from_state="State2", to_state="State2")} + + +def test_missing_retrieve_permission(): + """When the retrieve permission is missing, the state must not be leaked.""" + # @review Florian Spreckelsen 2022-03-22 + rec = db.Record() + rec.description = "old description" + rec.add_parent("TestRT") + rec.state = db.State(model="Model1", name="State1") + rec.insert(flags={"ACL": None}) + print(rec) + + # switch to anonymous + db.administration.set_server_property("AUTH_OPTIONAL", "TRUE") + db.configure_connection(password_method="unauthenticated") + assert db.Info().user_info.roles == ["anonymous"] + + rec2 = db.Record(id=rec.id) + with pytest.raises(db.TransactionError) as te: + rec2.retrieve() + assert te.value.has_error(db.AuthorizationError) + + rec2 = db.Record(id=rec.id) + rec2.retrieve(raise_exception_on_error=False) + assert len(rec2.get_errors()) > 0 + assert rec2.state is None