From 201f75e8099bc2939bdf4208c54dca1a9cf8b108 Mon Sep 17 00:00:00 2001 From: niko4299 <51059248+niko4299@users.noreply.github.com> Date: Wed, 14 Sep 2022 01:10:28 +0200 Subject: [PATCH] Add MG_ENTERPRISE and license checks (#547) --- src/auth/models.cpp | 110 ++++++++-- src/auth/models.hpp | 33 ++- src/glue/auth.cpp | 2 + src/glue/auth.hpp | 3 +- src/glue/auth_checker.cpp | 30 ++- src/glue/auth_checker.hpp | 7 +- src/glue/auth_handler.cpp | 188 +++++++++++++----- src/glue/auth_handler.hpp | 49 ++++- src/query/auth_checker.hpp | 9 +- src/query/context.hpp | 2 + src/query/interpreter.cpp | 62 +++++- src/query/interpreter.hpp | 39 ++-- src/query/plan/operator.cpp | 152 +++++++++----- src/query/procedure/mg_procedure_impl.cpp | 82 +++++--- tests/unit/auth.cpp | 5 + tests/unit/auth_checker.cpp | 4 + tests/unit/auth_handler.cpp | 43 ++-- tests/unit/bfs_common.hpp | 2 + tests/unit/bfs_fine_grained.cpp | 9 +- tests/unit/query_plan_common.hpp | 3 +- .../query_plan_create_set_remove_delete.cpp | 32 +++ tests/unit/query_plan_match_filter_return.cpp | 37 ++++ tests/unit/query_required_privileges.cpp | 5 +- tests/unit/query_trigger.cpp | 3 + 24 files changed, 703 insertions(+), 208 deletions(-) diff --git a/src/auth/models.cpp b/src/auth/models.cpp index 9b840d8dd..e51b000b0 100644 --- a/src/auth/models.cpp +++ b/src/auth/models.cpp @@ -101,6 +101,7 @@ std::string PermissionLevelToString(PermissionLevel level) { } } +#ifdef MG_ENTERPRISE FineGrainedPermission PermissionToFineGrainedPermission(const uint64_t permission) { if (permission & FineGrainedPermission::CREATE_DELETE) { return FineGrainedPermission::CREATE_DELETE; @@ -147,6 +148,7 @@ FineGrainedAccessPermissions Merge(const FineGrainedAccessPermissions &first, return FineGrainedAccessPermissions(permissions, global_permission); } +#endif Permissions::Permissions(uint64_t grants, uint64_t denies) { // The deny bitmask has higher priority than the grant bitmask. @@ -233,12 +235,16 @@ bool operator==(const Permissions &first, const Permissions &second) { bool operator!=(const Permissions &first, const Permissions &second) { return !(first == second); } +#ifdef MG_ENTERPRISE FineGrainedAccessPermissions::FineGrainedAccessPermissions(const std::unordered_map<std::string, uint64_t> &permissions, const std::optional<uint64_t> &global_permission) : permissions_(permissions), global_permission_(global_permission) {} PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission, const FineGrainedPermission fine_grained_permission) const { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return PermissionLevel::GRANT; + } const auto concrete_permission = std::invoke([&]() -> uint64_t { if (permissions_.contains(permission)) { return permissions_.at(permission); @@ -284,6 +290,9 @@ void FineGrainedAccessPermissions::Deny(const std::string &permission, } nlohmann::json FineGrainedAccessPermissions::Serialize() const { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return {}; + } nlohmann::json data = nlohmann::json::object(); data["permissions"] = permissions_; data["global_permission"] = global_permission_.has_value() ? global_permission_.value() : -1; @@ -294,7 +303,9 @@ FineGrainedAccessPermissions FineGrainedAccessPermissions::Deserialize(const nlo if (!data.is_object()) { throw AuthException("Couldn't load permissions data!"); } - + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return FineGrainedAccessPermissions{}; + } std::optional<uint64_t> global_permission; if (data["global_permission"].empty() || data["global_permission"] == -1) { @@ -358,6 +369,9 @@ const FineGrainedAccessPermissions &FineGrainedAccessHandler::edge_type_permissi FineGrainedAccessPermissions &FineGrainedAccessHandler::edge_type_permissions() { return edge_type_permissions_; } nlohmann::json FineGrainedAccessHandler::Serialize() const { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return {}; + } nlohmann::json data = nlohmann::json::object(); data["label_permissions"] = label_permissions_.Serialize(); data["edge_type_permissions"] = edge_type_permissions_.Serialize(); @@ -371,6 +385,9 @@ FineGrainedAccessHandler FineGrainedAccessHandler::Deserialize(const nlohmann::j if (!data["label_permissions"].is_object() || !data["edge_type_permissions"].is_object()) { throw AuthException("Couldn't load label_permissions or edge_type_permissions data!"); } + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return FineGrainedAccessHandler{}; + } auto label_permissions = FineGrainedAccessPermissions::Deserialize(data["label_permissions"]); auto edge_type_permissions = FineGrainedAccessPermissions::Deserialize(data["edge_type_permissions"]); @@ -385,18 +402,23 @@ bool operator==(const FineGrainedAccessHandler &first, const FineGrainedAccessHa bool operator!=(const FineGrainedAccessHandler &first, const FineGrainedAccessHandler &second) { return !(first == second); } +#endif Role::Role(const std::string &rolename) : rolename_(utils::ToLowerCase(rolename)) {} - +Role::Role(const std::string &rolename, const Permissions &permissions) + : rolename_(utils::ToLowerCase(rolename)), permissions_(permissions) {} +#ifdef MG_ENTERPRISE Role::Role(const std::string &rolename, const Permissions &permissions, FineGrainedAccessHandler fine_grained_access_handler) : rolename_(utils::ToLowerCase(rolename)), permissions_(permissions), fine_grained_access_handler_(std::move(fine_grained_access_handler)) {} +#endif const std::string &Role::rolename() const { return rolename_; } const Permissions &Role::permissions() const { return permissions_; } Permissions &Role::permissions() { return permissions_; } +#ifdef MG_ENTERPRISE const FineGrainedAccessHandler &Role::fine_grained_access_handler() const { return fine_grained_access_handler_; } FineGrainedAccessHandler &Role::fine_grained_access_handler() { return fine_grained_access_handler_; } @@ -407,12 +429,19 @@ const FineGrainedAccessPermissions &Role::GetFineGrainedAccessLabelPermissions() const FineGrainedAccessPermissions &Role::GetFineGrainedAccessEdgeTypePermissions() const { return fine_grained_access_handler_.edge_type_permissions(); } +#endif nlohmann::json Role::Serialize() const { nlohmann::json data = nlohmann::json::object(); data["rolename"] = rolename_; data["permissions"] = permissions_.Serialize(); - data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize(); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize(); + } else { + data["fine_grained_access_handler"] = {}; + } +#endif return data; } @@ -420,30 +449,46 @@ Role Role::Deserialize(const nlohmann::json &data) { if (!data.is_object()) { throw AuthException("Couldn't load role data!"); } - if (!data["rolename"].is_string() || !data["permissions"].is_object() || - !data["fine_grained_access_handler"].is_object()) { + if (!data["rolename"].is_string() || !data["permissions"].is_object()) { throw AuthException("Couldn't load role data!"); } auto permissions = Permissions::Deserialize(data["permissions"]); - auto fine_grained_access_handler = FineGrainedAccessHandler::Deserialize(data["fine_grained_access_handler"]); - return {data["rolename"], permissions, std::move(fine_grained_access_handler)}; +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + if (!data["fine_grained_access_handler"].is_object()) { + throw AuthException("Couldn't load user data!"); + } + auto fine_grained_access_handler = FineGrainedAccessHandler::Deserialize(data["fine_grained_access_handler"]); + return {data["rolename"], permissions, std::move(fine_grained_access_handler)}; + } +#endif + return {data["rolename"], permissions}; } bool operator==(const Role &first, const Role &second) { - return first.rolename_ == second.rolename_ && first.permissions_ == second.permissions_ && - first.fine_grained_access_handler_ == second.fine_grained_access_handler_; +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return first.rolename_ == second.rolename_ && first.permissions_ == second.permissions_ && + first.fine_grained_access_handler_ == second.fine_grained_access_handler_; + } +#endif + return first.rolename_ == second.rolename_ && first.permissions_ == second.permissions_; } User::User() {} User::User(const std::string &username) : username_(utils::ToLowerCase(username)) {} +User::User(const std::string &username, const std::string &password_hash, const Permissions &permissions) + : username_(utils::ToLowerCase(username)), password_hash_(password_hash), permissions_(permissions) {} +#ifdef MG_ENTERPRISE User::User(const std::string &username, const std::string &password_hash, const Permissions &permissions, FineGrainedAccessHandler fine_grained_access_handler) : username_(utils::ToLowerCase(username)), password_hash_(password_hash), permissions_(permissions), fine_grained_access_handler_(std::move(fine_grained_access_handler)) {} +#endif bool User::CheckPassword(const std::string &password) { if (password_hash_.empty()) return true; @@ -492,29 +537,41 @@ Permissions User::GetPermissions() const { return permissions_; } +#ifdef MG_ENTERPRISE FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return FineGrainedAccessPermissions{}; + } + if (role_) { return Merge(role()->fine_grained_access_handler().label_permissions(), fine_grained_access_handler_.label_permissions()); } + return fine_grained_access_handler_.label_permissions(); } FineGrainedAccessPermissions User::GetFineGrainedAccessEdgeTypePermissions() const { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return FineGrainedAccessPermissions{}; + } if (role_) { return Merge(role()->fine_grained_access_handler().edge_type_permissions(), fine_grained_access_handler_.edge_type_permissions()); } return fine_grained_access_handler_.edge_type_permissions(); } +#endif const std::string &User::username() const { return username_; } const Permissions &User::permissions() const { return permissions_; } Permissions &User::permissions() { return permissions_; } +#ifdef MG_ENTERPRISE const FineGrainedAccessHandler &User::fine_grained_access_handler() const { return fine_grained_access_handler_; } -FineGrainedAccessHandler &User::fine_grained_access_handler() { return fine_grained_access_handler_; } +FineGrainedAccessHandler &User::fine_grained_access_handler() { return fine_grained_access_handler_; } +#endif const Role *User::role() const { if (role_.has_value()) { return &role_.value(); @@ -527,7 +584,13 @@ nlohmann::json User::Serialize() const { data["username"] = username_; data["password_hash"] = password_hash_; data["permissions"] = permissions_.Serialize(); - data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize(); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + data["fine_grained_access_handler"] = fine_grained_access_handler_.Serialize(); + } else { + data["fine_grained_access_handler"] = {}; + } +#endif // The role shouldn't be serialized here, it is stored as a foreign key. return data; } @@ -536,19 +599,32 @@ User User::Deserialize(const nlohmann::json &data) { if (!data.is_object()) { throw AuthException("Couldn't load user data!"); } - if (!data["username"].is_string() || !data["password_hash"].is_string() || !data["permissions"].is_object() || - !data["fine_grained_access_handler"].is_object()) { + if (!data["username"].is_string() || !data["password_hash"].is_string() || !data["permissions"].is_object()) { throw AuthException("Couldn't load user data!"); } auto permissions = Permissions::Deserialize(data["permissions"]); - auto fine_grained_access_handler = FineGrainedAccessHandler::Deserialize(data["fine_grained_access_handler"]); - return {data["username"], data["password_hash"], permissions, fine_grained_access_handler}; +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + if (!data["fine_grained_access_handler"].is_object()) { + throw AuthException("Couldn't load user data!"); + } + auto fine_grained_access_handler = FineGrainedAccessHandler::Deserialize(data["fine_grained_access_handler"]); + return {data["username"], data["password_hash"], permissions, fine_grained_access_handler}; + } +#endif + return {data["username"], data["password_hash"], permissions}; } bool operator==(const User &first, const User &second) { +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return first.username_ == second.username_ && first.password_hash_ == second.password_hash_ && + first.permissions_ == second.permissions_ && first.role_ == second.role_ && + first.fine_grained_access_handler_ == second.fine_grained_access_handler_; + } +#endif return first.username_ == second.username_ && first.password_hash_ == second.password_hash_ && - first.permissions_ == second.permissions_ && first.role_ == second.role_ && - first.fine_grained_access_handler_ == second.fine_grained_access_handler_; + first.permissions_ == second.permissions_ && first.role_ == second.role_; } } // namespace memgraph::auth diff --git a/src/auth/models.hpp b/src/auth/models.hpp index 0b66cf928..f273f84f9 100644 --- a/src/auth/models.hpp +++ b/src/auth/models.hpp @@ -44,6 +44,7 @@ enum class Permission : uint64_t { }; // clang-format on +#ifdef MG_ENTERPRISE // clang-format off enum class FineGrainedPermission : uint64_t { NO_PERMISSION = 0, @@ -70,6 +71,7 @@ constexpr uint64_t kLabelPermissionAll = memgraph::auth::FineGrainedPermission:: memgraph::auth::FineGrainedPermission::READ; constexpr uint64_t kLabelPermissionMax = static_cast<uint64_t>(memgraph::auth::FineGrainedPermission::CREATE_DELETE); constexpr uint64_t kLabelPermissionMin = static_cast<uint64_t>(memgraph::auth::FineGrainedPermission::READ); +#endif // Function that converts a permission to its string representation. std::string PermissionToString(Permission permission); @@ -80,11 +82,13 @@ enum class PermissionLevel : uint8_t { GRANT, NEUTRAL, DENY }; // Function that converts a permission level to its string representation. std::string PermissionLevelToString(PermissionLevel level); +#ifdef MG_ENTERPRISE // Function that converts a label permission level to its string representation. std::string FineGrainedPermissionToString(FineGrainedPermission level); // Constructs a label permission from a permission FineGrainedPermission PermissionToFineGrainedPermission(uint64_t permission); +#endif class Permissions final { public: @@ -125,6 +129,7 @@ bool operator==(const Permissions &first, const Permissions &second); bool operator!=(const Permissions &first, const Permissions &second); +#ifdef MG_ENTERPRISE class FineGrainedAccessPermissions final { public: explicit FineGrainedAccessPermissions(const std::unordered_map<std::string, uint64_t> &permissions = {}, @@ -192,14 +197,16 @@ class FineGrainedAccessHandler final { }; bool operator==(const FineGrainedAccessHandler &first, const FineGrainedAccessHandler &second); +#endif class Role final { public: explicit Role(const std::string &rolename); - + Role(const std::string &rolename, const Permissions &permissions); +#ifdef MG_ENTERPRISE Role(const std::string &rolename, const Permissions &permissions, FineGrainedAccessHandler fine_grained_access_handler); - +#endif Role(const Role &) = default; Role &operator=(const Role &) = default; Role(Role &&) noexcept = default; @@ -209,11 +216,12 @@ class Role final { const std::string &rolename() const; const Permissions &permissions() const; Permissions &permissions(); +#ifdef MG_ENTERPRISE const FineGrainedAccessHandler &fine_grained_access_handler() const; FineGrainedAccessHandler &fine_grained_access_handler(); const FineGrainedAccessPermissions &GetFineGrainedAccessLabelPermissions() const; const FineGrainedAccessPermissions &GetFineGrainedAccessEdgeTypePermissions() const; - +#endif nlohmann::json Serialize() const; /// @throw AuthException if unable to deserialize. @@ -224,7 +232,9 @@ class Role final { private: std::string rolename_; Permissions permissions_; +#ifdef MG_ENTERPRISE FineGrainedAccessHandler fine_grained_access_handler_; +#endif }; bool operator==(const Role &first, const Role &second); @@ -235,10 +245,11 @@ class User final { User(); explicit User(const std::string &username); - + User(const std::string &username, const std::string &password_hash, const Permissions &permissions); +#ifdef MG_ENTERPRISE User(const std::string &username, const std::string &password_hash, const Permissions &permissions, FineGrainedAccessHandler fine_grained_access_handler); - +#endif User(const User &) = default; User &operator=(const User &) = default; User(User &&) noexcept = default; @@ -256,15 +267,17 @@ class User final { void ClearRole(); Permissions GetPermissions() const; + +#ifdef MG_ENTERPRISE FineGrainedAccessPermissions GetFineGrainedAccessLabelPermissions() const; FineGrainedAccessPermissions GetFineGrainedAccessEdgeTypePermissions() const; - + const FineGrainedAccessHandler &fine_grained_access_handler() const; + FineGrainedAccessHandler &fine_grained_access_handler(); +#endif const std::string &username() const; const Permissions &permissions() const; Permissions &permissions(); - const FineGrainedAccessHandler &fine_grained_access_handler() const; - FineGrainedAccessHandler &fine_grained_access_handler(); const Role *role() const; @@ -279,12 +292,16 @@ class User final { std::string username_; std::string password_hash_; Permissions permissions_; +#ifdef MG_ENTERPRISE FineGrainedAccessHandler fine_grained_access_handler_; +#endif std::optional<Role> role_; }; bool operator==(const User &first, const User &second); +#ifdef MG_ENTERPRISE FineGrainedAccessPermissions Merge(const FineGrainedAccessPermissions &first, const FineGrainedAccessPermissions &second); +#endif } // namespace memgraph::auth diff --git a/src/glue/auth.cpp b/src/glue/auth.cpp index f7ce72e0f..c78ec3950 100644 --- a/src/glue/auth.cpp +++ b/src/glue/auth.cpp @@ -61,6 +61,7 @@ auth::Permission PrivilegeToPermission(query::AuthQuery::Privilege privilege) { } } +#ifdef MG_ENTERPRISE auth::FineGrainedPermission FineGrainedPrivilegeToFineGrainedPermission( const query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) { switch (fine_grained_privilege) { @@ -72,4 +73,5 @@ auth::FineGrainedPermission FineGrainedPrivilegeToFineGrainedPermission( return auth::FineGrainedPermission::CREATE_DELETE; } } +#endif } // namespace memgraph::glue diff --git a/src/glue/auth.hpp b/src/glue/auth.hpp index 50e4e70e0..f91529f9d 100644 --- a/src/glue/auth.hpp +++ b/src/glue/auth.hpp @@ -20,11 +20,12 @@ namespace memgraph::glue { */ auth::Permission PrivilegeToPermission(query::AuthQuery::Privilege privilege); +#ifdef MG_ENTERPRISE /** * Converts query::AuthQuery::FineGrainedPrivilege to its corresponding * auth::EntityPermission. */ auth::FineGrainedPermission FineGrainedPrivilegeToFineGrainedPermission( query::AuthQuery::FineGrainedPrivilege fine_grained_privilege); - +#endif } // namespace memgraph::glue diff --git a/src/glue/auth_checker.cpp b/src/glue/auth_checker.cpp index 08e7fbbf1..80c996ad4 100644 --- a/src/glue/auth_checker.cpp +++ b/src/glue/auth_checker.cpp @@ -15,12 +15,17 @@ #include "auth/models.hpp" #include "glue/auth.hpp" #include "query/frontend/ast/ast.hpp" +#include "utils/license.hpp" #include "utils/synchronized.hpp" +#ifdef MG_ENTERPRISE namespace { bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba, const std::vector<memgraph::storage::LabelId> &labels, const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return true; + } return std::all_of(labels.begin(), labels.end(), [dba, &user, fine_grained_privilege](const auto &label) { return user.GetFineGrainedAccessLabelPermissions().Has( dba->LabelToName(label), memgraph::glue::FineGrainedPrivilegeToFineGrainedPermission( @@ -30,12 +35,18 @@ bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::qu bool IsUserAuthorizedGloballyLabels(const memgraph::auth::User &user, const memgraph::auth::FineGrainedPermission fine_grained_permission) { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return true; + } return user.GetFineGrainedAccessLabelPermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) == memgraph::auth::PermissionLevel::GRANT; } bool IsUserAuthorizedGloballyEdges(const memgraph::auth::User &user, const memgraph::auth::FineGrainedPermission fine_grained_permission) { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return true; + } return user.GetFineGrainedAccessEdgeTypePermissions().Has(memgraph::auth::kAsterisk, fine_grained_permission) == memgraph::auth::PermissionLevel::GRANT; } @@ -43,12 +54,15 @@ bool IsUserAuthorizedGloballyEdges(const memgraph::auth::User &user, bool IsUserAuthorizedEdgeType(const memgraph::auth::User &user, const memgraph::query::DbAccessor *dba, const memgraph::storage::EdgeTypeId &edgeType, const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return true; + } return user.GetFineGrainedAccessEdgeTypePermissions().Has( dba->EdgeTypeToName(edgeType), memgraph::glue::FineGrainedPrivilegeToFineGrainedPermission( fine_grained_privilege)) == memgraph::auth::PermissionLevel::GRANT; } } // namespace - +#endif namespace memgraph::glue { AuthChecker::AuthChecker( @@ -70,9 +84,12 @@ bool AuthChecker::IsUserAuthorized(const std::optional<std::string> &username, return maybe_user.has_value() && IsUserAuthorized(*maybe_user, privileges); } - +#ifdef MG_ENTERPRISE std::unique_ptr<memgraph::query::FineGrainedAuthChecker> AuthChecker::GetFineGrainedAuthChecker( const std::string &username, const memgraph::query::DbAccessor *dba) const { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return {}; + } try { auto locked_auth = auth_->Lock(); auto user = locked_auth->GetUser(username); @@ -86,6 +103,7 @@ std::unique_ptr<memgraph::query::FineGrainedAuthChecker> AuthChecker::GetFineGra throw memgraph::query::QueryRuntimeException(e.what()); } } +#endif bool AuthChecker::IsUserAuthorized(const memgraph::auth::User &user, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges) { @@ -96,6 +114,7 @@ bool AuthChecker::IsUserAuthorized(const memgraph::auth::User &user, }); } +#ifdef MG_ENTERPRISE FineGrainedAuthChecker::FineGrainedAuthChecker(auth::User user, const memgraph::query::DbAccessor *dba) : user_{std::move(user)}, dba_(dba){}; @@ -135,11 +154,18 @@ bool FineGrainedAuthChecker::Has(const memgraph::storage::EdgeTypeId &edge_type, bool FineGrainedAuthChecker::HasGlobalPrivilegeOnVertices( const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return true; + } return IsUserAuthorizedGloballyLabels(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege)); } bool FineGrainedAuthChecker::HasGlobalPrivilegeOnEdges( const memgraph::query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) const { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return true; + } return IsUserAuthorizedGloballyEdges(user_, FineGrainedPrivilegeToFineGrainedPermission(fine_grained_privilege)); }; +#endif } // namespace memgraph::glue diff --git a/src/glue/auth_checker.hpp b/src/glue/auth_checker.hpp index 56ffe4510..f5e9bc526 100644 --- a/src/glue/auth_checker.hpp +++ b/src/glue/auth_checker.hpp @@ -26,17 +26,17 @@ class AuthChecker : public query::AuthChecker { bool IsUserAuthorized(const std::optional<std::string> &username, const std::vector<query::AuthQuery::Privilege> &privileges) const override; - +#ifdef MG_ENTERPRISE std::unique_ptr<memgraph::query::FineGrainedAuthChecker> GetFineGrainedAuthChecker( const std::string &username, const memgraph::query::DbAccessor *dba) const override; - +#endif [[nodiscard]] static bool IsUserAuthorized(const memgraph::auth::User &user, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges); private: memgraph::utils::Synchronized<memgraph::auth::Auth, memgraph::utils::WritePrioritizedRWLock> *auth_; }; - +#ifdef MG_ENTERPRISE class FineGrainedAuthChecker : public query::FineGrainedAuthChecker { public: explicit FineGrainedAuthChecker(auth::User user, const memgraph::query::DbAccessor *dba); @@ -63,4 +63,5 @@ class FineGrainedAuthChecker : public query::FineGrainedAuthChecker { auth::User user_; const memgraph::query::DbAccessor *dba_; }; +#endif } // namespace memgraph::glue diff --git a/src/glue/auth_handler.cpp b/src/glue/auth_handler.cpp index aaed51c66..ae07b411f 100644 --- a/src/glue/auth_handler.cpp +++ b/src/glue/auth_handler.cpp @@ -17,6 +17,7 @@ #include "auth/models.hpp" #include "glue/auth.hpp" +#include "utils/license.hpp" namespace { @@ -28,7 +29,9 @@ struct PermissionForPrivilegeResult { struct FineGrainedPermissionForPrivilegeResult { std::string permission; +#ifdef MG_ENTERPRISE memgraph::auth::FineGrainedPermission permission_level; +#endif std::string description; }; @@ -117,10 +120,14 @@ std::vector<std::vector<memgraph::query::TypedValue>> ShowRolePrivileges( return ConstructPrivilegesResult(privilege_results); } +#ifdef MG_ENTERPRISE std::vector<FineGrainedPermissionForPrivilegeResult> GetFineGrainedPermissionForPrivilegeForUserOrRole( const memgraph::auth::FineGrainedAccessPermissions &permissions, const std::string &permission_type, const std::string &user_or_role) { std::vector<FineGrainedPermissionForPrivilegeResult> fine_grained_permissions; + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return fine_grained_permissions; + } const auto global_permission = permissions.GetGlobalPermission(); if (global_permission.has_value()) { const auto &permission_level = memgraph::auth::PermissionToFineGrainedPermission(global_permission.value()); @@ -159,7 +166,9 @@ std::vector<FineGrainedPermissionForPrivilegeResult> GetFineGrainedPermissionFor std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivilegesResult( const std::vector<FineGrainedPermissionForPrivilegeResult> &privileges) { std::vector<std::vector<memgraph::query::TypedValue>> grants; - + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return {}; + } grants.reserve(privileges.size()); for (const auto &permission : privileges) { grants.push_back( @@ -173,6 +182,9 @@ std::vector<std::vector<memgraph::query::TypedValue>> ConstructFineGrainedPrivil std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedUserPrivileges( const std::optional<memgraph::auth::User> &user) { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return {}; + } const auto &label_permissions = user->GetFineGrainedAccessLabelPermissions(); const auto &edge_type_permissions = user->GetFineGrainedAccessEdgeTypePermissions(); @@ -189,6 +201,9 @@ std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedUserPrivile std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedRolePrivileges( const std::optional<memgraph::auth::Role> &role) { + if (!memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + return {}; + } const auto &label_permissions = role->GetFineGrainedAccessLabelPermissions(); const auto &edge_type_permissions = role->GetFineGrainedAccessEdgeTypePermissions(); @@ -202,6 +217,8 @@ std::vector<std::vector<memgraph::query::TypedValue>> ShowFineGrainedRolePrivile return ConstructFineGrainedPrivilegesResult(all_fine_grained_permissions); } +#endif + } // namespace namespace memgraph::glue { @@ -236,10 +253,21 @@ bool AuthQueryHandler::CreateUser(const std::string &username, const std::option if (first_user) { spdlog::info("{} is first created user. Granting all privileges.", username); - GrantPrivilege( - username, memgraph::query::kPrivilegesAll, - {{{memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE, {memgraph::auth::kAsterisk}}}}, - {{{memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE, {memgraph::auth::kAsterisk}}}}); + GrantPrivilege(username, memgraph::query::kPrivilegesAll +#ifdef MG_ENTERPRISE + , + {{{memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE, {memgraph::auth::kAsterisk}}}}, + { + { + { + memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE, { + memgraph::auth::kAsterisk + } + } + } + } +#endif + ); } return user_added; @@ -433,7 +461,9 @@ std::vector<std::vector<memgraph::query::TypedValue>> AuthQueryHandler::GetPrivi try { auto locked_auth = auth_->ReadLock(); std::vector<std::vector<memgraph::query::TypedValue>> grants; +#ifdef MG_ENTERPRISE std::vector<std::vector<memgraph::query::TypedValue>> fine_grained_grants; +#endif auto user = locked_auth->GetUser(user_or_role); auto role = locked_auth->GetRole(user_or_role); if (!user && !role) { @@ -442,14 +472,24 @@ std::vector<std::vector<memgraph::query::TypedValue>> AuthQueryHandler::GetPrivi if (user) { grants = ShowUserPrivileges(user); - fine_grained_grants = ShowFineGrainedUserPrivileges(user); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + fine_grained_grants = ShowFineGrainedUserPrivileges(user); + } +#endif } else { grants = ShowRolePrivileges(role); - fine_grained_grants = ShowFineGrainedRolePrivileges(role); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + fine_grained_grants = ShowFineGrainedRolePrivileges(role); + } +#endif } - - grants.insert(grants.end(), fine_grained_grants.begin(), fine_grained_grants.end()); - +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + grants.insert(grants.end(), fine_grained_grants.begin(), fine_grained_grants.end()); + } +#endif return grants; } catch (const memgraph::auth::AuthException &e) { throw memgraph::query::QueryRuntimeException(e.what()); @@ -457,19 +497,28 @@ std::vector<std::vector<memgraph::query::TypedValue>> AuthQueryHandler::GetPrivi } void AuthQueryHandler::GrantPrivilege( - const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges, + const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges) { + &edge_type_privileges +#endif +) { EditPermissions( - user_or_role, privileges, label_privileges, edge_type_privileges, + user_or_role, privileges, +#ifdef MG_ENTERPRISE + label_privileges, edge_type_privileges, +#endif [](auto &permissions, const auto &permission) { // TODO (mferencevic): should we first check that the // privilege is granted/denied/revoked before // unconditionally granting/denying/revoking it? permissions.Grant(permission); - }, + } +#ifdef MG_ENTERPRISE + , [](auto &fine_grained_permissions, const auto &privilege_collection) { for (const auto &[privilege, entities] : privilege_collection) { const auto &permission = memgraph::glue::FineGrainedPrivilegeToFineGrainedPermission(privilege); @@ -477,23 +526,34 @@ void AuthQueryHandler::GrantPrivilege( fine_grained_permissions.Grant(entity, permission); } } - }); -} + } +#endif + ); +} // namespace memgraph::glue void AuthQueryHandler::DenyPrivilege( - const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges, + const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges) { + &edge_type_privileges +#endif +) { EditPermissions( - user_or_role, privileges, label_privileges, edge_type_privileges, + user_or_role, privileges, +#ifdef MG_ENTERPRISE + label_privileges, edge_type_privileges, +#endif [](auto &permissions, const auto &permission) { // TODO (mferencevic): should we first check that the // privilege is granted/denied/revoked before // unconditionally granting/denying/revoking it? permissions.Deny(permission); - }, + } +#ifdef MG_ENTERPRISE + , [](auto &fine_grained_permissions, const auto &privilege_collection) { for (const auto &[privilege, entities] : privilege_collection) { const auto &permission = memgraph::glue::FineGrainedPrivilegeToFineGrainedPermission(privilege); @@ -501,41 +561,67 @@ void AuthQueryHandler::DenyPrivilege( fine_grained_permissions.Deny(entity, permission); } } - }); -} + } +#endif + ); +} // namespace memgraph::glue void AuthQueryHandler::RevokePrivilege( - const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges, + const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges) { + &edge_type_privileges +#endif +) { EditPermissions( - user_or_role, privileges, label_privileges, edge_type_privileges, + user_or_role, privileges, +#ifdef MG_ENTERPRISE + label_privileges, edge_type_privileges, +#endif [](auto &permissions, const auto &permission) { // TODO (mferencevic): should we first check that the // privilege is granted/denied/revoked before // unconditionally granting/denying/revoking it? permissions.Revoke(permission); - }, + } +#ifdef MG_ENTERPRISE + , [](auto &fine_grained_permissions, const auto &privilege_collection) { for ([[maybe_unused]] const auto &[privilege, entities] : privilege_collection) { for (const auto &entity : entities) { fine_grained_permissions.Revoke(entity); } } - }); -} + } +#endif + ); +} // namespace memgraph::glue -template <class TEditPermissionsFun, class TEditFineGrainedPermissionsFun> +template <class TEditPermissionsFun +#ifdef MG_ENTERPRISE + , + class TEditFineGrainedPermissionsFun +#endif + > void AuthQueryHandler::EditPermissions( - const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges, + const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges, - const TEditPermissionsFun &edit_permissions_fun, - const TEditFineGrainedPermissionsFun &edit_fine_grained_permissions_fun) { + &edge_type_privileges +#endif + , + const TEditPermissionsFun &edit_permissions_fun +#ifdef MG_ENTERPRISE + , + const TEditFineGrainedPermissionsFun &edit_fine_grained_permissions_fun +#endif +) { if (!std::regex_match(user_or_role, name_regex_)) { throw memgraph::query::QueryRuntimeException("Invalid user or role name."); } @@ -555,28 +641,34 @@ void AuthQueryHandler::EditPermissions( for (const auto &permission : permissions) { edit_permissions_fun(user->permissions(), permission); } - for (const auto &label_privilege_collection : label_privileges) { - edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), - label_privilege_collection); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + for (const auto &label_privilege_collection : label_privileges) { + edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), + label_privilege_collection); + } + for (const auto &edge_type_privilege_collection : edge_type_privileges) { + edit_fine_grained_permissions_fun(user->fine_grained_access_handler().edge_type_permissions(), + edge_type_privilege_collection); + } } - for (const auto &edge_type_privilege_collection : edge_type_privileges) { - edit_fine_grained_permissions_fun(user->fine_grained_access_handler().edge_type_permissions(), - edge_type_privilege_collection); - } - +#endif locked_auth->SaveUser(*user); } else { for (const auto &permission : permissions) { edit_permissions_fun(role->permissions(), permission); } - for (const auto &label_privilege : label_privileges) { - edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), label_privilege); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + for (const auto &label_privilege : label_privileges) { + edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), label_privilege); + } + for (const auto &edge_type_privilege : edge_type_privileges) { + edit_fine_grained_permissions_fun(role->fine_grained_access_handler().edge_type_permissions(), + edge_type_privilege); + } } - for (const auto &edge_type_privilege : edge_type_privileges) { - edit_fine_grained_permissions_fun(role->fine_grained_access_handler().edge_type_permissions(), - edge_type_privilege); - } - +#endif locked_auth->SaveRole(*role); } } catch (const memgraph::auth::AuthException &e) { diff --git a/src/glue/auth_handler.hpp b/src/glue/auth_handler.hpp index 976ffb6e9..e1e75d472 100644 --- a/src/glue/auth_handler.hpp +++ b/src/glue/auth_handler.hpp @@ -57,35 +57,62 @@ class AuthQueryHandler final : public memgraph::query::AuthQueryHandler { std::vector<std::vector<memgraph::query::TypedValue>> GetPrivileges(const std::string &user_or_role) override; void GrantPrivilege( - const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges, + const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, + const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges) override; + &edge_type_privileges +#endif + ) override; void DenyPrivilege( - const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges, + const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, + const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges) override; + &edge_type_privileges +#endif + ) override; void RevokePrivilege( - const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges, + const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges) override; + &edge_type_privileges +#endif + ) override; private: - template <class TEditPermissionsFun, class TEditFineGrainedPermissionsFun> + template <class TEditPermissionsFun +#ifdef MG_ENTERPRISE + , + class TEditFineGrainedPermissionsFun +#endif + > void EditPermissions( - const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges, + const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges, - const TEditPermissionsFun &edit_permissions_fun, - const TEditFineGrainedPermissionsFun &edit_fine_grained_permissions_fun); + &edge_type_privileges +#endif + , + const TEditPermissionsFun &edit_permissions_fun +#ifdef MG_ENTERPRISE + , + const TEditFineGrainedPermissionsFun &edit_fine_grained_permissions_fun +#endif + ); }; } // namespace memgraph::glue diff --git a/src/query/auth_checker.hpp b/src/query/auth_checker.hpp index a76692a12..00abebc4a 100644 --- a/src/query/auth_checker.hpp +++ b/src/query/auth_checker.hpp @@ -26,10 +26,12 @@ class AuthChecker { [[nodiscard]] virtual bool IsUserAuthorized(const std::optional<std::string> &username, const std::vector<query::AuthQuery::Privilege> &privileges) const = 0; +#ifdef MG_ENTERPRISE [[nodiscard]] virtual std::unique_ptr<FineGrainedAuthChecker> GetFineGrainedAuthChecker( const std::string &username, const memgraph::query::DbAccessor *db_accessor) const = 0; +#endif }; - +#ifdef MG_ENTERPRISE class FineGrainedAuthChecker { public: virtual ~FineGrainedAuthChecker() = default; @@ -85,6 +87,7 @@ class AllowEverythingFineGrainedAuthChecker final : public query::FineGrainedAut return true; } }; // namespace memgraph::query +#endif class AllowEverythingAuthChecker final : public query::AuthChecker { public: @@ -93,10 +96,12 @@ class AllowEverythingAuthChecker final : public query::AuthChecker { return true; } +#ifdef MG_ENTERPRISE std::unique_ptr<FineGrainedAuthChecker> GetFineGrainedAuthChecker(const std::string & /*username*/, const query::DbAccessor * /*dba*/) const override { return std::make_unique<AllowEverythingFineGrainedAuthChecker>(); } -}; +#endif +}; // namespace memgraph::query } // namespace memgraph::query diff --git a/src/query/context.hpp b/src/query/context.hpp index 59663cd74..18f8eb27b 100644 --- a/src/query/context.hpp +++ b/src/query/context.hpp @@ -73,7 +73,9 @@ struct ExecutionContext { ExecutionStats execution_stats; TriggerContextCollector *trigger_context_collector{nullptr}; utils::AsyncTimer timer; +#ifdef MG_ENTERPRISE std::unique_ptr<FineGrainedAuthChecker> auth_checker{nullptr}; +#endif }; static_assert(std::is_move_assignable_v<ExecutionContext>, "ExecutionContext must be move assignable!"); diff --git a/src/query/interpreter.cpp b/src/query/interpreter.cpp index f0aa35806..deb098075 100644 --- a/src/query/interpreter.cpp +++ b/src/query/interpreter.cpp @@ -289,10 +289,12 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa std::string rolename = auth_query->role_; std::string user_or_role = auth_query->user_or_role_; std::vector<AuthQuery::Privilege> privileges = auth_query->privileges_; +#ifdef MG_ENTERPRISE std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> label_privileges = auth_query->label_privileges_; std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> edge_type_privileges = auth_query->edge_type_privileges_; +#endif auto password = EvaluateOptionalExpression(auth_query->password_, &evaluator); Callback callback; @@ -322,9 +324,19 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa // If the license is not valid we create users with admin access if (!valid_enterprise_license) { spdlog::warn("Granting all the privileges to {}.", username); - auth->GrantPrivilege(username, kPrivilegesAll, + auth->GrantPrivilege(username, kPrivilegesAll +#ifdef MG_ENTERPRISE + , {{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE, {auth::kAsterisk}}}}, - {{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE, {auth::kAsterisk}}}}); + { + { + { + AuthQuery::FineGrainedPrivilege::CREATE_DELETE, { auth::kAsterisk } + } + } + } +#endif + ); } return std::vector<std::vector<TypedValue>>(); @@ -399,20 +411,50 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa }; return callback; case AuthQuery::Action::GRANT_PRIVILEGE: - callback.fn = [auth, user_or_role, privileges, label_privileges, edge_type_privileges] { - auth->GrantPrivilege(user_or_role, privileges, label_privileges, edge_type_privileges); + callback.fn = [auth, user_or_role, privileges +#ifdef MG_ENTERPRISE + , + label_privileges, edge_type_privileges +#endif + ] { + auth->GrantPrivilege(user_or_role, privileges +#ifdef MG_ENTERPRISE + , + label_privileges, edge_type_privileges +#endif + ); return std::vector<std::vector<TypedValue>>(); }; return callback; case AuthQuery::Action::DENY_PRIVILEGE: - callback.fn = [auth, user_or_role, privileges, label_privileges, edge_type_privileges] { - auth->DenyPrivilege(user_or_role, privileges, label_privileges, edge_type_privileges); + callback.fn = [auth, user_or_role, privileges +#ifdef MG_ENTERPRISE + , + label_privileges, edge_type_privileges +#endif + ] { + auth->DenyPrivilege(user_or_role, privileges +#ifdef MG_ENTERPRISE + , + label_privileges, edge_type_privileges +#endif + ); return std::vector<std::vector<TypedValue>>(); }; return callback; case AuthQuery::Action::REVOKE_PRIVILEGE: { - callback.fn = [auth, user_or_role, privileges, label_privileges, edge_type_privileges] { - auth->RevokePrivilege(user_or_role, privileges, label_privileges, edge_type_privileges); + callback.fn = [auth, user_or_role, privileges +#ifdef MG_ENTERPRISE + , + label_privileges, edge_type_privileges +#endif + ] { + auth->RevokePrivilege(user_or_role, privileges +#ifdef MG_ENTERPRISE + , + label_privileges, edge_type_privileges +#endif + ); return std::vector<std::vector<TypedValue>>(); }; return callback; @@ -444,7 +486,7 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa default: break; } -} +} // namespace Callback HandleReplicationQuery(ReplicationQuery *repl_query, const Parameters ¶meters, InterpreterContext *interpreter_context, DbAccessor *db_accessor, @@ -985,7 +1027,7 @@ PullPlan::PullPlan(const std::shared_ptr<CachedPlan> plan, const Parameters &par ctx_.evaluation_context.properties = NamesToProperties(plan->ast_storage().properties_, dba); ctx_.evaluation_context.labels = NamesToLabels(plan->ast_storage().labels_, dba); #ifdef MG_ENTERPRISE - if (username.has_value() && dba) { + if (utils::license::global_license_checker.IsValidLicenseFast() && username.has_value() && dba) { ctx_.auth_checker = interpreter_context->auth_checker->GetFineGrainedAuthChecker(*username, dba); } #endif diff --git a/src/query/interpreter.hpp b/src/query/interpreter.hpp index 81c37d812..0f423f245 100644 --- a/src/query/interpreter.hpp +++ b/src/query/interpreter.hpp @@ -100,27 +100,42 @@ class AuthQueryHandler { /// @throw QueryRuntimeException if an error ocurred. virtual void GrantPrivilege( - const std::string &user_or_role, const std::vector<AuthQuery::Privilege> &privileges, - const std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> + const std::string &user_or_role, const std::vector<AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , + const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, - const std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges) = 0; + + const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> + &edge_type_privileges +#endif + ) = 0; /// @throw QueryRuntimeException if an error ocurred. virtual void DenyPrivilege( - const std::string &user_or_role, const std::vector<AuthQuery::Privilege> &privileges, - const std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> + const std::string &user_or_role, const std::vector<AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , + const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, - const std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges) = 0; + + const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> + &edge_type_privileges +#endif + ) = 0; /// @throw QueryRuntimeException if an error ocurred. virtual void RevokePrivilege( - const std::string &user_or_role, const std::vector<AuthQuery::Privilege> &privileges, - const std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> + const std::string &user_or_role, const std::vector<AuthQuery::Privilege> &privileges +#ifdef MG_ENTERPRISE + , + const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> &label_privileges, - const std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> - &edge_type_privileges) = 0; + + const std::vector<std::unordered_map<memgraph::query::AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> + &edge_type_privileges +#endif + ) = 0; }; enum class QueryHandlerResult { COMMIT, ABORT, NOTHING }; diff --git a/src/query/plan/operator.cpp b/src/query/plan/operator.cpp index c86b427fc..cbc27ccc4 100644 --- a/src/query/plan/operator.cpp +++ b/src/query/plan/operator.cpp @@ -46,6 +46,7 @@ #include "utils/event_counter.hpp" #include "utils/exceptions.hpp" #include "utils/fnv.hpp" +#include "utils/license.hpp" #include "utils/likely.hpp" #include "utils/logging.hpp" #include "utils/memory.hpp" @@ -239,12 +240,13 @@ CreateNode::CreateNodeCursor::CreateNodeCursor(const CreateNode &self, utils::Me bool CreateNode::CreateNodeCursor::Pull(Frame &frame, ExecutionContext &context) { SCOPED_PROFILE_OP("CreateNode"); - - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(self_.node_info_.labels, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { throw QueryRuntimeException("Vertex not created due to not having enough permission!"); } +#endif if (input_cursor_->Pull(frame, context)) { auto created_vertex = CreateLocalVertex(self_.node_info_, &frame, context); @@ -330,15 +332,21 @@ bool CreateExpand::CreateExpandCursor::Pull(Frame &frame, ExecutionContext &cont if (!input_cursor_->Pull(frame, context)) return false; - const auto fine_grained_permission = self_.existing_node_ - ? memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE - : memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE; - if (context.auth_checker && - !(context.auth_checker->Has(self_.edge_info_.edge_type, - memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE) && - context.auth_checker->Has(self_.node_info_.labels, fine_grained_permission))) { - throw QueryRuntimeException("Edge not created due to not having enough permission!"); +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast()) { + const auto fine_grained_permission = self_.existing_node_ + ? memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE + + : memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE; + + if (context.auth_checker && + !(context.auth_checker->Has(self_.edge_info_.edge_type, + memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE) && + context.auth_checker->Has(self_.node_info_.labels, fine_grained_permission))) { + throw QueryRuntimeException("Edge not created due to not having enough permission!"); + } } +#endif // get the origin vertex TypedValue &vertex_value = frame[self_.input_symbol_]; ExpectType(self_.input_symbol_, vertex_value, TypedValue::Type::Vertex); @@ -423,16 +431,19 @@ class ScanAllCursor : public Cursor { vertices_.emplace(std::move(next_vertices.value())); vertices_it_.emplace(vertices_.value().begin()); } - - if (context.auth_checker && !FindNextVertex(context)) { +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && + !FindNextVertex(context)) { return false; } +#endif frame[output_symbol_] = *vertices_it_.value(); ++vertices_it_.value(); return true; } +#ifdef MG_ENTERPRISE bool FindNextVertex(const ExecutionContext &context) { while (vertices_it_.value() != vertices_.value().end()) { if (context.auth_checker->Has(*vertices_it_.value(), memgraph::storage::View::OLD, @@ -441,9 +452,9 @@ class ScanAllCursor : public Cursor { } ++vertices_it_.value(); } - return false; } +#endif void Shutdown() override { input_cursor_->Shutdown(); } @@ -718,12 +729,14 @@ bool Expand::ExpandCursor::Pull(Frame &frame, ExecutionContext &context) { // attempt to get a value from the incoming edges if (in_edges_ && *in_edges_it_ != in_edges_->end()) { auto edge = *(*in_edges_it_)++; - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge.From(), self_.view_, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { continue; } +#endif frame[self_.common_.edge_symbol] = edge; pull_node(edge, EdgeAtom::Direction::IN); @@ -737,13 +750,14 @@ bool Expand::ExpandCursor::Pull(Frame &frame, ExecutionContext &context) { // we should do only one expansion for cycles, and it was // already done in the block above if (self_.common_.direction == EdgeAtom::Direction::BOTH && edge.IsCycle()) continue; - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge.To(), self_.view_, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { continue; } - +#endif frame[self_.common_.edge_symbol] = edge; pull_node(edge, EdgeAtom::Direction::OUT); return true; @@ -1073,13 +1087,14 @@ class ExpandVariableCursor : public Cursor { VertexAccessor current_vertex = current_edge.second == EdgeAtom::Direction::IN ? current_edge.first.From() : current_edge.first.To(); - - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(current_edge.first, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(current_vertex, storage::View::OLD, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { continue; } +#endif AppendEdge(current_edge.first, &edges_on_frame); if (!self_.common_.existing_node) { @@ -1241,12 +1256,14 @@ class STShortestPathCursor : public query::plan::Cursor { if (self_.common_.direction != EdgeAtom::Direction::IN) { auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types)); for (const auto &edge : out_edges) { - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge.To(), storage::View::OLD, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { continue; } +#endif if (ShouldExpand(edge.To(), edge, frame, evaluator) && !Contains(in_edge, edge.To())) { in_edge.emplace(edge.To(), edge); @@ -1265,12 +1282,14 @@ class STShortestPathCursor : public query::plan::Cursor { if (self_.common_.direction != EdgeAtom::Direction::OUT) { auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types)); for (const auto &edge : in_edges) { - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge.From(), storage::View::OLD, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { continue; } +#endif if (ShouldExpand(edge.From(), edge, frame, evaluator) && !Contains(in_edge, edge.From())) { in_edge.emplace(edge.From(), edge); @@ -1303,12 +1322,14 @@ class STShortestPathCursor : public query::plan::Cursor { if (self_.common_.direction != EdgeAtom::Direction::OUT) { auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types)); for (const auto &edge : out_edges) { - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge.To(), storage::View::OLD, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { continue; } +#endif if (ShouldExpand(vertex, edge, frame, evaluator) && !Contains(out_edge, edge.To())) { out_edge.emplace(edge.To(), edge); if (Contains(in_edge, edge.To())) { @@ -1326,12 +1347,14 @@ class STShortestPathCursor : public query::plan::Cursor { if (self_.common_.direction != EdgeAtom::Direction::IN) { auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types)); for (const auto &edge : in_edges) { - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge.From(), storage::View::OLD, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { continue; } +#endif if (ShouldExpand(vertex, edge, frame, evaluator) && !Contains(out_edge, edge.From())) { out_edge.emplace(edge.From(), edge); if (Contains(in_edge, edge.From())) { @@ -1381,13 +1404,14 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor { auto expand_pair = [this, &evaluator, &frame, &context](EdgeAccessor edge, VertexAccessor vertex) { // if we already processed the given vertex it doesn't get expanded if (processed_.find(vertex) != processed_.end()) return; - - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(vertex, storage::View::OLD, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { return; } +#endif frame[self_.filter_lambda_.inner_edge_symbol] = edge; frame[self_.filter_lambda_.inner_node_symbol] = vertex; @@ -1566,13 +1590,14 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor { const EdgeAccessor &edge, const VertexAccessor &vertex, const TypedValue &total_weight, int64_t depth) { auto *memory = evaluator.GetMemoryResource(); - - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(vertex, storage::View::OLD, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { return; } +#endif if (self_.filter_lambda_.expression) { frame[self_.filter_lambda_.inner_edge_symbol] = edge; frame[self_.filter_lambda_.inner_node_symbol] = vertex; @@ -1875,24 +1900,28 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor { if (self_.common_.direction != EdgeAtom::Direction::IN) { auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types)); for (const auto &edge : out_edges) { - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(edge.To(), storage::View::OLD, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { continue; } +#endif expand_vertex(edge, EdgeAtom::Direction::OUT, weight, depth); } } if (self_.common_.direction != EdgeAtom::Direction::OUT) { auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types)); for (const auto &edge : in_edges) { - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(edge.From(), storage::View::OLD, memgraph::query::AuthQuery::FineGrainedPrivilege::READ) && context.auth_checker->Has(edge, memgraph::query::AuthQuery::FineGrainedPrivilege::READ))) { continue; } +#endif expand_vertex(edge, EdgeAtom::Direction::IN, weight, depth); } } @@ -1915,8 +1944,8 @@ class ExpandAllShortestPathsCursor : public query::plan::Cursor { // Check if there is an external error. if (MustAbort(context)) throw HintedAbortError(); - // If traversal stack if filled, the DFS traversal tree is created. Traverse the tree iteratively by preserving - // the traversal state on stack. + // If traversal stack if filled, the DFS traversal tree is created. Traverse the tree iteratively by + // preserving the traversal state on stack. while (!traversal_stack_.empty()) { auto ¤t_level = traversal_stack_.back(); auto &edges_on_frame = frame[self_.common_.edge_symbol].ValueList(); @@ -2335,12 +2364,14 @@ bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) { if (MustAbort(context)) throw HintedAbortError(); if (expression_result.type() == TypedValue::Type::Edge) { auto &ea = expression_result.ValueEdge(); - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !(context.auth_checker->Has(ea, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE) && context.auth_checker->Has(ea.To(), storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::UPDATE) && context.auth_checker->Has(ea.From(), storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::UPDATE))) { throw QueryRuntimeException("Edge not deleted due to not having enough permission!"); } +#endif auto maybe_value = dba.RemoveEdge(&ea); if (maybe_value.HasError()) { switch (maybe_value.GetError()) { @@ -2366,10 +2397,12 @@ bool Delete::DeleteCursor::Pull(Frame &frame, ExecutionContext &context) { switch (expression_result.type()) { case TypedValue::Type::Vertex: { auto &va = expression_result.ValueVertex(); - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(va, storage::View::NEW, query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { throw QueryRuntimeException("Vertex not deleted due to not having enough permission!"); } +#endif if (self_.detach_) { auto res = dba.DetachRemoveVertex(&va); if (res.HasError()) { @@ -2473,12 +2506,13 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, ExecutionContext &contex switch (lhs.type()) { case TypedValue::Type::Vertex: { - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw QueryRuntimeException("Vertex property not set due to not having enough permission!"); } - +#endif auto old_value = PropsSetChecked(&lhs.ValueVertex(), self_.property_, rhs); context.execution_stats[ExecutionStats::Key::UPDATED_PROPERTIES] += 1; if (context.trigger_context_collector) { @@ -2489,15 +2523,17 @@ bool SetProperty::SetPropertyCursor::Pull(Frame &frame, ExecutionContext &contex break; } case TypedValue::Type::Edge: { - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw QueryRuntimeException("Edge property not set due to not having enough permission!"); } - +#endif auto old_value = PropsSetChecked(&lhs.ValueEdge(), self_.property_, rhs); context.execution_stats[ExecutionStats::Key::UPDATED_PROPERTIES] += 1; if (context.trigger_context_collector) { - // rhs cannot be moved because it was created with the allocator that is only valid during current pull + // rhs cannot be moved because it was created with the allocator that is only valid + // during current pull context.trigger_context_collector->RegisterSetObjectProperty(lhs.ValueEdge(), self_.property_, TypedValue{std::move(old_value)}, TypedValue{rhs}); } @@ -2686,20 +2722,23 @@ bool SetProperties::SetPropertiesCursor::Pull(Frame &frame, ExecutionContext &co switch (lhs.type()) { case TypedValue::Type::Vertex: - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw QueryRuntimeException("Vertex properties not set due to not having enough permission!"); } +#endif SetPropertiesOnRecord(&lhs.ValueVertex(), rhs, self_.op_, &context); break; case TypedValue::Type::Edge: - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw QueryRuntimeException("Edge properties not set due to not having enough permission!"); } - +#endif SetPropertiesOnRecord(&lhs.ValueEdge(), rhs, self_.op_, &context); break; case TypedValue::Type::Null: @@ -2737,10 +2776,12 @@ SetLabels::SetLabelsCursor::SetLabelsCursor(const SetLabels &self, utils::Memory bool SetLabels::SetLabelsCursor::Pull(Frame &frame, ExecutionContext &context) { SCOPED_PROFILE_OP("SetLabels"); - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { throw QueryRuntimeException("Couldn't set label due to not having enough permission!"); } +#endif if (!input_cursor_->Pull(frame, context)) return false; @@ -2750,10 +2791,13 @@ bool SetLabels::SetLabelsCursor::Pull(Frame &frame, ExecutionContext &context) { ExpectType(self_.input_symbol_, vertex_value, TypedValue::Type::Vertex); auto &vertex = vertex_value.ValueVertex(); - if (context.auth_checker && !context.auth_checker->Has(vertex, storage::View::OLD, - memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && + !context.auth_checker->Has(vertex, storage::View::OLD, + memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw QueryRuntimeException("Couldn't set label due to not having enough permission!"); } +#endif for (auto label : self_.labels_) { auto maybe_value = vertex.AddLabel(label); @@ -2837,20 +2881,22 @@ bool RemoveProperty::RemovePropertyCursor::Pull(Frame &frame, ExecutionContext & switch (lhs.type()) { case TypedValue::Type::Vertex: - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(lhs.ValueVertex(), storage::View::NEW, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw QueryRuntimeException("Vertex property not removed due to not having enough permission!"); } - +#endif remove_prop(&lhs.ValueVertex()); break; case TypedValue::Type::Edge: - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(lhs.ValueEdge(), memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw QueryRuntimeException("Edge property not removed due to not having enough permission!"); } - +#endif remove_prop(&lhs.ValueEdge()); break; case TypedValue::Type::Null: @@ -2888,10 +2934,12 @@ RemoveLabels::RemoveLabelsCursor::RemoveLabelsCursor(const RemoveLabels &self, u bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, ExecutionContext &context) { SCOPED_PROFILE_OP("RemoveLabels"); - if (context.auth_checker && +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && !context.auth_checker->Has(self_.labels_, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { throw QueryRuntimeException("Couldn't remove label due to not having enough permission!"); } +#endif if (!input_cursor_->Pull(frame, context)) return false; @@ -2900,10 +2948,14 @@ bool RemoveLabels::RemoveLabelsCursor::Pull(Frame &frame, ExecutionContext &cont if (vertex_value.IsNull()) return true; ExpectType(self_.input_symbol_, vertex_value, TypedValue::Type::Vertex); auto &vertex = vertex_value.ValueVertex(); - if (context.auth_checker && !context.auth_checker->Has(vertex, storage::View::OLD, - memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { + +#ifdef MG_ENTERPRISE + if (utils::license::global_license_checker.IsValidLicenseFast() && context.auth_checker && + !context.auth_checker->Has(vertex, storage::View::OLD, + memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw QueryRuntimeException("Couldn't remove label due to not having enough permission!"); } +#endif for (auto label : self_.labels_) { auto maybe_value = vertex.RemoveLabel(label); diff --git a/src/query/procedure/mg_procedure_impl.cpp b/src/query/procedure/mg_procedure_impl.cpp index 98217931e..03f60bf8b 100644 --- a/src/query/procedure/mg_procedure_impl.cpp +++ b/src/query/procedure/mg_procedure_impl.cpp @@ -32,6 +32,7 @@ #include "storage/v2/view.hpp" #include "utils/algorithm.hpp" #include "utils/concepts.hpp" +#include "utils/license.hpp" #include "utils/logging.hpp" #include "utils/math.hpp" #include "utils/memory.hpp" @@ -1589,11 +1590,12 @@ mgp_error mgp_vertex_set_property(struct mgp_vertex *v, const char *property_nam return WrapExceptions([=] { auto *ctx = v->graph->ctx; - if (ctx && ctx->auth_checker && +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker && !ctx->auth_checker->Has(v->impl, v->graph->view, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw AuthorizationException{"Insufficient permissions for setting a property on vertex!"}; } - +#endif if (!MgpVertexIsMutable(*v)) { throw ImmutableObjectException{"Cannot set a property on an immutable vertex!"}; } @@ -1635,12 +1637,14 @@ mgp_error mgp_vertex_add_label(struct mgp_vertex *v, mgp_label label) { return WrapExceptions([=] { auto *ctx = v->graph->ctx; - if (ctx && ctx->auth_checker && +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker && !(ctx->auth_checker->Has(v->impl, v->graph->view, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) && ctx->auth_checker->Has({v->graph->impl->NameToLabel(label.name)}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) { throw AuthorizationException{"Insufficient permissions for adding a label to vertex!"}; } +#endif if (!MgpVertexIsMutable(*v)) { throw ImmutableObjectException{"Cannot add a label to an immutable vertex!"}; @@ -1674,13 +1678,14 @@ mgp_error mgp_vertex_remove_label(struct mgp_vertex *v, mgp_label label) { return WrapExceptions([=] { auto *ctx = v->graph->ctx; - if (ctx && ctx->auth_checker && +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker && !(ctx->auth_checker->Has(v->impl, v->graph->view, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE) && ctx->auth_checker->Has({v->graph->impl->NameToLabel(label.name)}, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE))) { throw AuthorizationException{"Insufficient permissions for removing a label from vertex!"}; } - +#endif if (!MgpVertexIsMutable(*v)) { throw ImmutableObjectException{"Cannot remove a label from an immutable vertex!"}; } @@ -1856,6 +1861,7 @@ mgp_error mgp_vertex_iter_properties(mgp_vertex *v, mgp_memory *memory, mgp_prop void mgp_edges_iterator_destroy(mgp_edges_iterator *it) { DeleteRawMgpObject(it); } +#ifdef MG_ENTERPRISE namespace { void NextPermittedEdge(mgp_edges_iterator &it, const bool for_in) { if (const auto *ctx = it.source_vertex.graph->ctx; !ctx || !ctx->auth_checker) return; @@ -1879,6 +1885,7 @@ void NextPermittedEdge(mgp_edges_iterator &it, const bool for_in) { } }; } // namespace +#endif mgp_error mgp_vertex_iter_in_edges(mgp_vertex *v, mgp_memory *memory, mgp_edges_iterator **result) { return WrapExceptions( @@ -1903,8 +1910,11 @@ mgp_error mgp_vertex_iter_in_edges(mgp_vertex *v, mgp_memory *memory, mgp_edges_ } it->in.emplace(std::move(*maybe_edges)); it->in_it.emplace(it->in->begin()); - - NextPermittedEdge(*it, true); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + NextPermittedEdge(*it, true); + } +#endif if (*it->in_it != it->in->end()) { it->current_e.emplace(**it->in_it, v->graph, it->GetMemoryResource()); @@ -1939,7 +1949,11 @@ mgp_error mgp_vertex_iter_out_edges(mgp_vertex *v, mgp_memory *memory, mgp_edges it->out.emplace(std::move(*maybe_edges)); it->out_it.emplace(it->out->begin()); - NextPermittedEdge(*it, false); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + NextPermittedEdge(*it, false); + } +#endif if (*it->out_it != it->out->end()) { it->current_e.emplace(**it->out_it, v->graph, it->GetMemoryResource()); @@ -1981,7 +1995,11 @@ mgp_error mgp_edges_iterator_next(mgp_edges_iterator *it, mgp_edge **result) { ++*impl_it; - NextPermittedEdge(*it, for_in); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + NextPermittedEdge(*it, for_in); + } +#endif if (*impl_it == end) { it->current_e = std::nullopt; @@ -2073,10 +2091,12 @@ mgp_error mgp_edge_set_property(struct mgp_edge *e, const char *property_name, m return WrapExceptions([=] { auto *ctx = e->from.graph->ctx; - if (ctx && ctx->auth_checker && +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker && !ctx->auth_checker->Has(e->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::UPDATE)) { throw AuthorizationException{"Insufficient permissions for setting a property on edge!"}; } +#endif if (!MgpEdgeIsMutable(*e)) { throw ImmutableObjectException{"Cannot set a property on an immutable edge!"}; @@ -2164,11 +2184,15 @@ mgp_error mgp_graph_is_mutable(mgp_graph *graph, int *result) { mgp_error mgp_graph_create_vertex(struct mgp_graph *graph, mgp_memory *memory, mgp_vertex **result) { return WrapExceptions( [=]() -> mgp_vertex * { - if (graph->ctx && graph->ctx->auth_checker && + +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && graph->ctx && + graph->ctx->auth_checker && !graph->ctx->auth_checker->HasGlobalPrivilegeOnVertices( memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { throw AuthorizationException{"Insufficient permissions for creating vertices!"}; } +#endif if (!MgpGraphIsMutable(*graph)) { throw ImmutableObjectException{"Cannot create a vertex in an immutable graph!"}; @@ -2190,11 +2214,13 @@ mgp_error mgp_graph_delete_vertex(struct mgp_graph *graph, mgp_vertex *vertex) { return WrapExceptions([=] { auto *ctx = graph->ctx; - if (ctx && ctx->auth_checker && +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker && !ctx->auth_checker->Has(vertex->impl, graph->view, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { throw AuthorizationException{"Insufficient permissions for deleting a vertex!"}; } +#endif if (!MgpGraphIsMutable(*graph)) { throw ImmutableObjectException{"Cannot remove a vertex from an immutable graph!"}; @@ -2230,12 +2256,13 @@ mgp_error mgp_graph_delete_vertex(struct mgp_graph *graph, mgp_vertex *vertex) { mgp_error mgp_graph_detach_delete_vertex(struct mgp_graph *graph, mgp_vertex *vertex) { return WrapExceptions([=] { auto *ctx = graph->ctx; - - if (ctx && ctx->auth_checker && +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker && !ctx->auth_checker->Has(vertex->impl, graph->view, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { throw AuthorizationException{"Insufficient permissions for deleting a vertex!"}; } +#endif if (!MgpGraphIsMutable(*graph)) { throw ImmutableObjectException{"Cannot remove a vertex from an immutable graph!"}; @@ -2283,13 +2310,13 @@ mgp_error mgp_graph_create_edge(mgp_graph *graph, mgp_vertex *from, mgp_vertex * return WrapExceptions( [=]() -> mgp_edge * { auto *ctx = graph->ctx; - - if (ctx && ctx->auth_checker && +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker && !ctx->auth_checker->Has(from->graph->impl->NameToEdgeType(type.name), memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { throw AuthorizationException{"Insufficient permissions for creating edges!"}; } - +#endif if (!MgpGraphIsMutable(*graph)) { throw ImmutableObjectException{"Cannot create an edge in an immutable graph!"}; } @@ -2322,11 +2349,12 @@ mgp_error mgp_graph_create_edge(mgp_graph *graph, mgp_vertex *from, mgp_vertex * mgp_error mgp_graph_delete_edge(struct mgp_graph *graph, mgp_edge *edge) { return WrapExceptions([=] { auto *ctx = graph->ctx; - - if (ctx && ctx->auth_checker && +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast() && ctx && ctx->auth_checker && !ctx->auth_checker->Has(edge->impl, memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE)) { throw AuthorizationException{"Insufficient permissions for deleting an edge!"}; } +#endif if (!MgpGraphIsMutable(*graph)) { throw ImmutableObjectException{"Cannot remove an edge from an immutable graph!"}; } @@ -2356,6 +2384,7 @@ mgp_error mgp_graph_delete_edge(struct mgp_graph *graph, mgp_edge *edge) { }); } +#ifdef MG_ENTERPRISE namespace { void NextPermitted(mgp_vertices_iterator &it) { const auto *ctx = it.graph->ctx; @@ -2374,11 +2403,16 @@ void NextPermitted(mgp_vertices_iterator &it) { } }; } // namespace +#endif /// @throw anything VerticesIterable may throw mgp_vertices_iterator::mgp_vertices_iterator(mgp_graph *graph, memgraph::utils::MemoryResource *memory) : memory(memory), graph(graph), vertices(graph->impl->Vertices(graph->view)), current_it(vertices.begin()) { - NextPermitted(*this); +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + NextPermitted(*this); + } +#endif if (current_it != vertices.end()) { current_v.emplace(*current_it, graph, memory); @@ -2417,9 +2451,11 @@ mgp_error mgp_vertices_iterator_next(mgp_vertices_iterator *it, mgp_vertex **res } ++it->current_it; - - NextPermitted(*it); - +#ifdef MG_ENTERPRISE + if (memgraph::utils::license::global_license_checker.IsValidLicenseFast()) { + NextPermitted(*it); + } +#endif if (it->current_it == it->vertices.end()) { it->current_v = std::nullopt; return nullptr; diff --git a/tests/unit/auth.cpp b/tests/unit/auth.cpp index c50d78dfc..61ea5313d 100644 --- a/tests/unit/auth.cpp +++ b/tests/unit/auth.cpp @@ -161,6 +161,7 @@ TEST_F(AuthWithStorage, UserRolePermissions) { } } +#ifdef MG_ENTERPRISE TEST_F(AuthWithStorage, UserRoleFineGrainedAccessHandler) { ASSERT_FALSE(auth.HasUsers()); ASSERT_TRUE(auth.AddUser("test")); @@ -239,6 +240,7 @@ TEST_F(AuthWithStorage, UserRoleFineGrainedAccessHandler) { PermissionLevel::DENY); } } +#endif TEST_F(AuthWithStorage, RoleManipulations) { { @@ -488,6 +490,7 @@ TEST(AuthWithoutStorage, PermissionsMaskTest) { ASSERT_EQ(p4.denies(), 2); } +#ifdef MG_ENTERPRISE TEST(AuthWithoutStorage, FineGrainedAccessPermissions) { const std::string any_label = "AnyString"; const std::string check_label = "Label"; @@ -776,6 +779,7 @@ TEST(AuthWithoutStorage, FineGrainedAccessPermissions) { ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::READ), PermissionLevel::DENY); } } + TEST_F(AuthWithStorage, FineGrainedAccessCheckerMerge) { auto any_label = "AnyString"; auto check_label = "Label"; @@ -842,6 +846,7 @@ TEST_F(AuthWithStorage, FineGrainedAccessCheckerMerge) { ASSERT_EQ(fga_permissions3.Has(check_label, FineGrainedPermission::READ), PermissionLevel::GRANT); } } +#endif TEST(AuthWithoutStorage, UserSerializeDeserialize) { auto user = User("test"); diff --git a/tests/unit/auth_checker.cpp b/tests/unit/auth_checker.cpp index a62909ba8..05c29c425 100644 --- a/tests/unit/auth_checker.cpp +++ b/tests/unit/auth_checker.cpp @@ -17,7 +17,9 @@ #include "query_plan_common.hpp" #include "storage/v2/view.hpp" +#include "utils/license.hpp" +#ifdef MG_ENTERPRISE class FineGrainedAuthCheckerFixture : public testing::Test { protected: memgraph::storage::Storage db; @@ -37,6 +39,7 @@ class FineGrainedAuthCheckerFixture : public testing::Test { memgraph::query::EdgeAccessor r4{*dba.InsertEdge(&v1, &v3, edge_type_two)}; void SetUp() override { + memgraph::utils::license::global_license_checker.EnableTesting(); ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue()); ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue()); ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue()); @@ -205,3 +208,4 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantAndDenySpecificEdgeTypes) { ASSERT_FALSE(auth_checker.Has(r3, memgraph::query::AuthQuery::FineGrainedPrivilege::READ)); ASSERT_FALSE(auth_checker.Has(r4, memgraph::query::AuthQuery::FineGrainedPrivilege::READ)); } +#endif diff --git a/tests/unit/auth_handler.cpp b/tests/unit/auth_handler.cpp index 06c69c7e9..267056635 100644 --- a/tests/unit/auth_handler.cpp +++ b/tests/unit/auth_handler.cpp @@ -32,8 +32,9 @@ class AuthQueryHandlerFixture : public testing::Test { std::string edge_type_repr = "EdgeType1"; std::string label_repr = "Label1"; memgraph::auth::Permissions perms{}; +#ifdef MG_ENTERPRISE memgraph::auth::FineGrainedAccessHandler handler{}; - +#endif virtual void SetUp() { memgraph::utils::EnsureDir(test_folder_); memgraph::utils::license::global_license_checker.EnableTesting(); @@ -42,7 +43,9 @@ class AuthQueryHandlerFixture : public testing::Test { virtual void TearDown() { std::filesystem::remove_all(test_folder_); perms = memgraph::auth::Permissions{}; +#ifdef MG_ENTERPRISE handler = memgraph::auth::FineGrainedAccessHandler{}; +#endif } }; @@ -52,7 +55,7 @@ TEST_F(AuthQueryHandlerFixture, GivenAuthQueryHandlerWhenInitializedHaveNoUserna } TEST_F(AuthQueryHandlerFixture, GivenUserWhenNoDeniesOrGrantsThenNothingIsReturned) { - memgraph::auth::User user = memgraph::auth::User{user_name, "", perms, handler}; + memgraph::auth::User user = memgraph::auth::User{user_name, "", perms}; auth->SaveUser(user); { ASSERT_EQ(auth_handler.GetUsernames().size(), 1); } @@ -66,7 +69,7 @@ TEST_F(AuthQueryHandlerFixture, GivenUserWhenNoDeniesOrGrantsThenNothingIsReturn TEST_F(AuthQueryHandlerFixture, GivenUserWhenAddedGrantPermissionThenItIsReturned) { perms.Grant(memgraph::auth::Permission::MATCH); - memgraph::auth::User user = memgraph::auth::User{user_name, "", perms, handler}; + memgraph::auth::User user = memgraph::auth::User{user_name, "", perms}; auth->SaveUser(user); auto privileges = auth_handler.GetPrivileges(user_name); @@ -87,7 +90,7 @@ TEST_F(AuthQueryHandlerFixture, GivenUserWhenAddedGrantPermissionThenItIsReturne TEST_F(AuthQueryHandlerFixture, GivenUserWhenAddedDenyPermissionThenItIsReturned) { perms.Deny(memgraph::auth::Permission::MATCH); - memgraph::auth::User user = memgraph::auth::User{user_name, "", perms, handler}; + memgraph::auth::User user = memgraph::auth::User{user_name, "", perms}; auth->SaveUser(user); auto privileges = auth_handler.GetPrivileges(user_name); @@ -109,7 +112,7 @@ TEST_F(AuthQueryHandlerFixture, GivenUserWhenAddedDenyPermissionThenItIsReturned TEST_F(AuthQueryHandlerFixture, GivenUserWhenPrivilegeRevokedThenNothingIsReturned) { perms.Deny(memgraph::auth::Permission::MATCH); perms.Revoke(memgraph::auth::Permission::MATCH); - memgraph::auth::User user = memgraph::auth::User{user_name, "", perms, handler}; + memgraph::auth::User user = memgraph::auth::User{user_name, "", perms}; auth->SaveUser(user); auto privileges = auth_handler.GetPrivileges(user_name); @@ -118,7 +121,7 @@ TEST_F(AuthQueryHandlerFixture, GivenUserWhenPrivilegeRevokedThenNothingIsReturn TEST_F(AuthQueryHandlerFixture, GivenRoleWhenPrivilegeGrantedThenItIsReturned) { perms.Grant(memgraph::auth::Permission::MATCH); - memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms, handler}; + memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms}; auth->SaveRole(role); { ASSERT_EQ(auth_handler.GetRolenames().size(), 1); } @@ -143,7 +146,7 @@ TEST_F(AuthQueryHandlerFixture, GivenRoleWhenPrivilegeGrantedThenItIsReturned) { TEST_F(AuthQueryHandlerFixture, GivenRoleWhenPrivilegeDeniedThenItIsReturned) { perms.Deny(memgraph::auth::Permission::MATCH); - memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms, handler}; + memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms}; auth->SaveRole(role); auto privileges = auth_handler.GetPrivileges("Mates_role"); @@ -165,7 +168,7 @@ TEST_F(AuthQueryHandlerFixture, GivenRoleWhenPrivilegeDeniedThenItIsReturned) { TEST_F(AuthQueryHandlerFixture, GivenRoleWhenPrivilegeRevokedThenNothingIsReturned) { perms.Deny(memgraph::auth::Permission::MATCH); perms.Revoke(memgraph::auth::Permission::MATCH); - memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms, handler}; + memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms}; auth->SaveRole(role); auto privileges = auth_handler.GetPrivileges("Mates_role"); @@ -175,7 +178,7 @@ TEST_F(AuthQueryHandlerFixture, GivenRoleWhenPrivilegeRevokedThenNothingIsReturn TEST_F(AuthQueryHandlerFixture, GivenUserWhenGrantedTwoPrivilegesThenBothAreReturned) { perms.Grant(memgraph::auth::Permission::MATCH); perms.Grant(memgraph::auth::Permission::CREATE); - memgraph::auth::User user = memgraph::auth::User{user_name, "", perms, handler}; + memgraph::auth::User user = memgraph::auth::User{user_name, "", perms}; auth->SaveUser(user); auto privileges = auth_handler.GetPrivileges(user_name); @@ -184,9 +187,9 @@ TEST_F(AuthQueryHandlerFixture, GivenUserWhenGrantedTwoPrivilegesThenBothAreRetu TEST_F(AuthQueryHandlerFixture, GivenUserAndRoleWhenOneGrantedAndOtherGrantedThenBothArePrinted) { perms.Grant(memgraph::auth::Permission::MATCH); - memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms, handler}; + memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms}; auth->SaveRole(role); - memgraph::auth::User user = memgraph::auth::User{user_name, "", perms, handler}; + memgraph::auth::User user = memgraph::auth::User{user_name, "", perms}; user.SetRole(role); auth->SaveUser(user); @@ -208,9 +211,9 @@ TEST_F(AuthQueryHandlerFixture, GivenUserAndRoleWhenOneGrantedAndOtherGrantedThe TEST_F(AuthQueryHandlerFixture, GivenUserAndRoleWhenOneDeniedAndOtherDeniedThenBothArePrinted) { perms.Deny(memgraph::auth::Permission::MATCH); - memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms, handler}; + memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", perms}; auth->SaveRole(role); - memgraph::auth::User user = memgraph::auth::User{user_name, "", perms, handler}; + memgraph::auth::User user = memgraph::auth::User{user_name, "", perms}; user.SetRole(role); auth->SaveUser(user); @@ -233,12 +236,16 @@ TEST_F(AuthQueryHandlerFixture, GivenUserAndRoleWhenOneDeniedAndOtherDeniedThenB TEST_F(AuthQueryHandlerFixture, GivenUserAndRoleWhenOneGrantedAndOtherDeniedThenBothArePrinted) { memgraph::auth::Permissions role_perms{}; role_perms.Deny(memgraph::auth::Permission::MATCH); - memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", role_perms, handler}; + memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", role_perms}; auth->SaveRole(role); memgraph::auth::Permissions user_perms{}; user_perms.Grant(memgraph::auth::Permission::MATCH); - memgraph::auth::User user = memgraph::auth::User{user_name, "", user_perms, handler}; + memgraph::auth::User user = memgraph::auth::User{ + user_name, + "", + user_perms, + }; user.SetRole(role); auth->SaveUser(user); @@ -261,12 +268,12 @@ TEST_F(AuthQueryHandlerFixture, GivenUserAndRoleWhenOneGrantedAndOtherDeniedThen TEST_F(AuthQueryHandlerFixture, GivenUserAndRoleWhenOneDeniedAndOtherGrantedThenBothArePrinted) { memgraph::auth::Permissions role_perms{}; role_perms.Grant(memgraph::auth::Permission::MATCH); - memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", role_perms, handler}; + memgraph::auth::Role role = memgraph::auth::Role{"Mates_role", role_perms}; auth->SaveRole(role); memgraph::auth::Permissions user_perms{}; user_perms.Deny(memgraph::auth::Permission::MATCH); - memgraph::auth::User user = memgraph::auth::User{user_name, "", user_perms, handler}; + memgraph::auth::User user = memgraph::auth::User{user_name, "", user_perms}; user.SetRole(role); auth->SaveUser(user); @@ -286,6 +293,7 @@ TEST_F(AuthQueryHandlerFixture, GivenUserAndRoleWhenOneDeniedAndOtherGrantedThen ASSERT_EQ(result[2].ValueString(), "DENIED TO USER, GRANTED TO ROLE"); } +#ifdef MG_ENTERPRISE TEST_F(AuthQueryHandlerFixture, GivenUserWhenGrantedPrivilegeOnLabelThenIsDisplayed) { auto read_permission = memgraph::auth::FineGrainedAccessPermissions(); read_permission.Grant(label_repr, memgraph::auth::FineGrainedPermission::READ); @@ -722,3 +730,4 @@ TEST_F(AuthQueryHandlerFixture, GivenUserWhenGrantedReadAndDeniedUpdateThenOneIs ASSERT_TRUE(result[2].IsString()); ASSERT_EQ(result[2].ValueString(), "EDGE_TYPE PERMISSION GRANTED TO USER"); } +#endif diff --git a/tests/unit/bfs_common.hpp b/tests/unit/bfs_common.hpp index 76707f4b3..3c3114654 100644 --- a/tests/unit/bfs_common.hpp +++ b/tests/unit/bfs_common.hpp @@ -451,6 +451,7 @@ void BfsTest(Database *db, int lower_bound, int upper_bound, memgraph::query::Ed dba.Abort(); } +#ifdef MG_ENTERPRISE void BfsTestWithFineGrainedFiltering(Database *db, int lower_bound, int upper_bound, memgraph::query::EdgeAtom::Direction direction, std::vector<std::string> edge_types, bool known_sink, @@ -718,3 +719,4 @@ void BfsTestWithFineGrainedFiltering(Database *db, int lower_bound, int upper_bo db_accessor.Abort(); } +#endif diff --git a/tests/unit/bfs_fine_grained.cpp b/tests/unit/bfs_fine_grained.cpp index 3a232ca8a..594446e11 100644 --- a/tests/unit/bfs_fine_grained.cpp +++ b/tests/unit/bfs_fine_grained.cpp @@ -18,6 +18,7 @@ #include <gtest/internal/gtest-param-util-generated.h> #include "auth/models.hpp" +#include "utils/license.hpp" using namespace memgraph::query; using namespace memgraph::query::plan; @@ -73,11 +74,15 @@ class VertexDb : public Database { memgraph::storage::Storage db_; }; +#ifdef MG_ENTERPRISE class FineGrainedBfsTest : public ::testing::TestWithParam< std::tuple<int, int, EdgeAtom::Direction, std::vector<std::string>, bool, FineGrainedTestType>> { public: - static void SetUpTestCase() { db_ = std::make_unique<VertexDb>(); } + static void SetUpTestCase() { + memgraph::utils::license::global_license_checker.EnableTesting(); + db_ = std::make_unique<VertexDb>(); + } static void TearDownTestCase() { db_ = nullptr; } protected: @@ -99,7 +104,6 @@ TEST_P(FineGrainedBfsTest, All) { } std::unique_ptr<VertexDb> FineGrainedBfsTest::db_{nullptr}; - INSTANTIATE_TEST_CASE_P( FineGrained, FineGrainedBfsTest, testing::Combine(testing::Values(3), testing::Values(-1), @@ -108,3 +112,4 @@ INSTANTIATE_TEST_CASE_P( testing::Values(FineGrainedTestType::ALL_GRANTED, FineGrainedTestType::ALL_DENIED, FineGrainedTestType::EDGE_TYPE_A_DENIED, FineGrainedTestType::EDGE_TYPE_B_DENIED, FineGrainedTestType::LABEL_0_DENIED, FineGrainedTestType::LABEL_3_DENIED))); +#endif diff --git a/tests/unit/query_plan_common.hpp b/tests/unit/query_plan_common.hpp index 820167cfa..975099a0e 100644 --- a/tests/unit/query_plan_common.hpp +++ b/tests/unit/query_plan_common.hpp @@ -41,7 +41,7 @@ ExecutionContext MakeContext(const AstStorage &storage, const SymbolTable &symbo context.evaluation_context.labels = NamesToLabels(storage.labels_, dba); return context; } - +#ifdef MG_ENTERPRISE ExecutionContext MakeContextWithFineGrainedChecker(const AstStorage &storage, const SymbolTable &symbol_table, memgraph::query::DbAccessor *dba, memgraph::glue::FineGrainedAuthChecker *auth_checker) { @@ -53,6 +53,7 @@ ExecutionContext MakeContextWithFineGrainedChecker(const AstStorage &storage, co return context; } +#endif /** Helper function that collects all the results from the given Produce. */ std::vector<std::vector<TypedValue>> CollectProduce(const Produce &produce, ExecutionContext *context) { diff --git a/tests/unit/query_plan_create_set_remove_delete.cpp b/tests/unit/query_plan_create_set_remove_delete.cpp index 72cff71f8..9da260102 100644 --- a/tests/unit/query_plan_create_set_remove_delete.cpp +++ b/tests/unit/query_plan_create_set_remove_delete.cpp @@ -24,6 +24,7 @@ #include "query/exceptions.hpp" #include "query/interpret/frame.hpp" #include "query/plan/operator.hpp" +#include "utils/license.hpp" #include "query_plan_common.hpp" #include "storage/v2/id_types.hpp" @@ -77,7 +78,9 @@ TEST(QueryPlan, CreateNodeWithAttributes) { EXPECT_EQ(vertex_count, 1); } +#ifdef MG_ENTERPRISE TEST(QueryPlan, FineGrainedCreateNodeWithAttributes) { + memgraph::utils::license::global_license_checker.EnableTesting(); memgraph::query::AstStorage ast; memgraph::query::SymbolTable symbol_table; memgraph::storage::Storage db; @@ -117,6 +120,7 @@ TEST(QueryPlan, FineGrainedCreateNodeWithAttributes) { ASSERT_THROW(test_create(user), QueryRuntimeException); } } +#endif TEST(QueryPlan, CreateReturn) { // test CREATE (n:Person {age: 42}) RETURN n, n.age @@ -158,7 +162,10 @@ TEST(QueryPlan, CreateReturn) { EXPECT_EQ(1, CountIterable(dba.Vertices(memgraph::storage::View::OLD))); } +#ifdef MG_ENTERPRISE TEST(QueryPlan, FineGrainedCreateReturn) { + memgraph::utils::license::global_license_checker.EnableTesting(); + // test CREATE (n:Person {age: 42}) RETURN n, n.age memgraph::storage::Storage db; auto storage_dba = db.Access(); @@ -215,6 +222,7 @@ TEST(QueryPlan, FineGrainedCreateReturn) { ASSERT_THROW(CollectProduce(*produce, &context), QueryRuntimeException); } } +#endif TEST(QueryPlan, CreateExpand) { memgraph::storage::Storage db; @@ -293,6 +301,7 @@ TEST(QueryPlan, CreateExpand) { } } +#ifdef MG_ENTERPRISE class CreateExpandWithAuthFixture : public testing::Test { protected: memgraph::storage::Storage db; @@ -301,6 +310,8 @@ class CreateExpandWithAuthFixture : public testing::Test { AstStorage storage; SymbolTable symbol_table; + void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); } + void ExecuteCreateExpand(bool cycle, memgraph::auth::User &user) { const auto label_node_1 = dba.NameToLabel("Node1"); const auto label_node_2 = dba.NameToLabel("Node2"); @@ -465,6 +476,8 @@ class MatchCreateNodeWithAuthFixture : public testing::Test { AstStorage storage; SymbolTable symbol_table; + void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); } + void InitGraph() { // add three nodes we'll match and expand-create from memgraph::query::VertexAccessor v1{dba.InsertVertex()}; @@ -536,6 +549,7 @@ TEST_F(MatchCreateNodeWithAuthFixture, MatchCreateWithOneLabelDeniedThrows) { ASSERT_THROW(ExecuteMatchCreateTestSuite(user, 3), QueryRuntimeException); } +#endif TEST(QueryPlan, MatchCreateExpand) { memgraph::storage::Storage db; @@ -585,6 +599,7 @@ TEST(QueryPlan, MatchCreateExpand) { test_create_path(true, 0, 6); } +#ifdef MG_ENTERPRISE class MatchCreateExpandWithAuthFixture : public testing::Test { protected: memgraph::storage::Storage db; @@ -593,6 +608,8 @@ class MatchCreateExpandWithAuthFixture : public testing::Test { AstStorage storage; SymbolTable symbol_table; + void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); } + void InitGraph() { // add three nodes we'll match and expand-create from memgraph::query::VertexAccessor v1{dba.InsertVertex()}; @@ -730,6 +747,7 @@ TEST_F(MatchCreateExpandWithAuthFixture, MatchCreateExpandWithCycleExecutesWhenG ExecuteMatchCreateExpandTestSuite(true, 3, 3, user); } +#endif TEST(QueryPlan, Delete) { memgraph::storage::Storage db; @@ -802,6 +820,7 @@ TEST(QueryPlan, Delete) { } } +#ifdef MG_ENTERPRISE class DeleteOperatorWithAuthFixture : public testing::Test { protected: memgraph::storage::Storage db; @@ -810,6 +829,8 @@ class DeleteOperatorWithAuthFixture : public testing::Test { AstStorage storage; SymbolTable symbol_table; + void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); } + void InitGraph() { std::vector<memgraph::query::VertexAccessor> vertices; for (int i = 0; i < 4; ++i) { @@ -949,6 +970,7 @@ TEST_F(DeleteOperatorWithAuthFixture, DeleteNodeAndDeleteEdgePerformWhenGranted) TestDeleteNodesHypothesis(0); TestDeleteEdgesHypothesis(0); } +#endif TEST(QueryPlan, DeleteTwiceDeleteBlockingEdge) { // test deleting the same vertex and edge multiple times @@ -1242,7 +1264,9 @@ TEST(QueryPlan, SetLabels) { } } +#ifdef MG_ENTERPRISE TEST(QueryPlan, SetLabelsWithFineGrained) { + memgraph::utils::license::global_license_checker.EnableTesting(); auto set_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba, std::vector<memgraph::storage::LabelId> labels) { ASSERT_TRUE(dba.InsertVertex().AddLabel(labels[0]).HasValue()); @@ -1315,6 +1339,7 @@ TEST(QueryPlan, SetLabelsWithFineGrained) { QueryRuntimeException); } } +#endif TEST(QueryPlan, RemoveProperty) { memgraph::storage::Storage db; @@ -1413,7 +1438,9 @@ TEST(QueryPlan, RemoveLabels) { } } +#ifdef MG_ENTERPRISE TEST(QueryPlan, RemoveLabelsFineGrainedFiltering) { + memgraph::utils::license::global_license_checker.EnableTesting(); auto remove_labels = [&](memgraph::auth::User user, memgraph::query::DbAccessor dba, std::vector<memgraph::storage::LabelId> labels) { auto v1 = dba.InsertVertex(); @@ -1492,6 +1519,7 @@ TEST(QueryPlan, RemoveLabelsFineGrainedFiltering) { QueryRuntimeException); } } +#endif TEST(QueryPlan, NodeFilterSet) { memgraph::storage::Storage db; @@ -1858,6 +1886,7 @@ TEST(QueryPlan, DeleteRemoveProperty) { ////////////////////////////////////////////// //// FINE GRAINED AUTHORIZATION ///// ////////////////////////////////////////////// +#ifdef MG_ENTERPRISE class UpdatePropertiesWithAuthFixture : public testing::Test { protected: memgraph::storage::Storage db; @@ -1882,6 +1911,8 @@ class UpdatePropertiesWithAuthFixture : public testing::Test { const memgraph::storage::PropertyId edge_prop{dba.NameToProperty(edge_prop_name)}; const memgraph::storage::PropertyValue edge_prop_value{1}; + void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); } + void SetVertexProperty(memgraph::query::VertexAccessor vertex) { static_cast<void>(vertex.SetProperty(entity_prop, entity_prop_value)); } @@ -2484,3 +2515,4 @@ TEST_F(UpdatePropertiesWithAuthFixture, SetPropertyExpandWithAuthChecker) { test_remove_hypothesis(1); } } +#endif diff --git a/tests/unit/query_plan_match_filter_return.cpp b/tests/unit/query_plan_match_filter_return.cpp index 9a6c48b9c..2aa614cf1 100644 --- a/tests/unit/query_plan_match_filter_return.cpp +++ b/tests/unit/query_plan_match_filter_return.cpp @@ -33,6 +33,7 @@ #include "query/context.hpp" #include "query/exceptions.hpp" #include "query/plan/operator.hpp" +#include "utils/license.hpp" #include "utils/synchronized.hpp" using namespace memgraph::query; @@ -49,6 +50,7 @@ class MatchReturnFixture : public testing::Test { void AddVertices(int count) { for (int i = 0; i < count; i++) dba.InsertVertex(); } + void SetUp() override { memgraph::utils::license::global_license_checker.EnableTesting(); } std::vector<Path> PathResults(std::shared_ptr<Produce> &op) { std::vector<Path> res; @@ -58,12 +60,15 @@ class MatchReturnFixture : public testing::Test { } int PullCountAuthorized(ScanAllTuple scan_all, memgraph::auth::User user) { +#ifdef MG_ENTERPRISE auto output = NEXPR("n", IDENT("n")->MapTo(scan_all.sym_))->MapTo(symbol_table.CreateSymbol("named_expression_1", true)); auto produce = MakeProduce(scan_all.op_, output); memgraph::glue::FineGrainedAuthChecker auth_checker{user, &dba}; auto context = MakeContextWithFineGrainedChecker(storage, symbol_table, &dba, &auth_checker); return PullAll(*produce, &context); +#endif + return 0; } }; @@ -107,6 +112,7 @@ TEST_F(MatchReturnFixture, MatchReturnPath) { EXPECT_TRUE(std::is_permutation(expected_paths.begin(), expected_paths.end(), results.begin())); } +#ifdef MG_ENTERPRISE TEST_F(MatchReturnFixture, ScanAllWithAuthChecker) { std::string labelName = "l1"; const auto label = dba.NameToLabel(labelName); @@ -192,6 +198,7 @@ TEST_F(MatchReturnFixture, ScanAllWithAuthChecker) { test_hypothesis(user, memgraph::storage::View::NEW, 0); } } +#endif TEST(QueryPlan, MatchReturnCartesian) { memgraph::storage::Storage db; @@ -474,6 +481,8 @@ class ExpandFixture : public testing::Test { ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue()); ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue()); ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue()); + memgraph::utils::license::global_license_checker.EnableTesting(); + dba.AdvanceCommand(); } }; @@ -506,6 +515,7 @@ TEST_F(ExpandFixture, Expand) { EXPECT_EQ(8, test_expand(EdgeAtom::Direction::BOTH, memgraph::storage::View::OLD)); } +#ifdef MG_ENTERPRISE TEST_F(ExpandFixture, ExpandWithEdgeFiltering) { auto test_expand = [&](memgraph::auth::User user, EdgeAtom::Direction direction, memgraph::storage::View view) { auto n = MakeScanAll(storage, symbol_table, "n"); @@ -560,6 +570,7 @@ TEST_F(ExpandFixture, ExpandWithEdgeFiltering) { EXPECT_EQ(4, test_expand(user, EdgeAtom::Direction::IN, memgraph::storage::View::OLD)); EXPECT_EQ(8, test_expand(user, EdgeAtom::Direction::BOTH, memgraph::storage::View::OLD)); } +#endif TEST_F(ExpandFixture, ExpandPath) { auto n = MakeScanAll(storage, symbol_table, "n"); @@ -613,6 +624,8 @@ class QueryPlanExpandVariable : public testing::Test { std::nullopt_t nullopt = std::nullopt; void SetUp() { + memgraph::utils::license::global_license_checker.EnableTesting(); + // create the graph int chain_length = 3; std::vector<memgraph::query::VertexAccessor> layer; @@ -703,8 +716,10 @@ class QueryPlanExpandVariable : public testing::Test { auto cursor = input_op->MakeCursor(memgraph::utils::NewDeleteResource()); ExecutionContext context; if (user) { +#ifdef MG_ENTERPRISE memgraph::glue::FineGrainedAuthChecker auth_checker{*user, &dba}; context = MakeContextWithFineGrainedChecker(storage, symbol_table, &dba, &auth_checker); +#endif } else { context = MakeContext(storage, symbol_table, &dba); } @@ -721,8 +736,10 @@ class QueryPlanExpandVariable : public testing::Test { auto cursor = input_op->MakeCursor(memgraph::utils::NewDeleteResource()); ExecutionContext context; if (user) { +#ifdef MG_ENTERPRISE memgraph::glue::FineGrainedAuthChecker auth_checker{*user, &dba}; context = MakeContextWithFineGrainedChecker(storage, symbol_table, &dba, &auth_checker); +#endif } else { context = MakeContext(storage, symbol_table, &dba); } @@ -788,6 +805,7 @@ TEST_F(QueryPlanExpandVariable, OneVariableExpansion) { } } +#ifdef MG_ENTERPRISE TEST_F(QueryPlanExpandVariable, FineGrainedOneVariableExpansion) { auto test_expand = [&](int layer, EdgeAtom::Direction direction, std::optional<size_t> lower, std::optional<size_t> upper, bool reverse, memgraph::auth::User &user) { @@ -989,6 +1007,7 @@ TEST_F(QueryPlanExpandVariable, FineGrainedOneVariableExpansion) { } } } +#endif TEST_F(QueryPlanExpandVariable, EdgeUniquenessSingleAndVariableExpansion) { auto test_expand = [&](int layer, EdgeAtom::Direction direction, std::optional<size_t> lower, @@ -1049,6 +1068,7 @@ TEST_F(QueryPlanExpandVariable, EdgeUniquenessTwoVariableExpansions) { EXPECT_EQ(test_expand(0, EdgeAtom::Direction::OUT, 2, 2, true), (map_int{{2, 5 * 8}})); } +#ifdef MG_ENTERPRISE TEST_F(QueryPlanExpandVariable, FineGrainedEdgeUniquenessTwoVariableExpansions) { auto test_expand = [&](int layer, EdgeAtom::Direction direction, std::optional<size_t> lower, std::optional<size_t> upper, bool add_uniqueness_check, memgraph::auth::User &user) { @@ -1139,6 +1159,7 @@ TEST_F(QueryPlanExpandVariable, FineGrainedEdgeUniquenessTwoVariableExpansions) EXPECT_EQ(test_expand(1, EdgeAtom::Direction::OUT, 0, 2, true, user), (map_int{{0, 4}})); } } +#endif TEST_F(QueryPlanExpandVariable, NamedPath) { auto e = Edge("r", EdgeAtom::Direction::OUT); @@ -1172,6 +1193,7 @@ TEST_F(QueryPlanExpandVariable, NamedPath) { EXPECT_TRUE(std::is_permutation(results.begin(), results.end(), expected_paths.begin())); } +#ifdef MG_ENTERPRISE TEST_F(QueryPlanExpandVariable, FineGrainedFilterNamedPath) { auto e = Edge("r", EdgeAtom::Direction::OUT); auto expand = AddMatch<ExpandVariable>(nullptr, "n", 0, EdgeAtom::Direction::OUT, {}, 0, 2, e, "m", @@ -1310,6 +1332,7 @@ TEST_F(QueryPlanExpandVariable, FineGrainedFilterNamedPath) { EXPECT_TRUE(std::is_permutation(results.begin(), results.end(), expected_paths.begin())); } } +#endif TEST_F(QueryPlanExpandVariable, ExpandToSameSymbol) { auto test_expand = [&](int layer, EdgeAtom::Direction direction, std::optional<size_t> lower, @@ -1501,6 +1524,7 @@ TEST_F(QueryPlanExpandVariable, ExpandToSameSymbol) { } } +#ifdef MG_ENTERPRISE TEST_F(QueryPlanExpandVariable, FineGrainedExpandToSameSymbol) { auto test_expand = [&](int layer, EdgeAtom::Direction direction, std::optional<size_t> lower, std::optional<size_t> upper, bool reverse, memgraph::auth::User &user) { @@ -1699,6 +1723,7 @@ TEST_F(QueryPlanExpandVariable, FineGrainedExpandToSameSymbol) { } } } +#endif namespace std { template <> @@ -1743,6 +1768,8 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test { Symbol total_weight = symbol_table.CreateSymbol("total_weight", true); void SetUp() { + memgraph::utils::license::global_license_checker.EnableTesting(); + for (int i = 0; i < 5; i++) { v.push_back(dba.InsertVertex()); ASSERT_TRUE(v.back().SetProperty(prop.second, memgraph::storage::PropertyValue(i)).HasValue()); @@ -1796,8 +1823,10 @@ class QueryPlanExpandWeightedShortestPath : public testing::Test { std::vector<ResultType> results; memgraph::query::ExecutionContext context; if (user) { +#ifdef MG_ENTERPRISE memgraph::glue::FineGrainedAuthChecker auth_checker{*user, &dba}; context = MakeContextWithFineGrainedChecker(storage, symbol_table, &dba, &auth_checker); +#endif } else { context = MakeContext(storage, symbol_table, &dba); } @@ -2030,6 +2059,7 @@ TEST_F(QueryPlanExpandWeightedShortestPath, NegativeUpperBound) { EXPECT_THROW(ExpandWShortest(EdgeAtom::Direction::BOTH, -1, LITERAL(true)), QueryRuntimeException); } +#if MG_ENTERPRISE TEST_F(QueryPlanExpandWeightedShortestPath, FineGrainedFiltering) { // All edge_types and labels allowed { @@ -2129,6 +2159,7 @@ TEST_F(QueryPlanExpandWeightedShortestPath, FineGrainedFiltering) { ASSERT_EQ(filtered_results.size(), 4); } } +#endif /** A test fixture for all shortest paths expansion */ class QueryPlanExpandAllShortestPaths : public testing::Test { @@ -2166,6 +2197,8 @@ class QueryPlanExpandAllShortestPaths : public testing::Test { Symbol total_weight = symbol_table.CreateSymbol("total_weight", true); void SetUp() { + memgraph::utils::license::global_license_checker.EnableTesting(); + for (int i = 0; i < 5; i++) { v.push_back(dba.InsertVertex()); ASSERT_TRUE(v.back().SetProperty(prop.second, memgraph::storage::PropertyValue(i)).HasValue()); @@ -2219,8 +2252,10 @@ class QueryPlanExpandAllShortestPaths : public testing::Test { std::vector<ResultType> results; ExecutionContext context; if (user) { +#ifdef MG_ENTERPRISE memgraph::glue::FineGrainedAuthChecker auth_checker{*user, &dba}; context = MakeContextWithFineGrainedChecker(storage, symbol_table, &dba, &auth_checker); +#endif } else { context = MakeContext(storage, symbol_table, &dba); } @@ -2492,6 +2527,7 @@ TEST_F(QueryPlanExpandAllShortestPaths, MultiEdge) { EXPECT_EQ(results[5].total_weight, 9); } +#ifdef MG_ENTERPRISE TEST_F(QueryPlanExpandAllShortestPaths, BasicWithFineGrainedFiltering) { // All edge_types and labels allowed { @@ -2571,6 +2607,7 @@ TEST_F(QueryPlanExpandAllShortestPaths, BasicWithFineGrainedFiltering) { ASSERT_EQ(filtered_results.size(), 4); } } +#endif TEST(QueryPlan, ExpandOptional) { memgraph::storage::Storage db; diff --git a/tests/unit/query_required_privileges.cpp b/tests/unit/query_required_privileges.cpp index 82f607c12..d65be9caf 100644 --- a/tests/unit/query_required_privileges.cpp +++ b/tests/unit/query_required_privileges.cpp @@ -17,6 +17,7 @@ #include "query/frontend/ast/ast_visitor.hpp" #include "query/frontend/semantic/required_privileges.hpp" #include "storage/v2/id_types.hpp" +#include "utils/license.hpp" #include "query_common.hpp" @@ -97,8 +98,9 @@ TEST_F(TestPrivilegeExtractor, CreateIndex) { auto *query = CREATE_INDEX_ON(storage.GetLabelIx(LABEL_0), storage.GetPropertyIx(PROP_0)); EXPECT_THAT(GetRequiredPrivileges(query), UnorderedElementsAre(AuthQuery::Privilege::INDEX)); } - +#ifdef MG_ENTERPRISE TEST_F(TestPrivilegeExtractor, AuthQuery) { + memgraph::utils::license::global_license_checker.EnableTesting(); auto label_privileges = std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{}; auto edge_type_privileges = std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>{}; @@ -106,6 +108,7 @@ TEST_F(TestPrivilegeExtractor, AuthQuery) { label_privileges, edge_type_privileges); EXPECT_THAT(GetRequiredPrivileges(query), UnorderedElementsAre(AuthQuery::Privilege::AUTH)); } +#endif TEST_F(TestPrivilegeExtractor, ShowIndexInfo) { auto *query = storage.Create<InfoQuery>(); diff --git a/tests/unit/query_trigger.cpp b/tests/unit/query_trigger.cpp index e1325e76a..2c0559f50 100644 --- a/tests/unit/query_trigger.cpp +++ b/tests/unit/query_trigger.cpp @@ -39,9 +39,12 @@ class MockAuthChecker : public memgraph::query::AuthChecker { public: MOCK_CONST_METHOD2(IsUserAuthorized, bool(const std::optional<std::string> &username, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges)); + +#ifdef MG_ENTERPRISE MOCK_CONST_METHOD2(GetFineGrainedAuthChecker, std::unique_ptr<memgraph::query::FineGrainedAuthChecker>( const std::string &username, const memgraph::query::DbAccessor *db_accessor)); +#endif }; } // namespace