Compare commits
1 Commits
remove-gra
...
release/0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ad84e8629 |
@@ -1,9 +1,7 @@
|
|||||||
- name: Binaries
|
- name: Binaries
|
||||||
archive:
|
archive:
|
||||||
- build_debug/memgraph
|
- build_debug/memgraph
|
||||||
- build_debug/memgraph_ha
|
|
||||||
- build_release/memgraph
|
- build_release/memgraph
|
||||||
- build_release/memgraph_ha
|
|
||||||
- build_release/tools/src/mg_client
|
- build_release/tools/src/mg_client
|
||||||
- build_release/tools/src/mg_import_csv
|
- build_release/tools/src/mg_import_csv
|
||||||
- config
|
- config
|
||||||
|
|||||||
@@ -204,21 +204,3 @@ import_external_library(rocksdb STATIC
|
|||||||
-DCMAKE_INSTALL_LIBDIR=lib
|
-DCMAKE_INSTALL_LIBDIR=lib
|
||||||
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
|
||||||
BUILD_COMMAND $(MAKE) rocksdb)
|
BUILD_COMMAND $(MAKE) rocksdb)
|
||||||
|
|
||||||
# Setup libbcrypt
|
|
||||||
import_external_library(libbcrypt STATIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/bcrypt.a
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt
|
|
||||||
CONFIGURE_COMMAND sed s/-Wcast-align// -i ${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt/crypt_blowfish/Makefile
|
|
||||||
BUILD_COMMAND make -C ${CMAKE_CURRENT_SOURCE_DIR}/libbcrypt
|
|
||||||
CC=${CMAKE_C_COMPILER}
|
|
||||||
CXX=${CMAKE_CXX_COMPILER}
|
|
||||||
INSTALL_COMMAND true)
|
|
||||||
|
|
||||||
# Setup mgclient
|
|
||||||
import_external_library(mgclient STATIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mgclient/lib/libmgclient.a
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/mgclient/include
|
|
||||||
CMAKE_ARGS -DBUILD_TESTING=OFF)
|
|
||||||
find_package(OpenSSL REQUIRED)
|
|
||||||
target_link_libraries(mgclient INTERFACE ${OPENSSL_LIBRARIES})
|
|
||||||
|
|||||||
@@ -135,8 +135,3 @@ clone git://deps.memgraph.io/rocksdb.git rocksdb $rocksdb_tag
|
|||||||
sed -i 's/-Wshadow/-Wno-defaulted-function-deleted/' rocksdb/CMakeLists.txt
|
sed -i 's/-Wshadow/-Wno-defaulted-function-deleted/' rocksdb/CMakeLists.txt
|
||||||
# remove shared library from install dependencies
|
# remove shared library from install dependencies
|
||||||
sed -i 's/TARGETS ${ROCKSDB_SHARED_LIB}/TARGETS ${ROCKSDB_SHARED_LIB} OPTIONAL/' rocksdb/CMakeLists.txt
|
sed -i 's/TARGETS ${ROCKSDB_SHARED_LIB}/TARGETS ${ROCKSDB_SHARED_LIB} OPTIONAL/' rocksdb/CMakeLists.txt
|
||||||
|
|
||||||
# mgclient
|
|
||||||
mgclient_tag="fe94b3631385ef5dbe40a3d8458860dbcc33e6ea" # May 27, 2019
|
|
||||||
# git clone https://github.com/memgraph/mgclient.git
|
|
||||||
clone git://deps.memgraph.io/mgclient.git mgclient $mgclient_tag
|
|
||||||
|
|||||||
@@ -26,6 +26,3 @@ install(PROGRAMS $<TARGET_FILE:example>
|
|||||||
RENAME example.so)
|
RENAME example.so)
|
||||||
# Also install the source of the example, so user can read it.
|
# Also install the source of the example, so user can read it.
|
||||||
install(FILES example.c DESTINATION lib/memgraph/query_modules)
|
install(FILES example.c DESTINATION lib/memgraph/query_modules)
|
||||||
|
|
||||||
add_subdirectory(louvain)
|
|
||||||
add_subdirectory(connectivity)
|
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
/etc/memgraph/memgraph.conf
|
/etc/memgraph/memgraph.conf
|
||||||
/etc/logrotate.d/memgraph
|
/etc/logrotate.d/memgraph
|
||||||
/etc/logrotate.d/memgraph_audit
|
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ add_subdirectory(requests)
|
|||||||
add_subdirectory(io)
|
add_subdirectory(io)
|
||||||
add_subdirectory(telemetry)
|
add_subdirectory(telemetry)
|
||||||
add_subdirectory(communication)
|
add_subdirectory(communication)
|
||||||
add_subdirectory(auth)
|
|
||||||
add_subdirectory(slk)
|
|
||||||
add_subdirectory(storage/v2)
|
add_subdirectory(storage/v2)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
@@ -32,7 +30,6 @@ add_custom_target(generate_lcp_common DEPENDS ${generated_lcp_common_files})
|
|||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
set(mg_single_node_sources
|
set(mg_single_node_sources
|
||||||
${lcp_common_cpp_files}
|
${lcp_common_cpp_files}
|
||||||
audit/log.cpp
|
|
||||||
data_structures/concurrent/skiplist_gc.cpp
|
data_structures/concurrent/skiplist_gc.cpp
|
||||||
database/single_node/config.cpp
|
database/single_node/config.cpp
|
||||||
database/single_node/graph_db.cpp
|
database/single_node/graph_db.cpp
|
||||||
@@ -42,14 +39,12 @@ set(mg_single_node_sources
|
|||||||
durability/single_node/recovery.cpp
|
durability/single_node/recovery.cpp
|
||||||
durability/single_node/snapshooter.cpp
|
durability/single_node/snapshooter.cpp
|
||||||
durability/single_node/wal.cpp
|
durability/single_node/wal.cpp
|
||||||
glue/auth.cpp
|
|
||||||
glue/communication.cpp
|
glue/communication.cpp
|
||||||
query/common.cpp
|
query/common.cpp
|
||||||
query/dump.cpp
|
query/dump.cpp
|
||||||
query/frontend/ast/cypher_main_visitor.cpp
|
query/frontend/ast/cypher_main_visitor.cpp
|
||||||
query/frontend/ast/pretty_print.cpp
|
query/frontend/ast/pretty_print.cpp
|
||||||
query/frontend/parsing.cpp
|
query/frontend/parsing.cpp
|
||||||
query/frontend/semantic/required_privileges.cpp
|
|
||||||
query/frontend/semantic/symbol_generator.cpp
|
query/frontend/semantic/symbol_generator.cpp
|
||||||
query/frontend/stripped.cpp
|
query/frontend/stripped.cpp
|
||||||
query/interpret/awesome_memgraph_functions.cpp
|
query/interpret/awesome_memgraph_functions.cpp
|
||||||
@@ -84,8 +79,6 @@ add_custom_target(generate_lcp_single_node DEPENDS generate_lcp_common ${generat
|
|||||||
set(MG_SINGLE_NODE_LIBS stdc++fs Threads::Threads fmt cppitertools
|
set(MG_SINGLE_NODE_LIBS stdc++fs Threads::Threads fmt cppitertools
|
||||||
antlr_opencypher_parser_lib dl glog gflags
|
antlr_opencypher_parser_lib dl glog gflags
|
||||||
mg-utils mg-io mg-requests mg-communication)
|
mg-utils mg-io mg-requests mg-communication)
|
||||||
# These are enterprise subsystems
|
|
||||||
set(MG_SINGLE_NODE_LIBS ${MG_SINGLE_NODE_LIBS} mg-auth)
|
|
||||||
|
|
||||||
if (USE_LTALLOC)
|
if (USE_LTALLOC)
|
||||||
list(APPEND MG_SINGLE_NODE_LIBS ltalloc)
|
list(APPEND MG_SINGLE_NODE_LIBS ltalloc)
|
||||||
@@ -113,15 +106,12 @@ target_link_libraries(mg-single-node "-Wl,--dynamic-list=${CMAKE_SOURCE_DIR}/inc
|
|||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
set(mg_single_node_v2_sources
|
set(mg_single_node_v2_sources
|
||||||
${lcp_common_cpp_files}
|
${lcp_common_cpp_files}
|
||||||
audit/log.cpp
|
|
||||||
glue/auth.cpp
|
|
||||||
glue/communication.cpp
|
glue/communication.cpp
|
||||||
query/common.cpp
|
query/common.cpp
|
||||||
query/dump.cpp
|
query/dump.cpp
|
||||||
query/frontend/ast/cypher_main_visitor.cpp
|
query/frontend/ast/cypher_main_visitor.cpp
|
||||||
query/frontend/ast/pretty_print.cpp
|
query/frontend/ast/pretty_print.cpp
|
||||||
query/frontend/parsing.cpp
|
query/frontend/parsing.cpp
|
||||||
query/frontend/semantic/required_privileges.cpp
|
|
||||||
query/frontend/semantic/symbol_generator.cpp
|
query/frontend/semantic/symbol_generator.cpp
|
||||||
query/frontend/stripped.cpp
|
query/frontend/stripped.cpp
|
||||||
query/interpret/awesome_memgraph_functions.cpp
|
query/interpret/awesome_memgraph_functions.cpp
|
||||||
@@ -142,8 +132,6 @@ set(mg_single_node_v2_sources
|
|||||||
set(MG_SINGLE_NODE_V2_LIBS stdc++fs Threads::Threads fmt cppitertools
|
set(MG_SINGLE_NODE_V2_LIBS stdc++fs Threads::Threads fmt cppitertools
|
||||||
antlr_opencypher_parser_lib dl glog gflags mg-storage-v2
|
antlr_opencypher_parser_lib dl glog gflags mg-storage-v2
|
||||||
mg-utils mg-io mg-requests mg-communication)
|
mg-utils mg-io mg-requests mg-communication)
|
||||||
# These are enterprise subsystems
|
|
||||||
set(MG_SINGLE_NODE_V2_LIBS ${MG_SINGLE_NODE_V2_LIBS} mg-auth)
|
|
||||||
|
|
||||||
if (USE_LTALLOC)
|
if (USE_LTALLOC)
|
||||||
list(APPEND MG_SINGLE_NODE_V2_LIBS ltalloc)
|
list(APPEND MG_SINGLE_NODE_V2_LIBS ltalloc)
|
||||||
@@ -166,98 +154,8 @@ target_link_libraries(mg-single-node-v2 "-Wl,--dynamic-list=${CMAKE_SOURCE_DIR}/
|
|||||||
# END Memgraph Single Node v2
|
# END Memgraph Single Node v2
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
# Memgraph Single Node High Availability
|
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
set(mg_single_node_ha_sources
|
|
||||||
${lcp_common_cpp_files}
|
|
||||||
audit/log.cpp
|
|
||||||
data_structures/concurrent/skiplist_gc.cpp
|
|
||||||
database/single_node_ha/config.cpp
|
|
||||||
database/single_node_ha/graph_db.cpp
|
|
||||||
database/single_node_ha/graph_db_accessor.cpp
|
|
||||||
durability/single_node_ha/state_delta.cpp
|
|
||||||
durability/single_node_ha/paths.cpp
|
|
||||||
durability/single_node_ha/snapshooter.cpp
|
|
||||||
durability/single_node_ha/recovery.cpp
|
|
||||||
glue/auth.cpp
|
|
||||||
glue/communication.cpp
|
|
||||||
raft/coordination.cpp
|
|
||||||
raft/raft_server.cpp
|
|
||||||
raft/storage_info.cpp
|
|
||||||
query/common.cpp
|
|
||||||
query/frontend/ast/cypher_main_visitor.cpp
|
|
||||||
query/frontend/ast/pretty_print.cpp
|
|
||||||
query/frontend/parsing.cpp
|
|
||||||
query/frontend/semantic/required_privileges.cpp
|
|
||||||
query/frontend/semantic/symbol_generator.cpp
|
|
||||||
query/frontend/stripped.cpp
|
|
||||||
query/interpret/awesome_memgraph_functions.cpp
|
|
||||||
query/interpreter.cpp
|
|
||||||
query/plan/operator.cpp
|
|
||||||
query/plan/preprocess.cpp
|
|
||||||
query/plan/pretty_print.cpp
|
|
||||||
query/plan/profile.cpp
|
|
||||||
query/plan/rewrite/index_lookup.cpp
|
|
||||||
query/plan/rule_based_planner.cpp
|
|
||||||
query/plan/variable_start_planner.cpp
|
|
||||||
query/procedure/mg_procedure_impl.cpp
|
|
||||||
query/procedure/module.cpp
|
|
||||||
query/typed_value.cpp
|
|
||||||
storage/common/constraints/record.cpp
|
|
||||||
storage/common/constraints/unique_constraints.cpp
|
|
||||||
storage/common/types/slk.cpp
|
|
||||||
storage/common/types/property_value_store.cpp
|
|
||||||
storage/common/locking/record_lock.cpp
|
|
||||||
storage/single_node_ha/edge_accessor.cpp
|
|
||||||
storage/single_node_ha/record_accessor.cpp
|
|
||||||
storage/single_node_ha/vertex_accessor.cpp
|
|
||||||
transactions/single_node_ha/engine.cpp
|
|
||||||
memgraph_init.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
define_add_lcp(add_lcp_single_node_ha mg_single_node_ha_sources generated_lcp_single_node_ha_files)
|
|
||||||
|
|
||||||
add_lcp_single_node_ha(durability/single_node_ha/state_delta.lcp)
|
|
||||||
add_lcp_single_node_ha(database/single_node_ha/serialization.lcp SLK_SERIALIZE
|
|
||||||
DEPENDS durability/single_node_ha/state_delta.lcp)
|
|
||||||
add_lcp_single_node_ha(raft/raft_rpc_messages.lcp SLK_SERIALIZE)
|
|
||||||
add_lcp_single_node_ha(raft/log_entry.lcp SLK_SERIALIZE)
|
|
||||||
add_lcp_single_node_ha(raft/snapshot_metadata.lcp SLK_SERIALIZE)
|
|
||||||
add_lcp_single_node_ha(raft/storage_info_rpc_messages.lcp SLK_SERIALIZE)
|
|
||||||
|
|
||||||
add_custom_target(generate_lcp_single_node_ha DEPENDS generate_lcp_common ${generated_lcp_single_node_ha_files})
|
|
||||||
|
|
||||||
set(MG_SINGLE_NODE_HA_LIBS stdc++fs Threads::Threads fmt cppitertools
|
|
||||||
antlr_opencypher_parser_lib dl glog gflags
|
|
||||||
mg-utils mg-io mg-requests mg-communication mg-comm-rpc
|
|
||||||
mg-auth)
|
|
||||||
|
|
||||||
if (USE_LTALLOC)
|
|
||||||
list(APPEND MG_SINGLE_NODE_HA_LIBS ltalloc)
|
|
||||||
# TODO(mferencevic): Enable this when clang is updated on apollo.
|
|
||||||
# set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(mg-single-node-ha STATIC ${mg_single_node_ha_sources})
|
|
||||||
target_include_directories(mg-single-node-ha PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
|
||||||
target_link_libraries(mg-single-node-ha ${MG_SINGLE_NODE_HA_LIBS})
|
|
||||||
add_dependencies(mg-single-node-ha generate_opencypher_parser)
|
|
||||||
add_dependencies(mg-single-node-ha generate_lcp_single_node_ha)
|
|
||||||
target_compile_definitions(mg-single-node-ha PUBLIC MG_SINGLE_NODE_HA)
|
|
||||||
# TODO: Make these symbols visible once we add support for custom procedure
|
|
||||||
# modules in HA.
|
|
||||||
# NOTE: `include/mg_procedure.syms` describes a pattern match for symbols which
|
|
||||||
# should be dynamically exported, so that `dlopen` can correctly link the
|
|
||||||
# symbols in custom procedure module libraries.
|
|
||||||
# target_link_libraries(mg-single-node-ha "-Wl,--dynamic-list=${CMAKE_SOURCE_DIR}/include/mg_procedure.syms")
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
# END Memgraph Single Node High Availability
|
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
add_custom_target(generate_lcp)
|
add_custom_target(generate_lcp)
|
||||||
add_dependencies(generate_lcp generate_lcp_single_node generate_lcp_single_node_ha)
|
add_dependencies(generate_lcp generate_lcp_single_node)
|
||||||
|
|
||||||
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
||||||
|
|
||||||
@@ -330,8 +228,6 @@ install(FILES ${CMAKE_BINARY_DIR}/config/memgraph.conf
|
|||||||
# Install logrotate configuration (must use absolute path).
|
# Install logrotate configuration (must use absolute path).
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/release/logrotate.conf
|
install(FILES ${CMAKE_SOURCE_DIR}/release/logrotate.conf
|
||||||
DESTINATION /etc/logrotate.d RENAME memgraph)
|
DESTINATION /etc/logrotate.d RENAME memgraph)
|
||||||
install(FILES ${CMAKE_SOURCE_DIR}/release/logrotate_audit.conf
|
|
||||||
DESTINATION /etc/logrotate.d RENAME memgraph_audit)
|
|
||||||
# Create empty directories for default location of lib and log.
|
# Create empty directories for default location of lib and log.
|
||||||
install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}/var/log/memgraph
|
install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}/var/log/memgraph
|
||||||
\$ENV{DESTDIR}/var/lib/memgraph)")
|
\$ENV{DESTDIR}/var/lib/memgraph)")
|
||||||
@@ -351,18 +247,3 @@ install(
|
|||||||
${CMAKE_BINARY_DIR}/tools/src/mg_client
|
${CMAKE_BINARY_DIR}/tools/src/mg_client
|
||||||
WORKING_DIRECTORY ${examples})")
|
WORKING_DIRECTORY ${examples})")
|
||||||
install(DIRECTORY ${examples}/build/ DESTINATION share/memgraph/examples)
|
install(DIRECTORY ${examples}/build/ DESTINATION share/memgraph/examples)
|
||||||
|
|
||||||
|
|
||||||
# memgraph single node high availability executable
|
|
||||||
add_executable(memgraph_ha memgraph_ha.cpp)
|
|
||||||
target_link_libraries(memgraph_ha mg-single-node-ha kvstore_lib telemetry_lib)
|
|
||||||
set_target_properties(memgraph_ha PROPERTIES
|
|
||||||
# Set the executable output name to include version information.
|
|
||||||
OUTPUT_NAME "memgraph_ha-${memgraph_VERSION}-${COMMIT_HASH}_${CMAKE_BUILD_TYPE}"
|
|
||||||
# Output the executable in main binary dir.
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
||||||
# Create symlink to the built executable.
|
|
||||||
add_custom_command(TARGET memgraph_ha POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:memgraph_ha> ${CMAKE_BINARY_DIR}/memgraph_ha
|
|
||||||
BYPRODUCTS ${CMAKE_BINARY_DIR}/memgraph_ha
|
|
||||||
COMMENT "Creating symlink to memgraph single node high availability executable")
|
|
||||||
|
|||||||
@@ -10,12 +10,3 @@ add_library(mg-communication STATIC ${communication_src_files})
|
|||||||
target_link_libraries(mg-communication Threads::Threads mg-utils mg-io fmt glog gflags)
|
target_link_libraries(mg-communication Threads::Threads mg-utils mg-io fmt glog gflags)
|
||||||
target_link_libraries(mg-communication ${OPENSSL_LIBRARIES})
|
target_link_libraries(mg-communication ${OPENSSL_LIBRARIES})
|
||||||
target_include_directories(mg-communication SYSTEM PUBLIC ${OPENSSL_INCLUDE_DIR})
|
target_include_directories(mg-communication SYSTEM PUBLIC ${OPENSSL_INCLUDE_DIR})
|
||||||
|
|
||||||
set(communication_rpc_src_files
|
|
||||||
rpc/client.cpp
|
|
||||||
rpc/protocol.cpp
|
|
||||||
rpc/server.cpp)
|
|
||||||
|
|
||||||
add_library(mg-comm-rpc STATIC ${communication_rpc_src_files})
|
|
||||||
target_link_libraries(mg-comm-rpc Threads::Threads mg-communication mg-utils mg-io fmt glog gflags)
|
|
||||||
target_link_libraries(mg-comm-rpc mg-slk)
|
|
||||||
|
|||||||
@@ -60,10 +60,6 @@ class Session {
|
|||||||
/** Aborts currently running query. */
|
/** Aborts currently running query. */
|
||||||
virtual void Abort() = 0;
|
virtual void Abort() = 0;
|
||||||
|
|
||||||
/** Return `true` if the user was successfully authenticated. */
|
|
||||||
virtual bool Authenticate(const std::string &username,
|
|
||||||
const std::string &password) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the session after data has been read into the buffer.
|
* Executes the session after data has been read into the buffer.
|
||||||
* Goes through the bolt states in order to execute commands from the client.
|
* Goes through the bolt states in order to execute commands from the client.
|
||||||
|
|||||||
@@ -60,38 +60,6 @@ State StateInitRun(Session &session) {
|
|||||||
LOG(INFO) << fmt::format("Client connected '{}'", client_name.ValueString())
|
LOG(INFO) << fmt::format("Client connected '{}'", client_name.ValueString())
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
// Get authentication data.
|
|
||||||
std::string username, password;
|
|
||||||
auto &data = metadata.ValueMap();
|
|
||||||
if (!data.count("scheme")) {
|
|
||||||
LOG(WARNING) << "The client didn't supply authentication information!";
|
|
||||||
return State::Close;
|
|
||||||
}
|
|
||||||
if (data["scheme"].ValueString() == "basic") {
|
|
||||||
if (!data.count("principal") || !data.count("credentials")) {
|
|
||||||
LOG(WARNING) << "The client didn't supply authentication information!";
|
|
||||||
return State::Close;
|
|
||||||
}
|
|
||||||
username = data["principal"].ValueString();
|
|
||||||
password = data["credentials"].ValueString();
|
|
||||||
} else if (data["scheme"].ValueString() != "none") {
|
|
||||||
LOG(WARNING) << "Unsupported authentication scheme: "
|
|
||||||
<< data["scheme"].ValueString();
|
|
||||||
return State::Close;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authenticate the user.
|
|
||||||
if (!session.Authenticate(username, password)) {
|
|
||||||
if (!session.encoder_.MessageFailure(
|
|
||||||
{{"code", "Memgraph.ClientError.Security.Unauthenticated"},
|
|
||||||
{"message", "Authentication failure"}})) {
|
|
||||||
DLOG(WARNING) << "Couldn't send failure message to the client!";
|
|
||||||
}
|
|
||||||
// Throw an exception to indicate to the network stack that the session
|
|
||||||
// should be closed and cleaned up.
|
|
||||||
throw SessionClosedException("The client is not authenticated!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return success.
|
// Return success.
|
||||||
if (!session.encoder_.MessageSuccess()) {
|
if (!session.encoder_.MessageSuccess()) {
|
||||||
DLOG(WARNING) << "Couldn't send success message to the client!";
|
DLOG(WARNING) << "Couldn't send success message to the client!";
|
||||||
|
|||||||
@@ -87,16 +87,6 @@ DEFINE_bool(telemetry_enabled, false,
|
|||||||
"the database runtime (vertex and edge counts and resource usage) "
|
"the database runtime (vertex and edge counts and resource usage) "
|
||||||
"to allow for easier improvement of the product.");
|
"to allow for easier improvement of the product.");
|
||||||
|
|
||||||
// Audit logging flags.
|
|
||||||
DEFINE_bool(audit_enabled, false, "Set to true to enable audit logging.");
|
|
||||||
DEFINE_VALIDATED_int32(audit_buffer_size, audit::kBufferSizeDefault,
|
|
||||||
"Maximum number of items in the audit log buffer.",
|
|
||||||
FLAG_IN_RANGE(1, INT32_MAX));
|
|
||||||
DEFINE_VALIDATED_int32(
|
|
||||||
audit_buffer_flush_interval_ms, audit::kBufferFlushIntervalMillisDefault,
|
|
||||||
"Interval (in milliseconds) used for flushing the audit log buffer.",
|
|
||||||
FLAG_IN_RANGE(10, INT32_MAX));
|
|
||||||
|
|
||||||
// Query flags.
|
// Query flags.
|
||||||
DEFINE_uint64(query_execution_timeout_sec, 180,
|
DEFINE_uint64(query_execution_timeout_sec, 180,
|
||||||
"Maximum allowed query execution time. Queries exceeding this "
|
"Maximum allowed query execution time. Queries exceeding this "
|
||||||
@@ -116,41 +106,12 @@ using ServerT = communication::Server<BoltSession, SessionData>;
|
|||||||
using communication::ServerContext;
|
using communication::ServerContext;
|
||||||
|
|
||||||
void SingleNodeMain() {
|
void SingleNodeMain() {
|
||||||
// All enterprise features should be constructed before the main database
|
|
||||||
// storage. This will cause them to be destructed *after* the main database
|
|
||||||
// storage. That way any errors that happen during enterprise features
|
|
||||||
// destruction won't have an impact on the storage engine.
|
|
||||||
// Example: When the main storage is destructed it makes a snapshot. When
|
|
||||||
// audit logging is destructed it syncs all pending data to disk and that can
|
|
||||||
// fail. That is why it must be destructed *after* the main database storage
|
|
||||||
// to minimise the impact of their failure on the main storage.
|
|
||||||
|
|
||||||
// Begin enterprise features initialization
|
|
||||||
|
|
||||||
#ifdef MG_SINGLE_NODE_V2
|
#ifdef MG_SINGLE_NODE_V2
|
||||||
auto data_directory = std::filesystem::path(FLAGS_data_directory);
|
auto data_directory = std::filesystem::path(FLAGS_data_directory);
|
||||||
#else
|
#else
|
||||||
auto data_directory = std::filesystem::path(FLAGS_durability_directory);
|
auto data_directory = std::filesystem::path(FLAGS_durability_directory);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Auth
|
|
||||||
auth::Auth auth{data_directory / "auth"};
|
|
||||||
|
|
||||||
// Audit log
|
|
||||||
audit::Log audit_log{data_directory / "audit", FLAGS_audit_buffer_size,
|
|
||||||
FLAGS_audit_buffer_flush_interval_ms};
|
|
||||||
// Start the log if enabled.
|
|
||||||
if (FLAGS_audit_enabled) {
|
|
||||||
audit_log.Start();
|
|
||||||
}
|
|
||||||
// Setup SIGUSR2 to be used for reopening audit log files, when e.g. logrotate
|
|
||||||
// rotates our audit logs.
|
|
||||||
CHECK(utils::SignalHandler::RegisterHandler(
|
|
||||||
utils::Signal::User2, [&audit_log]() { audit_log.ReopenLog(); }))
|
|
||||||
<< "Unable to register SIGUSR2 handler!";
|
|
||||||
|
|
||||||
// End enterprise features initialization
|
|
||||||
|
|
||||||
// Main storage and execution engines initialization
|
// Main storage and execution engines initialization
|
||||||
|
|
||||||
#ifdef MG_SINGLE_NODE_V2
|
#ifdef MG_SINGLE_NODE_V2
|
||||||
@@ -190,7 +151,7 @@ void SingleNodeMain() {
|
|||||||
query::InterpreterContext interpreter_context{&db};
|
query::InterpreterContext interpreter_context{&db};
|
||||||
query::SetExecutionTimeout(&interpreter_context,
|
query::SetExecutionTimeout(&interpreter_context,
|
||||||
FLAGS_query_execution_timeout_sec);
|
FLAGS_query_execution_timeout_sec);
|
||||||
SessionData session_data{&db, &interpreter_context, &auth, &audit_log};
|
SessionData session_data{&db, &interpreter_context};
|
||||||
|
|
||||||
// Register modules
|
// Register modules
|
||||||
if (!FLAGS_query_modules_directory.empty()) {
|
if (!FLAGS_query_modules_directory.empty()) {
|
||||||
@@ -202,8 +163,6 @@ void SingleNodeMain() {
|
|||||||
}
|
}
|
||||||
// Register modules END
|
// Register modules END
|
||||||
|
|
||||||
interpreter_context.auth = &auth;
|
|
||||||
|
|
||||||
ServerContext context;
|
ServerContext context;
|
||||||
std::string service_name = "Bolt";
|
std::string service_name = "Bolt";
|
||||||
if (!FLAGS_bolt_key_file.empty() && !FLAGS_bolt_cert_file.empty()) {
|
if (!FLAGS_bolt_key_file.empty() && !FLAGS_bolt_cert_file.empty()) {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#include "glue/auth.hpp"
|
|
||||||
#include "glue/communication.hpp"
|
#include "glue/communication.hpp"
|
||||||
#include "query/exceptions.hpp"
|
#include "query/exceptions.hpp"
|
||||||
#include "requests/requests.hpp"
|
#include "requests/requests.hpp"
|
||||||
@@ -33,10 +32,6 @@ BoltSession::BoltSession(SessionData *data,
|
|||||||
db_(data->db),
|
db_(data->db),
|
||||||
#endif
|
#endif
|
||||||
interpreter_(data->interpreter_context),
|
interpreter_(data->interpreter_context),
|
||||||
#ifndef MG_SINGLE_NODE_HA
|
|
||||||
auth_(data->auth),
|
|
||||||
audit_log_(data->audit_log),
|
|
||||||
#endif
|
|
||||||
endpoint_(endpoint) {
|
endpoint_(endpoint) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,28 +45,8 @@ std::vector<std::string> BoltSession::Interpret(
|
|||||||
std::map<std::string, PropertyValue> params_pv;
|
std::map<std::string, PropertyValue> params_pv;
|
||||||
for (const auto &kv : params)
|
for (const auto &kv : params)
|
||||||
params_pv.emplace(kv.first, glue::ToPropertyValue(kv.second));
|
params_pv.emplace(kv.first, glue::ToPropertyValue(kv.second));
|
||||||
#ifndef MG_SINGLE_NODE_HA
|
|
||||||
audit_log_->Record(endpoint_.address(), user_ ? user_->username() : "", query,
|
|
||||||
PropertyValue(params_pv));
|
|
||||||
#endif
|
|
||||||
try {
|
try {
|
||||||
auto result = interpreter_.Prepare(query, params_pv);
|
return interpreter_.Prepare(query, params_pv);
|
||||||
#ifndef MG_SINGLE_NODE_HA
|
|
||||||
if (user_) {
|
|
||||||
const auto &permissions = user_->GetPermissions();
|
|
||||||
for (const auto &privilege : result.second) {
|
|
||||||
if (permissions.Has(glue::PrivilegeToPermission(privilege)) !=
|
|
||||||
auth::PermissionLevel::GRANT) {
|
|
||||||
interpreter_.Abort();
|
|
||||||
throw communication::bolt::ClientError(
|
|
||||||
"You are not authorized to execute this query! Please contact "
|
|
||||||
"your database administrator.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return result.first;
|
|
||||||
|
|
||||||
} catch (const query::QueryException &e) {
|
} catch (const query::QueryException &e) {
|
||||||
// Wrap QueryException into ClientError, because we want to allow the
|
// Wrap QueryException into ClientError, because we want to allow the
|
||||||
// client to fix their query.
|
// client to fix their query.
|
||||||
@@ -119,17 +94,6 @@ std::map<std::string, communication::bolt::Value> BoltSession::PullAll(
|
|||||||
|
|
||||||
void BoltSession::Abort() { interpreter_.Abort(); }
|
void BoltSession::Abort() { interpreter_.Abort(); }
|
||||||
|
|
||||||
bool BoltSession::Authenticate(const std::string &username,
|
|
||||||
const std::string &password) {
|
|
||||||
#ifdef MG_SINGLE_NODE_HA
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
if (!auth_->HasUsers()) return true;
|
|
||||||
user_ = auth_->Authenticate(username, password);
|
|
||||||
return !!user_;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MG_SINGLE_NODE_V2
|
#ifdef MG_SINGLE_NODE_V2
|
||||||
BoltSession::TypedValueResultStream::TypedValueResultStream(
|
BoltSession::TypedValueResultStream::TypedValueResultStream(
|
||||||
TEncoder *encoder, const storage::Storage *db)
|
TEncoder *encoder, const storage::Storage *db)
|
||||||
|
|||||||
@@ -31,16 +31,11 @@ struct SessionData {
|
|||||||
// Explicit constructor here to ensure that pointers to all objects are
|
// Explicit constructor here to ensure that pointers to all objects are
|
||||||
// supplied.
|
// supplied.
|
||||||
SessionData(database::GraphDb *_db,
|
SessionData(database::GraphDb *_db,
|
||||||
query::InterpreterContext *_interpreter_context,
|
query::InterpreterContext *_interpreter_context)
|
||||||
auth::Auth *_auth, audit::Log *_audit_log)
|
|
||||||
: db(_db),
|
: db(_db),
|
||||||
interpreter_context(_interpreter_context),
|
interpreter_context(_interpreter_context) {}
|
||||||
auth(_auth),
|
|
||||||
audit_log(_audit_log) {}
|
|
||||||
database::GraphDb *db;
|
database::GraphDb *db;
|
||||||
query::InterpreterContext *interpreter_context;
|
query::InterpreterContext *interpreter_context;
|
||||||
auth::Auth *auth;
|
|
||||||
audit::Log *audit_log;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoltSession final
|
class BoltSession final
|
||||||
@@ -63,9 +58,6 @@ class BoltSession final
|
|||||||
|
|
||||||
void Abort() override;
|
void Abort() override;
|
||||||
|
|
||||||
bool Authenticate(const std::string &username,
|
|
||||||
const std::string &password) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Wrapper around TEncoder which converts TypedValue to Value
|
/// Wrapper around TEncoder which converts TypedValue to Value
|
||||||
/// before forwarding the calls to original TEncoder.
|
/// before forwarding the calls to original TEncoder.
|
||||||
@@ -92,11 +84,6 @@ class BoltSession final
|
|||||||
const storage::Storage *db_;
|
const storage::Storage *db_;
|
||||||
#endif
|
#endif
|
||||||
query::Interpreter interpreter_;
|
query::Interpreter interpreter_;
|
||||||
#ifndef MG_SINGLE_NODE_HA
|
|
||||||
auth::Auth *auth_;
|
|
||||||
std::optional<auth::User> user_;
|
|
||||||
audit::Log *audit_log_;
|
|
||||||
#endif
|
|
||||||
io::network::Endpoint endpoint_;
|
io::network::Endpoint endpoint_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -127,19 +127,4 @@ class RemoveAttachedVertexException : public QueryRuntimeException {
|
|||||||
"connections. Consider using DETACH DELETE.") {}
|
"connections. Consider using DETACH DELETE.") {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class UserModificationInMulticommandTxException : public QueryException {
|
|
||||||
public:
|
|
||||||
UserModificationInMulticommandTxException()
|
|
||||||
: QueryException(
|
|
||||||
"Authentication clause not allowed in multicommand transactions.") {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class StreamClauseInMulticommandTxException : public QueryException {
|
|
||||||
public:
|
|
||||||
StreamClauseInMulticommandTxException()
|
|
||||||
: QueryException(
|
|
||||||
"Stream clause not allowed in multicommand transactions.") {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace query
|
} // namespace query
|
||||||
|
|||||||
@@ -2087,67 +2087,11 @@ cpp<#
|
|||||||
(:serialize (:slk))
|
(:serialize (:slk))
|
||||||
(:clone))
|
(:clone))
|
||||||
|
|
||||||
(lcp:define-class auth-query (query)
|
|
||||||
((action "Action" :scope :public)
|
|
||||||
(user "std::string" :scope :public)
|
|
||||||
(role "std::string" :scope :public)
|
|
||||||
(user-or-role "std::string" :scope :public)
|
|
||||||
(password "Expression *" :initval "nullptr" :scope :public
|
|
||||||
:slk-save #'slk-save-ast-pointer
|
|
||||||
:slk-load (slk-load-ast-pointer "Expression"))
|
|
||||||
(privileges "std::vector<Privilege>" :scope :public))
|
|
||||||
(:public
|
|
||||||
(lcp:define-enum action
|
|
||||||
(create-role drop-role show-roles create-user set-password drop-user
|
|
||||||
show-users set-role clear-role grant-privilege deny-privilege
|
|
||||||
revoke-privilege show-privileges show-role-for-user
|
|
||||||
show-users-for-role)
|
|
||||||
(:serialize))
|
|
||||||
(lcp:define-enum privilege
|
|
||||||
(create delete match merge set remove index stats auth constraint
|
|
||||||
dump)
|
|
||||||
(:serialize))
|
|
||||||
#>cpp
|
|
||||||
AuthQuery() = default;
|
|
||||||
|
|
||||||
DEFVISITABLE(QueryVisitor<void>);
|
|
||||||
cpp<#)
|
|
||||||
(:protected
|
|
||||||
#>cpp
|
|
||||||
AuthQuery(Action action, std::string user, std::string role,
|
|
||||||
std::string user_or_role, Expression *password,
|
|
||||||
std::vector<Privilege> privileges)
|
|
||||||
: action_(action),
|
|
||||||
user_(user),
|
|
||||||
role_(role),
|
|
||||||
user_or_role_(user_or_role),
|
|
||||||
password_(password),
|
|
||||||
privileges_(privileges) {}
|
|
||||||
cpp<#)
|
|
||||||
(:private
|
|
||||||
#>cpp
|
|
||||||
friend class AstStorage;
|
|
||||||
cpp<#)
|
|
||||||
(:serialize (:slk))
|
|
||||||
(:clone))
|
|
||||||
|
|
||||||
;; TODO: Generate this via LCP
|
|
||||||
#>cpp
|
|
||||||
/// Constant that holds all available privileges.
|
|
||||||
const std::vector<AuthQuery::Privilege> kPrivilegesAll = {
|
|
||||||
AuthQuery::Privilege::CREATE, AuthQuery::Privilege::DELETE,
|
|
||||||
AuthQuery::Privilege::MATCH, AuthQuery::Privilege::MERGE,
|
|
||||||
AuthQuery::Privilege::SET, AuthQuery::Privilege::REMOVE,
|
|
||||||
AuthQuery::Privilege::INDEX, AuthQuery::Privilege::STATS,
|
|
||||||
AuthQuery::Privilege::AUTH,
|
|
||||||
AuthQuery::Privilege::CONSTRAINT, AuthQuery::Privilege::DUMP};
|
|
||||||
cpp<#
|
|
||||||
|
|
||||||
(lcp:define-class info-query (query)
|
(lcp:define-class info-query (query)
|
||||||
((info-type "InfoType" :scope :public))
|
((info-type "InfoType" :scope :public))
|
||||||
(:public
|
(:public
|
||||||
(lcp:define-enum info-type
|
(lcp:define-enum info-type
|
||||||
(storage index constraint raft)
|
(storage index constraint)
|
||||||
(:serialize))
|
(:serialize))
|
||||||
|
|
||||||
#>cpp
|
#>cpp
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ class RemoveProperty;
|
|||||||
class RemoveLabels;
|
class RemoveLabels;
|
||||||
class Merge;
|
class Merge;
|
||||||
class Unwind;
|
class Unwind;
|
||||||
class AuthQuery;
|
|
||||||
class ExplainQuery;
|
class ExplainQuery;
|
||||||
class ProfileQuery;
|
class ProfileQuery;
|
||||||
class IndexQuery;
|
class IndexQuery;
|
||||||
@@ -113,7 +112,7 @@ class ExpressionVisitor
|
|||||||
template <class TResult>
|
template <class TResult>
|
||||||
class QueryVisitor
|
class QueryVisitor
|
||||||
: public ::utils::Visitor<TResult, CypherQuery, ExplainQuery, ProfileQuery,
|
: public ::utils::Visitor<TResult, CypherQuery, ExplainQuery, ProfileQuery,
|
||||||
IndexQuery, AuthQuery, InfoQuery,
|
IndexQuery, InfoQuery,
|
||||||
ConstraintQuery, DumpQuery> {};
|
ConstraintQuery, DumpQuery> {};
|
||||||
|
|
||||||
} // namespace query
|
} // namespace query
|
||||||
|
|||||||
@@ -62,9 +62,6 @@ antlrcpp::Any CypherMainVisitor::visitInfoQuery(
|
|||||||
} else if (ctx->constraintInfo()) {
|
} else if (ctx->constraintInfo()) {
|
||||||
info_query->info_type_ = InfoQuery::InfoType::CONSTRAINT;
|
info_query->info_type_ = InfoQuery::InfoType::CONSTRAINT;
|
||||||
return info_query;
|
return info_query;
|
||||||
} else if (ctx->raftInfo()) {
|
|
||||||
info_query->info_type_ = InfoQuery::InfoType::RAFT;
|
|
||||||
return info_query;
|
|
||||||
} else {
|
} else {
|
||||||
throw utils::NotYetImplemented("Info query: '{}'", ctx->getText());
|
throw utils::NotYetImplemented("Info query: '{}'", ctx->getText());
|
||||||
}
|
}
|
||||||
@@ -174,15 +171,6 @@ antlrcpp::Any CypherMainVisitor::visitDropIndex(
|
|||||||
return index_query;
|
return index_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitAuthQuery(
|
|
||||||
MemgraphCypher::AuthQueryContext *ctx) {
|
|
||||||
CHECK(ctx->children.size() == 1)
|
|
||||||
<< "AuthQuery should have exactly one child!";
|
|
||||||
auto *auth_query = ctx->children[0]->accept(this).as<AuthQuery *>();
|
|
||||||
query_ = auth_query;
|
|
||||||
return auth_query;
|
|
||||||
}
|
|
||||||
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitDumpQuery(
|
antlrcpp::Any CypherMainVisitor::visitDumpQuery(
|
||||||
MemgraphCypher::DumpQueryContext *ctx) {
|
MemgraphCypher::DumpQueryContext *ctx) {
|
||||||
auto *dump_query = storage_->Create<DumpQuery>();
|
auto *dump_query = storage_->Create<DumpQuery>();
|
||||||
@@ -434,235 +422,6 @@ antlrcpp::Any CypherMainVisitor::visitCallProcedure(
|
|||||||
return call_proc;
|
return call_proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return std::string
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitUserOrRoleName(
|
|
||||||
MemgraphCypher::UserOrRoleNameContext *ctx) {
|
|
||||||
std::string value = ctx->symbolicName()->accept(this).as<std::string>();
|
|
||||||
const std::regex NAME_REGEX("[a-zA-Z0-9_.+-]+");
|
|
||||||
if (!std::regex_match(value, NAME_REGEX)) {
|
|
||||||
throw SyntaxException("Invalid user or role name.");
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitCreateRole(
|
|
||||||
MemgraphCypher::CreateRoleContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::CREATE_ROLE;
|
|
||||||
auth->role_ = ctx->role->accept(this).as<std::string>();
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitDropRole(
|
|
||||||
MemgraphCypher::DropRoleContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::DROP_ROLE;
|
|
||||||
auth->role_ = ctx->role->accept(this).as<std::string>();
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitShowRoles(
|
|
||||||
MemgraphCypher::ShowRolesContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::SHOW_ROLES;
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitCreateUser(
|
|
||||||
MemgraphCypher::CreateUserContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::CREATE_USER;
|
|
||||||
auth->user_ = ctx->user->accept(this).as<std::string>();
|
|
||||||
if (ctx->password) {
|
|
||||||
if (!ctx->password->StringLiteral() && !ctx->literal()->CYPHERNULL()) {
|
|
||||||
throw SyntaxException("Password should be a string literal or null.");
|
|
||||||
}
|
|
||||||
auth->password_ = ctx->password->accept(this);
|
|
||||||
}
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitSetPassword(
|
|
||||||
MemgraphCypher::SetPasswordContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::SET_PASSWORD;
|
|
||||||
auth->user_ = ctx->user->accept(this).as<std::string>();
|
|
||||||
if (!ctx->password->StringLiteral() && !ctx->literal()->CYPHERNULL()) {
|
|
||||||
throw SyntaxException("Password should be a string literal or null.");
|
|
||||||
}
|
|
||||||
auth->password_ = ctx->password->accept(this);
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitDropUser(
|
|
||||||
MemgraphCypher::DropUserContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::DROP_USER;
|
|
||||||
auth->user_ = ctx->user->accept(this).as<std::string>();
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitShowUsers(
|
|
||||||
MemgraphCypher::ShowUsersContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::SHOW_USERS;
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitSetRole(
|
|
||||||
MemgraphCypher::SetRoleContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::SET_ROLE;
|
|
||||||
auth->user_ = ctx->user->accept(this).as<std::string>();
|
|
||||||
auth->role_ = ctx->role->accept(this).as<std::string>();
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitClearRole(
|
|
||||||
MemgraphCypher::ClearRoleContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::CLEAR_ROLE;
|
|
||||||
auth->user_ = ctx->user->accept(this).as<std::string>();
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitGrantPrivilege(
|
|
||||||
MemgraphCypher::GrantPrivilegeContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::GRANT_PRIVILEGE;
|
|
||||||
auth->user_or_role_ = ctx->userOrRole->accept(this).as<std::string>();
|
|
||||||
if (ctx->privilegeList()) {
|
|
||||||
for (auto *privilege : ctx->privilegeList()->privilege()) {
|
|
||||||
auth->privileges_.push_back(privilege->accept(this));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* grant all privileges */
|
|
||||||
auth->privileges_ = kPrivilegesAll;
|
|
||||||
}
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitDenyPrivilege(
|
|
||||||
MemgraphCypher::DenyPrivilegeContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::DENY_PRIVILEGE;
|
|
||||||
auth->user_or_role_ = ctx->userOrRole->accept(this).as<std::string>();
|
|
||||||
if (ctx->privilegeList()) {
|
|
||||||
for (auto *privilege : ctx->privilegeList()->privilege()) {
|
|
||||||
auth->privileges_.push_back(privilege->accept(this));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* deny all privileges */
|
|
||||||
auth->privileges_ = kPrivilegesAll;
|
|
||||||
}
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitRevokePrivilege(
|
|
||||||
MemgraphCypher::RevokePrivilegeContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::REVOKE_PRIVILEGE;
|
|
||||||
auth->user_or_role_ = ctx->userOrRole->accept(this).as<std::string>();
|
|
||||||
if (ctx->privilegeList()) {
|
|
||||||
for (auto *privilege : ctx->privilegeList()->privilege()) {
|
|
||||||
auth->privileges_.push_back(privilege->accept(this));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* revoke all privileges */
|
|
||||||
auth->privileges_ = kPrivilegesAll;
|
|
||||||
}
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery::Privilege
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitPrivilege(
|
|
||||||
MemgraphCypher::PrivilegeContext *ctx) {
|
|
||||||
if (ctx->CREATE()) return AuthQuery::Privilege::CREATE;
|
|
||||||
if (ctx->DELETE()) return AuthQuery::Privilege::DELETE;
|
|
||||||
if (ctx->MATCH()) return AuthQuery::Privilege::MATCH;
|
|
||||||
if (ctx->MERGE()) return AuthQuery::Privilege::MERGE;
|
|
||||||
if (ctx->SET()) return AuthQuery::Privilege::SET;
|
|
||||||
if (ctx->REMOVE()) return AuthQuery::Privilege::REMOVE;
|
|
||||||
if (ctx->INDEX()) return AuthQuery::Privilege::INDEX;
|
|
||||||
if (ctx->STATS()) return AuthQuery::Privilege::STATS;
|
|
||||||
if (ctx->AUTH()) return AuthQuery::Privilege::AUTH;
|
|
||||||
if (ctx->CONSTRAINT()) return AuthQuery::Privilege::CONSTRAINT;
|
|
||||||
LOG(FATAL) << "Should not get here - unknown privilege!";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitShowPrivileges(
|
|
||||||
MemgraphCypher::ShowPrivilegesContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::SHOW_PRIVILEGES;
|
|
||||||
auth->user_or_role_ = ctx->userOrRole->accept(this).as<std::string>();
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitShowRoleForUser(
|
|
||||||
MemgraphCypher::ShowRoleForUserContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::SHOW_ROLE_FOR_USER;
|
|
||||||
auth->user_ = ctx->user->accept(this).as<std::string>();
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitShowUsersForRole(
|
|
||||||
MemgraphCypher::ShowUsersForRoleContext *ctx) {
|
|
||||||
AuthQuery *auth = storage_->Create<AuthQuery>();
|
|
||||||
auth->action_ = AuthQuery::Action::SHOW_USERS_FOR_ROLE;
|
|
||||||
auth->role_ = ctx->role->accept(this).as<std::string>();
|
|
||||||
return auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
antlrcpp::Any CypherMainVisitor::visitCypherReturn(
|
antlrcpp::Any CypherMainVisitor::visitCypherReturn(
|
||||||
MemgraphCypher::CypherReturnContext *ctx) {
|
MemgraphCypher::CypherReturnContext *ctx) {
|
||||||
auto *return_clause = storage_->Create<Return>();
|
auto *return_clause = storage_->Create<Return>();
|
||||||
|
|||||||
@@ -176,11 +176,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
|
|||||||
antlrcpp::Any visitConstraintQuery(
|
antlrcpp::Any visitConstraintQuery(
|
||||||
MemgraphCypher::ConstraintQueryContext *ctx) override;
|
MemgraphCypher::ConstraintQueryContext *ctx) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitAuthQuery(MemgraphCypher::AuthQueryContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return DumpQuery*
|
* @return DumpQuery*
|
||||||
*/
|
*/
|
||||||
@@ -219,28 +214,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
|
|||||||
*/
|
*/
|
||||||
antlrcpp::Any visitCallProcedure(MemgraphCypher::CallProcedureContext *ctx) override;
|
antlrcpp::Any visitCallProcedure(MemgraphCypher::CallProcedureContext *ctx) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return std::string
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitUserOrRoleName(
|
|
||||||
MemgraphCypher::UserOrRoleNameContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitCreateRole(
|
|
||||||
MemgraphCypher::CreateRoleContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitDropRole(MemgraphCypher::DropRoleContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitShowRoles(MemgraphCypher::ShowRolesContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return IndexQuery*
|
* @return IndexQuery*
|
||||||
*/
|
*/
|
||||||
@@ -252,79 +225,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
|
|||||||
*/
|
*/
|
||||||
antlrcpp::Any visitDropIndex(MemgraphCypher::DropIndexContext *ctx) override;
|
antlrcpp::Any visitDropIndex(MemgraphCypher::DropIndexContext *ctx) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitCreateUser(
|
|
||||||
MemgraphCypher::CreateUserContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitSetPassword(
|
|
||||||
MemgraphCypher::SetPasswordContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitDropUser(MemgraphCypher::DropUserContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitShowUsers(MemgraphCypher::ShowUsersContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitSetRole(MemgraphCypher::SetRoleContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitClearRole(MemgraphCypher::ClearRoleContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitGrantPrivilege(
|
|
||||||
MemgraphCypher::GrantPrivilegeContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitDenyPrivilege(
|
|
||||||
MemgraphCypher::DenyPrivilegeContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitRevokePrivilege(
|
|
||||||
MemgraphCypher::RevokePrivilegeContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery::Privilege
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitPrivilege(MemgraphCypher::PrivilegeContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitShowPrivileges(
|
|
||||||
MemgraphCypher::ShowPrivilegesContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitShowRoleForUser(
|
|
||||||
MemgraphCypher::ShowRoleForUserContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return AuthQuery*
|
|
||||||
*/
|
|
||||||
antlrcpp::Any visitShowUsersForRole(
|
|
||||||
MemgraphCypher::ShowUsersForRoleContext *ctx) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Return*
|
* @return Return*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -46,9 +46,7 @@ indexInfo : INDEX INFO ;
|
|||||||
|
|
||||||
constraintInfo : CONSTRAINT INFO ;
|
constraintInfo : CONSTRAINT INFO ;
|
||||||
|
|
||||||
raftInfo : RAFT INFO ;
|
infoQuery : SHOW ( storageInfo | indexInfo | constraintInfo ) ;
|
||||||
|
|
||||||
infoQuery : SHOW ( storageInfo | indexInfo | constraintInfo | raftInfo ) ;
|
|
||||||
|
|
||||||
explainQuery : EXPLAIN cypherQuery ;
|
explainQuery : EXPLAIN cypherQuery ;
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ OPTIONAL : O P T I O N A L ;
|
|||||||
OR : O R ;
|
OR : O R ;
|
||||||
ORDER : O R D E R ;
|
ORDER : O R D E R ;
|
||||||
PROFILE : P R O F I L E ;
|
PROFILE : P R O F I L E ;
|
||||||
RAFT : R A F T ;
|
|
||||||
REDUCE : R E D U C E ;
|
REDUCE : R E D U C E ;
|
||||||
REMOVE : R E M O V E ;
|
REMOVE : R E M O V E ;
|
||||||
RETURN : R E T U R N ;
|
RETURN : R E T U R N ;
|
||||||
|
|||||||
@@ -7,26 +7,8 @@ options { tokenVocab=MemgraphCypherLexer; }
|
|||||||
import Cypher ;
|
import Cypher ;
|
||||||
|
|
||||||
memgraphCypherKeyword : cypherKeyword
|
memgraphCypherKeyword : cypherKeyword
|
||||||
| ALTER
|
|
||||||
| AUTH
|
|
||||||
| CLEAR
|
|
||||||
| DATABASE
|
| DATABASE
|
||||||
| DENY
|
|
||||||
| DROP
|
|
||||||
| DUMP
|
| DUMP
|
||||||
| FOR
|
|
||||||
| FROM
|
|
||||||
| GRANT
|
|
||||||
| IDENTIFIED
|
|
||||||
| PASSWORD
|
|
||||||
| PRIVILEGES
|
|
||||||
| REVOKE
|
|
||||||
| ROLE
|
|
||||||
| ROLES
|
|
||||||
| STATS
|
|
||||||
| TO
|
|
||||||
| USER
|
|
||||||
| USERS
|
|
||||||
;
|
;
|
||||||
|
|
||||||
symbolicName : UnescapedSymbolicName
|
symbolicName : UnescapedSymbolicName
|
||||||
@@ -40,63 +22,7 @@ query : cypherQuery
|
|||||||
| profileQuery
|
| profileQuery
|
||||||
| infoQuery
|
| infoQuery
|
||||||
| constraintQuery
|
| constraintQuery
|
||||||
| authQuery
|
|
||||||
| dumpQuery
|
| dumpQuery
|
||||||
;
|
;
|
||||||
|
|
||||||
authQuery : createRole
|
|
||||||
| dropRole
|
|
||||||
| showRoles
|
|
||||||
| createUser
|
|
||||||
| setPassword
|
|
||||||
| dropUser
|
|
||||||
| showUsers
|
|
||||||
| setRole
|
|
||||||
| clearRole
|
|
||||||
| grantPrivilege
|
|
||||||
| denyPrivilege
|
|
||||||
| revokePrivilege
|
|
||||||
| showPrivileges
|
|
||||||
| showRoleForUser
|
|
||||||
| showUsersForRole
|
|
||||||
;
|
|
||||||
|
|
||||||
userOrRoleName : symbolicName ;
|
|
||||||
|
|
||||||
createRole : CREATE ROLE role=userOrRoleName ;
|
|
||||||
|
|
||||||
dropRole : DROP ROLE role=userOrRoleName ;
|
|
||||||
|
|
||||||
showRoles : SHOW ROLES ;
|
|
||||||
|
|
||||||
createUser : CREATE USER user=userOrRoleName
|
|
||||||
( IDENTIFIED BY password=literal )? ;
|
|
||||||
|
|
||||||
setPassword : SET PASSWORD FOR user=userOrRoleName TO password=literal;
|
|
||||||
|
|
||||||
dropUser : DROP USER user=userOrRoleName ;
|
|
||||||
|
|
||||||
showUsers : SHOW USERS ;
|
|
||||||
|
|
||||||
setRole : SET ROLE FOR user=userOrRoleName TO role=userOrRoleName;
|
|
||||||
|
|
||||||
clearRole : CLEAR ROLE FOR user=userOrRoleName ;
|
|
||||||
|
|
||||||
grantPrivilege : GRANT ( ALL PRIVILEGES | privileges=privilegeList ) TO userOrRole=userOrRoleName ;
|
|
||||||
|
|
||||||
denyPrivilege : DENY ( ALL PRIVILEGES | privileges=privilegeList ) TO userOrRole=userOrRoleName ;
|
|
||||||
|
|
||||||
revokePrivilege : REVOKE ( ALL PRIVILEGES | privileges=privilegeList ) FROM userOrRole=userOrRoleName ;
|
|
||||||
|
|
||||||
privilege : CREATE | DELETE | MATCH | MERGE | SET
|
|
||||||
| REMOVE | INDEX | STATS | AUTH | CONSTRAINT | DUMP ;
|
|
||||||
|
|
||||||
privilegeList : privilege ( ',' privilege )* ;
|
|
||||||
|
|
||||||
showPrivileges : SHOW PRIVILEGES FOR userOrRole=userOrRoleName ;
|
|
||||||
|
|
||||||
showRoleForUser : SHOW ROLE FOR user=userOrRoleName ;
|
|
||||||
|
|
||||||
showUsersForRole : SHOW USERS FOR role=userOrRoleName ;
|
|
||||||
|
|
||||||
dumpQuery: DUMP DATABASE ;
|
dumpQuery: DUMP DATABASE ;
|
||||||
|
|||||||
@@ -10,24 +10,5 @@ lexer grammar MemgraphCypherLexer ;
|
|||||||
|
|
||||||
import CypherLexer ;
|
import CypherLexer ;
|
||||||
|
|
||||||
ALTER : A L T E R ;
|
|
||||||
AUTH : A U T H ;
|
|
||||||
CLEAR : C L E A R ;
|
|
||||||
DATABASE : D A T A B A S E ;
|
DATABASE : D A T A B A S E ;
|
||||||
DENY : D E N Y ;
|
|
||||||
DROP : D R O P ;
|
|
||||||
DUMP : D U M P ;
|
DUMP : D U M P ;
|
||||||
FOR : F O R ;
|
|
||||||
FROM : F R O M ;
|
|
||||||
GRANT : G R A N T ;
|
|
||||||
GRANTS : G R A N T S ;
|
|
||||||
IDENTIFIED : I D E N T I F I E D ;
|
|
||||||
PASSWORD : P A S S W O R D ;
|
|
||||||
PRIVILEGES : P R I V I L E G E S ;
|
|
||||||
REVOKE : R E V O K E ;
|
|
||||||
ROLE : R O L E ;
|
|
||||||
ROLES : R O L E S ;
|
|
||||||
STATS : S T A T S ;
|
|
||||||
TO : T O ;
|
|
||||||
USER : U S E R ;
|
|
||||||
USERS : U S E R S ;
|
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
|
||||||
#include "auth/auth.hpp"
|
|
||||||
#include "glue/auth.hpp"
|
|
||||||
#include "glue/communication.hpp"
|
#include "glue/communication.hpp"
|
||||||
#ifndef MG_SINGLE_NODE_HA
|
#ifndef MG_SINGLE_NODE_HA
|
||||||
#include "query/dump.hpp"
|
#include "query/dump.hpp"
|
||||||
@@ -13,15 +11,11 @@
|
|||||||
#include "query/exceptions.hpp"
|
#include "query/exceptions.hpp"
|
||||||
#include "query/frontend/ast/cypher_main_visitor.hpp"
|
#include "query/frontend/ast/cypher_main_visitor.hpp"
|
||||||
#include "query/frontend/opencypher/parser.hpp"
|
#include "query/frontend/opencypher/parser.hpp"
|
||||||
#include "query/frontend/semantic/required_privileges.hpp"
|
|
||||||
#include "query/frontend/semantic/symbol_generator.hpp"
|
#include "query/frontend/semantic/symbol_generator.hpp"
|
||||||
#include "query/interpret/eval.hpp"
|
#include "query/interpret/eval.hpp"
|
||||||
#include "query/plan/planner.hpp"
|
#include "query/plan/planner.hpp"
|
||||||
#include "query/plan/profile.hpp"
|
#include "query/plan/profile.hpp"
|
||||||
#include "query/plan/vertex_count_cache.hpp"
|
#include "query/plan/vertex_count_cache.hpp"
|
||||||
#ifdef MG_SINGLE_NODE_HA
|
|
||||||
#include "raft/exceptions.hpp"
|
|
||||||
#endif
|
|
||||||
#include "utils/exceptions.hpp"
|
#include "utils/exceptions.hpp"
|
||||||
#include "utils/flag_validation.hpp"
|
#include "utils/flag_validation.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
@@ -45,7 +39,6 @@ struct ParsedQuery {
|
|||||||
frontend::StrippedQuery stripped_query;
|
frontend::StrippedQuery stripped_query;
|
||||||
AstStorage ast_storage;
|
AstStorage ast_storage;
|
||||||
Query *query;
|
Query *query;
|
||||||
std::vector<AuthQuery::Privilege> required_privileges;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ParsedQuery ParseQuery(const std::string &query_string,
|
ParsedQuery ParseQuery(const std::string &query_string,
|
||||||
@@ -105,8 +98,7 @@ ParsedQuery ParseQuery(const std::string &query_string,
|
|||||||
|
|
||||||
visitor.visit(parser->tree());
|
visitor.visit(parser->tree());
|
||||||
|
|
||||||
CachedQuery cached_query{std::move(ast_storage), visitor.query(),
|
CachedQuery cached_query{std::move(ast_storage), visitor.query()};
|
||||||
query::GetRequiredPrivileges(visitor.query())};
|
|
||||||
|
|
||||||
it = accessor.insert({hash, std::move(cached_query)}).first;
|
it = accessor.insert({hash, std::move(cached_query)}).first;
|
||||||
}
|
}
|
||||||
@@ -124,8 +116,7 @@ ParsedQuery ParseQuery(const std::string &query_string,
|
|||||||
std::move(parameters),
|
std::move(parameters),
|
||||||
std::move(stripped_query),
|
std::move(stripped_query),
|
||||||
std::move(ast_storage),
|
std::move(ast_storage),
|
||||||
query,
|
query};
|
||||||
it->second.required_privileges};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SingleNodeLogicalPlan final : public LogicalPlan {
|
class SingleNodeLogicalPlan final : public LogicalPlan {
|
||||||
@@ -164,302 +155,6 @@ TypedValue EvaluateOptionalExpression(Expression *expression,
|
|||||||
return expression ? expression->Accept(*eval) : TypedValue();
|
return expression ? expression->Accept(*eval) : TypedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
Callback HandleAuthQuery(AuthQuery *auth_query, auth::Auth *auth,
|
|
||||||
const Parameters ¶meters,
|
|
||||||
DbAccessor *db_accessor) {
|
|
||||||
// Empty frame for evaluation of password expression. This is OK since
|
|
||||||
// password should be either null or string literal and it's evaluation
|
|
||||||
// should not depend on frame.
|
|
||||||
Frame frame(0);
|
|
||||||
SymbolTable symbol_table;
|
|
||||||
EvaluationContext evaluation_context;
|
|
||||||
// TODO: MemoryResource for EvaluationContext, it should probably be passed as
|
|
||||||
// the argument to Callback.
|
|
||||||
evaluation_context.timestamp =
|
|
||||||
std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
||||||
std::chrono::system_clock::now().time_since_epoch())
|
|
||||||
.count();
|
|
||||||
evaluation_context.parameters = parameters;
|
|
||||||
ExpressionEvaluator evaluator(&frame, symbol_table, evaluation_context,
|
|
||||||
db_accessor, storage::View::OLD);
|
|
||||||
|
|
||||||
AuthQuery::Action action = auth_query->action_;
|
|
||||||
std::string username = auth_query->user_;
|
|
||||||
std::string rolename = auth_query->role_;
|
|
||||||
std::string user_or_role = auth_query->user_or_role_;
|
|
||||||
std::vector<AuthQuery::Privilege> privileges = auth_query->privileges_;
|
|
||||||
auto password = EvaluateOptionalExpression(auth_query->password_, &evaluator);
|
|
||||||
|
|
||||||
Callback callback;
|
|
||||||
|
|
||||||
switch (auth_query->action_) {
|
|
||||||
case AuthQuery::Action::CREATE_USER:
|
|
||||||
callback.fn = [auth, username, password] {
|
|
||||||
CHECK(password.IsString() || password.IsNull());
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
auto user = auth->AddUser(
|
|
||||||
username,
|
|
||||||
password.IsString()
|
|
||||||
? std::make_optional(std::string(password.ValueString()))
|
|
||||||
: std::nullopt);
|
|
||||||
if (!user) {
|
|
||||||
throw QueryRuntimeException("User or role '{}' already exists.",
|
|
||||||
username);
|
|
||||||
}
|
|
||||||
return std::vector<std::vector<TypedValue>>();
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::DROP_USER:
|
|
||||||
callback.fn = [auth, username] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
auto user = auth->GetUser(username);
|
|
||||||
if (!user) {
|
|
||||||
throw QueryRuntimeException("User '{}' doesn't exist.", username);
|
|
||||||
}
|
|
||||||
if (!auth->RemoveUser(username)) {
|
|
||||||
throw QueryRuntimeException("Couldn't remove user '{}'.", username);
|
|
||||||
}
|
|
||||||
return std::vector<std::vector<TypedValue>>();
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::SET_PASSWORD:
|
|
||||||
callback.fn = [auth, username, password] {
|
|
||||||
CHECK(password.IsString() || password.IsNull());
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
auto user = auth->GetUser(username);
|
|
||||||
if (!user) {
|
|
||||||
throw QueryRuntimeException("User '{}' doesn't exist.", username);
|
|
||||||
}
|
|
||||||
user->UpdatePassword(
|
|
||||||
password.IsString()
|
|
||||||
? std::make_optional(std::string(password.ValueString()))
|
|
||||||
: std::nullopt);
|
|
||||||
auth->SaveUser(*user);
|
|
||||||
return std::vector<std::vector<TypedValue>>();
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::CREATE_ROLE:
|
|
||||||
callback.fn = [auth, rolename] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
auto role = auth->AddRole(rolename);
|
|
||||||
if (!role) {
|
|
||||||
throw QueryRuntimeException("User or role '{}' already exists.",
|
|
||||||
rolename);
|
|
||||||
}
|
|
||||||
return std::vector<std::vector<TypedValue>>();
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::DROP_ROLE:
|
|
||||||
callback.fn = [auth, rolename] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
auto role = auth->GetRole(rolename);
|
|
||||||
if (!role) {
|
|
||||||
throw QueryRuntimeException("Role '{}' doesn't exist.", rolename);
|
|
||||||
}
|
|
||||||
if (!auth->RemoveRole(rolename)) {
|
|
||||||
throw QueryRuntimeException("Couldn't remove role '{}'.", rolename);
|
|
||||||
}
|
|
||||||
return std::vector<std::vector<TypedValue>>();
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::SHOW_USERS:
|
|
||||||
callback.header = {"user"};
|
|
||||||
callback.fn = [auth] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
std::vector<std::vector<TypedValue>> users;
|
|
||||||
for (const auto &user : auth->AllUsers()) {
|
|
||||||
users.push_back({TypedValue(user.username())});
|
|
||||||
}
|
|
||||||
return users;
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::SHOW_ROLES:
|
|
||||||
callback.header = {"role"};
|
|
||||||
callback.fn = [auth] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
std::vector<std::vector<TypedValue>> roles;
|
|
||||||
for (const auto &role : auth->AllRoles()) {
|
|
||||||
roles.push_back({TypedValue(role.rolename())});
|
|
||||||
}
|
|
||||||
return roles;
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::SET_ROLE:
|
|
||||||
callback.fn = [auth, username, rolename] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
auto user = auth->GetUser(username);
|
|
||||||
if (!user) {
|
|
||||||
throw QueryRuntimeException("User '{}' doesn't exist .", username);
|
|
||||||
}
|
|
||||||
auto role = auth->GetRole(rolename);
|
|
||||||
if (!role) {
|
|
||||||
throw QueryRuntimeException("Role '{}' doesn't exist .", rolename);
|
|
||||||
}
|
|
||||||
if (user->role()) {
|
|
||||||
throw QueryRuntimeException(
|
|
||||||
"User '{}' is already a member of role '{}'.", username,
|
|
||||||
user->role()->rolename());
|
|
||||||
}
|
|
||||||
user->SetRole(*role);
|
|
||||||
auth->SaveUser(*user);
|
|
||||||
return std::vector<std::vector<TypedValue>>();
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::CLEAR_ROLE:
|
|
||||||
callback.fn = [auth, username] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
auto user = auth->GetUser(username);
|
|
||||||
if (!user) {
|
|
||||||
throw QueryRuntimeException("User '{}' doesn't exist .", username);
|
|
||||||
}
|
|
||||||
user->ClearRole();
|
|
||||||
auth->SaveUser(*user);
|
|
||||||
return std::vector<std::vector<TypedValue>>();
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::GRANT_PRIVILEGE:
|
|
||||||
case AuthQuery::Action::DENY_PRIVILEGE:
|
|
||||||
case AuthQuery::Action::REVOKE_PRIVILEGE: {
|
|
||||||
callback.fn = [auth, user_or_role, action, privileges] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
std::vector<auth::Permission> permissions;
|
|
||||||
for (const auto &privilege : privileges) {
|
|
||||||
permissions.push_back(glue::PrivilegeToPermission(privilege));
|
|
||||||
}
|
|
||||||
auto user = auth->GetUser(user_or_role);
|
|
||||||
auto role = auth->GetRole(user_or_role);
|
|
||||||
if (!user && !role) {
|
|
||||||
throw QueryRuntimeException("User or role '{}' doesn't exist.",
|
|
||||||
user_or_role);
|
|
||||||
}
|
|
||||||
if (user) {
|
|
||||||
for (const auto &permission : permissions) {
|
|
||||||
// TODO (mferencevic): should we first check that the privilege
|
|
||||||
// is granted/denied/revoked before unconditionally
|
|
||||||
// granting/denying/revoking it?
|
|
||||||
if (action == AuthQuery::Action::GRANT_PRIVILEGE) {
|
|
||||||
user->permissions().Grant(permission);
|
|
||||||
} else if (action == AuthQuery::Action::DENY_PRIVILEGE) {
|
|
||||||
user->permissions().Deny(permission);
|
|
||||||
} else {
|
|
||||||
user->permissions().Revoke(permission);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auth->SaveUser(*user);
|
|
||||||
} else {
|
|
||||||
for (const auto &permission : permissions) {
|
|
||||||
// TODO (mferencevic): should we first check that the privilege
|
|
||||||
// is granted/denied/revoked before unconditionally
|
|
||||||
// granting/denying/revoking it?
|
|
||||||
if (action == AuthQuery::Action::GRANT_PRIVILEGE) {
|
|
||||||
role->permissions().Grant(permission);
|
|
||||||
} else if (action == AuthQuery::Action::DENY_PRIVILEGE) {
|
|
||||||
role->permissions().Deny(permission);
|
|
||||||
} else {
|
|
||||||
role->permissions().Revoke(permission);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auth->SaveRole(*role);
|
|
||||||
}
|
|
||||||
return std::vector<std::vector<TypedValue>>();
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
}
|
|
||||||
case AuthQuery::Action::SHOW_PRIVILEGES:
|
|
||||||
callback.header = {"privilege", "effective", "description"};
|
|
||||||
callback.fn = [auth, user_or_role] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
std::vector<std::vector<TypedValue>> grants;
|
|
||||||
auto user = auth->GetUser(user_or_role);
|
|
||||||
auto role = auth->GetRole(user_or_role);
|
|
||||||
if (!user && !role) {
|
|
||||||
throw QueryRuntimeException("User or role '{}' doesn't exist.",
|
|
||||||
user_or_role);
|
|
||||||
}
|
|
||||||
if (user) {
|
|
||||||
const auto &permissions = user->GetPermissions();
|
|
||||||
for (const auto &privilege : kPrivilegesAll) {
|
|
||||||
auto permission = glue::PrivilegeToPermission(privilege);
|
|
||||||
auto effective = permissions.Has(permission);
|
|
||||||
if (permissions.Has(permission) != auth::PermissionLevel::NEUTRAL) {
|
|
||||||
std::vector<std::string> description;
|
|
||||||
auto user_level = user->permissions().Has(permission);
|
|
||||||
if (user_level == auth::PermissionLevel::GRANT) {
|
|
||||||
description.push_back("GRANTED TO USER");
|
|
||||||
} else if (user_level == auth::PermissionLevel::DENY) {
|
|
||||||
description.push_back("DENIED TO USER");
|
|
||||||
}
|
|
||||||
if (user->role()) {
|
|
||||||
auto role_level = user->role()->permissions().Has(permission);
|
|
||||||
if (role_level == auth::PermissionLevel::GRANT) {
|
|
||||||
description.push_back("GRANTED TO ROLE");
|
|
||||||
} else if (role_level == auth::PermissionLevel::DENY) {
|
|
||||||
description.push_back("DENIED TO ROLE");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
grants.push_back(
|
|
||||||
{TypedValue(auth::PermissionToString(permission)),
|
|
||||||
TypedValue(auth::PermissionLevelToString(effective)),
|
|
||||||
TypedValue(utils::Join(description, ", "))});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const auto &permissions = role->permissions();
|
|
||||||
for (const auto &privilege : kPrivilegesAll) {
|
|
||||||
auto permission = glue::PrivilegeToPermission(privilege);
|
|
||||||
auto effective = permissions.Has(permission);
|
|
||||||
if (effective != auth::PermissionLevel::NEUTRAL) {
|
|
||||||
std::string description;
|
|
||||||
if (effective == auth::PermissionLevel::GRANT) {
|
|
||||||
description = "GRANTED TO ROLE";
|
|
||||||
} else if (effective == auth::PermissionLevel::DENY) {
|
|
||||||
description = "DENIED TO ROLE";
|
|
||||||
}
|
|
||||||
grants.push_back(
|
|
||||||
{TypedValue(auth::PermissionToString(permission)),
|
|
||||||
TypedValue(auth::PermissionLevelToString(effective)),
|
|
||||||
TypedValue(description)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return grants;
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::SHOW_ROLE_FOR_USER:
|
|
||||||
callback.header = {"role"};
|
|
||||||
callback.fn = [auth, username] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
auto user = auth->GetUser(username);
|
|
||||||
if (!user) {
|
|
||||||
throw QueryRuntimeException("User '{}' doesn't exist .", username);
|
|
||||||
}
|
|
||||||
return std::vector<std::vector<TypedValue>>{std::vector<TypedValue>{
|
|
||||||
TypedValue(user->role() ? user->role()->rolename() : "null")}};
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
case AuthQuery::Action::SHOW_USERS_FOR_ROLE:
|
|
||||||
callback.header = {"users"};
|
|
||||||
callback.fn = [auth, rolename] {
|
|
||||||
std::lock_guard<std::mutex> lock(auth->WithLock());
|
|
||||||
auto role = auth->GetRole(rolename);
|
|
||||||
if (!role) {
|
|
||||||
throw QueryRuntimeException("Role '{}' doesn't exist.", rolename);
|
|
||||||
}
|
|
||||||
std::vector<std::vector<TypedValue>> users;
|
|
||||||
for (const auto &user : auth->AllUsersForRole(rolename)) {
|
|
||||||
users.emplace_back(
|
|
||||||
std::vector<TypedValue>{TypedValue(user.username())});
|
|
||||||
}
|
|
||||||
return users;
|
|
||||||
};
|
|
||||||
return callback;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Interpreter::Interpreter(InterpreterContext *interpreter_context)
|
Interpreter::Interpreter(InterpreterContext *interpreter_context)
|
||||||
: interpreter_context_(interpreter_context) {
|
: interpreter_context_(interpreter_context) {
|
||||||
CHECK(interpreter_context_) << "Interpreter context must not be NULL";
|
CHECK(interpreter_context_) << "Interpreter context must not be NULL";
|
||||||
@@ -630,7 +325,7 @@ PreparedQuery Interpreter::PrepareTransactionQuery(
|
|||||||
LOG(FATAL) << "Should not get here -- unknown transaction query!";
|
LOG(FATAL) << "Should not get here -- unknown transaction query!";
|
||||||
}
|
}
|
||||||
|
|
||||||
return {{}, {}, [handler = std::move(handler)](AnyStream *) {
|
return {{}, [handler = std::move(handler)](AnyStream *) {
|
||||||
handler();
|
handler();
|
||||||
return QueryHandlerResult::NOTHING;
|
return QueryHandlerResult::NOTHING;
|
||||||
}};
|
}};
|
||||||
@@ -663,7 +358,7 @@ PreparedQuery PrepareCypherQuery(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return PreparedQuery{
|
return PreparedQuery{
|
||||||
std::move(header), std::move(parsed_query.required_privileges),
|
std::move(header),
|
||||||
[plan = std::move(plan), parameters = std::move(parsed_query.parameters),
|
[plan = std::move(plan), parameters = std::move(parsed_query.parameters),
|
||||||
output_symbols = std::move(output_symbols), summary, dba,
|
output_symbols = std::move(output_symbols), summary, dba,
|
||||||
interpreter_context, execution_memory](AnyStream *stream) {
|
interpreter_context, execution_memory](AnyStream *stream) {
|
||||||
@@ -717,7 +412,6 @@ PreparedQuery PrepareExplainQuery(
|
|||||||
|
|
||||||
return PreparedQuery{
|
return PreparedQuery{
|
||||||
{"QUERY PLAN"},
|
{"QUERY PLAN"},
|
||||||
std::move(parsed_query.required_privileges),
|
|
||||||
[rows = std::move(printed_plan_rows)](AnyStream *stream) {
|
[rows = std::move(printed_plan_rows)](AnyStream *stream) {
|
||||||
for (const auto &row : rows) {
|
for (const auto &row : rows) {
|
||||||
stream->Result(row);
|
stream->Result(row);
|
||||||
@@ -769,7 +463,6 @@ PreparedQuery PrepareProfileQuery(
|
|||||||
|
|
||||||
return PreparedQuery{
|
return PreparedQuery{
|
||||||
{"OPERATOR", "ACTUAL HITS", "RELATIVE TIME", "ABSOLUTE TIME"},
|
{"OPERATOR", "ACTUAL HITS", "RELATIVE TIME", "ABSOLUTE TIME"},
|
||||||
std::move(parsed_query.required_privileges),
|
|
||||||
[plan = std::move(cypher_query_plan),
|
[plan = std::move(cypher_query_plan),
|
||||||
parameters = std::move(parsed_inner_query.parameters), summary, dba,
|
parameters = std::move(parsed_inner_query.parameters), summary, dba,
|
||||||
interpreter_context, execution_memory](AnyStream *stream) {
|
interpreter_context, execution_memory](AnyStream *stream) {
|
||||||
@@ -797,7 +490,6 @@ PreparedQuery PrepareDumpQuery(
|
|||||||
#ifndef MG_SINGLE_NODE_HA
|
#ifndef MG_SINGLE_NODE_HA
|
||||||
return PreparedQuery{
|
return PreparedQuery{
|
||||||
{"QUERY"},
|
{"QUERY"},
|
||||||
std::move(parsed_query.required_privileges),
|
|
||||||
[interpreter_context](AnyStream *stream) {
|
[interpreter_context](AnyStream *stream) {
|
||||||
auto dba = interpreter_context->db->Access();
|
auto dba = interpreter_context->db->Access();
|
||||||
query::DbAccessor query_dba{&dba};
|
query::DbAccessor query_dba{&dba};
|
||||||
@@ -913,7 +605,6 @@ PreparedQuery PrepareIndexQuery(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return PreparedQuery{{},
|
return PreparedQuery{{},
|
||||||
std::move(parsed_query.required_privileges),
|
|
||||||
[handler = std::move(handler)](AnyStream *stream) {
|
[handler = std::move(handler)](AnyStream *stream) {
|
||||||
handler();
|
handler();
|
||||||
#ifdef MG_SINGLE_NODE_V2
|
#ifdef MG_SINGLE_NODE_V2
|
||||||
@@ -924,52 +615,6 @@ PreparedQuery PrepareIndexQuery(
|
|||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedQuery PrepareAuthQuery(
|
|
||||||
ParsedQuery parsed_query, bool in_explicit_transaction,
|
|
||||||
std::map<std::string, TypedValue> *summary,
|
|
||||||
InterpreterContext *interpreter_context, DbAccessor *dba,
|
|
||||||
utils::MonotonicBufferResource *execution_memory) {
|
|
||||||
#ifdef MG_SINGLE_NODE_HA
|
|
||||||
throw utils::NotYetImplemented(
|
|
||||||
"Managing user privileges is not yet supported in Memgraph HA "
|
|
||||||
"instance.");
|
|
||||||
#else
|
|
||||||
if (in_explicit_transaction) {
|
|
||||||
throw UserModificationInMulticommandTxException();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *auth_query = utils::Downcast<AuthQuery>(parsed_query.query);
|
|
||||||
|
|
||||||
auto callback = HandleAuthQuery(auth_query, interpreter_context->auth,
|
|
||||||
parsed_query.parameters, dba);
|
|
||||||
|
|
||||||
SymbolTable symbol_table;
|
|
||||||
std::vector<Symbol> output_symbols;
|
|
||||||
for (const auto &column : callback.header) {
|
|
||||||
output_symbols.emplace_back(symbol_table.CreateSymbol(column, "false"));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto plan =
|
|
||||||
std::make_shared<CachedPlan>(std::make_unique<SingleNodeLogicalPlan>(
|
|
||||||
std::make_unique<plan::OutputTable>(
|
|
||||||
output_symbols,
|
|
||||||
[fn = callback.fn](Frame *, ExecutionContext *) { return fn(); }),
|
|
||||||
0.0, AstStorage{}, symbol_table));
|
|
||||||
|
|
||||||
return PreparedQuery{
|
|
||||||
callback.header, std::move(parsed_query.required_privileges),
|
|
||||||
[callback = std::move(callback), plan = std::move(plan),
|
|
||||||
parameters = std::move(parsed_query.parameters),
|
|
||||||
output_symbols = std::move(output_symbols), summary, dba,
|
|
||||||
interpreter_context, execution_memory](AnyStream *stream) {
|
|
||||||
PullAllPlan(stream, *plan, parameters, output_symbols, false, summary,
|
|
||||||
dba, interpreter_context, execution_memory);
|
|
||||||
return callback.should_abort_query ? QueryHandlerResult::ABORT
|
|
||||||
: QueryHandlerResult::COMMIT;
|
|
||||||
}};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
PreparedQuery PrepareInfoQuery(
|
PreparedQuery PrepareInfoQuery(
|
||||||
ParsedQuery parsed_query, std::map<std::string, TypedValue> *summary,
|
ParsedQuery parsed_query, std::map<std::string, TypedValue> *summary,
|
||||||
InterpreterContext *interpreter_context,
|
InterpreterContext *interpreter_context,
|
||||||
@@ -1102,26 +747,9 @@ PreparedQuery PrepareInfoQuery(
|
|||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case InfoQuery::InfoType::RAFT:
|
|
||||||
#if defined(MG_SINGLE_NODE_HA)
|
|
||||||
header = {"info", "value"};
|
|
||||||
handler = [dba] {
|
|
||||||
std::vector<std::vector<TypedValue>> results(
|
|
||||||
{{TypedValue("is_leader"), TypedValue(dba->raft()->IsLeader())},
|
|
||||||
{TypedValue("term_id"),
|
|
||||||
TypedValue(static_cast<int64_t>(dba->raft()->TermId()))}});
|
|
||||||
// It is critical to abort this query because it can be executed on
|
|
||||||
// machines that aren't the leader.
|
|
||||||
return std::pair{results, QueryHandlerResult::ABORT};
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
throw utils::NotYetImplemented("raft info");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PreparedQuery{std::move(header),
|
return PreparedQuery{std::move(header),
|
||||||
std::move(parsed_query.required_privileges),
|
|
||||||
[handler = std::move(handler)](AnyStream *stream) {
|
[handler = std::move(handler)](AnyStream *stream) {
|
||||||
auto [results, action] = handler();
|
auto [results, action] = handler();
|
||||||
|
|
||||||
@@ -1246,14 +874,13 @@ PreparedQuery PrepareConstraintQuery(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return PreparedQuery{{},
|
return PreparedQuery{{},
|
||||||
std::move(parsed_query.required_privileges),
|
|
||||||
[handler = std::move(handler)](AnyStream *stream) {
|
[handler = std::move(handler)](AnyStream *stream) {
|
||||||
handler();
|
handler();
|
||||||
return QueryHandlerResult::COMMIT;
|
return QueryHandlerResult::COMMIT;
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::vector<std::string>, std::vector<query::AuthQuery::Privilege>>
|
std::vector<std::string>
|
||||||
Interpreter::Prepare(const std::string &query_string,
|
Interpreter::Prepare(const std::string &query_string,
|
||||||
const std::map<std::string, PropertyValue> ¶ms) {
|
const std::map<std::string, PropertyValue> ¶ms) {
|
||||||
// Clear the last prepared query.
|
// Clear the last prepared query.
|
||||||
@@ -1266,7 +893,7 @@ Interpreter::Prepare(const std::string &query_string,
|
|||||||
if (query_upper == "BEGIN" || query_upper == "COMMIT" ||
|
if (query_upper == "BEGIN" || query_upper == "COMMIT" ||
|
||||||
query_upper == "ROLLBACK") {
|
query_upper == "ROLLBACK") {
|
||||||
prepared_query_ = PrepareTransactionQuery(query_upper);
|
prepared_query_ = PrepareTransactionQuery(query_upper);
|
||||||
return {prepared_query_->header, prepared_query_->privileges};
|
return prepared_query_->header;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All queries other than transaction control queries advance the command in
|
// All queries other than transaction control queries advance the command in
|
||||||
@@ -1318,17 +945,6 @@ Interpreter::Prepare(const std::string &query_string,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MG_SINGLE_NODE_HA
|
|
||||||
{
|
|
||||||
InfoQuery *info_query = nullptr;
|
|
||||||
if (!execution_db_accessor_->raft()->IsLeader() &&
|
|
||||||
(!(info_query = utils::Downcast<InfoQuery>(parsed_query.query)) ||
|
|
||||||
info_query->info_type_ != InfoQuery::InfoType::RAFT)) {
|
|
||||||
throw raft::CantExecuteQueries();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
utils::Timer planning_timer;
|
utils::Timer planning_timer;
|
||||||
PreparedQuery prepared_query;
|
PreparedQuery prepared_query;
|
||||||
|
|
||||||
@@ -1357,10 +973,6 @@ Interpreter::Prepare(const std::string &query_string,
|
|||||||
prepared_query = PrepareIndexQuery(
|
prepared_query = PrepareIndexQuery(
|
||||||
std::move(parsed_query), in_explicit_transaction_, &summary_,
|
std::move(parsed_query), in_explicit_transaction_, &summary_,
|
||||||
interpreter_context_, dba, &execution_memory_);
|
interpreter_context_, dba, &execution_memory_);
|
||||||
} else if (utils::Downcast<AuthQuery>(parsed_query.query)) {
|
|
||||||
prepared_query = PrepareAuthQuery(
|
|
||||||
std::move(parsed_query), in_explicit_transaction_, &summary_,
|
|
||||||
interpreter_context_, &*execution_db_accessor_, &execution_memory_);
|
|
||||||
} else if (utils::Downcast<InfoQuery>(parsed_query.query)) {
|
} else if (utils::Downcast<InfoQuery>(parsed_query.query)) {
|
||||||
#ifdef MG_SINGLE_NODE_V2
|
#ifdef MG_SINGLE_NODE_V2
|
||||||
prepared_query = PrepareInfoQuery(
|
prepared_query = PrepareInfoQuery(
|
||||||
@@ -1388,7 +1000,7 @@ Interpreter::Prepare(const std::string &query_string,
|
|||||||
summary_["planning_time"] = planning_timer.Elapsed().count();
|
summary_["planning_time"] = planning_timer.Elapsed().count();
|
||||||
prepared_query_ = std::move(prepared_query);
|
prepared_query_ = std::move(prepared_query);
|
||||||
|
|
||||||
return {prepared_query_->header, prepared_query_->privileges};
|
return prepared_query_->header;
|
||||||
} catch (const utils::BasicException &) {
|
} catch (const utils::BasicException &) {
|
||||||
AbortCommand();
|
AbortCommand();
|
||||||
throw;
|
throw;
|
||||||
|
|||||||
@@ -21,10 +21,6 @@
|
|||||||
DECLARE_bool(query_cost_planner);
|
DECLARE_bool(query_cost_planner);
|
||||||
DECLARE_int32(query_plan_cache_ttl);
|
DECLARE_int32(query_plan_cache_ttl);
|
||||||
|
|
||||||
namespace auth {
|
|
||||||
class Auth;
|
|
||||||
} // namespace auth
|
|
||||||
|
|
||||||
namespace query {
|
namespace query {
|
||||||
|
|
||||||
static constexpr size_t kExecutionMemoryBlockSize = 1U * 1024U * 1024U;
|
static constexpr size_t kExecutionMemoryBlockSize = 1U * 1024U * 1024U;
|
||||||
@@ -36,7 +32,6 @@ enum class QueryHandlerResult { COMMIT, ABORT, NOTHING };
|
|||||||
*/
|
*/
|
||||||
struct PreparedQuery {
|
struct PreparedQuery {
|
||||||
std::vector<std::string> header;
|
std::vector<std::string> header;
|
||||||
std::vector<AuthQuery::Privilege> privileges;
|
|
||||||
std::function<QueryHandlerResult(AnyStream *stream)> query_handler;
|
std::function<QueryHandlerResult(AnyStream *stream)> query_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,7 +69,6 @@ class CachedPlan {
|
|||||||
struct CachedQuery {
|
struct CachedQuery {
|
||||||
AstStorage ast_storage;
|
AstStorage ast_storage;
|
||||||
Query *query;
|
Query *query;
|
||||||
std::vector<AuthQuery::Privilege> required_privileges;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QueryCacheEntry {
|
struct QueryCacheEntry {
|
||||||
@@ -144,8 +138,6 @@ struct InterpreterContext {
|
|||||||
// The default execution timeout is 3 minutes.
|
// The default execution timeout is 3 minutes.
|
||||||
double execution_timeout_sec{180.0};
|
double execution_timeout_sec{180.0};
|
||||||
|
|
||||||
auth::Auth *auth{nullptr};
|
|
||||||
|
|
||||||
utils::SkipList<QueryCacheEntry> ast_cache;
|
utils::SkipList<QueryCacheEntry> ast_cache;
|
||||||
utils::SkipList<PlanCacheEntry> plan_cache;
|
utils::SkipList<PlanCacheEntry> plan_cache;
|
||||||
};
|
};
|
||||||
@@ -181,7 +173,7 @@ class Interpreter final {
|
|||||||
* leader and a query other than an Info Raft query was given
|
* leader and a query other than an Info Raft query was given
|
||||||
* @throw query::QueryException
|
* @throw query::QueryException
|
||||||
*/
|
*/
|
||||||
std::pair<std::vector<std::string>, std::vector<query::AuthQuery::Privilege>>
|
std::vector<std::string>
|
||||||
Prepare(const std::string &query,
|
Prepare(const std::string &query,
|
||||||
const std::map<std::string, PropertyValue> ¶ms);
|
const std::map<std::string, PropertyValue> ¶ms);
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,3 @@ add_subdirectory(property_based)
|
|||||||
|
|
||||||
# integration test binaries
|
# integration test binaries
|
||||||
add_subdirectory(integration)
|
add_subdirectory(integration)
|
||||||
|
|
||||||
# feature benchmark test binaries
|
|
||||||
add_subdirectory(feature_benchmark)
|
|
||||||
|
|||||||
@@ -31,22 +31,22 @@ add_benchmark(data_structures/concurrent/map_concurrent.cpp)
|
|||||||
target_link_libraries(${test_prefix}map_concurrent mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}map_concurrent mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(data_structures/ring_buffer.cpp)
|
add_benchmark(data_structures/ring_buffer.cpp)
|
||||||
target_link_libraries(${test_prefix}ring_buffer mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}ring_buffer mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(query/eval.cpp)
|
add_benchmark(query/eval.cpp)
|
||||||
target_link_libraries(${test_prefix}eval mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}eval mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(query/execution.cpp)
|
add_benchmark(query/execution.cpp)
|
||||||
target_link_libraries(${test_prefix}execution mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}execution mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(query/planner.cpp)
|
add_benchmark(query/planner.cpp)
|
||||||
target_link_libraries(${test_prefix}planner mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}planner mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(query/profile.cpp)
|
add_benchmark(query/profile.cpp)
|
||||||
target_link_libraries(${test_prefix}profile mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}profile mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(query/stripped.cpp)
|
add_benchmark(query/stripped.cpp)
|
||||||
target_link_libraries(${test_prefix}stripped mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}stripped mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(edge_storage.cpp)
|
add_benchmark(edge_storage.cpp)
|
||||||
target_link_libraries(${test_prefix}edge_storage mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}edge_storage mg-single-node kvstore_dummy_lib)
|
||||||
@@ -54,9 +54,6 @@ target_link_libraries(${test_prefix}edge_storage mg-single-node kvstore_dummy_li
|
|||||||
add_benchmark(mvcc.cpp)
|
add_benchmark(mvcc.cpp)
|
||||||
target_link_libraries(${test_prefix}mvcc mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}mvcc mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(rpc.cpp)
|
|
||||||
target_link_libraries(${test_prefix}rpc mg-comm-rpc)
|
|
||||||
|
|
||||||
add_benchmark(skip_list_random.cpp)
|
add_benchmark(skip_list_random.cpp)
|
||||||
target_link_libraries(${test_prefix}skip_list_random mg-utils)
|
target_link_libraries(${test_prefix}skip_list_random mg-utils)
|
||||||
|
|
||||||
@@ -73,7 +70,7 @@ add_benchmark(tx_engine.cpp)
|
|||||||
target_link_libraries(${test_prefix}tx_engine mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}tx_engine mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(expansion.cpp)
|
add_benchmark(expansion.cpp)
|
||||||
target_link_libraries(${test_prefix}expansion mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}expansion mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_benchmark(storage_v2_gc.cpp)
|
add_benchmark(storage_v2_gc.cpp)
|
||||||
target_link_libraries(${test_prefix}storage_v2_gc mg-storage-v2)
|
target_link_libraries(${test_prefix}storage_v2_gc mg-storage-v2)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
#include "communication/result_stream_faker.hpp"
|
#include "communication/result_stream_faker.hpp"
|
||||||
#include "query/frontend/opencypher/parser.hpp"
|
#include "query/frontend/opencypher/parser.hpp"
|
||||||
#include "query/frontend/semantic/required_privileges.hpp"
|
|
||||||
#include "query/frontend/semantic/symbol_generator.hpp"
|
#include "query/frontend/semantic/symbol_generator.hpp"
|
||||||
#include "query/interpreter.hpp"
|
#include "query/interpreter.hpp"
|
||||||
#include "query/plan/planner.hpp"
|
#include "query/plan/planner.hpp"
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
- name: feature_benchmark__ha__read
|
|
||||||
cd: ha/read
|
|
||||||
commands: ./runner.sh
|
|
||||||
infiles:
|
|
||||||
- runner.sh # runner script
|
|
||||||
- raft.json # raft configuration file
|
|
||||||
- coordination.json # coordination configuration file
|
|
||||||
- ../../../../build_release/tests/feature_benchmark/ha/read/benchmark # benchmark binary
|
|
||||||
- ../../../../build_release/memgraph_ha # memgraph binary
|
|
||||||
enable_network: true
|
|
||||||
|
|
||||||
- name: feature_benchmark__ha__write
|
|
||||||
cd: ha/write
|
|
||||||
commands: ./runner.sh
|
|
||||||
infiles:
|
|
||||||
- runner.sh # runner script
|
|
||||||
- raft.json # raft configuration file
|
|
||||||
- coordination.json # coordination configuration file
|
|
||||||
- ../../../../build_release/tests/feature_benchmark/ha/write/benchmark # benchmark binary
|
|
||||||
- ../../../../build_release/memgraph_ha # memgraph binary
|
|
||||||
enable_network: true
|
|
||||||
@@ -6,30 +6,3 @@ add_subdirectory(ssl)
|
|||||||
|
|
||||||
# transactions test binaries
|
# transactions test binaries
|
||||||
add_subdirectory(transactions)
|
add_subdirectory(transactions)
|
||||||
|
|
||||||
# auth test binaries
|
|
||||||
add_subdirectory(auth)
|
|
||||||
|
|
||||||
# distributed ha/basic binaries
|
|
||||||
add_subdirectory(ha/basic)
|
|
||||||
|
|
||||||
# distributed ha/constraints binaries
|
|
||||||
add_subdirectory(ha/constraints)
|
|
||||||
|
|
||||||
# distributed ha/index binaries
|
|
||||||
add_subdirectory(ha/index)
|
|
||||||
|
|
||||||
# distributed ha/large_log_entries binaries
|
|
||||||
add_subdirectory(ha/large_log_entries)
|
|
||||||
|
|
||||||
# distributed ha/leader_election binaries
|
|
||||||
add_subdirectory(ha/leader_election)
|
|
||||||
|
|
||||||
# distributed ha/term_updates binaries
|
|
||||||
add_subdirectory(ha/term_updates)
|
|
||||||
|
|
||||||
# audit test binaries
|
|
||||||
add_subdirectory(audit)
|
|
||||||
|
|
||||||
# ldap test binaries
|
|
||||||
add_subdirectory(ldap)
|
|
||||||
|
|||||||
@@ -22,105 +22,3 @@
|
|||||||
- runner.sh # runner script
|
- runner.sh # runner script
|
||||||
- ../../../build_debug/memgraph # memgraph binary
|
- ../../../build_debug/memgraph # memgraph binary
|
||||||
- ../../../build_debug/tests/integration/transactions/tester # tester binary
|
- ../../../build_debug/tests/integration/transactions/tester # tester binary
|
||||||
|
|
||||||
- name: integration__auth
|
|
||||||
cd: auth
|
|
||||||
commands: TIMEOUT=820 ./runner.py
|
|
||||||
infiles:
|
|
||||||
- runner.py # runner script
|
|
||||||
- ../../../build_debug/memgraph # memgraph binary
|
|
||||||
- ../../../build_debug/tests/integration/auth/checker # checker binary
|
|
||||||
- ../../../build_debug/tests/integration/auth/tester # tester binary
|
|
||||||
|
|
||||||
- name: integration__audit
|
|
||||||
cd: audit
|
|
||||||
commands: ./runner.py
|
|
||||||
infiles:
|
|
||||||
- runner.py # runner script
|
|
||||||
- ../../../build_debug/memgraph # memgraph binary
|
|
||||||
- ../../../build_debug/tests/integration/audit/tester # tester binary
|
|
||||||
|
|
||||||
- name: integration__ldap
|
|
||||||
cd: ldap
|
|
||||||
commands: |
|
|
||||||
./prepare.sh
|
|
||||||
./runner.py
|
|
||||||
infiles:
|
|
||||||
- prepare.sh # preparation script
|
|
||||||
- runner.py # runner script
|
|
||||||
- schema.ldif # schema file
|
|
||||||
- ve3 # Python virtual environment
|
|
||||||
- ../../../src/auth/reference_modules/ldap.py # LDAP auth module
|
|
||||||
- ../../../build_debug/memgraph # memgraph binary
|
|
||||||
- ../../../build_debug/tests/integration/ldap/tester # tester binary
|
|
||||||
enable_network: true
|
|
||||||
|
|
||||||
- name: integration__ha_basic
|
|
||||||
cd: ha/basic
|
|
||||||
commands: TIMEOUT=480 ./runner.py
|
|
||||||
infiles:
|
|
||||||
- runner.py # runner script
|
|
||||||
- raft.json # raft configuration
|
|
||||||
- ../ha_test.py # raft test base module
|
|
||||||
- ../../../../build_debug/memgraph_ha # memgraph ha binary
|
|
||||||
- ../../../../build_debug/tests/integration/ha/basic/tester # tester binary
|
|
||||||
|
|
||||||
- name: integration__ha_constraints
|
|
||||||
cd: ha/constraints
|
|
||||||
commands: ./runner.py
|
|
||||||
infiles:
|
|
||||||
- runner.py # runner script
|
|
||||||
- raft.json # raft configuration
|
|
||||||
- ../ha_test.py # raft test base module
|
|
||||||
- ../../../../build_debug/memgraph_ha # memgraph ha binary
|
|
||||||
- ../../../../build_debug/tests/integration/ha/constraints/tester # tester binary
|
|
||||||
|
|
||||||
- name: integration__ha_index
|
|
||||||
cd: ha/index
|
|
||||||
commands: ./runner.py
|
|
||||||
infiles:
|
|
||||||
- runner.py # runner script
|
|
||||||
- raft.json # raft configuration
|
|
||||||
- ../ha_test.py # raft test base module
|
|
||||||
- ../../../../build_debug/memgraph_ha # memgraph ha binary
|
|
||||||
- ../../../../build_debug/tests/integration/ha/index/tester # tester binary
|
|
||||||
|
|
||||||
- name: integration__ha_large_log_entries
|
|
||||||
cd: ha/large_log_entries
|
|
||||||
commands: TIMEOUT=600 ./runner.py
|
|
||||||
infiles:
|
|
||||||
- runner.py # runner script
|
|
||||||
- raft.json # raft configuration
|
|
||||||
- ../ha_test.py # raft test base module
|
|
||||||
- ../../../../build_debug/memgraph_ha # memgraph ha binary
|
|
||||||
- ../../../../build_debug/tests/integration/ha/large_log_entries/tester # tester binary
|
|
||||||
|
|
||||||
- name: integration__ha_leader_election
|
|
||||||
cd: ha/leader_election
|
|
||||||
commands: TIMEOUT=300 ./runner.py
|
|
||||||
infiles:
|
|
||||||
- runner.py # runner script
|
|
||||||
- raft.json # raft configuration
|
|
||||||
- ../ha_test.py # raft test base module
|
|
||||||
- ../../../../build_debug/memgraph_ha # memgraph ha binary
|
|
||||||
- ../../../../build_debug/tests/integration/ha/leader_election/tester # tester binary
|
|
||||||
|
|
||||||
- name: integration__ha_log_compaction
|
|
||||||
cd: ha/log_compaction
|
|
||||||
commands: ./runner.py
|
|
||||||
infiles:
|
|
||||||
- runner.py # runner script
|
|
||||||
- raft.json # raft configuration
|
|
||||||
- ../ha_test.py # raft test base module
|
|
||||||
- ../../../../build_debug/memgraph_ha # memgraph ha binary
|
|
||||||
- ../../../../build_debug/tests/manual/ha_client # tester binary
|
|
||||||
|
|
||||||
- name: integration__ha_term_updates
|
|
||||||
cd: ha/term_updates
|
|
||||||
commands: ./runner.py
|
|
||||||
infiles:
|
|
||||||
- runner.py # runner script
|
|
||||||
- raft.json # raft configuration
|
|
||||||
- ../ha_test.py # raft test base module
|
|
||||||
- ../../../../build_debug/memgraph_ha # memgraph ha binary
|
|
||||||
- ../../../../build_debug/tests/integration/ha/term_updates/tester # tester binary
|
|
||||||
|
|||||||
@@ -30,30 +30,23 @@ target_link_libraries(${test_prefix}binomial mg-utils)
|
|||||||
add_manual_test(bolt_client.cpp)
|
add_manual_test(bolt_client.cpp)
|
||||||
target_link_libraries(${test_prefix}bolt_client mg-communication)
|
target_link_libraries(${test_prefix}bolt_client mg-communication)
|
||||||
|
|
||||||
add_manual_test(ha_client.cpp)
|
|
||||||
target_link_libraries(${test_prefix}ha_client mg-utils mg-communication)
|
|
||||||
|
|
||||||
add_manual_test(ha_proxy.cpp)
|
|
||||||
target_include_directories(${test_prefix}ha_proxy PRIVATE ${CMAKE_BINARY_DIR}/src)
|
|
||||||
target_link_libraries(${test_prefix}ha_proxy mg-utils mg-communication)
|
|
||||||
|
|
||||||
add_manual_test(kvstore_console.cpp)
|
add_manual_test(kvstore_console.cpp)
|
||||||
target_link_libraries(${test_prefix}kvstore_console kvstore_lib gflags glog)
|
target_link_libraries(${test_prefix}kvstore_console kvstore_lib gflags glog)
|
||||||
|
|
||||||
add_manual_test(query_hash.cpp)
|
add_manual_test(query_hash.cpp)
|
||||||
target_link_libraries(${test_prefix}query_hash mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_hash mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_manual_test(query_planner.cpp interactive_planning.cpp)
|
add_manual_test(query_planner.cpp interactive_planning.cpp)
|
||||||
target_link_libraries(${test_prefix}query_planner mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_planner mg-single-node-v2 kvstore_dummy_lib)
|
||||||
if (READLINE_FOUND)
|
if (READLINE_FOUND)
|
||||||
target_link_libraries(${test_prefix}query_planner readline)
|
target_link_libraries(${test_prefix}query_planner readline)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_manual_test(expression_pretty_printer.cpp)
|
add_manual_test(expression_pretty_printer.cpp)
|
||||||
target_link_libraries(${test_prefix}expression_pretty_printer mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}expression_pretty_printer mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_manual_test(single_query.cpp)
|
add_manual_test(single_query.cpp)
|
||||||
target_link_libraries(${test_prefix}single_query mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}single_query mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_manual_test(sl_position_and_count.cpp)
|
add_manual_test(sl_position_and_count.cpp)
|
||||||
target_link_libraries(${test_prefix}sl_position_and_count mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}sl_position_and_count mg-single-node kvstore_dummy_lib)
|
||||||
@@ -62,7 +55,7 @@ add_manual_test(snapshot_explorer.cpp)
|
|||||||
target_link_libraries(${test_prefix}snapshot_explorer mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}snapshot_explorer mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
add_manual_test(stripped_timing.cpp)
|
add_manual_test(stripped_timing.cpp)
|
||||||
target_link_libraries(${test_prefix}stripped_timing mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}stripped_timing mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_manual_test(ssl_client.cpp)
|
add_manual_test(ssl_client.cpp)
|
||||||
target_link_libraries(${test_prefix}ssl_client mg-communication)
|
target_link_libraries(${test_prefix}ssl_client mg-communication)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ int main(int argc, char *argv[]) {
|
|||||||
query::Interpreter interpreter{&interpreter_context};
|
query::Interpreter interpreter{&interpreter_context};
|
||||||
|
|
||||||
ResultStreamFaker stream(&db);
|
ResultStreamFaker stream(&db);
|
||||||
auto [header, _] = interpreter.Prepare(argv[1], {});
|
auto header = interpreter.Prepare(argv[1], {});
|
||||||
stream.Header(header);
|
stream.Header(header);
|
||||||
auto summary = interpreter.PullAll(&stream);
|
auto summary = interpreter.PullAll(&stream);
|
||||||
stream.Summary(summary);
|
stream.Summary(summary);
|
||||||
|
|||||||
@@ -15,18 +15,6 @@
|
|||||||
commands: TIMEOUT=43200 ./continuous_integration --large-dataset
|
commands: TIMEOUT=43200 ./continuous_integration --large-dataset
|
||||||
infiles: *STRESS_INFILES
|
infiles: *STRESS_INFILES
|
||||||
|
|
||||||
- name: stress_ha_normal_operation
|
|
||||||
commands: TIMEOUT=200 ./continuous_integration_ha
|
|
||||||
infiles: &STRESS_HA_INFILES
|
|
||||||
- . # current directory
|
|
||||||
- ../../build_release/memgraph_ha # memgraph release binary
|
|
||||||
- ../../build_release/tests/stress/ # stress client binaries
|
|
||||||
|
|
||||||
- name: stress_ha_normal_opration_large
|
|
||||||
project: release
|
|
||||||
commands: TIMEOUT=7500 ./continuous_integration_ha --large-dataset
|
|
||||||
infiles: *STRESS_HA_INFILES
|
|
||||||
|
|
||||||
- name: durability
|
- name: durability
|
||||||
commands: TIMEOUT=300 ./ve3/bin/python3 durability --num-steps 5
|
commands: TIMEOUT=300 ./ve3/bin/python3 durability --num-steps 5
|
||||||
infiles: &DURABILITY_INFILES
|
infiles: &DURABILITY_INFILES
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ function(add_unit_test test_cpp)
|
|||||||
endfunction(add_unit_test)
|
endfunction(add_unit_test)
|
||||||
|
|
||||||
add_unit_test(bolt_encoder.cpp)
|
add_unit_test(bolt_encoder.cpp)
|
||||||
target_link_libraries(${test_prefix}bolt_encoder mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}bolt_encoder mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(commit_log_v2.cpp)
|
add_unit_test(commit_log_v2.cpp)
|
||||||
target_link_libraries(${test_prefix}commit_log_v2 glog gflags)
|
target_link_libraries(${test_prefix}commit_log_v2 glog gflags)
|
||||||
@@ -34,7 +34,7 @@ add_unit_test(concurrent_map.cpp)
|
|||||||
target_link_libraries(${test_prefix}concurrent_map mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}concurrent_map mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(cypher_main_visitor.cpp)
|
add_unit_test(cypher_main_visitor.cpp)
|
||||||
target_link_libraries(${test_prefix}cypher_main_visitor mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}cypher_main_visitor mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(database_key_index.cpp)
|
add_unit_test(database_key_index.cpp)
|
||||||
target_link_libraries(${test_prefix}database_key_index mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}database_key_index mg-single-node kvstore_dummy_lib)
|
||||||
@@ -52,7 +52,7 @@ add_unit_test(deferred_deleter.cpp)
|
|||||||
target_link_libraries(${test_prefix}deferred_deleter mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}deferred_deleter mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(bfs_single_node.cpp)
|
add_unit_test(bfs_single_node.cpp)
|
||||||
target_link_libraries(${test_prefix}bfs_single_node mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}bfs_single_node mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(durability.cpp)
|
add_unit_test(durability.cpp)
|
||||||
target_link_libraries(${test_prefix}durability mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}durability mg-single-node kvstore_dummy_lib)
|
||||||
@@ -73,7 +73,7 @@ add_unit_test(graph_db.cpp)
|
|||||||
target_link_libraries(${test_prefix}graph_db mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}graph_db mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(interpreter.cpp)
|
add_unit_test(interpreter.cpp)
|
||||||
target_link_libraries(${test_prefix}interpreter mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}interpreter mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(kvstore.cpp)
|
add_unit_test(kvstore.cpp)
|
||||||
target_link_libraries(${test_prefix}kvstore kvstore_lib glog)
|
target_link_libraries(${test_prefix}kvstore kvstore_lib glog)
|
||||||
@@ -99,68 +99,62 @@ target_link_libraries(${test_prefix}pod_buffer mg-single-node kvstore_dummy_lib)
|
|||||||
add_unit_test(property_value_store.cpp)
|
add_unit_test(property_value_store.cpp)
|
||||||
target_link_libraries(${test_prefix}property_value_store kvstore_lib mg-single-node)
|
target_link_libraries(${test_prefix}property_value_store kvstore_lib mg-single-node)
|
||||||
|
|
||||||
add_unit_test(replication_log.cpp)
|
|
||||||
target_link_libraries(${test_prefix}replication_log mg-single-node-ha kvstore_lib glog)
|
|
||||||
|
|
||||||
add_unit_test(query_cost_estimator.cpp)
|
add_unit_test(query_cost_estimator.cpp)
|
||||||
target_link_libraries(${test_prefix}query_cost_estimator mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_cost_estimator mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_expression_evaluator.cpp)
|
add_unit_test(query_expression_evaluator.cpp)
|
||||||
target_link_libraries(${test_prefix}query_expression_evaluator mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_expression_evaluator mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(plan_pretty_print.cpp)
|
add_unit_test(plan_pretty_print.cpp)
|
||||||
target_link_libraries(${test_prefix}plan_pretty_print mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}plan_pretty_print mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_dump.cpp)
|
add_unit_test(query_dump.cpp)
|
||||||
target_link_libraries(${test_prefix}query_dump mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_dump mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_pretty_print.cpp)
|
add_unit_test(query_pretty_print.cpp)
|
||||||
target_link_libraries(${test_prefix}query_pretty_print mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_pretty_print mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_profile.cpp)
|
add_unit_test(query_profile.cpp)
|
||||||
target_link_libraries(${test_prefix}query_profile mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_profile mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_plan_accumulate_aggregate.cpp)
|
add_unit_test(query_plan_accumulate_aggregate.cpp)
|
||||||
target_link_libraries(${test_prefix}query_plan_accumulate_aggregate mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_plan_accumulate_aggregate mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_plan_bag_semantics.cpp)
|
add_unit_test(query_plan_bag_semantics.cpp)
|
||||||
target_link_libraries(${test_prefix}query_plan_bag_semantics mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_plan_bag_semantics mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_plan_create_set_remove_delete.cpp)
|
add_unit_test(query_plan_create_set_remove_delete.cpp)
|
||||||
target_link_libraries(${test_prefix}query_plan_create_set_remove_delete mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_plan_create_set_remove_delete mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
# Storage V2 in query execution
|
# Storage V2 in query execution
|
||||||
add_unit_test(query_plan_v2_create_set_remove_delete.cpp)
|
add_unit_test(query_plan_v2_create_set_remove_delete.cpp)
|
||||||
target_link_libraries(${test_prefix}query_plan_v2_create_set_remove_delete mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_plan_v2_create_set_remove_delete mg-single-node-v2 kvstore_dummy_lib)
|
||||||
# END Storage V2 in query execution
|
# END Storage V2 in query execution
|
||||||
|
|
||||||
add_unit_test(query_plan_edge_cases.cpp)
|
add_unit_test(query_plan_edge_cases.cpp)
|
||||||
target_link_libraries(${test_prefix}query_plan_edge_cases mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_plan_edge_cases mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_plan_match_filter_return.cpp)
|
add_unit_test(query_plan_match_filter_return.cpp)
|
||||||
target_link_libraries(${test_prefix}query_plan_match_filter_return mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_plan_match_filter_return mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_plan.cpp)
|
add_unit_test(query_plan.cpp)
|
||||||
target_link_libraries(${test_prefix}query_plan mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_plan mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
# Test query/procedure
|
# Test query/procedure
|
||||||
add_unit_test(query_procedure_mgp_type.cpp)
|
add_unit_test(query_procedure_mgp_type.cpp)
|
||||||
target_link_libraries(${test_prefix}query_procedure_mgp_type mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_procedure_mgp_type mg-single-node-v2 kvstore_dummy_lib)
|
||||||
target_include_directories(${test_prefix}query_procedure_mgp_type PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
target_include_directories(${test_prefix}query_procedure_mgp_type PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||||
|
|
||||||
add_unit_test(query_procedure_mgp_module.cpp)
|
add_unit_test(query_procedure_mgp_module.cpp)
|
||||||
target_link_libraries(${test_prefix}query_procedure_mgp_module mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_procedure_mgp_module mg-single-node-v2 kvstore_dummy_lib)
|
||||||
target_include_directories(${test_prefix}query_procedure_mgp_module PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
target_include_directories(${test_prefix}query_procedure_mgp_module PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||||
# END query/procedure
|
# END query/procedure
|
||||||
|
|
||||||
add_unit_test(query_required_privileges.cpp)
|
|
||||||
target_link_libraries(${test_prefix}query_required_privileges mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
|
||||||
|
|
||||||
add_unit_test(query_semantic.cpp)
|
add_unit_test(query_semantic.cpp)
|
||||||
target_link_libraries(${test_prefix}query_semantic mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_semantic mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(query_variable_start_planner.cpp)
|
add_unit_test(query_variable_start_planner.cpp)
|
||||||
target_link_libraries(${test_prefix}query_variable_start_planner mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}query_variable_start_planner mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(queue.cpp)
|
add_unit_test(queue.cpp)
|
||||||
target_link_libraries(${test_prefix}queue mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}queue mg-single-node kvstore_dummy_lib)
|
||||||
@@ -186,16 +180,6 @@ target_link_libraries(${test_prefix}skiplist_reverse_iteration mg-single-node kv
|
|||||||
add_unit_test(skiplist_suffix.cpp)
|
add_unit_test(skiplist_suffix.cpp)
|
||||||
target_link_libraries(${test_prefix}skiplist_suffix mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}skiplist_suffix mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
# TODO: REPLACE single-node-ha
|
|
||||||
add_unit_test(slk_advanced.cpp)
|
|
||||||
target_link_libraries(${test_prefix}slk_advanced mg-single-node-ha kvstore_dummy_lib)
|
|
||||||
|
|
||||||
add_unit_test(slk_core.cpp)
|
|
||||||
target_link_libraries(${test_prefix}slk_core mg-slk glog gflags fmt)
|
|
||||||
|
|
||||||
add_unit_test(slk_streams.cpp)
|
|
||||||
target_link_libraries(${test_prefix}slk_streams mg-slk glog gflags fmt)
|
|
||||||
|
|
||||||
add_unit_test(small_vector.cpp)
|
add_unit_test(small_vector.cpp)
|
||||||
target_link_libraries(${test_prefix}small_vector mg-utils)
|
target_link_libraries(${test_prefix}small_vector mg-utils)
|
||||||
|
|
||||||
@@ -209,13 +193,13 @@ add_unit_test(storage_stat.cpp)
|
|||||||
target_link_libraries(${test_prefix}storage_stat mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}storage_stat mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(stripped.cpp)
|
add_unit_test(stripped.cpp)
|
||||||
target_link_libraries(${test_prefix}stripped mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}stripped mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(transaction_engine_single_node.cpp)
|
add_unit_test(transaction_engine_single_node.cpp)
|
||||||
target_link_libraries(${test_prefix}transaction_engine_single_node mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}transaction_engine_single_node mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(typed_value.cpp)
|
add_unit_test(typed_value.cpp)
|
||||||
target_link_libraries(${test_prefix}typed_value mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}typed_value mg-single-node-v2 kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(unique_constraints.cpp)
|
add_unit_test(unique_constraints.cpp)
|
||||||
target_link_libraries(${test_prefix}unique_constraints mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}unique_constraints mg-single-node kvstore_dummy_lib)
|
||||||
@@ -240,9 +224,6 @@ target_link_libraries(${test_prefix}communication_buffer mg-communication)
|
|||||||
add_unit_test(network_timeouts.cpp)
|
add_unit_test(network_timeouts.cpp)
|
||||||
target_link_libraries(${test_prefix}network_timeouts mg-communication)
|
target_link_libraries(${test_prefix}network_timeouts mg-communication)
|
||||||
|
|
||||||
add_unit_test(rpc.cpp)
|
|
||||||
target_link_libraries(${test_prefix}rpc mg-comm-rpc)
|
|
||||||
|
|
||||||
# Test data structures
|
# Test data structures
|
||||||
|
|
||||||
add_unit_test(ring_buffer.cpp)
|
add_unit_test(ring_buffer.cpp)
|
||||||
@@ -309,11 +290,6 @@ target_link_libraries(${test_prefix}utils_timestamp mg-utils)
|
|||||||
add_unit_test(utils_watchdog.cpp)
|
add_unit_test(utils_watchdog.cpp)
|
||||||
target_link_libraries(${test_prefix}utils_watchdog mg-utils)
|
target_link_libraries(${test_prefix}utils_watchdog mg-utils)
|
||||||
|
|
||||||
# Test mg-auth
|
|
||||||
|
|
||||||
add_unit_test(auth.cpp)
|
|
||||||
target_link_libraries(${test_prefix}auth mg-auth kvstore_lib)
|
|
||||||
|
|
||||||
# Test storage v2
|
# Test storage v2
|
||||||
|
|
||||||
add_unit_test(property_value_v2.cpp)
|
add_unit_test(property_value_v2.cpp)
|
||||||
|
|||||||
@@ -50,11 +50,6 @@ class TestSession : public Session<TestInputStream, TestOutputStream> {
|
|||||||
|
|
||||||
void Abort() override {}
|
void Abort() override {}
|
||||||
|
|
||||||
bool Authenticate(const std::string &username,
|
|
||||||
const std::string &password) override {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string query_;
|
std::string query_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2119,230 +2119,6 @@ TEST_P(CypherMainVisitorTest, UnionAll) {
|
|||||||
ASSERT_FALSE(return_clause->body_.distinct);
|
ASSERT_FALSE(return_clause->body_.distinct);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_auth_query(Base *ast_generator, std::string input,
|
|
||||||
AuthQuery::Action action, std::string user,
|
|
||||||
std::string role, std::string user_or_role,
|
|
||||||
std::optional<TypedValue> password,
|
|
||||||
std::vector<AuthQuery::Privilege> privileges) {
|
|
||||||
auto *auth_query =
|
|
||||||
dynamic_cast<AuthQuery *>(ast_generator->ParseQuery(input));
|
|
||||||
ASSERT_TRUE(auth_query);
|
|
||||||
EXPECT_EQ(auth_query->action_, action);
|
|
||||||
EXPECT_EQ(auth_query->user_, user);
|
|
||||||
EXPECT_EQ(auth_query->role_, role);
|
|
||||||
EXPECT_EQ(auth_query->user_or_role_, user_or_role);
|
|
||||||
ASSERT_EQ(static_cast<bool>(auth_query->password_),
|
|
||||||
static_cast<bool>(password));
|
|
||||||
if (password) {
|
|
||||||
ast_generator->CheckLiteral(auth_query->password_, *password);
|
|
||||||
}
|
|
||||||
EXPECT_EQ(auth_query->privileges_, privileges);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, UserOrRoleName) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CREATE ROLE `us|er`"),
|
|
||||||
SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CREATE ROLE `us er`"),
|
|
||||||
SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "CREATE ROLE `user`",
|
|
||||||
AuthQuery::Action::CREATE_ROLE, "", "user", "", {}, {});
|
|
||||||
check_auth_query(&ast_generator, "CREATE ROLE us___er",
|
|
||||||
AuthQuery::Action::CREATE_ROLE, "", "us___er", "", {}, {});
|
|
||||||
check_auth_query(&ast_generator, "CREATE ROLE `us+er`",
|
|
||||||
AuthQuery::Action::CREATE_ROLE, "", "us+er", "", {}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, CreateRole) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CREATE ROLE"), SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "CREATE ROLE rola",
|
|
||||||
AuthQuery::Action::CREATE_ROLE, "", "rola", "", {}, {});
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CREATE ROLE lagano rolamo"),
|
|
||||||
SyntaxException);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, DropRole) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("DROP ROLE"), SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "DROP ROLE rola",
|
|
||||||
AuthQuery::Action::DROP_ROLE, "", "rola", "", {}, {});
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("DROP ROLE lagano rolamo"),
|
|
||||||
SyntaxException);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, ShowRoles) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SHOW ROLES ROLES"), SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "SHOW ROLES", AuthQuery::Action::SHOW_ROLES,
|
|
||||||
"", "", "", {}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, CreateUser) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CREATE USER"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CREATE USER 123"), SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "CREATE USER user",
|
|
||||||
AuthQuery::Action::CREATE_USER, "user", "", "", {}, {});
|
|
||||||
check_auth_query(&ast_generator, "CREATE USER user IDENTIFIED BY 'password'",
|
|
||||||
AuthQuery::Action::CREATE_USER, "user", "", "",
|
|
||||||
TypedValue("password"), {});
|
|
||||||
check_auth_query(&ast_generator, "CREATE USER user IDENTIFIED BY ''",
|
|
||||||
AuthQuery::Action::CREATE_USER, "user", "", "",
|
|
||||||
TypedValue(""), {});
|
|
||||||
check_auth_query(&ast_generator, "CREATE USER user IDENTIFIED BY null",
|
|
||||||
AuthQuery::Action::CREATE_USER, "user", "", "", TypedValue(),
|
|
||||||
{});
|
|
||||||
ASSERT_THROW(
|
|
||||||
ast_generator.ParseQuery("CRATE USER user IDENTIFIED BY password"),
|
|
||||||
SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CREATE USER user IDENTIFIED BY 5"),
|
|
||||||
SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CREATE USER user IDENTIFIED BY "),
|
|
||||||
SyntaxException);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, SetPassword) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SET PASSWORD FOR"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SET PASSWORD FOR user "),
|
|
||||||
SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "SET PASSWORD FOR user TO null",
|
|
||||||
AuthQuery::Action::SET_PASSWORD, "user", "", "",
|
|
||||||
TypedValue(), {});
|
|
||||||
check_auth_query(&ast_generator, "SET PASSWORD FOR user TO 'password'",
|
|
||||||
AuthQuery::Action::SET_PASSWORD, "user", "", "",
|
|
||||||
TypedValue("password"), {});
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SET PASSWORD FOR user To 5"),
|
|
||||||
SyntaxException);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, DropUser) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("DROP USER"), SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "DROP USER user",
|
|
||||||
AuthQuery::Action::DROP_USER, "user", "", "", {}, {});
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("DROP USER lagano rolamo"),
|
|
||||||
SyntaxException);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, ShowUsers) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SHOW USERS ROLES"), SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "SHOW USERS", AuthQuery::Action::SHOW_USERS,
|
|
||||||
"", "", "", {}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, SetRole) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SET ROLE"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SET ROLE user"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SET ROLE FOR user"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SET ROLE FOR user TO"),
|
|
||||||
SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "SET ROLE FOR user TO role",
|
|
||||||
AuthQuery::Action::SET_ROLE, "user", "role", "", {}, {});
|
|
||||||
check_auth_query(&ast_generator, "SET ROLE FOR user TO null",
|
|
||||||
AuthQuery::Action::SET_ROLE, "user", "null", "", {}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, ClearRole) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CLEAR ROLE"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CLEAR ROLE user"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("CLEAR ROLE FOR user TO"),
|
|
||||||
SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "CLEAR ROLE FOR user",
|
|
||||||
AuthQuery::Action::CLEAR_ROLE, "user", "", "", {}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, GrantPrivilege) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("GRANT"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("GRANT TO user"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("GRANT BLABLA TO user"),
|
|
||||||
SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("GRANT MATCH, TO user"),
|
|
||||||
SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("GRANT MATCH, BLABLA TO user"),
|
|
||||||
SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "GRANT MATCH TO user",
|
|
||||||
AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
|
|
||||||
{AuthQuery::Privilege::MATCH});
|
|
||||||
check_auth_query(&ast_generator, "GRANT MATCH, AUTH TO user",
|
|
||||||
AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
|
|
||||||
{AuthQuery::Privilege::MATCH, AuthQuery::Privilege::AUTH});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, DenyPrivilege) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("DENY"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("DENY TO user"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("DENY BLABLA TO user"),
|
|
||||||
SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("DENY MATCH, TO user"),
|
|
||||||
SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("DENY MATCH, BLABLA TO user"),
|
|
||||||
SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "DENY MATCH TO user",
|
|
||||||
AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
|
|
||||||
{AuthQuery::Privilege::MATCH});
|
|
||||||
check_auth_query(&ast_generator, "DENY MATCH, AUTH TO user",
|
|
||||||
AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
|
|
||||||
{AuthQuery::Privilege::MATCH, AuthQuery::Privilege::AUTH});
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, RevokePrivilege) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("REVOKE"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("REVOKE FROM user"), SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("REVOKE BLABLA FROM user"),
|
|
||||||
SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("REVOKE MATCH, FROM user"),
|
|
||||||
SyntaxException);
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("REVOKE MATCH, BLABLA FROM user"),
|
|
||||||
SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "REVOKE MATCH FROM user",
|
|
||||||
AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
|
|
||||||
{AuthQuery::Privilege::MATCH});
|
|
||||||
check_auth_query(&ast_generator, "REVOKE MATCH, AUTH FROM user",
|
|
||||||
AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
|
|
||||||
{AuthQuery::Privilege::MATCH, AuthQuery::Privilege::AUTH});
|
|
||||||
check_auth_query(&ast_generator, "REVOKE ALL PRIVILEGES FROM user",
|
|
||||||
AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
|
|
||||||
kPrivilegesAll);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, ShowPrivileges) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SHOW PRIVILEGES FOR"),
|
|
||||||
SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "SHOW PRIVILEGES FOR user",
|
|
||||||
AuthQuery::Action::SHOW_PRIVILEGES, "", "", "user", {}, {});
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SHOW PRIVILEGES FOR user1, user2"),
|
|
||||||
SyntaxException);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, ShowRoleForUser) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SHOW ROLE FOR "), SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "SHOW ROLE FOR user",
|
|
||||||
AuthQuery::Action::SHOW_ROLE_FOR_USER, "user", "", "", {},
|
|
||||||
{});
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SHOW ROLE FOR user1, user2"),
|
|
||||||
SyntaxException);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, ShowUsersForRole) {
|
|
||||||
auto &ast_generator = *GetParam();
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SHOW USERS FOR "), SyntaxException);
|
|
||||||
check_auth_query(&ast_generator, "SHOW USERS FOR role",
|
|
||||||
AuthQuery::Action::SHOW_USERS_FOR_ROLE, "", "role", "", {},
|
|
||||||
{});
|
|
||||||
ASSERT_THROW(ast_generator.ParseQuery("SHOW USERS FOR role1, role2"),
|
|
||||||
SyntaxException);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(CypherMainVisitorTest, TestExplainRegularQuery) {
|
TEST_P(CypherMainVisitorTest, TestExplainRegularQuery) {
|
||||||
auto &ast_generator = *GetParam();
|
auto &ast_generator = *GetParam();
|
||||||
EXPECT_TRUE(dynamic_cast<ExplainQuery *>(
|
EXPECT_TRUE(dynamic_cast<ExplainQuery *>(
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class InterpreterTest : public ::testing::Test {
|
|||||||
const std::map<std::string, PropertyValue> ¶ms = {}) {
|
const std::map<std::string, PropertyValue> ¶ms = {}) {
|
||||||
ResultStreamFaker stream(&db_);
|
ResultStreamFaker stream(&db_);
|
||||||
|
|
||||||
auto [header, _] = interpreter_.Prepare(query, params);
|
auto header = interpreter_.Prepare(query, params);
|
||||||
stream.Header(header);
|
stream.Header(header);
|
||||||
auto summary = interpreter_.PullAll(&stream);
|
auto summary = interpreter_.PullAll(&stream);
|
||||||
stream.Summary(summary);
|
stream.Summary(summary);
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ auto Execute(storage::Storage *db, const std::string &query) {
|
|||||||
query::Interpreter interpreter(&context);
|
query::Interpreter interpreter(&context);
|
||||||
ResultStreamFaker stream(db);
|
ResultStreamFaker stream(db);
|
||||||
|
|
||||||
auto [header, _] = interpreter.Prepare(query, {});
|
auto header = interpreter.Prepare(query, {});
|
||||||
stream.Header(header);
|
stream.Header(header);
|
||||||
auto summary = interpreter.PullAll(&stream);
|
auto summary = interpreter.PullAll(&stream);
|
||||||
stream.Summary(summary);
|
stream.Summary(summary);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class QueryExecution : public testing::Test {
|
|||||||
auto Execute(const std::string &query) {
|
auto Execute(const std::string &query) {
|
||||||
ResultStreamFaker stream(&*db_);
|
ResultStreamFaker stream(&*db_);
|
||||||
|
|
||||||
auto [header, _] = interpreter_->Prepare(query, {});
|
auto header = interpreter_->Prepare(query, {});
|
||||||
stream.Header(header);
|
stream.Header(header);
|
||||||
auto summary = interpreter_->PullAll(&stream);
|
auto summary = interpreter_->PullAll(&stream);
|
||||||
stream.Summary(summary);
|
stream.Summary(summary);
|
||||||
|
|||||||
@@ -15,11 +15,6 @@ if (READLINE_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
target_link_libraries(mg_client ${CLIENT_LIBS})
|
target_link_libraries(mg_client ${CLIENT_LIBS})
|
||||||
|
|
||||||
# Memgraph Dump Target
|
|
||||||
add_executable(mg_dump mg_dump/main.cpp)
|
|
||||||
target_include_directories(mg_dump PRIVATE ${MGCLIENT_INCLUDE_DIR})
|
|
||||||
target_link_libraries(mg_dump fmt gflags glog mgclient pthread)
|
|
||||||
|
|
||||||
# Strip the executable in release build.
|
# Strip the executable in release build.
|
||||||
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
|
||||||
if (lower_build_type STREQUAL "release")
|
if (lower_build_type STREQUAL "release")
|
||||||
@@ -37,4 +32,4 @@ endif()
|
|||||||
install(TARGETS mg_client RUNTIME DESTINATION bin)
|
install(TARGETS mg_client RUNTIME DESTINATION bin)
|
||||||
|
|
||||||
# Target for building all the tool executables.
|
# Target for building all the tool executables.
|
||||||
add_custom_target(tools DEPENDS mg_import_csv mg_client mg_dump)
|
add_custom_target(tools DEPENDS mg_import_csv mg_client)
|
||||||
|
|||||||
Reference in New Issue
Block a user