Skip to content
Snippets Groups Projects
Commit aaef8fda authored by Henrik tom Wörden's avatar Henrik tom Wörden
Browse files

Merge branch 'f-test-referenced-entity-permissions' into 'dev'

TST: Add xfailing tests for the permissions for referenced entities

See merge request !69
parents 70c1fc9c 4739abe2
No related branches found
No related tags found
1 merge request!69TST: Add xfailing tests for the permissions for referenced entities
Pipeline #44521 passed
...@@ -36,6 +36,7 @@ from nose.tools import (assert_equal, ...@@ -36,6 +36,7 @@ from nose.tools import (assert_equal,
assert_is_not_none) assert_is_not_none)
from pytest import raises, mark from pytest import raises, mark
test_user = "test_user" test_user = "test_user"
test_role = "test_role" test_role = "test_role"
test_pw = "passphrase1P!" test_pw = "passphrase1P!"
...@@ -1195,3 +1196,119 @@ def test_deny_update_role(): ...@@ -1195,3 +1196,119 @@ def test_deny_update_role():
p.name = "TestPropertyEvenNewer" p.name = "TestPropertyEvenNewer"
with raises(db.TransactionError) as te: with raises(db.TransactionError) as te:
p.update() p.update()
@mark.xfail(reason="Fix insufficient permission checks of referenced entity names.")
def test_query_with_invisible_reference():
"""
Names of references that are not visible to the test user should not be usable as query
filters.
"""
db.administration.set_server_property(
"QUERY_FILTER_ENTITIES_WITHOUT_RETRIEVE_PERMISSIONS", "TRUE")
rt = db.RecordType(name="TestRT").insert()
rec_invisible = db.Record(name="TestInvisible").add_parent(rt).insert()
rec_visible = db.Record(name="TestVisible").add_parent(
rt).add_property(name=rt.name, value=rec_invisible.id).insert()
# test user is only allowed to see rec_visible, not rec_invisble
grant_permission(rec_visible, "RETRIEVE:*")
deny_permission(rec_invisible, "RETRIEVE:*")
# as admin, I'm allowed to filter this
assert len(db.execute_query(f"FIND {rt.name} WITH {rt.name}={rec_invisible.name}")) == 1
switch_to_test_user()
# Retrival is forbidden
with raises(db.TransactionError) as te:
retrieved_invisible = db.Record(id=rec_invisible.id).retrieve()
assert te.value.has_error(db.AuthorizationError)
retrieved_visible = db.Record(id=rec_visible.id).retrieve()
assert retrieved_visible.name == rec_visible.name
assert retrieved_visible.get_property(rt.name) is not None
assert retrieved_visible.get_property(rt.name).value == rec_invisible.id
# We cant see rec_invisible, so its name can't be used as a valid query filter.
assert len(db.execute_query(
f"FIND {rt.name} WITH {rt.name} WITH name={rec_invisible.name}")) == 0
assert len(db.execute_query(f"FIND {rt.name} WITH {rt.name}={rec_invisible.name}")) == 0
assert len(db.execute_query(f"FIND {rt.name} WITH {rt.name} LIKE '*invis*'")) == 0
@mark.xfail(reason="Fix insufficient permission checks of referenced entity selectors.")
def test_select_query_with_invisible_reference():
"""SELECT queries must not leak property values of invisible referenced entities."""
visible_rt = db.RecordType(name="TestTypeVisible").insert()
invisible_rt = db.RecordType(name="TestTypeInvisible").insert()
other_rt = db.RecordType(name="TestTypeOther").insert()
prop = db.Property(name="TestProp", datatype=db.INTEGER).insert()
other_rec = db.Record(name="TestOther").add_parent(other_rt).insert()
referenced_visible = db.Record(name="TestReferencedVisible").add_parent(visible_rt).insert()
# invisible rec will have one int property, one reference to the (invisible)
# other rt and one to the visible rt.
invisible_rec = db.Record(name="TestInvisible").add_parent(invisible_rt)
invisible_rec.add_property(name=prop.name, value=42)
invisible_rec.add_property(name=other_rt.name, value=other_rec.id)
invisible_rec.add_property(name=visible_rt.name, value=referenced_visible.id)
invisible_rec.insert()
visible_rec = db.Record(name="TestVisible").add_parent(visible_rt.name)
visible_rec.add_property(name=invisible_rt.name, value=invisible_rec.id)
visible_rec.insert()
# Everything is there when queried as admin
select_query = (
f"SELECT name, {invisible_rt.name}, {invisible_rt.name}.name, "
f"{invisible_rt.name}.{prop.name}, {invisible_rt.name}.{other_rt.name}, "
f"{invisible_rt.name}.{other_rt.name}.name FROM {visible_rec.id}")
select_results = db.execute_query(select_query)
value_args = ["name", f"{invisible_rt.name}", (invisible_rt.name, "name"),
(invisible_rt.name, prop.name), (invisible_rt.name, other_rt.name),
(invisible_rt.name, other_rt.name, "name")]
values = select_results.get_property_values(*value_args)[0]
assert values[0] == visible_rec.name
assert values[1] == invisible_rec.id
assert values[2] == invisible_rec.name
assert values[3] == invisible_rec.get_property(prop.name).value
assert values[4] == other_rec.id
assert values[5] == other_rec.name
for rec in [referenced_visible, visible_rec]:
grant_permission(rec, "RETRIEVE:*")
for rec in [invisible_rec, other_rec]:
deny_permission(rec, "RETRIEVE:*")
switch_to_test_user()
select_results = db.execute_query(select_query)
values = select_results.get_property_values(*value_args)[0]
assert values[0] == visible_rec.name
assert values[1] == invisible_rec.id # id is ok
assert values[2] is None # name isn't
assert values[3] is None # prop isn't either
assert values[4] is None # neither id ...
assert values[5] is None # ... nor name of other rec referenced by invisible
# Special case of visible referencing invisible referencing visible
switch_to_admin_user()
select_query = (
f"SELECT {invisible_rt.name}.{visible_rt.name}, "
f"{invisible_rt.name}.{visible_rt.name}.name FROM {visible_rec.id}")
value_args = [(invisible_rt.name, visible_rt.name),
(invisible_rt.name, visible_rt.name, "name")]
select_results = db.execute_query(select_query)
values = select_results.get_property_values(*value_args)[0]
assert values[0] == referenced_visible.id
assert values[1] == referenced_visible.name
switch_to_test_user()
select_results = db.execute_query(select_query)
values = select_results.get_property_values(*value_args)[0]
assert values[0] is None
assert values[1] is None
...@@ -1101,6 +1101,8 @@ def test_query_cache(): ...@@ -1101,6 +1101,8 @@ def test_query_cache():
def test_query_cache_with_permissions(): def test_query_cache_with_permissions():
db.administration.set_server_property(
"QUERY_FILTER_ENTITIES_WITHOUT_RETRIEVE_PERMISSIONS", "TRUE")
db.RecordType("TestRT").insert() db.RecordType("TestRT").insert()
db.RecordType("TestRT2").insert() db.RecordType("TestRT2").insert()
public_record = db.Record().add_parent("TestRT").insert() public_record = db.Record().add_parent("TestRT").insert()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment