[E129 < T0996] C-API: Implement using Fine Grained Access Checker in iterator over vertices ()

* implemented skipping vertices in Constructor and mgp_vertices_iterator_next

* Added utility function for moving iterator to next permitted vertex

* removed ifdef directive

* NextPermitted parameter type changed from mgp_vertices_iterator* to mgp_vertices_iterator&

* created support for lba-procedures e2e testing; Added test for vertex iterator skipping unauthorized vertices

* removed fixture from tests; converted generator to regular function;
This commit is contained in:
Boris Taševski 2022-08-12 19:34:47 +02:00 committed by GitHub
parent 116262d9a0
commit a98463b0bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 150 additions and 7 deletions

View File

@ -2250,6 +2250,39 @@ mgp_error mgp_graph_delete_edge(struct mgp_graph *graph, mgp_edge *edge) {
});
}
namespace {
void NextPermitted(mgp_vertices_iterator &it) {
const auto *checker = it.graph->ctx->fine_grained_access_checker;
if (!checker) {
return;
}
while (it.current_it != it.vertices.end()) {
auto labels = (*it.current_it).impl_.Labels(it.graph->view);
if (!labels.HasValue()) {
break;
}
if (checker->IsUserAuthorizedLabels(labels.GetValue(), it.graph->ctx->db_accessor)) {
break;
}
++it.current_it;
}
};
} // namespace
/// @throw anything VerticesIterable may throw
mgp_vertices_iterator::mgp_vertices_iterator(mgp_graph *graph, memgraph::utils::MemoryResource *memory)
: memory(memory), graph(graph), vertices(graph->impl->Vertices(graph->view)), current_it(vertices.begin()) {
NextPermitted(*this);
if (current_it != vertices.end()) {
current_v.emplace(*current_it, graph, memory);
}
}
void mgp_vertices_iterator_destroy(mgp_vertices_iterator *it) { DeleteRawMgpObject(it); }
mgp_error mgp_graph_iter_vertices(mgp_graph *graph, mgp_memory *memory, mgp_vertices_iterator **result) {
@ -2280,10 +2313,16 @@ mgp_error mgp_vertices_iterator_next(mgp_vertices_iterator *it, mgp_vertex **res
"should have been set to std::nullopt");
return nullptr;
}
if (++it->current_it == it->vertices.end()) {
++it->current_it;
NextPermitted(*it);
if (it->current_it == it->vertices.end()) {
it->current_v = std::nullopt;
return nullptr;
}
memgraph::utils::OnScopeExit clean_up([it] { it->current_v = std::nullopt; });
it->current_v.emplace(*it->current_it, it->graph, it->GetMemoryResource());
clean_up.Disable();

View File

@ -673,12 +673,7 @@ struct mgp_vertices_iterator {
using allocator_type = memgraph::utils::Allocator<mgp_vertices_iterator>;
/// @throw anything VerticesIterable may throw
mgp_vertices_iterator(mgp_graph *graph, memgraph::utils::MemoryResource *memory)
: memory(memory), graph(graph), vertices(graph->impl->Vertices(graph->view)), current_it(vertices.begin()) {
if (current_it != vertices.end()) {
current_v.emplace(*current_it, graph, memory);
}
}
mgp_vertices_iterator(mgp_graph *graph, memgraph::utils::MemoryResource *memory);
memgraph::utils::MemoryResource *GetMemoryResource() const { return memory; }

View File

@ -40,6 +40,7 @@ add_subdirectory(write_procedures)
add_subdirectory(magic_functions)
add_subdirectory(module_file_manager)
add_subdirectory(monitoring_server)
add_subdirectory(lba_procedures)
copy_e2e_python_files(pytest_runner pytest_runner.sh "")
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/memgraph-selfsigned.crt DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -0,0 +1,8 @@
function(copy_lba_procedures_e2e_python_files FILE_NAME)
copy_e2e_python_files(lba_procedures ${FILE_NAME})
endfunction()
copy_lba_procedures_e2e_python_files(common.py)
copy_lba_procedures_e2e_python_files(lba_procedures.py)
add_subdirectory(procedures)

View File

@ -0,0 +1,24 @@
# Copyright 2021 Memgraph Ltd.
#
# Use of this software is governed by the Business Source License
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
# License, and you may not use this file except in compliance with the Business Source License.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0, included in the file
# licenses/APL.txt.
import mgclient
import typing
def execute_and_fetch_all(cursor: mgclient.Cursor, query: str, params: dict = {}) -> typing.List[tuple]:
cursor.execute(query, params)
return cursor.fetchall()
def connect(**kwargs) -> mgclient.Connection:
connection = mgclient.connect(host="localhost", port=7687, **kwargs)
connection.autocommit = True
return connection

View File

@ -0,0 +1,30 @@
# Copyright 2022 Memgraph Ltd.
#
# Use of this software is governed by the Business Source License
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
# License, and you may not use this file except in compliance with the Business Source License.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0, included in the file
# licenses/APL.txt.
import sys
import pytest
from common import connect, execute_and_fetch_all
def test_lba_procedures_vertices_iterator_count_only_permitted_vertices():
cursor = connect(username="Josip", password="").cursor()
result = execute_and_fetch_all(cursor, "CALL read.number_of_visible_nodes() YIELD nr_of_nodes RETURN nr_of_nodes ;")
assert result[0][0] == 10
cursor = connect(username="Boris", password="").cursor()
result = execute_and_fetch_all(cursor, "CALL read.number_of_visible_nodes() YIELD nr_of_nodes RETURN nr_of_nodes ;")
assert result[0][0] == 6
if __name__ == "__main__":
sys.exit(pytest.main([__file__, "-rA"]))

View File

@ -0,0 +1 @@
copy_lba_procedures_e2e_python_files(read.py)

View File

@ -0,0 +1,17 @@
# Copyright 2021 Memgraph Ltd.
#
# Use of this software is governed by the Business Source License
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
# License, and you may not use this file except in compliance with the Business Source License.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0, included in the file
# licenses/APL.txt.
import mgp
@mgp.read_proc
def number_of_visible_nodes(ctx: mgp.ProcCtx) -> mgp.Record(nr_of_nodes=int):
return mgp.Record(nr_of_nodes=len(mgp.Vertices(ctx.graph._graph)))

View File

@ -0,0 +1,28 @@
template_cluster: &template_cluster
cluster:
main:
args: ["--bolt-port", "7687", "--log-level=TRACE"]
log_file: "lba-e2e.log"
setup_queries: [
"Create (:Label1 {id: 1}) ;",
"Create (:Label1 {id: 2}) ;",
"Create (:Label1 {id: 3}) ;",
"Create (:Label1 {id: 4}) ;",
"Create (:Label1 {id: 5}) ;",
"Create (:Label1 {id: 6}) ;",
"Create (:Label2 {id: 1}) ;",
"Create (:Label2 {id: 2}) ;",
"Create (:Label2 {id: 3}) ;",
"Create (:Label2 {id: 4}) ;",
"Create User Josip ;",
"Create User Boris ;",
"Grant Labels :Label1 to Boris;",
]
validation_queries: []
workloads:
- name: "Label-based auth"
binary: "tests/e2e/pytest_runner.sh"
proc: "tests/e2e/lba_procedures/procedures/"
args: ["lba_procedures/lba_procedures.py"]
<<: *template_cluster