Compare commits

...

1 Commits

Author SHA1 Message Date
Matej Ferencevic
8ad84e8629 Prepare release v0.50.0
Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2598
2019-12-11 17:48:11 +01:00
39 changed files with 56 additions and 1678 deletions

View File

@@ -1,9 +1,7 @@
- name: Binaries
archive:
- build_debug/memgraph
- build_debug/memgraph_ha
- build_release/memgraph
- build_release/memgraph_ha
- build_release/tools/src/mg_client
- build_release/tools/src/mg_import_csv
- config

View File

@@ -204,21 +204,3 @@ import_external_library(rocksdb STATIC
-DCMAKE_INSTALL_LIBDIR=lib
-DCMAKE_SKIP_INSTALL_ALL_DEPENDENCY=true
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})

View File

@@ -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
# remove shared library from install dependencies
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

View File

@@ -26,6 +26,3 @@ install(PROGRAMS $<TARGET_FILE:example>
RENAME example.so)
# Also install the source of the example, so user can read it.
install(FILES example.c DESTINATION lib/memgraph/query_modules)
add_subdirectory(louvain)
add_subdirectory(connectivity)

View File

@@ -1,3 +1,2 @@
/etc/memgraph/memgraph.conf
/etc/logrotate.d/memgraph
/etc/logrotate.d/memgraph_audit

View File

