[E129-MG < T1040-MG] Add exceptions in LBA cursors (#536)
Exceptions added in update and create delete operators instead of logging
This commit is contained in:
parent
c09b175c76
commit
b2d5a8eeca
@ -243,8 +243,7 @@ bool CreateNode::CreateNodeCursor::Pull(Frame &frame, ExecutionContext &context)
|
||||
if (context.auth_checker &&
|
||||
!context.auth_checker->Accept(*context.db_accessor, self_.node_info_.labels,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
spdlog::info("Vertex will not be created due to not having enough permission!");
|
||||
return false;
|
||||
throw QueryRuntimeException("Vertex not created due to not having enough permission!");
|
||||
}
|
||||
|
||||
if (input_cursor_->Pull(frame, context)) {
|
||||
@ -338,8 +337,7 @@ bool CreateExpand::CreateExpandCursor::Pull(Frame &frame, ExecutionContext &cont
|
||||
!(context.auth_checker->Accept(*context.db_accessor, self_.edge_info_.edge_type,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE) &&
|
||||
context.auth_checker->Accept(*context.db_accessor, self_.node_info_.labels, fine_grained_permission))) {
|
||||
spdlog::info("Edge will not be created due to not having enough permission!");
|
||||
return false;
|
||||
throw QueryRuntimeException("Edge not created due to not having enough permission!");
|
||||
}
|
||||
// get the origin vertex
|
||||
TypedValue &vertex_value = frame[self_.input_symbol_];
|
||||
@ -2341,8 +2339,7 @@ bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
query::AuthQuery::FineGrainedPrivilege::UPDATE) &&
|
||||
context.auth_checker->Accept(*context.db_accessor, ea.From(), storage::View::NEW,
|
||||
query::AuthQuery::FineGrainedPrivilege::UPDATE))) {
|
||||
spdlog::info("Edge will not be deleted due to not having enough permission!");
|
||||
continue;
|
||||
throw QueryRuntimeException("Edge not deleted due to not having enough permission!");
|
||||
}
|
||||
auto maybe_value = dba.RemoveEdge(&ea);
|
||||
if (maybe_value.HasError()) {
|
||||
@ -2372,8 +2369,7 @@ bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) {
|
||||
if (context.auth_checker &&
|
||||
!context.auth_checker->Accept(*context.db_accessor, va, storage::View::NEW,
|
||||
query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) {
|
||||
spdlog::info("Vertex will not be deleted due to not having enough permission!");
|
||||
break;
|
||||
throw QueryRuntimeException("Vertex not deleted due to not having enough permission!");
|
||||
}
|
||||
if (self_.detach_) {
|
||||
auto res = dba.DetachRemoveVertex(&va);
|
||||
@ -2481,8 +2477,7 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, ExecutionContext &contex
|
||||
if (context.auth_checker &&
|
||||
!context.auth_checker->Accept(*context.db_accessor, lhs.ValueVertex(), storage::View::NEW,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
spdlog::info("Vertex property will not be set due to not having enough permission.");
|
||||
break;
|
||||
throw QueryRuntimeException("Vertex property not set due to not having enough permission!");
|
||||
}
|
||||
|
||||
auto old_value = PropsSetChecked(&lhs.ValueVertex(), self_.property_, rhs);
|
||||
@ -2498,8 +2493,7 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, ExecutionContext &contex
|
||||
if (context.auth_checker &&
|
||||
!context.auth_checker->Accept(*context.db_accessor, lhs.ValueEdge(),
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
spdlog::info("Edge property will not be set due to not having enough permission.");
|
||||
break;
|
||||
throw QueryRuntimeException("Edge property not set due to not having enough permission!");
|
||||
}
|
||||
|
||||
auto old_value = PropsSetChecked(&lhs.ValueEdge(), self_.property_, rhs);
|
||||
@ -2697,8 +2691,7 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, ExecutionContext &co
|
||||
if (context.auth_checker &&
|
||||
!context.auth_checker->Accept(*context.db_accessor, lhs.ValueVertex(), storage::View::NEW,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
spdlog::info("Vertex properties will not be set due to not having enough permission.");
|
||||
break;
|
||||
throw QueryRuntimeException("Vertex properties not set due to not having enough permission!");
|
||||
}
|
||||
|
||||
SetPropertiesOnRecord(&lhs.ValueVertex(), rhs, self_.op_, &context);
|
||||
@ -2707,8 +2700,7 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, ExecutionContext &co
|
||||
if (context.auth_checker &&
|
||||
!context.auth_checker->Accept(*context.db_accessor, lhs.ValueEdge(),
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
spdlog::info("Edge properties will not be set due to not having enough permission!");
|
||||
break;
|
||||
throw QueryRuntimeException("Edge properties not set due to not having enough permission!");
|
||||
}
|
||||
|
||||
SetPropertiesOnRecord(&lhs.ValueEdge(), rhs, self_.op_, &context);
|
||||
@ -2840,8 +2832,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, ExecutionContext &
|
||||
if (context.auth_checker &&
|
||||
!context.auth_checker->Accept(*context.db_accessor, lhs.ValueVertex(), storage::View::NEW,
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
spdlog::info("Vertex property will not be removed due to not having enough permission.");
|
||||
break;
|
||||
throw QueryRuntimeException("Vertex property not removed due to not having enough permission!");
|
||||
}
|
||||
|
||||
remove_prop(&lhs.ValueVertex());
|
||||
@ -2850,8 +2841,7 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, ExecutionContext &
|
||||
if (context.auth_checker &&
|
||||
!context.auth_checker->Accept(*context.db_accessor, lhs.ValueEdge(),
|
||||
memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) {
|
||||
spdlog::info("Edge property will not be removed due to not having enough permission.");
|
||||
break;
|
||||
throw QueryRuntimeException("Edge property not removed due to not having enough permission!");
|
||||
}
|
||||
|
||||
remove_prop(&lhs.ValueEdge());
|
||||
|
@ -9,9 +9,12 @@
|
||||
# by the Apache License, Version 2.0, included in the file
|
||||
# licenses/APL.txt.
|
||||
|
||||
import common
|
||||
import sys
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
from mgclient import DatabaseError
|
||||
|
||||
import common
|
||||
|
||||
|
||||
def test_create_node_all_labels_granted():
|
||||
@ -29,9 +32,9 @@ def test_create_node_all_labels_denied():
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS * TO user;")
|
||||
results = common.execute_and_fetch_all(user_connnection.cursor(), "CREATE (n:label1) RETURN n;")
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "CREATE (n:label1) RETURN n;")
|
||||
|
||||
|
||||
def test_create_node_specific_label_granted():
|
||||
@ -49,9 +52,9 @@ def test_create_node_specific_label_denied():
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS :label1 TO user;")
|
||||
results = common.execute_and_fetch_all(user_connnection.cursor(), "CREATE (n:label1) RETURN n;")
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "CREATE (n:label1) RETURN n;")
|
||||
|
||||
|
||||
def test_delete_node_all_labels_granted():
|
||||
@ -71,11 +74,9 @@ def test_delete_node_all_labels_denied():
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n:test_delete) DELETE n")
|
||||
|
||||
results = common.execute_and_fetch_all(admin_connection.cursor(), "MATCH (n:test_delete) RETURN n;")
|
||||
|
||||
assert len(results) == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n:test_delete) DELETE n")
|
||||
|
||||
|
||||
def test_delete_node_specific_label_granted():
|
||||
@ -95,11 +96,9 @@ def test_delete_node_specific_label_denied():
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS :test_delete TO user;")
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n:test_delete) DELETE n;")
|
||||
|
||||
results = common.execute_and_fetch_all(admin_connection.cursor(), "MATCH (n:test_delete) RETURN n;")
|
||||
|
||||
assert len(results) == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n:test_delete) DELETE n;")
|
||||
|
||||
|
||||
def test_create_edge_all_labels_all_edge_types_granted():
|
||||
@ -110,7 +109,8 @@ def test_create_edge_all_labels_all_edge_types_granted():
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
user_connnection.cursor(),
|
||||
"CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
assert len(results) == 1
|
||||
@ -122,11 +122,12 @@ def test_create_edge_all_labels_all_edge_types_denied():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_create_edge_all_labels_denied_all_edge_types_granted():
|
||||
@ -135,11 +136,12 @@ def test_create_edge_all_labels_denied_all_edge_types_granted():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_create_edge_all_labels_granted_all_edge_types_denied():
|
||||
@ -148,11 +150,12 @@ def test_create_edge_all_labels_granted_all_edge_types_denied():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_create_edge_all_labels_granted_specific_edge_types_denied():
|
||||
@ -160,12 +163,16 @@ def test_create_edge_all_labels_granted_specific_edge_types_denied():
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON EDGE_TYPES :edge_type TO user;")
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(),
|
||||
"DENY CREATE_DELETE ON EDGE_TYPES :edge_type TO user;",
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_create_edge_first_node_label_granted():
|
||||
@ -174,13 +181,16 @@ def test_create_edge_first_node_label_granted():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS :label1 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS :label2 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES :edge_type TO user;")
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(),
|
||||
"GRANT CREATE_DELETE ON EDGE_TYPES :edge_type TO user;",
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_create_edge_second_node_label_granted():
|
||||
@ -189,13 +199,16 @@ def test_create_edge_second_node_label_granted():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS :label2 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS :label1 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES :edge_type TO user;")
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(),
|
||||
"GRANT CREATE_DELETE ON EDGE_TYPES :edge_type TO user;",
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"CREATE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_delete_edge_all_labels_denied_all_edge_types_granted():
|
||||
@ -204,15 +217,12 @@ def test_delete_edge_all_labels_denied_all_edge_types_granted():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY UPDATE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r"
|
||||
)
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
admin_connection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r",
|
||||
)
|
||||
|
||||
|
||||
def test_delete_edge_all_labels_granted_all_edge_types_denied():
|
||||
@ -221,15 +231,12 @@ def test_delete_edge_all_labels_granted_all_edge_types_denied():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r"
|
||||
)
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
admin_connection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r",
|
||||
)
|
||||
|
||||
|
||||
def test_delete_edge_all_labels_granted_specific_edge_types_denied():
|
||||
@ -238,17 +245,15 @@ def test_delete_edge_all_labels_granted_specific_edge_types_denied():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(), "DENY CREATE_DELETE ON EDGE_TYPES :edge_type_delete TO user;"
|
||||
)
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r"
|
||||
admin_connection.cursor(),
|
||||
"DENY CREATE_DELETE ON EDGE_TYPES :edge_type_delete TO user;",
|
||||
)
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
admin_connection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r",
|
||||
)
|
||||
|
||||
|
||||
def test_delete_edge_first_node_label_granted():
|
||||
@ -258,17 +263,15 @@ def test_delete_edge_first_node_label_granted():
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT UPDATE ON LABELS :test_delete_1 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY UPDATE ON LABELS :test_delete_2 TO user;")
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES :edge_type_delete TO user;"
|
||||
)
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r"
|
||||
admin_connection.cursor(),
|
||||
"GRANT CREATE_DELETE ON EDGE_TYPES :edge_type_delete TO user;",
|
||||
)
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
admin_connection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r",
|
||||
)
|
||||
|
||||
|
||||
def test_delete_edge_second_node_label_granted():
|
||||
@ -278,36 +281,38 @@ def test_delete_edge_second_node_label_granted():
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT UPDATE ON LABELS :test_delete_2 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY UPDATE ON LABELS :test_delete_1 TO user;")
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES :edge_type_delete TO user;"
|
||||
)
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r"
|
||||
admin_connection.cursor(),
|
||||
"GRANT CREATE_DELETE ON EDGE_TYPES :edge_type_delete TO user;",
|
||||
)
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
admin_connection.cursor(), "MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MATCH (n:test_delete_1)-[r:edge_type_delete]->(m:test_delete_2) DELETE r",
|
||||
)
|
||||
|
||||
|
||||
def test_delete_node_with_edge_label_denied():
|
||||
admin_connection = common.connect(username="admin", password="test")
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS :test_delete_1 TO user;")
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n) DETACH DELETE n;")
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(),
|
||||
"DENY CREATE_DELETE ON LABELS :test_delete_1 TO user;",
|
||||
)
|
||||
|
||||
results = common.execute_and_fetch_all(admin_connection.cursor(), "MATCH (n:test_delete_1) RETURN n;")
|
||||
|
||||
assert len(results) == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n) DETACH DELETE n;")
|
||||
|
||||
|
||||
def test_delete_node_with_edge_label_granted():
|
||||
admin_connection = common.connect(username="admin", password="test")
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS :test_delete_1 TO user;")
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(),
|
||||
"GRANT CREATE_DELETE ON LABELS :test_delete_1 TO user;",
|
||||
)
|
||||
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n) DETACH DELETE n;")
|
||||
|
||||
@ -331,9 +336,9 @@ def test_merge_node_all_labels_denied():
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS * TO user;")
|
||||
results = common.execute_and_fetch_all(user_connnection.cursor(), "MERGE (n:label1) RETURN n;")
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "MERGE (n:label1) RETURN n;")
|
||||
|
||||
|
||||
def test_merge_node_specific_label_granted():
|
||||
@ -351,9 +356,9 @@ def test_merge_node_specific_label_denied():
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS :label1 TO user;")
|
||||
results = common.execute_and_fetch_all(user_connnection.cursor(), "MERGE (n:label1) RETURN n;")
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(user_connnection.cursor(), "MERGE (n:label1) RETURN n;")
|
||||
|
||||
|
||||
def test_merge_edge_all_labels_all_edge_types_granted():
|
||||
@ -363,7 +368,8 @@ def test_merge_edge_all_labels_all_edge_types_granted():
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
user_connnection.cursor(),
|
||||
"MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
assert len(results) == 1
|
||||
@ -375,11 +381,12 @@ def test_merge_edge_all_labels_all_edge_types_denied():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_merge_edge_all_labels_denied_all_edge_types_granted():
|
||||
@ -388,11 +395,12 @@ def test_merge_edge_all_labels_denied_all_edge_types_granted():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_merge_edge_all_labels_granted_all_edge_types_denied():
|
||||
@ -401,11 +409,12 @@ def test_merge_edge_all_labels_granted_all_edge_types_denied():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON EDGE_TYPES * TO user;")
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_merge_edge_all_labels_granted_specific_edge_types_denied():
|
||||
@ -413,12 +422,16 @@ def test_merge_edge_all_labels_granted_specific_edge_types_denied():
|
||||
user_connnection = common.connect(username="user", password="test")
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS * TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON EDGE_TYPES :edge_type TO user;")
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(),
|
||||
"DENY CREATE_DELETE ON EDGE_TYPES :edge_type TO user;",
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_merge_edge_first_node_label_granted():
|
||||
@ -427,13 +440,16 @@ def test_merge_edge_first_node_label_granted():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS :label1 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS :label2 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES :edge_type TO user;")
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(),
|
||||
"GRANT CREATE_DELETE ON EDGE_TYPES :edge_type TO user;",
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
def test_merge_edge_second_node_label_granted():
|
||||
@ -442,13 +458,16 @@ def test_merge_edge_second_node_label_granted():
|
||||
common.reset_and_prepare(admin_connection.cursor())
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON LABELS :label2 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "DENY CREATE_DELETE ON LABELS :label1 TO user;")
|
||||
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT CREATE_DELETE ON EDGE_TYPES :edge_type TO user;")
|
||||
|
||||
results = common.execute_and_fetch_all(
|
||||
user_connnection.cursor(), "MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;"
|
||||
common.execute_and_fetch_all(
|
||||
admin_connection.cursor(),
|
||||
"GRANT CREATE_DELETE ON EDGE_TYPES :edge_type TO user;",
|
||||
)
|
||||
|
||||
assert len(results) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
common.execute_and_fetch_all(
|
||||
user_connnection.cursor(),
|
||||
"MERGE (n:label1)-[r:edge_type]->(m:label2) RETURN n,r,m;",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -11,6 +11,9 @@
|
||||
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
from mgclient import DatabaseError
|
||||
|
||||
from common import connect, execute_and_fetch_all, reset_update_permissions
|
||||
|
||||
update_property_query = "MATCH (n:update_label) SET n.prop = 2 RETURN n.prop;"
|
||||
@ -52,28 +55,14 @@ def test_can_not_update_node_when_given_deny():
|
||||
|
||||
test_cursor = connect(username="user", password="test").cursor()
|
||||
|
||||
update_property_actual = execute_and_fetch_all(test_cursor, update_property_query)
|
||||
update_properties_actual = execute_and_fetch_all(test_cursor, update_properties_query)
|
||||
remove_property_actual = execute_and_fetch_all(test_cursor, remove_property_query)
|
||||
with pytest.raises(DatabaseError):
|
||||
execute_and_fetch_all(test_cursor, update_property_query)
|
||||
|
||||
assert update_property_actual[0][0] == 1
|
||||
assert update_properties_actual[0][0] == 1
|
||||
assert remove_property_actual[0][0] == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
execute_and_fetch_all(test_cursor, update_properties_query)
|
||||
|
||||
|
||||
def test_can_not_update_node_when_given_nothing():
|
||||
admin_cursor = connect(username="admin", password="test").cursor()
|
||||
reset_update_permissions(admin_cursor)
|
||||
|
||||
test_cursor = connect(username="user", password="test").cursor()
|
||||
|
||||
update_property_actual = execute_and_fetch_all(test_cursor, update_property_query)
|
||||
update_properties_actual = execute_and_fetch_all(test_cursor, update_properties_query)
|
||||
remove_property_actual = execute_and_fetch_all(test_cursor, remove_property_query)
|
||||
|
||||
assert len(update_property_actual) == 0
|
||||
assert len(update_properties_actual) == 0
|
||||
assert len(remove_property_actual) == 0
|
||||
with pytest.raises(DatabaseError):
|
||||
execute_and_fetch_all(test_cursor, remove_property_query)
|
||||
|
||||
|
||||
def test_can_not_update_node_when_given_read():
|
||||
@ -83,13 +72,14 @@ def test_can_not_update_node_when_given_read():
|
||||
|
||||
test_cursor = connect(username="user", password="test").cursor()
|
||||
|
||||
update_property_actual = execute_and_fetch_all(test_cursor, update_property_query)
|
||||
update_properties_actual = execute_and_fetch_all(test_cursor, update_properties_query)
|
||||
remove_property_actual = execute_and_fetch_all(test_cursor, remove_property_query)
|
||||
with pytest.raises(DatabaseError):
|
||||
execute_and_fetch_all(test_cursor, update_property_query)
|
||||
|
||||
assert update_property_actual[0][0] == 1
|
||||
assert update_properties_actual[0][0] == 1
|
||||
assert remove_property_actual[0][0] == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
execute_and_fetch_all(test_cursor, update_properties_query)
|
||||
|
||||
with pytest.raises(DatabaseError):
|
||||
execute_and_fetch_all(test_cursor, remove_property_query)
|
||||
|
||||
|
||||
def test_can_not_update_node_when_given_read_globally():
|
||||
@ -99,13 +89,14 @@ def test_can_not_update_node_when_given_read_globally():
|
||||
|
||||
test_cursor = connect(username="user", password="test").cursor()
|
||||
|
||||
update_property_actual = execute_and_fetch_all(test_cursor, update_property_query)
|
||||
update_properties_actual = execute_and_fetch_all(test_cursor, update_properties_query)
|
||||
remove_property_actual = execute_and_fetch_all(test_cursor, remove_property_query)
|
||||
with pytest.raises(DatabaseError):
|
||||
execute_and_fetch_all(test_cursor, update_property_query)
|
||||
|
||||
assert update_property_actual[0][0] == 1
|
||||
assert update_properties_actual[0][0] == 1
|
||||
assert remove_property_actual[0][0] == 1
|
||||
with pytest.raises(DatabaseError):
|
||||
execute_and_fetch_all(test_cursor, update_properties_query)
|
||||
|
||||
with pytest.raises(DatabaseError):
|
||||
execute_and_fetch_all(test_cursor, remove_property_query)
|
||||
|
||||
|
||||
def test_can_update_node_when_given_update_globally():
|
||||
|
@ -114,7 +114,7 @@ TEST(QueryPlan, FineGrainedCreateNodeWithAttributes) {
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("label1",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
EXPECT_EQ(test_create(user), 0);
|
||||
ASSERT_THROW(test_create(user), QueryRuntimeException);
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,8 +212,7 @@ TEST(QueryPlan, FineGrainedCreateReturn) {
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
|
||||
auto context = MakeContextWithFineGrainedChecker(storage, symbol_table, &dba, &auth_checker);
|
||||
auto results = CollectProduce(*produce, &context);
|
||||
EXPECT_EQ(0, results.size());
|
||||
ASSERT_THROW(CollectProduce(*produce, &context), QueryRuntimeException);
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,23 +293,20 @@ TEST(QueryPlan, CreateExpand) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(QueryPlan, FineGrainedCreateExpand) {
|
||||
auto test_create_path = [&](bool cycle, int expected_nodes_created, int expected_edges_created,
|
||||
memgraph::auth::User &user) {
|
||||
memgraph::storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
memgraph::query::DbAccessor dba(&storage_dba);
|
||||
class CreateExpandWithAuthFixture : public testing::Test {
|
||||
protected:
|
||||
memgraph::storage::Storage db;
|
||||
memgraph::storage::Storage::Accessor storage_dba{db.Access()};
|
||||
memgraph::query::DbAccessor dba{&storage_dba};
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
void ExecuteCreateExpand(bool cycle, memgraph::auth::User &user) {
|
||||
const auto label_node_1 = dba.NameToLabel("Node1");
|
||||
const auto label_node_2 = dba.NameToLabel("Node2");
|
||||
const auto property = PROPERTY_PAIR("property");
|
||||
const auto edge_type = dba.NameToEdgeType("edge_type");
|
||||
|
||||
SymbolTable symbol_table;
|
||||
AstStorage storage;
|
||||
int before_v = CountIterable(dba.Vertices(memgraph::storage::View::OLD));
|
||||
int before_e = CountEdges(&dba, memgraph::storage::View::OLD);
|
||||
|
||||
// data for the first node
|
||||
NodeCreationInfo n;
|
||||
n.symbol = symbol_table.CreateSymbol("n", true);
|
||||
@ -336,84 +332,100 @@ TEST(QueryPlan, FineGrainedCreateExpand) {
|
||||
auto context = MakeContextWithFineGrainedChecker(storage, symbol_table, &dba, &auth_checker);
|
||||
PullAll(*create_expand, &context);
|
||||
dba.AdvanceCommand();
|
||||
}
|
||||
|
||||
EXPECT_EQ(CountIterable(dba.Vertices(memgraph::storage::View::OLD)) - before_v, expected_nodes_created);
|
||||
EXPECT_EQ(CountEdges(&dba, memgraph::storage::View::OLD) - before_e, expected_edges_created);
|
||||
};
|
||||
void TestCreateExpandHypothesis(int expected_nodes_created, int expected_edges_created) {
|
||||
EXPECT_EQ(CountIterable(dba.Vertices(memgraph::storage::View::NEW)), expected_nodes_created);
|
||||
EXPECT_EQ(CountEdges(&dba, memgraph::storage::View::NEW), expected_edges_created);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CreateExpandWithAuthFixture, CreateExpandWithNoGrantsOnCreateDelete) {
|
||||
// All labels denied, All edge types denied
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
test_create_path(false, 0, 0, user);
|
||||
test_create_path(true, 0, 0, user);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
ASSERT_THROW(ExecuteCreateExpand(false, user), QueryRuntimeException);
|
||||
ASSERT_THROW(ExecuteCreateExpand(true, user), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(CreateExpandWithAuthFixture, CreateExpandWithLabelsGrantedOnly) {
|
||||
// All labels granted, All edge types denied
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
test_create_path(false, 1, 0, user);
|
||||
test_create_path(true, 1, 0, user);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
ASSERT_THROW(ExecuteCreateExpand(false, user), QueryRuntimeException);
|
||||
ASSERT_THROW(ExecuteCreateExpand(true, user), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(CreateExpandWithAuthFixture, CreateExpandWithEdgeTypesGrantedOnly) {
|
||||
// All labels denied, All edge types granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
test_create_path(false, 0, 0, user);
|
||||
test_create_path(true, 0, 0, user);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
ASSERT_THROW(ExecuteCreateExpand(false, user), QueryRuntimeException);
|
||||
ASSERT_THROW(ExecuteCreateExpand(true, user), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(CreateExpandWithAuthFixture, CreateExpandWithFirstLabelGranted) {
|
||||
// First label granted, All edge types granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("Node1",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("Node2",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("Node2", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("Node1",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("Node2",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("Node2", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_create_path(false, 1, 0, user);
|
||||
test_create_path(true, 1, 0, user);
|
||||
}
|
||||
ASSERT_THROW(ExecuteCreateExpand(false, user), QueryRuntimeException);
|
||||
ASSERT_THROW(ExecuteCreateExpand(true, user), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(CreateExpandWithAuthFixture, CreateExpandWithSecondLabelGranted) {
|
||||
// Second label granted, All edge types granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("Node2",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("Node1",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("Node2",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("Node1",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_create_path(false, 0, 0, user);
|
||||
test_create_path(true, 0, 0, user);
|
||||
}
|
||||
ASSERT_THROW(ExecuteCreateExpand(false, user), QueryRuntimeException);
|
||||
ASSERT_THROW(ExecuteCreateExpand(true, user), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(CreateExpandWithAuthFixture, CreateExpandWithoutCycleWithEverythingGranted) {
|
||||
// All labels granted, All edge types granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_create_path(false, 2, 1, user);
|
||||
test_create_path(true, 1, 1, user);
|
||||
}
|
||||
ExecuteCreateExpand(false, user);
|
||||
TestCreateExpandHypothesis(2, 1);
|
||||
}
|
||||
|
||||
TEST_F(CreateExpandWithAuthFixture, CreateExpandWithCycleWithEverythingGranted) {
|
||||
// All labels granted, All edge types granted
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
ExecuteCreateExpand(true, user);
|
||||
TestCreateExpandHypothesis(1, 1);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, MatchCreateNode) {
|
||||
@ -445,12 +457,15 @@ TEST(QueryPlan, MatchCreateNode) {
|
||||
EXPECT_EQ(CountIterable(dba.Vertices(memgraph::storage::View::OLD)), 6);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, FineGrainedMatchCreateNode) {
|
||||
auto test_match_create_node = [&](memgraph::auth::User &user, int expected_nodes) {
|
||||
memgraph::storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
memgraph::query::DbAccessor dba(&storage_dba);
|
||||
class MatchCreateNodeWithAuthFixture : public testing::Test {
|
||||
protected:
|
||||
memgraph::storage::Storage db;
|
||||
memgraph::storage::Storage::Accessor storage_dba{db.Access()};
|
||||
memgraph::query::DbAccessor dba{&storage_dba};
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
void InitGraph() {
|
||||
// add three nodes we'll match and expand-create from
|
||||
memgraph::query::VertexAccessor v1{dba.InsertVertex()};
|
||||
memgraph::query::VertexAccessor v2{dba.InsertVertex()};
|
||||
@ -459,10 +474,9 @@ TEST(QueryPlan, FineGrainedMatchCreateNode) {
|
||||
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
|
||||
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
|
||||
dba.AdvanceCommand();
|
||||
}
|
||||
|
||||
SymbolTable symbol_table;
|
||||
AstStorage storage;
|
||||
// first node
|
||||
void ExecuteMatchCreate(memgraph::auth::User &user) {
|
||||
auto n_scan_all = MakeScanAll(storage, symbol_table, "n");
|
||||
// second node
|
||||
NodeCreationInfo m{};
|
||||
@ -477,41 +491,50 @@ TEST(QueryPlan, FineGrainedMatchCreateNode) {
|
||||
|
||||
PullAll(*create_node, &context);
|
||||
dba.AdvanceCommand();
|
||||
}
|
||||
|
||||
EXPECT_EQ(CountIterable(dba.Vertices(memgraph::storage::View::OLD)), expected_nodes);
|
||||
};
|
||||
void MatchCreateAssertion(int expected_result_size) {
|
||||
EXPECT_EQ(CountIterable(dba.Vertices(memgraph::storage::View::OLD)), expected_result_size);
|
||||
}
|
||||
|
||||
void ExecuteMatchCreateTestSuite(memgraph::auth::User &user, int expected_result_size) {
|
||||
InitGraph();
|
||||
ExecuteMatchCreate(user);
|
||||
MatchCreateAssertion(expected_result_size);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(MatchCreateNodeWithAuthFixture, MatchCreateWithAllLabelsDeniedThrows) {
|
||||
// All labels denied
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_match_create_node(user, 3);
|
||||
}
|
||||
ASSERT_THROW(ExecuteMatchCreateTestSuite(user, 3), QueryRuntimeException);
|
||||
}
|
||||
|
||||
// All labels granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
TEST_F(MatchCreateNodeWithAuthFixture, MatchCreateWithAllLabelsGrantedExecutes) {
|
||||
// All labels granteddenieddenieddenied
|
||||
|
||||
test_match_create_node(user, 6);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
ExecuteMatchCreateTestSuite(user, 6);
|
||||
}
|
||||
|
||||
TEST_F(MatchCreateNodeWithAuthFixture, MatchCreateWithOneLabelDeniedThrows) {
|
||||
// Label2 denied
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l1",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l3",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l1",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l3",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
user.fine_grained_access_handler().label_permissions().Deny("l2",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("l2",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_match_create_node(user, 3);
|
||||
}
|
||||
ASSERT_THROW(ExecuteMatchCreateTestSuite(user, 3), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, MatchCreateExpand) {
|
||||
@ -562,13 +585,15 @@ TEST(QueryPlan, MatchCreateExpand) {
|
||||
test_create_path(true, 0, 6);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, FineGrainedMatchCreateExpand) {
|
||||
auto test_create_path = [&](bool cycle, int expected_nodes_created, int expected_edges_created,
|
||||
memgraph::auth::User &user) {
|
||||
memgraph::storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
memgraph::query::DbAccessor dba(&storage_dba);
|
||||
class MatchCreateExpandWithAuthFixture : public testing::Test {
|
||||
protected:
|
||||
memgraph::storage::Storage db;
|
||||
memgraph::storage::Storage::Accessor storage_dba{db.Access()};
|
||||
memgraph::query::DbAccessor dba{&storage_dba};
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
void InitGraph() {
|
||||
// add three nodes we'll match and expand-create from
|
||||
memgraph::query::VertexAccessor v1{dba.InsertVertex()};
|
||||
memgraph::query::VertexAccessor v2{dba.InsertVertex()};
|
||||
@ -576,16 +601,11 @@ TEST(QueryPlan, FineGrainedMatchCreateExpand) {
|
||||
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
|
||||
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
|
||||
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
|
||||
memgraph::storage::EdgeTypeId edge_type = dba.NameToEdgeType("edge_type");
|
||||
|
||||
dba.AdvanceCommand();
|
||||
}
|
||||
|
||||
SymbolTable symbol_table;
|
||||
AstStorage storage;
|
||||
|
||||
int before_v = CountIterable(dba.Vertices(memgraph::storage::View::OLD));
|
||||
int before_e = CountEdges(&dba, memgraph::storage::View::OLD);
|
||||
|
||||
void ExecuteMatchCreateExpand(memgraph::auth::User &user, bool cycle) {
|
||||
// data for the first node
|
||||
auto n_scan_all = MakeScanAll(storage, symbol_table, "n");
|
||||
|
||||
@ -598,87 +618,117 @@ TEST(QueryPlan, FineGrainedMatchCreateExpand) {
|
||||
EdgeCreationInfo r;
|
||||
r.symbol = symbol_table.CreateSymbol("r", true);
|
||||
r.direction = EdgeAtom::Direction::OUT;
|
||||
r.edge_type = edge_type;
|
||||
r.edge_type = dba.NameToEdgeType("edge_type");
|
||||
;
|
||||
|
||||
auto create_expand = std::make_shared<CreateExpand>(m, r, n_scan_all.op_, n_scan_all.sym_, cycle);
|
||||
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
|
||||
auto context = MakeContextWithFineGrainedChecker(storage, symbol_table, &dba, &auth_checker);
|
||||
PullAll(*create_expand, &context);
|
||||
dba.AdvanceCommand();
|
||||
}
|
||||
|
||||
EXPECT_EQ(CountIterable(dba.Vertices(memgraph::storage::View::OLD)) - before_v, expected_nodes_created);
|
||||
EXPECT_EQ(CountEdges(&dba, memgraph::storage::View::OLD) - before_e, expected_edges_created);
|
||||
};
|
||||
void MatchCreateExpandAssertion(int expected_nodes_size, int expected_edges_size) {
|
||||
EXPECT_EQ(CountIterable(dba.Vertices(memgraph::storage::View::NEW)), expected_nodes_size);
|
||||
EXPECT_EQ(CountEdges(&dba, memgraph::storage::View::NEW), expected_edges_size);
|
||||
}
|
||||
|
||||
void ExecuteMatchCreateExpandTestSuite(bool cycle, int expected_nodes_size, int expected_edges_size,
|
||||
memgraph::auth::User &user) {
|
||||
InitGraph();
|
||||
ExecuteMatchCreateExpand(user, cycle);
|
||||
MatchCreateExpandAssertion(expected_nodes_size, expected_edges_size);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(MatchCreateExpandWithAuthFixture, MatchCreateExpandThrowsWhenDeniedEverything) {
|
||||
// All labels denied, All edge types denied
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
test_create_path(false, 0, 0, user);
|
||||
test_create_path(true, 0, 0, user);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
ASSERT_THROW(ExecuteMatchCreateExpandTestSuite(false, 0, 0, user), QueryRuntimeException);
|
||||
ASSERT_THROW(ExecuteMatchCreateExpandTestSuite(true, 0, 0, user), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(MatchCreateExpandWithAuthFixture, MatchCreateExpandThrowsWhenDeniedEdgeTypes) {
|
||||
// All labels granted, All edge types denied
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
test_create_path(false, 0, 0, user);
|
||||
test_create_path(true, 0, 0, user);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
ASSERT_THROW(ExecuteMatchCreateExpandTestSuite(false, 0, 0, user), QueryRuntimeException);
|
||||
ASSERT_THROW(ExecuteMatchCreateExpandTestSuite(true, 0, 0, user), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(MatchCreateExpandWithAuthFixture, MatchCreateExpandThrowsWhenDeniedLabels) {
|
||||
// All labels denied, All edge types granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
test_create_path(false, 0, 0, user);
|
||||
test_create_path(true, 0, 0, user);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
ASSERT_THROW(ExecuteMatchCreateExpandTestSuite(false, 0, 0, user), QueryRuntimeException);
|
||||
ASSERT_THROW(ExecuteMatchCreateExpandTestSuite(true, 0, 0, user), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(MatchCreateExpandWithAuthFixture, MatchCreateExpandThrowsWhenDeniedOneLabel) {
|
||||
// First two label granted, All edge types granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l1", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l3", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("l2", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l1", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l3", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("l2", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_create_path(false, 0, 0, user);
|
||||
test_create_path(true, 0, 0, user);
|
||||
}
|
||||
ASSERT_THROW(ExecuteMatchCreateExpandTestSuite(false, 0, 0, user), QueryRuntimeException);
|
||||
ASSERT_THROW(ExecuteMatchCreateExpandTestSuite(true, 0, 0, user), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(MatchCreateExpandWithAuthFixture, MatchCreateExpandWithoutCycleExecutesWhenGrantedSpecificallyEverything) {
|
||||
// All label granted, Specific edge type granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"edge_type", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"edge_type", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_create_path(false, 3, 3, user);
|
||||
test_create_path(true, 0, 3, user);
|
||||
}
|
||||
ExecuteMatchCreateExpandTestSuite(false, 6, 3, user);
|
||||
}
|
||||
|
||||
TEST_F(MatchCreateExpandWithAuthFixture, MatchCreateExpandWithCycleExecutesWhenGrantedSpecificallyEverything) {
|
||||
// All label granted, Specific edge type granted
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"edge_type", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
ExecuteMatchCreateExpandTestSuite(true, 3, 3, user);
|
||||
}
|
||||
|
||||
TEST_F(MatchCreateExpandWithAuthFixture, MatchCreateExpandWithoutCycleExecutesWhenGrantedEverything) {
|
||||
// All labels granted, All edge types granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_create_path(false, 3, 3, user);
|
||||
test_create_path(true, 0, 3, user);
|
||||
}
|
||||
ExecuteMatchCreateExpandTestSuite(false, 6, 3, user);
|
||||
}
|
||||
|
||||
TEST_F(MatchCreateExpandWithAuthFixture, MatchCreateExpandWithCycleExecutesWhenGrantedEverything) {
|
||||
// All labels granted, All edge types granted
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
ExecuteMatchCreateExpandTestSuite(true, 3, 3, user);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, Delete) {
|
||||
@ -752,8 +802,15 @@ TEST(QueryPlan, Delete) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(QueryPlan, FineGrainedDelete) {
|
||||
auto init_graph = [](memgraph::query::DbAccessor &dba) {
|
||||
class DeleteOperatorWithAuthFixture : public testing::Test {
|
||||
protected:
|
||||
memgraph::storage::Storage db;
|
||||
memgraph::storage::Storage::Accessor storage_dba{db.Access()};
|
||||
memgraph::query::DbAccessor dba{&storage_dba};
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
void InitGraph() {
|
||||
std::vector<memgraph::query::VertexAccessor> vertices;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
memgraph::query::VertexAccessor v{dba.InsertVertex()};
|
||||
@ -768,20 +825,15 @@ TEST(QueryPlan, FineGrainedDelete) {
|
||||
}
|
||||
|
||||
dba.AdvanceCommand();
|
||||
|
||||
assertInitGraphValid();
|
||||
}
|
||||
|
||||
void TestDeleteNodesHypothesis(int expected_result_size) {
|
||||
EXPECT_EQ(expected_result_size, CountIterable(dba.Vertices(memgraph::storage::View::NEW)));
|
||||
};
|
||||
|
||||
auto test_delete_node = [&](memgraph::auth::User &user, int expected_nodes) {
|
||||
memgraph::storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
memgraph::query::DbAccessor dba(&storage_dba);
|
||||
|
||||
// make a fully-connected (one-direction, no cycles) with 4 nodes
|
||||
init_graph(dba);
|
||||
EXPECT_EQ(4, CountIterable(dba.Vertices(memgraph::storage::View::OLD)));
|
||||
EXPECT_EQ(6, CountEdges(&dba, memgraph::storage::View::OLD));
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
void DeleteAllNodes(memgraph::auth::User &user) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto n_get = storage.Create<Identifier>("n")->MapTo(n.sym_);
|
||||
Frame frame(symbol_table.max_position());
|
||||
@ -790,21 +842,20 @@ TEST(QueryPlan, FineGrainedDelete) {
|
||||
auto delete_op = std::make_shared<plan::Delete>(n.op_, std::vector<Expression *>{n_get}, true);
|
||||
PullAll(*delete_op, &context);
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(expected_nodes, CountIterable(dba.Vertices(memgraph::storage::View::NEW)));
|
||||
};
|
||||
|
||||
auto test_delete_edges = [&](memgraph::auth::User &user, int expected_edges) {
|
||||
memgraph::storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
memgraph::query::DbAccessor dba(&storage_dba);
|
||||
|
||||
void ExecuteDeleteNodesTestSuite(memgraph::auth::User &user, int expected_nodes) {
|
||||
// make a fully-connected (one-direction, no cycles) with 4 nodes
|
||||
init_graph(dba);
|
||||
EXPECT_EQ(4, CountIterable(dba.Vertices(memgraph::storage::View::OLD)));
|
||||
EXPECT_EQ(6, CountEdges(&dba, memgraph::storage::View::OLD));
|
||||
InitGraph();
|
||||
DeleteAllNodes(user);
|
||||
TestDeleteNodesHypothesis(expected_nodes);
|
||||
};
|
||||
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
void TestDeleteEdgesHypothesis(int expected_result_size) {
|
||||
EXPECT_EQ(expected_result_size, CountEdges(&dba, memgraph::storage::View::NEW));
|
||||
};
|
||||
|
||||
void DeleteAllEdges(memgraph::auth::User &user) {
|
||||
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||
auto r_m = MakeExpand(storage, symbol_table, n.op_, n.sym_, "r", EdgeAtom::Direction::OUT, {}, "m", false,
|
||||
memgraph::storage::View::NEW);
|
||||
@ -814,66 +865,89 @@ TEST(QueryPlan, FineGrainedDelete) {
|
||||
auto context = MakeContextWithFineGrainedChecker(storage, symbol_table, &dba, &auth_checker);
|
||||
PullAll(*delete_op, &context);
|
||||
dba.AdvanceCommand();
|
||||
EXPECT_EQ(expected_edges, CountEdges(&dba, memgraph::storage::View::NEW));
|
||||
};
|
||||
|
||||
void ExecuteDeleteEdgesTestSuite(memgraph::auth::User &user, int expected_edges) {
|
||||
// make a fully-connected (one-direction, no cycles) with 4 nodes
|
||||
InitGraph();
|
||||
DeleteAllEdges(user);
|
||||
TestDeleteEdgesHypothesis(expected_edges);
|
||||
};
|
||||
|
||||
private:
|
||||
void assertInitGraphValid() {
|
||||
EXPECT_EQ(4, CountIterable(dba.Vertices(memgraph::storage::View::OLD)));
|
||||
EXPECT_EQ(6, CountEdges(&dba, memgraph::storage::View::OLD));
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(DeleteOperatorWithAuthFixture, DeleteNodeThrowsExceptionWhenAllLabelsDenied) {
|
||||
// All labels denied
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_delete_node(user, 4);
|
||||
}
|
||||
ASSERT_THROW(ExecuteDeleteNodesTestSuite(user, 0), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(DeleteOperatorWithAuthFixture, DeleteNodeThrowsExceptionWhenPartialLabelsGranted) {
|
||||
// One Label granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l1",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
test_delete_node(user, 3);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l1",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*", memgraph::auth::FineGrainedPermission::READ);
|
||||
ASSERT_THROW(ExecuteDeleteNodesTestSuite(user, 0), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(DeleteOperatorWithAuthFixture, DeleteNodeExecutesWhenGrantedAllLabels) {
|
||||
// All labels granted
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
ExecuteDeleteNodesTestSuite(user, 0);
|
||||
}
|
||||
TEST_F(DeleteOperatorWithAuthFixture, DeleteNodeThrowsExceptionWhenEdgeTypesNotGranted) {
|
||||
// All labels granted,All edge types denied
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_delete_edges(user, 6);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
ASSERT_THROW(ExecuteDeleteNodesTestSuite(user, 0), QueryRuntimeException);
|
||||
}
|
||||
TEST_F(DeleteOperatorWithAuthFixture, DeleteEdgesThrowsErrorWhenPartialGrant) {
|
||||
// Specific label granted, Specific edge types granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l1", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l2", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("l3", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("l4", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"type0", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"type1", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny(
|
||||
"type2", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny(
|
||||
"type3", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_delete_edges(user, 5);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l1", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Grant("l2", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("l3", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().label_permissions().Deny("l4", memgraph::auth::FineGrainedPermission::UPDATE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"type0", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"type1", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny("type2",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Deny("type3",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
ASSERT_THROW(ExecuteDeleteEdgesTestSuite(user, 0), QueryRuntimeException);
|
||||
}
|
||||
|
||||
TEST_F(DeleteOperatorWithAuthFixture, DeleteNodeAndDeleteEdgePerformWhenGranted) {
|
||||
// All labels granted, All edge_types granted
|
||||
{
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
test_delete_node(user, 0);
|
||||
test_delete_edges(user, 0);
|
||||
}
|
||||
memgraph::auth::User user{"test"};
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*",
|
||||
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(
|
||||
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
|
||||
|
||||
InitGraph();
|
||||
DeleteAllNodes(user);
|
||||
TestDeleteNodesHypothesis(0);
|
||||
TestDeleteEdgesHypothesis(0);
|
||||
}
|
||||
|
||||
TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) {
|
||||
@ -1883,6 +1957,43 @@ TEST_F(UpdatePropertiesWithAuthFixture, SetPropertyWithAuthChecker) {
|
||||
test_remove_hypothesis(0);
|
||||
}
|
||||
|
||||
{
|
||||
auto user = memgraph::auth::User{"granted_read_label"};
|
||||
|
||||
user.fine_grained_access_handler().label_permissions().Grant(vertex_label_name,
|
||||
memgraph::auth::FineGrainedPermission::READ);
|
||||
|
||||
SetVertexProperty(v);
|
||||
ASSERT_THROW(ExecuteSetPropertyOnVertex(user, 2), QueryRuntimeException);
|
||||
test_hypothesis(1);
|
||||
|
||||
SetVertexProperty(v);
|
||||
ASSERT_THROW(ExecuteSetPropertiesOnVertex(user, 2), QueryRuntimeException);
|
||||
test_hypothesis(1);
|
||||
|
||||
SetVertexProperty(v);
|
||||
ASSERT_THROW(ExecuteRemovePropertyOnVertex(user), QueryRuntimeException);
|
||||
test_remove_hypothesis(1);
|
||||
}
|
||||
|
||||
{
|
||||
auto user = memgraph::auth::User{"granted_read_global"};
|
||||
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*", memgraph::auth::FineGrainedPermission::READ);
|
||||
|
||||
SetVertexProperty(v);
|
||||
ASSERT_THROW(ExecuteSetPropertyOnVertex(user, 2), QueryRuntimeException);
|
||||
test_hypothesis(1);
|
||||
|
||||
SetVertexProperty(v);
|
||||
ASSERT_THROW(ExecuteSetPropertiesOnVertex(user, 2), QueryRuntimeException);
|
||||
test_hypothesis(1);
|
||||
|
||||
SetVertexProperty(v);
|
||||
ASSERT_THROW(ExecuteRemovePropertyOnVertex(user), QueryRuntimeException);
|
||||
test_remove_hypothesis(1);
|
||||
}
|
||||
|
||||
{
|
||||
auto user = memgraph::auth::User{"granted_update_label_denied_read_global"};
|
||||
|
||||
@ -2115,6 +2226,45 @@ TEST_F(UpdatePropertiesWithAuthFixture, SetPropertyExpandWithAuthChecker) {
|
||||
test_remove_hypothesis(0);
|
||||
}
|
||||
|
||||
{
|
||||
auto user = memgraph::auth::User{"granted_read_edge_type"};
|
||||
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*", memgraph::auth::FineGrainedPermission::READ);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant(edge_type_name,
|
||||
memgraph::auth::FineGrainedPermission::READ);
|
||||
|
||||
SetEdgeProperty(edge.GetValue());
|
||||
ASSERT_THROW(ExecuteSetPropertyOnEdge(user, 2), QueryRuntimeException);
|
||||
test_hypothesis(1);
|
||||
|
||||
SetEdgeProperty(edge.GetValue());
|
||||
ASSERT_THROW(ExecuteSetPropertiesOnEdge(user, 2), QueryRuntimeException);
|
||||
test_hypothesis(1);
|
||||
|
||||
SetEdgeProperty(edge.GetValue());
|
||||
ASSERT_THROW(ExecuteRemovePropertyOnEdge(user), QueryRuntimeException);
|
||||
test_remove_hypothesis(1);
|
||||
}
|
||||
|
||||
{
|
||||
auto user = memgraph::auth::User{"granted_read_global"};
|
||||
|
||||
user.fine_grained_access_handler().label_permissions().Grant("*", memgraph::auth::FineGrainedPermission::READ);
|
||||
user.fine_grained_access_handler().edge_type_permissions().Grant("*", memgraph::auth::FineGrainedPermission::READ);
|
||||
|
||||
SetEdgeProperty(edge.GetValue());
|
||||
ASSERT_THROW(ExecuteSetPropertyOnEdge(user, 2), QueryRuntimeException);
|
||||
test_hypothesis(1);
|
||||
|
||||
SetEdgeProperty(edge.GetValue());
|
||||
ASSERT_THROW(ExecuteSetPropertiesOnEdge(user, 2), QueryRuntimeException);
|
||||
test_hypothesis(1);
|
||||
|
||||
SetEdgeProperty(edge.GetValue());
|
||||
ASSERT_THROW(ExecuteRemovePropertyOnEdge(user), QueryRuntimeException);
|
||||
test_remove_hypothesis(1);
|
||||
}
|
||||
|
||||
{
|
||||
auto user = memgraph::auth::User{"granted_update_global_denied_read_edge_type"};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user