@@ -7,8 +7,6 @@ add_subdirectory(requests)
add_subdirectory(io)
add_subdirectory(telemetry)
add_subdirectory(communication)
add_subdirectory(auth)
add_subdirectory(slk)
add_subdirectory(storage/v2)
# ----------------------------------------------------------------------------
@@ -32,7 +30,6 @@ add_custom_target(generate_lcp_common DEPENDS ${generated_lcp_common_files})
# ----------------------------------------------------------------------------
set(mg_single_node_sources
${lcp_common_cpp_files}
audit/log.cpp
data_structures/concurrent/skiplist_gc.cpp
database/single_node/config.cpp
database/single_node/graph_db.cpp
@@ -42,14 +39,12 @@ set(mg_single_node_sources
durability/single_node/recovery.cpp
durability/single_node/snapshooter.cpp
durability/single_node/wal.cpp
glue/auth.cpp
glue/communication.cpp
query/common.cpp
query/dump.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
@@ -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
antlr_opencypher_parser_lib dl glog gflags
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)
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
${lcp_common_cpp_files}
audit/log.cpp
glue/auth.cpp
glue/communication.cpp
query/common.cpp
query/dump.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
@@ -142,8 +132,6 @@ set(mg_single_node_v2_sources
set(MG_SINGLE_NODE_V2_LIBS stdc++fs Threads::Threads fmt cppitertools
antlr_opencypher_parser_lib dl glog gflags mg-storage-v2
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)
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
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# 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_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)
@@ -330,8 +228,6 @@ install(FILES ${CMAKE_BINARY_DIR}/config/memgraph.conf
# Install logrotate configuration (must use absolute path).
install(FILES ${CMAKE_SOURCE_DIR}/release/logrotate.conf
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.
install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}/var/log/memgraph
\$ENV{DESTDIR}/var/lib/memgraph)")
@@ -351,18 +247,3 @@ install(
${CMAKE_BINARY_DIR}/tools/src/mg_client
WORKING_DIRECTORY ${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")

View File

@@ -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 ${OPENSSL_LIBRARIES})
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)

View File

@@ -60,10 +60,6 @@ class Session {
/** Aborts currently running query. */
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.
* Goes through the bolt states in order to execute commands from the client.

View File

@@ -60,38 +60,6 @@ State StateInitRun(Session &session) {
LOG(INFO) << fmt::format("Client connected '{}'", client_name.ValueString())
<< 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.
if (!session.encoder_.MessageSuccess()) {
DLOG(WARNING) << "Couldn't send success message to the client!";

View File

@@ -87,16 +87,6 @@ DEFINE_bool(telemetry_enabled, false,
"the database runtime (vertex and edge counts and resource usage) "
"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.
DEFINE_uint64(query_execution_timeout_sec, 180,
"Maximum allowed query execution time. Queries exceeding this "
@@ -116,41 +106,12 @@ using ServerT = communication::Server<BoltSession, SessionData>;
using communication::ServerContext;
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
auto data_directory = std::filesystem::path(FLAGS_data_directory);
#else
auto data_directory = std::filesystem::path(FLAGS_durability_directory);
#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
#ifdef MG_SINGLE_NODE_V2
@@ -190,7 +151,7 @@ void SingleNodeMain() {
query::InterpreterContext interpreter_context{&db};
query::SetExecutionTimeout(&interpreter_context,
FLAGS_query_execution_timeout_sec);
SessionData session_data{&db, &interpreter_context, &auth, &audit_log};
SessionData session_data{&db, &interpreter_context};
// Register modules
if (!FLAGS_query_modules_directory.empty()) {
@@ -202,8 +163,6 @@ void SingleNodeMain() {
}
// Register modules END
interpreter_context.auth = &auth;
ServerContext context;
std::string service_name = "Bolt";
if (!FLAGS_bolt_key_file.empty() && !FLAGS_bolt_cert_file.empty()) {

View File

@@ -3,7 +3,6 @@
#include <glog/logging.h>
#include "config.hpp"
#include "glue/auth.hpp"
#include "glue/communication.hpp"
#include "query/exceptions.hpp"
#include "requests/requests.hpp"
@@ -33,10 +32,6 @@ BoltSession::BoltSession(SessionData *data,
db_(data->db),
#endif
interpreter_(data->interpreter_context),
#ifndef MG_SINGLE_NODE_HA
auth_(data->auth),
audit_log_(data->audit_log),
#endif
endpoint_(endpoint) {
}
@@ -50,28 +45,8 @@ std::vector<std::string> BoltSession::Interpret(
std::map<std::string, PropertyValue> params_pv;
for (const auto &kv : params)
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 {
auto result = 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;
return interpreter_.Prepare(query, params_pv);
} catch (const query::QueryException &e) {
// Wrap QueryException into ClientError, because we want to allow the
// client to fix their query.
@@ -119,17 +94,6 @@ std::map<std::string, communication::bolt::Value> BoltSession::PullAll(
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
BoltSession::TypedValueResultStream::TypedValueResultStream(
TEncoder *encoder, const storage::Storage *db)

View File

@@ -31,16 +31,11 @@ struct SessionData {
// Explicit constructor here to ensure that pointers to all objects are
// supplied.
SessionData(database::GraphDb *_db,
query::InterpreterContext *_interpreter_context,
auth::Auth *_auth, audit::Log *_audit_log)
query::InterpreterContext *_interpreter_context)
: db(_db),
interpreter_context(_interpreter_context),
auth(_auth),
audit_log(_audit_log) {}
interpreter_context(_interpreter_context) {}
database::GraphDb *db;
query::InterpreterContext *interpreter_context;
auth::Auth *auth;
audit::Log *audit_log;
};
class BoltSession final
@@ -63,9 +58,6 @@ class BoltSession final
void Abort() override;
bool Authenticate(const std::string &username,
const std::string &password) override;
private:
/// Wrapper around TEncoder which converts TypedValue to Value
/// before forwarding the calls to original TEncoder.
@@ -92,11 +84,6 @@ class BoltSession final
const storage::Storage *db_;
#endif
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_;
};

View File

@@ -127,19 +127,4 @@ class RemoveAttachedVertexException : public QueryRuntimeException {
"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

View File

@@ -2087,67 +2087,11 @@ cpp<#
(:serialize (:slk))
(: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)
((info-type "InfoType" :scope :public))
(:public
(lcp:define-enum info-type
(storage index constraint raft)
(storage index constraint)
(:serialize))
#>cpp

View File

@@ -62,7 +62,6 @@ class RemoveProperty;
class RemoveLabels;
class Merge;
class Unwind;
class AuthQuery;
class ExplainQuery;
class ProfileQuery;
class IndexQuery;
@@ -113,7 +112,7 @@ class ExpressionVisitor
template <class TResult>
class QueryVisitor
: public ::utils::Visitor<TResult, CypherQuery, ExplainQuery, ProfileQuery,
IndexQuery, AuthQuery, InfoQuery,
IndexQuery, InfoQuery,
ConstraintQuery, DumpQuery> {};
} // namespace query

View File

@@ -62,9 +62,6 @@ antlrcpp::Any CypherMainVisitor::visitInfoQuery(
} else if (ctx->constraintInfo()) {
info_query->info_type_ = InfoQuery::InfoType::CONSTRAINT;
return info_query;
} else if (ctx->raftInfo()) {
info_query->info_type_ = InfoQuery::InfoType::RAFT;
return info_query;
} else {
throw utils::NotYetImplemented("Info query: '{}'", ctx->getText());
}
@@ -174,15 +171,6 @@ antlrcpp::Any CypherMainVisitor::visitDropIndex(
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(
MemgraphCypher::DumpQueryContext *ctx) {
auto *dump_query = storage_->Create<DumpQuery>();
@@ -434,235 +422,6 @@ antlrcpp::Any CypherMainVisitor::visitCallProcedure(
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(
MemgraphCypher::CypherReturnContext *ctx) {
auto *return_clause = storage_->Create<Return>();

View File

@@ -176,11 +176,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
antlrcpp::Any visitConstraintQuery(
MemgraphCypher::ConstraintQueryContext *ctx) override;
/**
* @return AuthQuery*
*/
antlrcpp::Any visitAuthQuery(MemgraphCypher::AuthQueryContext *ctx) override;
/**
* @return DumpQuery*
*/
@@ -219,28 +214,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
*/
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*
*/
@@ -252,79 +225,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
*/
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*
*/

View File

@@ -46,9 +46,7 @@ indexInfo : INDEX INFO ;
constraintInfo : CONSTRAINT INFO ;
raftInfo : RAFT INFO ;
infoQuery : SHOW ( storageInfo | indexInfo | constraintInfo | raftInfo ) ;
infoQuery : SHOW ( storageInfo | indexInfo | constraintInfo ) ;
explainQuery : EXPLAIN cypherQuery ;

View File

@@ -116,7 +116,6 @@ OPTIONAL : O P T I O N A L ;
OR : O R ;
ORDER : O R D E R ;
PROFILE : P R O F I L E ;
RAFT : R A F T ;
REDUCE : R E D U C E ;
REMOVE : R E M O V E ;
RETURN : R E T U R N ;

View File

@@ -7,26 +7,8 @@ options { tokenVocab=MemgraphCypherLexer; }
import Cypher ;
memgraphCypherKeyword : cypherKeyword
| ALTER
| AUTH
| CLEAR
| DATABASE
| DENY
| DROP
| DUMP
| FOR
| FROM
| GRANT
| IDENTIFIED
| PASSWORD
| PRIVILEGES
| REVOKE
| ROLE
| ROLES
| STATS
| TO
| USER
| USERS
;
symbolicName : UnescapedSymbolicName
@@ -40,63 +22,7 @@ query : cypherQuery
| profileQuery
| infoQuery
| constraintQuery
| authQuery
| 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 ;

View File

@@ -10,24 +10,5 @@ lexer grammar MemgraphCypherLexer ;
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 ;
DENY : D E N Y ;
DROP : D R O 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 ;

View File

@@ -4,8 +4,6 @@
#include <glog/logging.h>
#include "auth/auth.hpp"
#include "glue/auth.hpp"
#include "glue/communication.hpp"
#ifndef MG_SINGLE_NODE_HA
#include "query/dump.hpp"
@@ -13,15 +11,11 @@
#include "query/exceptions.hpp"
#include "query/frontend/ast/cypher_main_visitor.hpp"
#include "query/frontend/opencypher/parser.hpp"
#include "query/frontend/semantic/required_privileges.hpp"
#include "query/frontend/semantic/symbol_generator.hpp"
#include "query/interpret/eval.hpp"
#include "query/plan/planner.hpp"
#include "query/plan/profile.hpp"
#include "query/plan/vertex_count_cache.hpp"
#ifdef MG_SINGLE_NODE_HA
#include "raft/exceptions.hpp"
#endif
#include "utils/exceptions.hpp"
#include "utils/flag_validation.hpp"
#include "utils/string.hpp"
@@ -45,7 +39,6 @@ struct ParsedQuery {
frontend::StrippedQuery stripped_query;
AstStorage ast_storage;
Query *query;
std::vector<AuthQuery::Privilege> required_privileges;
};
ParsedQuery ParseQuery(const std::string &query_string,
@@ -105,8 +98,7 @@ ParsedQuery ParseQuery(const std::string &query_string,
visitor.visit(parser->tree());
CachedQuery cached_query{std::move(ast_storage), visitor.query(),
query::GetRequiredPrivileges(visitor.query())};
CachedQuery cached_query{std::move(ast_storage), visitor.query()};
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(stripped_query),
std::move(ast_storage),
query,
it->second.required_privileges};
query};
}
class SingleNodeLogicalPlan final : public LogicalPlan {
@@ -164,302 +155,6 @@ TypedValue EvaluateOptionalExpression(Expression *expression,
return expression ? expression->Accept(*eval) : TypedValue();
}
Callback HandleAuthQuery(AuthQuery *auth_query, auth::Auth *auth,
const Parameters &parameters,
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_context_(interpreter_context) {
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!";
}
return {{}, {}, [handler = std::move(handler)](AnyStream *) {
return {{}, [handler = std::move(handler)](AnyStream *) {
handler();
return QueryHandlerResult::NOTHING;
}};
@@ -663,7 +358,7 @@ PreparedQuery PrepareCypherQuery(
}
return PreparedQuery{
std::move(header), std::move(parsed_query.required_privileges),
std::move(header),
[plan = std::move(plan), parameters = std::move(parsed_query.parameters),
output_symbols = std::move(output_symbols), summary, dba,
interpreter_context, execution_memory](AnyStream *stream) {
@@ -717,7 +412,6 @@ PreparedQuery PrepareExplainQuery(
return PreparedQuery{
{"QUERY PLAN"},
std::move(parsed_query.required_privileges),
[rows = std::move(printed_plan_rows)](AnyStream *stream) {
for (const auto &row : rows) {
stream->Result(row);
@@ -769,7 +463,6 @@ PreparedQuery PrepareProfileQuery(
return PreparedQuery{
{"OPERATOR", "ACTUAL HITS", "RELATIVE TIME", "ABSOLUTE TIME"},
std::move(parsed_query.required_privileges),
[plan = std::move(cypher_query_plan),
parameters = std::move(parsed_inner_query.parameters), summary, dba,
interpreter_context, execution_memory](AnyStream *stream) {
@@ -797,7 +490,6 @@ PreparedQuery PrepareDumpQuery(
#ifndef MG_SINGLE_NODE_HA
return PreparedQuery{
{"QUERY"},
std::move(parsed_query.required_privileges),
[interpreter_context](AnyStream *stream) {
auto dba = interpreter_context->db->Access();
query::DbAccessor query_dba{&dba};
@@ -913,7 +605,6 @@ PreparedQuery PrepareIndexQuery(
}
return PreparedQuery{{},
std::move(parsed_query.required_privileges),
[handler = std::move(handler)](AnyStream *stream) {
handler();
#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(
ParsedQuery parsed_query, std::map<std::string, TypedValue> *summary,
InterpreterContext *interpreter_context,
@@ -1102,26 +747,9 @@ PreparedQuery PrepareInfoQuery(
};
break;
#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),
std::move(parsed_query.required_privileges),
[handler = std::move(handler)](AnyStream *stream) {
auto [results, action] = handler();
@@ -1246,14 +874,13 @@ PreparedQuery PrepareConstraintQuery(
}
return PreparedQuery{{},
std::move(parsed_query.required_privileges),
[handler = std::move(handler)](AnyStream *stream) {
handler();
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,
const std::map<std::string, PropertyValue> &params) {
// Clear the last prepared query.
@@ -1266,7 +893,7 @@ Interpreter::Prepare(const std::string &query_string,
if (query_upper == "BEGIN" || query_upper == "COMMIT" ||
query_upper == "ROLLBACK") {
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
@@ -1318,17 +945,6 @@ Interpreter::Prepare(const std::string &query_string,
}
#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;
PreparedQuery prepared_query;
@@ -1357,10 +973,6 @@ Interpreter::Prepare(const std::string &query_string,
prepared_query = PrepareIndexQuery(
std::move(parsed_query), in_explicit_transaction_, &summary_,
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)) {
#ifdef MG_SINGLE_NODE_V2
prepared_query = PrepareInfoQuery(
@@ -1388,7 +1000,7 @@ Interpreter::Prepare(const std::string &query_string,
summary_["planning_time"] = planning_timer.Elapsed().count();
prepared_query_ = std::move(prepared_query);
return {prepared_query_->header, prepared_query_->privileges};
return prepared_query_->header;
} catch (const utils::BasicException &) {
AbortCommand();
throw;

View File

@@ -21,10 +21,6 @@
DECLARE_bool(query_cost_planner);
DECLARE_int32(query_plan_cache_ttl);
namespace auth {
class Auth;
} // namespace auth
namespace query {
static constexpr size_t kExecutionMemoryBlockSize = 1U * 1024U * 1024U;
@@ -36,7 +32,6 @@ enum class QueryHandlerResult { COMMIT, ABORT, NOTHING };
*/
struct PreparedQuery {
std::vector<std::string> header;
std::vector<AuthQuery::Privilege> privileges;
std::function<QueryHandlerResult(AnyStream *stream)> query_handler;
};
@@ -74,7 +69,6 @@ class CachedPlan {
struct CachedQuery {
AstStorage ast_storage;
Query *query;
std::vector<AuthQuery::Privilege> required_privileges;
};
struct QueryCacheEntry {
@@ -144,8 +138,6 @@ struct InterpreterContext {
// The default execution timeout is 3 minutes.
double execution_timeout_sec{180.0};
auth::Auth *auth{nullptr};
utils::SkipList<QueryCacheEntry> ast_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
* @throw query::QueryException
*/
std::pair<std::vector<std::string>, std::vector<query::AuthQuery::Privilege>>
std::vector<std::string>
Prepare(const std::string &query,
const std::map<std::string, PropertyValue> &params);

View File

@@ -23,6 +23,3 @@ add_subdirectory(property_based)
# integration test binaries
add_subdirectory(integration)
# feature benchmark test binaries
add_subdirectory(feature_benchmark)

View File

@@ -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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
target_link_libraries(${test_prefix}storage_v2_gc mg-storage-v2)

View File

@@ -5,7 +5,6 @@
#include "communication/result_stream_faker.hpp"
#include "query/frontend/opencypher/parser.hpp"
#include "query/frontend/semantic/required_privileges.hpp"
#include "query/frontend/semantic/symbol_generator.hpp"
#include "query/interpreter.hpp"
#include "query/plan/planner.hpp"

View File

@@ -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

View File

@@ -6,30 +6,3 @@ add_subdirectory(ssl)
# transactions test binaries
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)

View File

@@ -22,105 +22,3 @@
- runner.sh # runner script
- ../../../build_debug/memgraph # memgraph 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

View File

@@ -30,30 +30,23 @@ target_link_libraries(${test_prefix}binomial mg-utils)
add_manual_test(bolt_client.cpp)
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)
target_link_libraries(${test_prefix}kvstore_console kvstore_lib gflags glog)
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)
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)
target_link_libraries(${test_prefix}query_planner readline)
endif()
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)
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)
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)
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)
target_link_libraries(${test_prefix}ssl_client mg-communication)

View File

@@ -16,7 +16,7 @@ int main(int argc, char *argv[]) {
query::Interpreter interpreter{&interpreter_context};
ResultStreamFaker stream(&db);
auto [header, _] = interpreter.Prepare(argv[1], {});
auto header = interpreter.Prepare(argv[1], {});
stream.Header(header);
auto summary = interpreter.PullAll(&stream);
stream.Summary(summary);

View File

@@ -15,18 +15,6 @@
commands: TIMEOUT=43200 ./continuous_integration --large-dataset
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
commands: TIMEOUT=300 ./ve3/bin/python3 durability --num-steps 5
infiles: &DURABILITY_INFILES

View File

@@ -19,7 +19,7 @@ function(add_unit_test test_cpp)
endfunction(add_unit_test)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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
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)
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)
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
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)
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)
# 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)
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)
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)
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)
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)
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)
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)
target_link_libraries(${test_prefix}transaction_engine_single_node mg-single-node kvstore_dummy_lib)
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)
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)
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
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)
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
add_unit_test(property_value_v2.cpp)

View File

@@ -50,11 +50,6 @@ class TestSession : public Session<TestInputStream, TestOutputStream> {
void Abort() override {}
bool Authenticate(const std::string &username,
const std::string &password) override {
return true;
}
private:
std::string query_;
};

View File

@@ -2119,230 +2119,6 @@ TEST_P(CypherMainVisitorTest, UnionAll) {
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) {
auto &ast_generator = *GetParam();
EXPECT_TRUE(dynamic_cast<ExplainQuery *>(

View File

@@ -40,7 +40,7 @@ class InterpreterTest : public ::testing::Test {
const std::map<std::string, PropertyValue> &params = {}) {
ResultStreamFaker stream(&db_);
auto [header, _] = interpreter_.Prepare(query, params);
auto header = interpreter_.Prepare(query, params);
stream.Header(header);
auto summary = interpreter_.PullAll(&stream);
stream.Summary(summary);

View File

@@ -184,7 +184,7 @@ auto Execute(storage::Storage *db, const std::string &query) {
query::Interpreter interpreter(&context);
ResultStreamFaker stream(db);
auto [header, _] = interpreter.Prepare(query, {});
auto header = interpreter.Prepare(query, {});
stream.Header(header);
auto summary = interpreter.PullAll(&stream);
stream.Summary(summary);

View File

@@ -39,7 +39,7 @@ class QueryExecution : public testing::Test {
auto Execute(const std::string &query) {
ResultStreamFaker stream(&*db_);
auto [header, _] = interpreter_->Prepare(query, {});
auto header = interpreter_->Prepare(query, {});
stream.Header(header);
auto summary = interpreter_->PullAll(&stream);
stream.Summary(summary);

View File

@@ -15,11 +15,6 @@ if (READLINE_FOUND)
endif()
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.
string(TOLOWER ${CMAKE_BUILD_TYPE} lower_build_type)
if (lower_build_type STREQUAL "release")
@@ -37,4 +32,4 @@ endif()
install(TARGETS mg_client RUNTIME DESTINATION bin)
# 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)