[E129-MG < T1004-MG] Expand cypher with more granular label permissions ()

* Added enum for more granular access control; Expanded functionality of fine grained access checker; Propagated changes to Edit, Deny and Revoke permissions methods in interpreter

* Introduced Merge method for merging two colle with permissions

* e2e tests implementation started

* Expanded cypher to support fine grained permissions

* ast.lcp::AuthQuery removed labels, added support for label permissions

* promoted label permissions to vector

* removed unnecesary enum value

* expanded glue/auth with LabelPrivilegeToLabelPermission

* added const

* extended Grant Deny and Revoke Privileges with new label privileges

* extended Edit Grant Deny and Revoke Privileges to properly use new model

* Fixed unit tests

* FineGrainedAccessChecker Grant and Deny methods reworked

* Revoke cypher slightly reworked; Revoke for labels works without label permissions

* EditPermission's label_permission lambda now takes two parameters

* constants naming enforced; replaced asterisks with string constant

* removed faulty test addition

* Naming fixes; FineGrainedAccessChecker unit tests introduced

* unnecessary includes removed; minor code improvements

* minor fix

* Access checker reworked; denies and grant merged into single permission object; Created global_permission that applies to all non-created permissions. Grant, Deny and Revoke reworked; Merge method reworked

* Fixed wrong check;

* Fix after merge; renamed constants; removed unused constant

* Fix after merge; workloads.yaml for lbaprocedures e2e tests updated with new grammar

* Fixes after merge

* Fixes after merge

* fixed Revoke that was not fixed after the merge

* updated cypher main visitor tests

* PR review changes; Naming and const fixed, replaced double tertiary with lambda

* unwrapping the iterator fix

* merge 1003 minor fix

* minor spelling fixes

* Introduced visitPrivilegesList because of the doubled code

* const added

* string const to enum

* redundant braces

* added const

* minor code improvement

* e2e tests expanded

* if -> switch

* enum class inherits uint8_t now

* LabelPrililege::EDIT -> LabelPrivilege::UPDATE

* LabelPermission -> EntityPermission; LabelPrivilege -> EntityPrivilege

* EntityPrivilege -> FineGrainedPrivilege; EntityPermission -> FineGrainedPermission
This commit is contained in:
Boris Taševski 2022-08-22 14:11:43 +02:00 committed by GitHub
parent b489ac7cff
commit 05f120b7d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 762 additions and 417 deletions

View File

@ -32,6 +32,7 @@ DEFINE_string(auth_password_strength_regex, default_password_regex.data(),
namespace memgraph::auth {
namespace {
// Constant list of all available permissions.
const std::vector<Permission> kPermissionsAll = {
Permission::MATCH, Permission::CREATE, Permission::MERGE, Permission::DELETE,
@ -208,7 +209,7 @@ FineGrainedAccessPermissions::FineGrainedAccessPermissions(const std::unordered_
: permissions_(permissions), global_permission_(global_permission) {}
PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission,
const LabelPermission label_permission) const {
const FineGrainedPermission label_permission) const {
const auto concrete_permission = std::invoke([&]() -> uint64_t {
if (permissions_.contains(permission)) {
return permissions_.at(permission);
@ -226,8 +227,8 @@ PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission,
return temp_permission > 0 ? PermissionLevel::GRANT : PermissionLevel::DENY;
}
void FineGrainedAccessPermissions::Grant(const std::string &permission, const LabelPermission label_permission) {
if (permission == ASTERISK) {
void FineGrainedAccessPermissions::Grant(const std::string &permission, const FineGrainedPermission label_permission) {
if (permission == kAsterisk) {
global_permission_ = CalculateGrant(label_permission);
} else {
permissions_[permission] |= CalculateGrant(label_permission);
@ -235,7 +236,7 @@ void FineGrainedAccessPermissions::Grant(const std::string &permission, const La
}
void FineGrainedAccessPermissions::Revoke(const std::string &permission) {
if (permission == ASTERISK) {
if (permission == kAsterisk) {
permissions_.clear();
global_permission_ = std::nullopt;
} else {
@ -243,8 +244,8 @@ void FineGrainedAccessPermissions::Revoke(const std::string &permission) {
}
}
void FineGrainedAccessPermissions::Deny(const std::string &permission, const LabelPermission label_permission) {
if (permission == ASTERISK) {
void FineGrainedAccessPermissions::Deny(const std::string &permission, const FineGrainedPermission label_permission) {
if (permission == kAsterisk) {
global_permission_ = CalculateDeny(label_permission);
} else {
permissions_[permission] = CalculateDeny(label_permission);
@ -279,7 +280,7 @@ const std::unordered_map<std::string, uint64_t> &FineGrainedAccessPermissions::G
}
const std::optional<uint64_t> &FineGrainedAccessPermissions::GetGlobalPermission() const { return global_permission_; };
uint64_t FineGrainedAccessPermissions::CalculateGrant(LabelPermission label_permission) {
uint64_t FineGrainedAccessPermissions::CalculateGrant(FineGrainedPermission label_permission) {
uint64_t shift{1};
uint64_t result{0};
auto uint_label_permission = static_cast<uint64_t>(label_permission);
@ -292,17 +293,17 @@ uint64_t FineGrainedAccessPermissions::CalculateGrant(LabelPermission label_perm
return result;
}
uint64_t FineGrainedAccessPermissions::CalculateDeny(LabelPermission label_permission) {
uint64_t FineGrainedAccessPermissions::CalculateDeny(FineGrainedPermission label_permission) {
uint64_t shift{1};
uint64_t result{0};
auto uint_label_permission = static_cast<uint64_t>(label_permission);
while (uint_label_permission <= LabelPermissionMax) {
while (uint_label_permission <= kLabelPermissionMax) {
result |= uint_label_permission;
uint_label_permission <<= shift;
}
return LabelPermissionAll - result;
return kLabelPermissionAll - result;
}
bool operator==(const FineGrainedAccessPermissions &first, const FineGrainedAccessPermissions &second) {

View File

@ -15,7 +15,7 @@
#include <json/json.hpp>
namespace memgraph::auth {
const std::string ASTERISK = "*";
const std::string kAsterisk = "*";
// These permissions must have values that are applicable for usage in a
// bitmask.
// clang-format off
@ -45,27 +45,30 @@ enum class Permission : uint64_t {
// clang-format on
// clang-format off
enum class LabelPermission : uint64_t {
enum class FineGrainedPermission : uint64_t {
READ = 1,
EDIT = 1U << 1U,
UPDATE = 1U << 1U,
CREATE_DELETE = 1U << 2U
};
// clang-format on
constexpr inline uint64_t operator|(LabelPermission lhs, LabelPermission rhs) {
constexpr inline uint64_t operator|(FineGrainedPermission lhs, FineGrainedPermission rhs) {
return static_cast<uint64_t>(lhs) | static_cast<uint64_t>(rhs);
}
constexpr inline uint64_t operator|(uint64_t lhs, LabelPermission rhs) { return lhs | static_cast<uint64_t>(rhs); }
constexpr inline uint64_t operator|(uint64_t lhs, FineGrainedPermission rhs) {
return lhs | static_cast<uint64_t>(rhs);
}
constexpr inline uint64_t operator&(uint64_t lhs, LabelPermission rhs) {
constexpr inline uint64_t operator&(uint64_t lhs, FineGrainedPermission rhs) {
return (lhs & static_cast<uint64_t>(rhs)) != 0;
}
constexpr uint64_t LabelPermissionAll = memgraph::auth::LabelPermission::CREATE_DELETE |
memgraph::auth::LabelPermission::EDIT | memgraph::auth::LabelPermission::READ;
constexpr uint64_t LabelPermissionMax = static_cast<uint64_t>(memgraph::auth::LabelPermission::CREATE_DELETE);
constexpr uint64_t LabelPermissionMin = static_cast<uint64_t>(memgraph::auth::LabelPermission::READ);
constexpr uint64_t kLabelPermissionAll = memgraph::auth::FineGrainedPermission::CREATE_DELETE |
memgraph::auth::FineGrainedPermission::UPDATE |
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);
// Function that converts a permission to its string representation.
std::string PermissionToString(Permission permission);
@ -125,13 +128,13 @@ class FineGrainedAccessPermissions final {
FineGrainedAccessPermissions &operator=(FineGrainedAccessPermissions &&) = default;
~FineGrainedAccessPermissions() = default;
PermissionLevel Has(const std::string &permission, LabelPermission label_permission) const;
PermissionLevel Has(const std::string &permission, FineGrainedPermission label_permission) const;
void Grant(const std::string &permission, LabelPermission label_permission);
void Grant(const std::string &permission, FineGrainedPermission label_permission);
void Revoke(const std::string &permission);
void Deny(const std::string &permission, LabelPermission label_permission);
void Deny(const std::string &permission, FineGrainedPermission label_permission);
nlohmann::json Serialize() const;
@ -145,8 +148,8 @@ class FineGrainedAccessPermissions final {
std::unordered_map<std::string, uint64_t> permissions_{};
std::optional<uint64_t> global_permission_;
static uint64_t CalculateGrant(LabelPermission label_permission);
static uint64_t CalculateDeny(LabelPermission label_permission);
static uint64_t CalculateGrant(FineGrainedPermission label_permission);
static uint64_t CalculateDeny(FineGrainedPermission label_permission);
};
bool operator==(const FineGrainedAccessPermissions &first, const FineGrainedAccessPermissions &second);

View File

@ -10,6 +10,7 @@
// licenses/APL.txt.
#include "glue/auth.hpp"
#include "auth/models.hpp"
namespace memgraph::glue {
@ -59,4 +60,16 @@ auth::Permission PrivilegeToPermission(query::AuthQuery::Privilege privilege) {
return auth::Permission::WEBSOCKET;
}
}
auth::FineGrainedPermission FineGrainedPrivilegeToFineGrainedPermission(
const query::AuthQuery::FineGrainedPrivilege fine_grained_privilege) {
switch (fine_grained_privilege) {
case query::AuthQuery::FineGrainedPrivilege::READ:
return auth::FineGrainedPermission::READ;
case query::AuthQuery::FineGrainedPrivilege::UPDATE:
return auth::FineGrainedPermission::UPDATE;
case query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE:
return auth::FineGrainedPermission::CREATE_DELETE;
}
}
} // namespace memgraph::glue

View File

@ -20,4 +20,11 @@ namespace memgraph::glue {
*/
auth::Permission PrivilegeToPermission(query::AuthQuery::Privilege privilege);
/**
* Converts query::AuthQuery::FineGrainedPrivilege to its corresponding
* auth::EntityPermission.
*/
auth::FineGrainedPermission FineGrainedPrivilegeToFineGrainedPermission(
query::AuthQuery::FineGrainedPrivilege fine_grained_privilege);
} // namespace memgraph::glue

View File

@ -21,15 +21,16 @@ namespace {
bool IsUserAuthorizedLabels(const memgraph::auth::User &user, const memgraph::query::DbAccessor &dba,
const std::vector<memgraph::storage::LabelId> &labels) {
return std::all_of(labels.begin(), labels.end(), [&dba, &user](const auto label) {
return user.GetFineGrainedAccessLabelPermissions().Has(
dba.LabelToName(label), memgraph::auth::LabelPermission::READ) == memgraph::auth::PermissionLevel::GRANT;
return user.GetFineGrainedAccessLabelPermissions().Has(dba.LabelToName(label),
memgraph::auth::FineGrainedPermission::READ) ==
memgraph::auth::PermissionLevel::GRANT;
});
}
bool IsUserAuthorizedEdgeType(const memgraph::auth::User &user, const memgraph::query::DbAccessor &dba,
const memgraph::storage::EdgeTypeId &edgeType) {
return user.GetFineGrainedAccessEdgeTypePermissions().Has(dba.EdgeTypeToName(edgeType),
memgraph::auth::LabelPermission::READ) ==
memgraph::auth::FineGrainedPermission::READ) ==
memgraph::auth::PermissionLevel::GRANT;
}
} // namespace

View File

@ -509,7 +509,10 @@ class AuthQueryHandler final : public memgraph::query::AuthQueryHandler {
if (first_user) {
spdlog::info("{} is first created user. Granting all privileges.", username);
GrantPrivilege(username, memgraph::query::kPrivilegesAll, {"*"}, {"*"});
GrantPrivilege(
username, memgraph::query::kPrivilegesAll,
{{{memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE, {memgraph::auth::kAsterisk}}}},
{{{memgraph::query::AuthQuery::FineGrainedPrivilege::CREATE_DELETE, {memgraph::auth::kAsterisk}}}});
}
return user_added;
@ -754,59 +757,87 @@ class AuthQueryHandler final : public memgraph::query::AuthQueryHandler {
}
}
void GrantPrivilege(const std::string &user_or_role,
const std::vector<memgraph::query::AuthQuery::Privilege> &privileges,
const std::vector<std::string> &labels, const std::vector<std::string> &edge_types) override {
void GrantPrivilege(
const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges,
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 {
EditPermissions(
user_or_role, privileges, labels, edge_types,
user_or_role, privileges, label_privileges, edge_type_privileges,
[](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);
},
[](auto &label_permissions, const auto &label) {
label_permissions.Grant(label, memgraph::auth::LabelPermission::CREATE_DELETE);
[](auto &fine_grained_permissions, const auto &privilege_collection) {
for (const auto &[privilege, entities] : privilege_collection) {
const auto &permission = memgraph::glue::FineGrainedPrivilegeToFineGrainedPermission(privilege);
for (const auto &entity : entities) {
fine_grained_permissions.Grant(entity, permission);
}
}
});
}
void DenyPrivilege(const std::string &user_or_role,
const std::vector<memgraph::query::AuthQuery::Privilege> &privileges,
const std::vector<std::string> &labels, const std::vector<std::string> &edge_types) override {
void DenyPrivilege(
const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges,
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 {
EditPermissions(
user_or_role, privileges, labels, edge_types,
user_or_role, privileges, label_privileges, edge_type_privileges,
[](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);
},
[](auto &label_permissions, const auto &label) {
label_permissions.Deny(label, memgraph::auth::LabelPermission::READ);
[](auto &fine_grained_permissions, const auto &privilege_collection) {
for (const auto &[privilege, entities] : privilege_collection) {
const auto &permission = memgraph::glue::FineGrainedPrivilegeToFineGrainedPermission(privilege);
for (const auto &entity : entities) {
fine_grained_permissions.Deny(entity, permission);
}
}
});
}
void RevokePrivilege(const std::string &user_or_role,
const std::vector<memgraph::query::AuthQuery::Privilege> &privileges,
const std::vector<std::string> &labels, const std::vector<std::string> &edge_types) override {
void RevokePrivilege(
const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges,
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 {
EditPermissions(
user_or_role, privileges, labels, edge_types,
user_or_role, privileges, label_privileges, edge_type_privileges,
[](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);
},
[](auto &label_permissions, const auto &label) { label_permissions.Revoke(label); });
[](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);
}
}
});
}
private:
template <class TEditPermissionsFun, class TEditFineGrainedPermissionsFun>
void EditPermissions(const std::string &user_or_role,
const std::vector<memgraph::query::AuthQuery::Privilege> &privileges,
const std::vector<std::string> &labels, const std::vector<std::string> &edgeTypes,
const TEditPermissionsFun &edit_permissions_fun,
const TEditFineGrainedPermissionsFun &edit_fine_grained_permissions_fun) {
void EditPermissions(
const std::string &user_or_role, const std::vector<memgraph::query::AuthQuery::Privilege> &privileges,
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) {
if (!std::regex_match(user_or_role, name_regex_)) {
throw memgraph::query::QueryRuntimeException("Invalid user or role name.");
}
@ -826,11 +857,13 @@ class AuthQueryHandler final : public memgraph::query::AuthQueryHandler {
for (const auto &permission : permissions) {
edit_permissions_fun(user->permissions(), permission);
}
for (const auto &label : labels) {
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), label);
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 &edgeType : edgeTypes) {
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().edge_type_permissions(), edgeType);
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);
}
locked_auth->SaveUser(*user);
@ -838,11 +871,12 @@ class AuthQueryHandler final : public memgraph::query::AuthQueryHandler {
for (const auto &permission : permissions) {
edit_permissions_fun(role->permissions(), permission);
}
for (const auto &label : labels) {
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), label);
for (const auto &label_privilege : label_privileges) {
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), label_privilege);
}
for (const auto &edgeType : edgeTypes) {
edit_fine_grained_permissions_fun(role->fine_grained_access_handler().edge_type_permissions(), edgeType);
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);
}
locked_auth->SaveRole(*role);

View File

@ -2244,8 +2244,8 @@ cpp<#
:slk-save #'slk-save-ast-pointer
:slk-load (slk-load-ast-pointer "Expression"))
(privileges "std::vector<Privilege>" :scope :public)
(labels "std::vector<std::string>" :scope :public)
(edge-types "std::vector<std::string>" :scope :public))
(label-privileges "std::vector<std::unordered_map<FineGrainedPrivilege, std::vector<std::string>>>" :scope :public)
(edge-type-privileges "std::vector<std::unordered_map<FineGrainedPrivilege, std::vector<std::string>>>" :scope :public))
(:public
(lcp:define-enum action
(create-role drop-role show-roles create-user set-password drop-user
@ -2258,6 +2258,9 @@ cpp<#
dump replication durability read_file free_memory trigger config stream module_read module_write
websocket)
(:serialize))
(lcp:define-enum fine-grained-privilege
(read update create_delete)
(:serialize))
#>cpp
AuthQuery() = default;
@ -2267,16 +2270,17 @@ cpp<#
#>cpp
AuthQuery(Action action, std::string user, std::string role,
std::string user_or_role, Expression *password,
std::vector<Privilege> privileges, std::vector<std::string> labels,
std::vector<std::string> edge_types)
std::vector<Privilege> privileges,
std::vector<std::unordered_map<FineGrainedPrivilege, std::vector<std::string>>> label_privileges,
std::vector<std::unordered_map<FineGrainedPrivilege, std::vector<std::string>>> edge_type_privileges)
: action_(action),
user_(user),
role_(role),
user_or_role_(user_or_role),
password_(password),
privileges_(privileges),
labels_(labels),
edge_types_(edge_types) {}
label_privileges_(label_privileges),
edge_type_privileges_(edge_type_privileges) {}
cpp<#)
(:private
#>cpp

View File

@ -45,6 +45,8 @@ namespace memgraph::query::frontend {
const std::string CypherMainVisitor::kAnonPrefix = "anon";
namespace {
enum class EntityType : uint8_t { LABELS, EDGE_TYPES };
template <typename TVisitor>
std::optional<std::pair<memgraph::query::Expression *, size_t>> VisitMemoryLimit(
MemgraphCypher::MemoryLimitContext *memory_limit_ctx, TVisitor *visitor) {
@ -1269,17 +1271,6 @@ antlrcpp::Any CypherMainVisitor::visitClearRole(MemgraphCypher::ClearRoleContext
return auth;
}
void CypherMainVisitor::extractPrivilege(AuthQuery *auth,
antlropencypher::MemgraphCypher::PrivilegeContext *privilege) {
if (privilege->EDGE_TYPES()) {
auth->edge_types_ = std::any_cast<std::vector<std::string>>(privilege->edgeTypeList()->accept(this));
} else if (privilege->LABELS()) {
auth->labels_ = std::any_cast<std::vector<std::string>>(privilege->labelList()->accept(this));
} else {
auth->privileges_.push_back(std::any_cast<AuthQuery::Privilege>(privilege->accept(this)));
}
}
/**
* @return AuthQuery*
*/
@ -1287,10 +1278,14 @@ antlrcpp::Any CypherMainVisitor::visitGrantPrivilege(MemgraphCypher::GrantPrivil
AuthQuery *auth = storage_->Create<AuthQuery>();
auth->action_ = AuthQuery::Action::GRANT_PRIVILEGE;
auth->user_or_role_ = std::any_cast<std::string>(ctx->userOrRole->accept(this));
if (ctx->privilegeList()) {
for (auto *privilege : ctx->privilegeList()->privilege()) {
extractPrivilege(auth, privilege);
}
if (ctx->privilegesList()) {
const auto [label_privileges, edge_type_privileges, privileges] = std::any_cast<
std::tuple<std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>,
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>,
std::vector<memgraph::query::AuthQuery::Privilege>>>(ctx->privilegesList()->accept(this));
auth->label_privileges_ = label_privileges;
auth->edge_type_privileges_ = edge_type_privileges;
auth->privileges_ = privileges;
} else {
/* grant all privileges */
auth->privileges_ = kPrivilegesAll;
@ -1305,10 +1300,11 @@ antlrcpp::Any CypherMainVisitor::visitDenyPrivilege(MemgraphCypher::DenyPrivileg
AuthQuery *auth = storage_->Create<AuthQuery>();
auth->action_ = AuthQuery::Action::DENY_PRIVILEGE;
auth->user_or_role_ = std::any_cast<std::string>(ctx->userOrRole->accept(this));
if (ctx->privilegeList()) {
for (auto *privilege : ctx->privilegeList()->privilege()) {
extractPrivilege(auth, privilege);
}
if (ctx->privilegesList()) {
std::tie(auth->label_privileges_, auth->edge_type_privileges_, auth->privileges_) = std::any_cast<
std::tuple<std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>,
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>,
std::vector<memgraph::query::AuthQuery::Privilege>>>(ctx->privilegesList()->accept(this));
} else {
/* deny all privileges */
auth->privileges_ = kPrivilegesAll;
@ -1316,6 +1312,38 @@ antlrcpp::Any CypherMainVisitor::visitDenyPrivilege(MemgraphCypher::DenyPrivileg
return auth;
}
/**
* @return std::tuple<std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>,
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>,
std::vector<memgraph::query::AuthQuery::Privilege>>
*/
antlrcpp::Any CypherMainVisitor::visitPrivilegesList(MemgraphCypher::PrivilegesListContext *ctx) {
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> label_privileges;
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> edge_type_privileges;
std::vector<memgraph::query::AuthQuery::Privilege> privileges;
for (auto *it : ctx->privilegeOrEntityPrivileges()) {
if (it->entityPrivilegeList()) {
const auto result =
std::any_cast<std::pair<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>,
std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>>(
it->entityPrivilegeList()->accept(this));
if (!result.first.empty()) {
label_privileges.emplace_back(result.first);
}
if (!result.second.empty()) {
edge_type_privileges.emplace_back(result.second);
}
} else {
privileges.push_back(std::any_cast<AuthQuery::Privilege>(it->privilege()->accept(this)));
}
}
return std::tuple<std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>,
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>,
std::vector<memgraph::query::AuthQuery::Privilege>>(label_privileges, edge_type_privileges,
privileges);
}
/**
* @return AuthQuery*
*/
@ -1323,9 +1351,22 @@ antlrcpp::Any CypherMainVisitor::visitRevokePrivilege(MemgraphCypher::RevokePriv
AuthQuery *auth = storage_->Create<AuthQuery>();
auth->action_ = AuthQuery::Action::REVOKE_PRIVILEGE;
auth->user_or_role_ = std::any_cast<std::string>(ctx->userOrRole->accept(this));
if (ctx->privilegeList()) {
for (auto *privilege : ctx->privilegeList()->privilege()) {
extractPrivilege(auth, privilege);
if (ctx->revokePrivilegesList()) {
for (auto *it : ctx->revokePrivilegesList()->privilegeOrEntities()) {
if (it->entitiesList()) {
const auto entity_type = std::any_cast<EntityType>(it->entityType()->accept(this));
if (entity_type == EntityType::LABELS) {
auth->label_privileges_.push_back(
{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE,
std::any_cast<std::vector<std::string>>(it->entitiesList()->accept(this))}});
} else {
auth->edge_type_privileges_.push_back(
{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE,
std::any_cast<std::vector<std::string>>(it->entitiesList()->accept(this))}});
}
} else {
auth->privileges_.push_back(std::any_cast<AuthQuery::Privilege>(it->privilege()->accept(this)));
}
}
} else {
/* revoke all privileges */
@ -1334,33 +1375,46 @@ antlrcpp::Any CypherMainVisitor::visitRevokePrivilege(MemgraphCypher::RevokePriv
return auth;
}
antlrcpp::Any CypherMainVisitor::visitLabelList(MemgraphCypher::LabelListContext *ctx) {
std::vector<std::string> labels;
if (ctx->listOfLabels()) {
for (auto *label : ctx->listOfLabels()->label()) {
labels.push_back(std::any_cast<std::string>(label->symbolicName()->accept(this)));
}
} else {
labels.emplace_back("*");
}
/**
* @return std::pair<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>,
std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>
*/
antlrcpp::Any CypherMainVisitor::visitEntityPrivilegeList(MemgraphCypher::EntityPrivilegeListContext *ctx) {
std::pair<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>,
std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>
result;
return labels;
for (auto *it : ctx->entityPrivilege()) {
const auto key = std::any_cast<AuthQuery::FineGrainedPrivilege>(it->granularPrivilege()->accept(this));
const auto entityType = std::any_cast<EntityType>(it->entityType()->accept(this));
auto value = std::any_cast<std::vector<std::string>>(it->entitiesList()->accept(this));
switch (entityType) {
case EntityType::LABELS:
result.first[key] = std::move(value);
break;
case EntityType::EDGE_TYPES:
result.second[key] = std::move(value);
break;
}
}
return result;
}
/**
* @return AuthQuery*
* @return std::vector<std::string>
*/
antlrcpp::Any CypherMainVisitor::visitEdgeTypeList(MemgraphCypher::EdgeTypeListContext *ctx) {
std::vector<std::string> edgeTypes;
if (ctx->listOfEdgeTypes()) {
for (auto *edgeType : ctx->listOfEdgeTypes()->edgeType()) {
edgeTypes.push_back(std::any_cast<std::string>(edgeType->symbolicName()->accept(this)));
antlrcpp::Any CypherMainVisitor::visitEntitiesList(MemgraphCypher::EntitiesListContext *ctx) {
std::vector<std::string> entities;
if (ctx->listOfEntities()) {
for (auto *entity : ctx->listOfEntities()->entity()) {
entities.push_back(std::any_cast<std::string>(entity->symbolicName()->accept(this)));
}
} else {
edgeTypes.emplace_back("*");
entities.emplace_back("*");
}
return edgeTypes;
return entities;
}
/**
@ -1391,6 +1445,25 @@ antlrcpp::Any CypherMainVisitor::visitPrivilege(MemgraphCypher::PrivilegeContext
LOG_FATAL("Should not get here - unknown privilege!");
}
/**
* @return AuthQuery::FineGrainedPrivilege
*/
antlrcpp::Any CypherMainVisitor::visitGranularPrivilege(MemgraphCypher::GranularPrivilegeContext *ctx) {
if (ctx->READ()) return AuthQuery::FineGrainedPrivilege::READ;
if (ctx->UPDATE()) return AuthQuery::FineGrainedPrivilege::UPDATE;
if (ctx->CREATE_DELETE()) return AuthQuery::FineGrainedPrivilege::CREATE_DELETE;
LOG_FATAL("Should not get here - unknown label privilege!");
}
/**
* @return EntityType
*/
antlrcpp::Any CypherMainVisitor::visitEntityType(MemgraphCypher::EntityTypeContext *ctx) {
if (ctx->LABELS()) return EntityType::LABELS;
if (ctx->EDGE_TYPES()) return EntityType::EDGE_TYPES;
LOG_FATAL("Should not get here - unknown entity type!");
}
/**
* @return AuthQuery*
*/
@ -2166,8 +2239,8 @@ antlrcpp::Any CypherMainVisitor::visitFunctionInvocation(MemgraphCypher::Functio
}
auto is_user_defined_function = [](const std::string &function_name) {
// Dots are present only in user-defined functions, since modules are case-sensitive, so must be user-defined
// functions. Builtin functions should be case insensitive.
// Dots are present only in user-defined functions, since modules are case-sensitive, so must be
// user-defined functions. Builtin functions should be case insensitive.
return function_name.find('.') != std::string::npos;
};
@ -2183,8 +2256,8 @@ antlrcpp::Any CypherMainVisitor::visitFunctionInvocation(MemgraphCypher::Functio
antlrcpp::Any CypherMainVisitor::visitFunctionName(MemgraphCypher::FunctionNameContext *ctx) {
auto function_name = ctx->getText();
// Dots are present only in user-defined functions, since modules are case-sensitive, so must be user-defined
// functions. Builtin functions should be case insensitive.
// Dots are present only in user-defined functions, since modules are case-sensitive, so must be
// user-defined functions. Builtin functions should be case insensitive.
if (function_name.find('.') != std::string::npos) {
return function_name;
}

View File

@ -468,12 +468,33 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
/**
* @return AuthQuery*
*/
antlrcpp::Any visitRevokePrivilege(MemgraphCypher::RevokePrivilegeContext *ctx) override;
antlrcpp::Any visitPrivilegesList(MemgraphCypher::PrivilegesListContext *ctx) override;
/**
* @return AuthQuery*
*/
antlrcpp::Any visitEdgeTypeList(MemgraphCypher::EdgeTypeListContext *ctx) override;
antlrcpp::Any visitRevokePrivilege(MemgraphCypher::RevokePrivilegeContext *ctx) override;
/**
* @return std::pair<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>,
std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>
*/
antlrcpp::Any visitEntityPrivilegeList(MemgraphCypher::EntityPrivilegeListContext *ctx) override;
/**
* @return std::vector<std::string>
*/
antlrcpp::Any visitEntitiesList(MemgraphCypher::EntitiesListContext *ctx) override;
/**
* @return AuthQuery::FineGrainedPrivilege
*/
antlrcpp::Any visitGranularPrivilege(MemgraphCypher::GranularPrivilegeContext *ctx) override;
/**
* @return std::string
*/
antlrcpp::Any visitEntityType(MemgraphCypher::EntityTypeContext *ctx) override;
/**
* @return AuthQuery::Privilege
@ -485,11 +506,6 @@ class CypherMainVisitor : public antlropencypher::MemgraphCypherBaseVisitor {
*/
antlrcpp::Any visitShowPrivileges(MemgraphCypher::ShowPrivilegesContext *ctx) override;
/**
* @return AuthQuery::LabelList
*/
antlrcpp::Any visitLabelList(MemgraphCypher::LabelListContext *ctx) override;
/**
* @return AuthQuery*
*/

View File

@ -37,6 +37,7 @@ memgraphCypherKeyword : cypherKeyword
| CONFIG
| CONFIGS
| CONSUMER_GROUP
| CREATE_DELETE
| CREDENTIALS
| CSV
| DATA
@ -229,11 +230,11 @@ setRole : SET ROLE FOR user=userOrRoleName TO role=userOrRoleName;
clearRole : CLEAR ROLE FOR user=userOrRoleName ;
grantPrivilege : GRANT ( ALL PRIVILEGES | privileges=privilegeList ) TO userOrRole=userOrRoleName ;
grantPrivilege : GRANT ( ALL PRIVILEGES | privileges=privilegesList ) TO userOrRole=userOrRoleName ;
denyPrivilege : DENY ( ALL PRIVILEGES | privileges=privilegeList ) TO userOrRole=userOrRoleName ;
denyPrivilege : DENY ( ALL PRIVILEGES | privileges=privilegesList ) TO userOrRole=userOrRoleName ;
revokePrivilege : REVOKE ( ALL PRIVILEGES | privileges=privilegeList ) FROM userOrRole=userOrRoleName ;
revokePrivilege : REVOKE ( ALL PRIVILEGES | privileges=revokePrivilegesList ) FROM userOrRole=userOrRoleName ;
privilege : CREATE
| DELETE
@ -256,23 +257,29 @@ privilege : CREATE
| MODULE_READ
| MODULE_WRITE
| WEBSOCKET
| EDGE_TYPES edgeTypes=edgeTypeList
| LABELS labels=labelList
;
privilegeList : privilege ( ',' privilege )* ;
granularPrivilege : READ | UPDATE | CREATE_DELETE ;
edgeTypeList : '*' | listOfEdgeTypes ;
entityType : LABELS | EDGE_TYPES ;
listOfEdgeTypes : edgeType ( ',' edgeType )* ;
privilegeOrEntityPrivileges : privilege | entityPrivileges=entityPrivilegeList ;
edgeType : COLON symbolicName ;
privilegesList : privilegeOrEntityPrivileges ( ',' privilegeOrEntityPrivileges )* ;
labelList : '*' | listOfLabels ;
entityPrivilegeList : entityPrivilege ( ',' entityPrivilege )* ;
listOfLabels : label ( ',' label )* ;
entityPrivilege : granularPrivilege ON entityType entities=entitiesList ;
label : COLON symbolicName ;
privilegeOrEntities : privilege | entityType entities=entitiesList ;
revokePrivilegesList : privilegeOrEntities ( ',' privilegeOrEntities )* ;
entitiesList : ASTERISK | listOfEntities ;
listOfEntities : entity ( ',' entity )* ;
entity : COLON symbolicName ;
showPrivileges : SHOW PRIVILEGES FOR userOrRole=userOrRoleName ;

View File

@ -42,6 +42,7 @@ COMMITTED : C O M M I T T E D ;
CONFIG : C O N F I G ;
CONFIGS : C O N F I G S;
CONSUMER_GROUP : C O N S U M E R UNDERSCORE G R O U P ;
CREATE_DELETE : C R E A T E UNDERSCORE D E L E T E ;
CREDENTIALS : C R E D E N T I A L S ;
CSV : C S V ;
DATA : D A T A ;

View File

@ -20,7 +20,9 @@
#include <functional>
#include <limits>
#include <optional>
#include <unordered_map>
#include "auth/models.hpp"
#include "glue/communication.hpp"
#include "memory/memory_control.hpp"
#include "query/constants.hpp"
@ -283,8 +285,10 @@ 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_;
std::vector<std::string> edgeTypes = auth_query->edge_types_;
std::vector<std::string> labels = auth_query->labels_;
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_;
auto password = EvaluateOptionalExpression(auth_query->password_, &evaluator);
Callback callback;
@ -314,7 +318,9 @@ 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,
{{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE, {auth::kAsterisk}}}},
{{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE, {auth::kAsterisk}}}});
}
return std::vector<std::vector<TypedValue>>();
@ -389,20 +395,20 @@ Callback HandleAuthQuery(AuthQuery *auth_query, AuthQueryHandler *auth, const Pa
};
return callback;
case AuthQuery::Action::GRANT_PRIVILEGE:
callback.fn = [auth, user_or_role, privileges, labels, edgeTypes] {
auth->GrantPrivilege(user_or_role, privileges, labels, edgeTypes);
callback.fn = [auth, user_or_role, privileges, label_privileges, edge_type_privileges] {
auth->GrantPrivilege(user_or_role, privileges, label_privileges, edge_type_privileges);
return std::vector<std::vector<TypedValue>>();
};
return callback;
case AuthQuery::Action::DENY_PRIVILEGE:
callback.fn = [auth, user_or_role, privileges, labels, edgeTypes] {
auth->DenyPrivilege(user_or_role, privileges, labels, edgeTypes);
callback.fn = [auth, user_or_role, privileges, label_privileges, edge_type_privileges] {
auth->DenyPrivilege(user_or_role, privileges, label_privileges, edge_type_privileges);
return std::vector<std::vector<TypedValue>>();
};
return callback;
case AuthQuery::Action::REVOKE_PRIVILEGE: {
callback.fn = [auth, user_or_role, privileges, labels, edgeTypes] {
auth->RevokePrivilege(user_or_role, privileges, labels, edgeTypes);
callback.fn = [auth, user_or_role, privileges, label_privileges, edge_type_privileges] {
auth->RevokePrivilege(user_or_role, privileges, label_privileges, edge_type_privileges);
return std::vector<std::vector<TypedValue>>();
};
return callback;

View File

@ -99,16 +99,28 @@ class AuthQueryHandler {
virtual std::vector<std::vector<TypedValue>> GetPrivileges(const std::string &user_or_role) = 0;
/// @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::string> &labels, const std::vector<std::string> &edgeTypes) = 0;
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>>>
&label_privileges,
const std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>
&edge_type_privileges) = 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::string> &labels, const std::vector<std::string> &edgeTypes) = 0;
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>>>
&label_privileges,
const std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>
&edge_type_privileges) = 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::string> &labels, const std::vector<std::string> &edgeTypes) = 0;
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>>>
&label_privileges,
const std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>>
&edge_type_privileges) = 0;
};
enum class QueryHandlerResult { COMMIT, ABORT, NOTHING };

View File

@ -6,20 +6,42 @@ import pytest
def test_all_edge_types_all_labels_granted():
admin_connection = common.connect(username="admin", password="test")
user_connnection = common.connect(username="user", password="test")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT LABELS * TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT EDGE_TYPES * TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT READ ON LABELS * TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT READ ON EDGE_TYPES * TO user;")
results = common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n)-[r]->(m) RETURN n,r,m;")
assert len(results) == 3
def test_deny_all_edge_types_and_all_labels():
admin_connection = common.connect(username="admin", password="test")
user_connnection = common.connect(username="user", password="test")
common.execute_and_fetch_all(admin_connection.cursor(), "DENY READ ON LABELS * TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "DENY READ ON EDGE_TYPES * TO user;")
results = common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n)-[r]->(m) RETURN n,r,m;")
assert len(results) == 0
def test_revoke_all_edge_types_and_all_labels():
admin_connection = common.connect(username="admin", password="test")
user_connnection = common.connect(username="user", password="test")
common.execute_and_fetch_all(admin_connection.cursor(), "REVOKE LABELS * FROM user;")
common.execute_and_fetch_all(admin_connection.cursor(), "REVOKE EDGE_TYPES * FROM user;")
results = common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n)-[r]->(m) RETURN n,r,m;")
assert len(results) == 0
def test_deny_edge_type():
admin_connection = common.connect(username="admin", password="test")
user_connnection = common.connect(username="user", password="test")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT LABELS :label1, :label2, :label3 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT EDGE_TYPES :edgeType2 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "DENY EDGE_TYPES :edgeType1 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT READ ON LABELS :label1, :label2, :label3 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT READ ON EDGE_TYPES :edgeType2 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "DENY READ ON EDGE_TYPES :edgeType1 TO user;")
results = common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n)-[r]->(m) RETURN n,r,m;")
@ -29,9 +51,9 @@ def test_deny_edge_type():
def test_denied_node_label():
admin_connection = common.connect(username="admin", password="test")
user_connnection = common.connect(username="user", password="test")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT LABELS :label1,:label3 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT EDGE_TYPES :edgeType1, :edgeType2 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "DENY LABELS :label2 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT READ ON LABELS :label1,:label3 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT READ ON EDGE_TYPES :edgeType1, :edgeType2 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "DENY READ ON LABELS :label2 TO user;")
results = common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n)-[r]->(m) RETURN n,r,m;")
@ -41,9 +63,9 @@ def test_denied_node_label():
def test_denied_one_of_node_label():
admin_connection = common.connect(username="admin", password="test")
user_connnection = common.connect(username="user", password="test")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT LABELS :label1,:label2 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT EDGE_TYPES :edgeType1, :edgeType2 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "DENY LABELS :label3 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT READ ON LABELS :label1,:label2 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "GRANT READ ON EDGE_TYPES :edgeType1, :edgeType2 TO user;")
common.execute_and_fetch_all(admin_connection.cursor(), "DENY READ ON LABELS :label3 TO user;")
results = common.execute_and_fetch_all(user_connnection.cursor(), "MATCH (n)-[r]->(m) RETURN n,r,m;")

View File

@ -16,7 +16,7 @@ template_cluster: &template_cluster
"Create (:Label2 {id: 4}) ;",
"Create User Josip ;",
"Create User Boris ;",
"Grant Labels :Label1 to Boris;",
"Grant Read On Labels :Label1 to Boris;",
]
validation_queries: []

View File

@ -177,29 +177,32 @@ TEST_F(AuthWithStorage, UserRoleFineGrainedAccessHandler) {
user->GetFineGrainedAccessEdgeTypePermissions());
// Grant one label to user .
user->fine_grained_access_handler().label_permissions().Grant("labelTest", LabelPermission::CREATE_DELETE);
user->fine_grained_access_handler().label_permissions().Grant("labelTest", FineGrainedPermission::CREATE_DELETE);
// Grant one edge type to user .
user->fine_grained_access_handler().edge_type_permissions().Grant("edgeTypeTest", LabelPermission::CREATE_DELETE);
user->fine_grained_access_handler().edge_type_permissions().Grant("edgeTypeTest",
FineGrainedPermission::CREATE_DELETE);
// Check permissions.
ASSERT_EQ(user->fine_grained_access_handler().label_permissions().Has("labelTest", LabelPermission::READ),
PermissionLevel::GRANT);
ASSERT_EQ(user->fine_grained_access_handler().edge_type_permissions().Has("edgeTypeTest", LabelPermission::READ),
ASSERT_EQ(user->fine_grained_access_handler().label_permissions().Has("labelTest", FineGrainedPermission::READ),
PermissionLevel::GRANT);
ASSERT_EQ(
user->fine_grained_access_handler().edge_type_permissions().Has("edgeTypeTest", FineGrainedPermission::READ),
PermissionLevel::GRANT);
ASSERT_EQ(user->fine_grained_access_handler().label_permissions(), user->GetFineGrainedAccessLabelPermissions());
ASSERT_EQ(user->fine_grained_access_handler().edge_type_permissions(),
user->GetFineGrainedAccessEdgeTypePermissions());
// Deny one label to user .
user->fine_grained_access_handler().label_permissions().Deny("labelTest1", LabelPermission::READ);
user->fine_grained_access_handler().label_permissions().Deny("labelTest1", FineGrainedPermission::READ);
// Deny one edge type to user .
user->fine_grained_access_handler().edge_type_permissions().Deny("edgeTypeTest1", LabelPermission::READ);
user->fine_grained_access_handler().edge_type_permissions().Deny("edgeTypeTest1", FineGrainedPermission::READ);
// Check permissions.
ASSERT_EQ(user->fine_grained_access_handler().label_permissions().Has("labelTest1", LabelPermission::READ),
PermissionLevel::DENY);
ASSERT_EQ(user->fine_grained_access_handler().edge_type_permissions().Has("edgeTypeTest1", LabelPermission::READ),
ASSERT_EQ(user->fine_grained_access_handler().label_permissions().Has("labelTest1", FineGrainedPermission::READ),
PermissionLevel::DENY);
ASSERT_EQ(
user->fine_grained_access_handler().edge_type_permissions().Has("edgeTypeTest1", FineGrainedPermission::READ),
PermissionLevel::DENY);
ASSERT_EQ(user->fine_grained_access_handler().label_permissions(), user->GetFineGrainedAccessLabelPermissions());
ASSERT_EQ(user->fine_grained_access_handler().edge_type_permissions(),
user->GetFineGrainedAccessEdgeTypePermissions());
@ -210,28 +213,29 @@ TEST_F(AuthWithStorage, UserRoleFineGrainedAccessHandler) {
ASSERT_NE(role, std::nullopt);
// Grant label and edge type to role and role to user.
role->fine_grained_access_handler().label_permissions().Grant("roleLabelTest", LabelPermission::CREATE_DELETE);
role->fine_grained_access_handler().edge_type_permissions().Grant("roleEdgeTypeTest", LabelPermission::CREATE_DELETE);
role->fine_grained_access_handler().label_permissions().Grant("roleLabelTest", FineGrainedPermission::CREATE_DELETE);
role->fine_grained_access_handler().edge_type_permissions().Grant("roleEdgeTypeTest",
FineGrainedPermission::CREATE_DELETE);
user->SetRole(*role);
// Check permissions.
{
ASSERT_EQ(user->GetFineGrainedAccessLabelPermissions().Has("roleLabelTest", LabelPermission::READ),
ASSERT_EQ(user->GetFineGrainedAccessLabelPermissions().Has("roleLabelTest", FineGrainedPermission::READ),
PermissionLevel::GRANT);
ASSERT_EQ(user->GetFineGrainedAccessEdgeTypePermissions().Has("roleEdgeTypeTest", LabelPermission::READ),
ASSERT_EQ(user->GetFineGrainedAccessEdgeTypePermissions().Has("roleEdgeTypeTest", FineGrainedPermission::READ),
PermissionLevel::GRANT);
}
// Deny label and edge type to role and role to user.
role->fine_grained_access_handler().label_permissions().Deny("roleLabelTest1", LabelPermission::READ);
role->fine_grained_access_handler().edge_type_permissions().Deny("roleEdgeTypeTest1", LabelPermission::READ);
role->fine_grained_access_handler().label_permissions().Deny("roleLabelTest1", FineGrainedPermission::READ);
role->fine_grained_access_handler().edge_type_permissions().Deny("roleEdgeTypeTest1", FineGrainedPermission::READ);
user->SetRole(*role);
// Check permissions.
{
ASSERT_EQ(user->GetFineGrainedAccessLabelPermissions().Has("roleLabelTest1", LabelPermission::READ),
ASSERT_EQ(user->GetFineGrainedAccessLabelPermissions().Has("roleLabelTest1", FineGrainedPermission::READ),
PermissionLevel::DENY);
ASSERT_EQ(user->GetFineGrainedAccessEdgeTypePermissions().Has("roleEdgeTypeTest1", LabelPermission::READ),
ASSERT_EQ(user->GetFineGrainedAccessEdgeTypePermissions().Has("roleEdgeTypeTest1", FineGrainedPermission::READ),
PermissionLevel::DENY);
}
}
@ -500,14 +504,14 @@ TEST(AuthWithoutStorage, FineGrainedAccessPermissions) {
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::DENY);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(any_label, FineGrainedPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_FALSE(fga_permissions.GetPermissions().empty());
@ -515,7 +519,7 @@ TEST(AuthWithoutStorage, FineGrainedAccessPermissions) {
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(any_label, FineGrainedPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_FALSE(fga_permissions.GetPermissions().empty());
@ -523,25 +527,25 @@ TEST(AuthWithoutStorage, FineGrainedAccessPermissions) {
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(any_label, FineGrainedPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), LabelPermissionAll);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), kLabelPermissionAll);
ASSERT_FALSE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Revoke(any_label);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), LabelPermissionAll);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), kLabelPermissionAll);
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(any_label, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Revoke(any_label);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
@ -550,7 +554,7 @@ TEST(AuthWithoutStorage, FineGrainedAccessPermissions) {
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(any_label, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Revoke(asterisk);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
@ -559,16 +563,16 @@ TEST(AuthWithoutStorage, FineGrainedAccessPermissions) {
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Revoke(any_label);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), LabelPermission::EDIT | LabelPermission::READ);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), FineGrainedPermission::UPDATE | FineGrainedPermission::READ);
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(any_label, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Revoke(any_label);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
@ -577,7 +581,7 @@ TEST(AuthWithoutStorage, FineGrainedAccessPermissions) {
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(any_label, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Revoke(asterisk);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
@ -586,8 +590,8 @@ TEST(AuthWithoutStorage, FineGrainedAccessPermissions) {
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(check_label, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(non_check_label, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(check_label, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(non_check_label, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Revoke(asterisk);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
@ -596,180 +600,180 @@ TEST(AuthWithoutStorage, FineGrainedAccessPermissions) {
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::EDIT);
fga_permissions.Grant(asterisk, FineGrainedPermission::UPDATE);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, FineGrainedPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(asterisk, LabelPermission::EDIT);
fga_permissions.Deny(asterisk, FineGrainedPermission::UPDATE);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(asterisk, LabelPermission::READ);
fga_permissions.Deny(asterisk, FineGrainedPermission::READ);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::DENY);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::READ);
fga_permissions.Grant(check_label, LabelPermission::EDIT);
fga_permissions.Grant(asterisk, FineGrainedPermission::READ);
fga_permissions.Grant(check_label, FineGrainedPermission::UPDATE);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::READ);
fga_permissions.Deny(check_label, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(asterisk, FineGrainedPermission::READ);
fga_permissions.Deny(check_label, FineGrainedPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::EDIT);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, FineGrainedPermission::UPDATE);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::CREATE_DELETE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, FineGrainedPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::CREATE_DELETE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, FineGrainedPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, LabelPermission::EDIT);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, FineGrainedPermission::UPDATE);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, LabelPermission::READ);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, FineGrainedPermission::READ);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, LabelPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(any_label, FineGrainedPermission::READ), PermissionLevel::DENY);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::READ);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, FineGrainedPermission::READ);
fga_permissions.Revoke(asterisk);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::READ), PermissionLevel::DENY);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::EDIT);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, FineGrainedPermission::UPDATE);
fga_permissions.Revoke(asterisk);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::READ), PermissionLevel::DENY);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::CREATE_DELETE);
fga_permissions.Grant(asterisk, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, FineGrainedPermission::CREATE_DELETE);
fga_permissions.Revoke(asterisk);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, LabelPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, LabelPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(check_label, FineGrainedPermission::READ), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions.Has(non_check_label, FineGrainedPermission::READ), PermissionLevel::DENY);
}
}
TEST_F(AuthWithStorage, FineGrainedAccessCheckerMerge) {
@ -779,63 +783,63 @@ TEST_F(AuthWithStorage, FineGrainedAccessCheckerMerge) {
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
fga_permissions1.Grant(asterisk, LabelPermission::READ);
fga_permissions1.Grant(asterisk, FineGrainedPermission::READ);
auto fga_permissions3 = memgraph::auth::Merge(fga_permissions1, fga_permissions2);
ASSERT_EQ(fga_permissions3.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions3.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
fga_permissions2.Grant(asterisk, LabelPermission::READ);
fga_permissions2.Grant(asterisk, FineGrainedPermission::READ);
auto fga_permissions3 = memgraph::auth::Merge(fga_permissions1, fga_permissions2);
ASSERT_EQ(fga_permissions3.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions3.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
fga_permissions1.Grant(asterisk, LabelPermission::READ);
fga_permissions2.Grant(asterisk, LabelPermission::EDIT);
fga_permissions1.Grant(asterisk, FineGrainedPermission::READ);
fga_permissions2.Grant(asterisk, FineGrainedPermission::UPDATE);
auto fga_permissions3 = memgraph::auth::Merge(fga_permissions1, fga_permissions2);
ASSERT_EQ(fga_permissions3.Has(any_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions3.Has(any_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions3.Has(any_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(any_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions3.Has(any_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
fga_permissions1.Grant(asterisk, LabelPermission::READ);
fga_permissions1.Grant(check_label, LabelPermission::EDIT);
fga_permissions2.Grant(asterisk, LabelPermission::EDIT);
fga_permissions1.Grant(asterisk, FineGrainedPermission::READ);
fga_permissions1.Grant(check_label, FineGrainedPermission::UPDATE);
fga_permissions2.Grant(asterisk, FineGrainedPermission::UPDATE);
auto fga_permissions3 = memgraph::auth::Merge(fga_permissions1, fga_permissions2);
ASSERT_EQ(fga_permissions3.Has(check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(check_label, LabelPermission::EDIT), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions3.Has(check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions3.Has(check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(check_label, FineGrainedPermission::UPDATE), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions3.Has(check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
fga_permissions1.Grant(asterisk, LabelPermission::READ);
fga_permissions1.Grant(check_label, LabelPermission::CREATE_DELETE);
fga_permissions2.Grant(asterisk, LabelPermission::EDIT);
fga_permissions2.Grant(check_label, LabelPermission::READ);
fga_permissions1.Grant(asterisk, FineGrainedPermission::READ);
fga_permissions1.Grant(check_label, FineGrainedPermission::CREATE_DELETE);
fga_permissions2.Grant(asterisk, FineGrainedPermission::UPDATE);
fga_permissions2.Grant(check_label, FineGrainedPermission::READ);
auto fga_permissions3 = memgraph::auth::Merge(fga_permissions1, fga_permissions2);
ASSERT_EQ(fga_permissions3.Has(check_label, LabelPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(check_label, LabelPermission::EDIT), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(check_label, LabelPermission::READ), PermissionLevel::GRANT);
ASSERT_EQ(fga_permissions3.Has(check_label, FineGrainedPermission::CREATE_DELETE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(check_label, FineGrainedPermission::UPDATE), PermissionLevel::DENY);
ASSERT_EQ(fga_permissions3.Has(check_label, FineGrainedPermission::READ), PermissionLevel::GRANT);
}
}

View File

@ -46,7 +46,8 @@ class FineGrainedAuthCheckerFixture : public testing::Test {
TEST_F(FineGrainedAuthCheckerFixture, GrantedAllLabels) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Grant("*", memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Grant("*",
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, v1, memgraph::storage::View::NEW));
@ -59,7 +60,8 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantedAllLabels) {
TEST_F(FineGrainedAuthCheckerFixture, GrantedAllEdgeTypes) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().edge_type_permissions().Grant("*", memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().edge_type_permissions().Grant(
"*", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, r1));
@ -70,7 +72,7 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantedAllEdgeTypes) {
TEST_F(FineGrainedAuthCheckerFixture, DeniedAllLabels) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Deny("*", memgraph::auth::LabelPermission::READ);
user.fine_grained_access_handler().label_permissions().Deny("*", memgraph::auth::FineGrainedPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_FALSE(auth_checker.Accept(dba, v1, memgraph::storage::View::NEW));
@ -83,7 +85,7 @@ TEST_F(FineGrainedAuthCheckerFixture, DeniedAllLabels) {
TEST_F(FineGrainedAuthCheckerFixture, DeniedAllEdgeTypes) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().edge_type_permissions().Deny("*", memgraph::auth::LabelPermission::READ);
user.fine_grained_access_handler().edge_type_permissions().Deny("*", memgraph::auth::FineGrainedPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_FALSE(auth_checker.Accept(dba, r1));
@ -94,7 +96,8 @@ TEST_F(FineGrainedAuthCheckerFixture, DeniedAllEdgeTypes) {
TEST_F(FineGrainedAuthCheckerFixture, GrantLabel) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Grant("l1", memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Grant("l1",
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, v1, memgraph::storage::View::NEW));
@ -103,7 +106,7 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantLabel) {
TEST_F(FineGrainedAuthCheckerFixture, DenyLabel) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Deny("l3", memgraph::auth::LabelPermission::READ);
user.fine_grained_access_handler().label_permissions().Deny("l3", memgraph::auth::FineGrainedPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_FALSE(auth_checker.Accept(dba, v3, memgraph::storage::View::NEW));
@ -112,9 +115,11 @@ TEST_F(FineGrainedAuthCheckerFixture, DenyLabel) {
TEST_F(FineGrainedAuthCheckerFixture, GrantAndDenySpecificLabels) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Grant("l1", memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Grant("l2", memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Deny("l3", memgraph::auth::LabelPermission::READ);
user.fine_grained_access_handler().label_permissions().Grant("l1",
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Grant("l2",
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Deny("l3", memgraph::auth::FineGrainedPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, v1, memgraph::storage::View::NEW));
@ -127,9 +132,11 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantAndDenySpecificLabels) {
TEST_F(FineGrainedAuthCheckerFixture, MultipleVertexLabels) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Grant("l1", memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Grant("l2", memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Deny("l3", memgraph::auth::LabelPermission::READ);
user.fine_grained_access_handler().label_permissions().Grant("l1",
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Grant("l2",
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
user.fine_grained_access_handler().label_permissions().Deny("l3", memgraph::auth::FineGrainedPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l3")).HasValue());
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l1")).HasValue());
@ -143,8 +150,8 @@ TEST_F(FineGrainedAuthCheckerFixture, MultipleVertexLabels) {
TEST_F(FineGrainedAuthCheckerFixture, GrantEdgeType) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().edge_type_permissions().Grant("edge_type_1",
memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().edge_type_permissions().Grant(
"edge_type_1", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, r1));
@ -152,7 +159,8 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantEdgeType) {
TEST_F(FineGrainedAuthCheckerFixture, DenyEdgeType) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().edge_type_permissions().Deny("edge_type_1", memgraph::auth::LabelPermission::READ);
user.fine_grained_access_handler().edge_type_permissions().Deny("edge_type_1",
memgraph::auth::FineGrainedPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_FALSE(auth_checker.Accept(dba, r1));
@ -160,9 +168,10 @@ TEST_F(FineGrainedAuthCheckerFixture, DenyEdgeType) {
TEST_F(FineGrainedAuthCheckerFixture, GrantAndDenySpecificEdgeTypes) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().edge_type_permissions().Grant("edge_type_1",
memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().edge_type_permissions().Deny("edge_type_2", memgraph::auth::LabelPermission::READ);
user.fine_grained_access_handler().edge_type_permissions().Grant(
"edge_type_1", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
user.fine_grained_access_handler().edge_type_permissions().Deny("edge_type_2",
memgraph::auth::FineGrainedPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, r1));

View File

@ -2056,9 +2056,11 @@ TEST_P(CypherMainVisitorTest, UnionAll) {
ASSERT_FALSE(return_clause->body_.distinct);
}
void check_auth_query(Base *ast_generator, std::string input, AuthQuery::Action action, std::string user,
std::string role, std::string user_or_role, std::optional<TypedValue> password,
std::vector<AuthQuery::Privilege> privileges) {
void check_auth_query(
Base *ast_generator, std::string input, AuthQuery::Action action, std::string user, std::string role,
std::string user_or_role, std::optional<TypedValue> password, std::vector<AuthQuery::Privilege> privileges,
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> label_privileges,
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> edge_type_privileges) {
auto *auth_query = dynamic_cast<AuthQuery *>(ast_generator->ParseQuery(input));
ASSERT_TRUE(auth_query);
EXPECT_EQ(auth_query->action_, action);
@ -2070,48 +2072,55 @@ void check_auth_query(Base *ast_generator, std::string input, AuthQuery::Action
ast_generator->CheckLiteral(auth_query->password_, *password);
}
EXPECT_EQ(auth_query->privileges_, privileges);
EXPECT_EQ(auth_query->label_privileges_, label_privileges);
EXPECT_EQ(auth_query->edge_type_privileges_, edge_type_privileges);
}
TEST_P(CypherMainVisitorTest, UserOrRoleName) {
auto &ast_generator = *GetParam();
check_auth_query(&ast_generator, "CREATE ROLE `user`", AuthQuery::Action::CREATE_ROLE, "", "user", "", {}, {});
check_auth_query(&ast_generator, "CREATE ROLE us___er", AuthQuery::Action::CREATE_ROLE, "", "us___er", "", {}, {});
check_auth_query(&ast_generator, "CREATE ROLE `us+er`", AuthQuery::Action::CREATE_ROLE, "", "us+er", "", {}, {});
check_auth_query(&ast_generator, "CREATE ROLE `us|er`", AuthQuery::Action::CREATE_ROLE, "", "us|er", "", {}, {});
check_auth_query(&ast_generator, "CREATE ROLE `us er`", AuthQuery::Action::CREATE_ROLE, "", "us er", "", {}, {});
check_auth_query(&ast_generator, "CREATE ROLE `user`", AuthQuery::Action::CREATE_ROLE, "", "user", "", {}, {}, {},
{});
check_auth_query(&ast_generator, "CREATE ROLE us___er", AuthQuery::Action::CREATE_ROLE, "", "us___er", "", {}, {}, {},
{});
check_auth_query(&ast_generator, "CREATE ROLE `us+er`", AuthQuery::Action::CREATE_ROLE, "", "us+er", "", {}, {}, {},
{});
check_auth_query(&ast_generator, "CREATE ROLE `us|er`", AuthQuery::Action::CREATE_ROLE, "", "us|er", "", {}, {}, {},
{});
check_auth_query(&ast_generator, "CREATE ROLE `us er`", AuthQuery::Action::CREATE_ROLE, "", "us er", "", {}, {}, {},
{});
}
TEST_P(CypherMainVisitorTest, CreateRole) {
auto &ast_generator = *GetParam();
ASSERT_THROW(ast_generator.ParseQuery("CREATE ROLE"), SyntaxException);
check_auth_query(&ast_generator, "CREATE ROLE rola", AuthQuery::Action::CREATE_ROLE, "", "rola", "", {}, {});
check_auth_query(&ast_generator, "CREATE ROLE rola", AuthQuery::Action::CREATE_ROLE, "", "rola", "", {}, {}, {}, {});
ASSERT_THROW(ast_generator.ParseQuery("CREATE ROLE lagano rolamo"), SyntaxException);
}
TEST_P(CypherMainVisitorTest, DropRole) {
auto &ast_generator = *GetParam();
ASSERT_THROW(ast_generator.ParseQuery("DROP ROLE"), SyntaxException);
check_auth_query(&ast_generator, "DROP ROLE rola", AuthQuery::Action::DROP_ROLE, "", "rola", "", {}, {});
check_auth_query(&ast_generator, "DROP ROLE rola", AuthQuery::Action::DROP_ROLE, "", "rola", "", {}, {}, {}, {});
ASSERT_THROW(ast_generator.ParseQuery("DROP ROLE lagano rolamo"), SyntaxException);
}
TEST_P(CypherMainVisitorTest, ShowRoles) {
auto &ast_generator = *GetParam();
ASSERT_THROW(ast_generator.ParseQuery("SHOW ROLES ROLES"), SyntaxException);
check_auth_query(&ast_generator, "SHOW ROLES", AuthQuery::Action::SHOW_ROLES, "", "", "", {}, {});
check_auth_query(&ast_generator, "SHOW ROLES", AuthQuery::Action::SHOW_ROLES, "", "", "", {}, {}, {}, {});
}
TEST_P(CypherMainVisitorTest, CreateUser) {
auto &ast_generator = *GetParam();
ASSERT_THROW(ast_generator.ParseQuery("CREATE USER"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("CREATE USER 123"), SyntaxException);
check_auth_query(&ast_generator, "CREATE USER user", AuthQuery::Action::CREATE_USER, "user", "", "", {}, {});
check_auth_query(&ast_generator, "CREATE USER user", AuthQuery::Action::CREATE_USER, "user", "", "", {}, {}, {}, {});
check_auth_query(&ast_generator, "CREATE USER user IDENTIFIED BY 'password'", AuthQuery::Action::CREATE_USER, "user",
"", "", TypedValue("password"), {});
"", "", TypedValue("password"), {}, {}, {});
check_auth_query(&ast_generator, "CREATE USER user IDENTIFIED BY ''", AuthQuery::Action::CREATE_USER, "user", "", "",
TypedValue(""), {});
TypedValue(""), {}, {}, {});
check_auth_query(&ast_generator, "CREATE USER user IDENTIFIED BY null", AuthQuery::Action::CREATE_USER, "user", "",
"", TypedValue(), {});
"", TypedValue(), {}, {}, {});
ASSERT_THROW(ast_generator.ParseQuery("CRATE USER user IDENTIFIED BY password"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("CREATE USER user IDENTIFIED BY 5"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("CREATE USER user IDENTIFIED BY "), SyntaxException);
@ -2122,23 +2131,23 @@ TEST_P(CypherMainVisitorTest, SetPassword) {
ASSERT_THROW(ast_generator.ParseQuery("SET PASSWORD FOR"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("SET PASSWORD FOR user "), SyntaxException);
check_auth_query(&ast_generator, "SET PASSWORD FOR user TO null", AuthQuery::Action::SET_PASSWORD, "user", "", "",
TypedValue(), {});
TypedValue(), {}, {}, {});
check_auth_query(&ast_generator, "SET PASSWORD FOR user TO 'password'", AuthQuery::Action::SET_PASSWORD, "user", "",
"", TypedValue("password"), {});
"", TypedValue("password"), {}, {}, {});
ASSERT_THROW(ast_generator.ParseQuery("SET PASSWORD FOR user To 5"), SyntaxException);
}
TEST_P(CypherMainVisitorTest, DropUser) {
auto &ast_generator = *GetParam();
ASSERT_THROW(ast_generator.ParseQuery("DROP USER"), SyntaxException);
check_auth_query(&ast_generator, "DROP USER user", AuthQuery::Action::DROP_USER, "user", "", "", {}, {});
check_auth_query(&ast_generator, "DROP USER user", AuthQuery::Action::DROP_USER, "user", "", "", {}, {}, {}, {});
ASSERT_THROW(ast_generator.ParseQuery("DROP USER lagano rolamo"), SyntaxException);
}
TEST_P(CypherMainVisitorTest, ShowUsers) {
auto &ast_generator = *GetParam();
ASSERT_THROW(ast_generator.ParseQuery("SHOW USERS ROLES"), SyntaxException);
check_auth_query(&ast_generator, "SHOW USERS", AuthQuery::Action::SHOW_USERS, "", "", "", {}, {});
check_auth_query(&ast_generator, "SHOW USERS", AuthQuery::Action::SHOW_USERS, "", "", "", {}, {}, {}, {});
}
TEST_P(CypherMainVisitorTest, SetRole) {
@ -2147,10 +2156,10 @@ TEST_P(CypherMainVisitorTest, SetRole) {
ASSERT_THROW(ast_generator.ParseQuery("SET ROLE user"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("SET ROLE FOR user"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("SET ROLE FOR user TO"), SyntaxException);
check_auth_query(&ast_generator, "SET ROLE FOR user TO role", AuthQuery::Action::SET_ROLE, "user", "role", "", {},
{});
check_auth_query(&ast_generator, "SET ROLE FOR user TO null", AuthQuery::Action::SET_ROLE, "user", "null", "", {},
{});
check_auth_query(&ast_generator, "SET ROLE FOR user TO role", AuthQuery::Action::SET_ROLE, "user", "role", "", {}, {},
{}, {});
check_auth_query(&ast_generator, "SET ROLE FOR user TO null", AuthQuery::Action::SET_ROLE, "user", "null", "", {}, {},
{}, {});
}
TEST_P(CypherMainVisitorTest, ClearRole) {
@ -2158,7 +2167,8 @@ TEST_P(CypherMainVisitorTest, ClearRole) {
ASSERT_THROW(ast_generator.ParseQuery("CLEAR ROLE"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("CLEAR ROLE user"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("CLEAR ROLE FOR user TO"), SyntaxException);
check_auth_query(&ast_generator, "CLEAR ROLE FOR user", AuthQuery::Action::CLEAR_ROLE, "user", "", "", {}, {});
check_auth_query(&ast_generator, "CLEAR ROLE FOR user", AuthQuery::Action::CLEAR_ROLE, "user", "", "", {}, {}, {},
{});
}
TEST_P(CypherMainVisitorTest, GrantPrivilege) {
@ -2169,50 +2179,97 @@ TEST_P(CypherMainVisitorTest, GrantPrivilege) {
ASSERT_THROW(ast_generator.ParseQuery("GRANT MATCH, TO user"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("GRANT MATCH, BLABLA TO user"), SyntaxException);
check_auth_query(&ast_generator, "GRANT MATCH TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MATCH});
{AuthQuery::Privilege::MATCH}, {}, {});
check_auth_query(&ast_generator, "GRANT MATCH, AUTH TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MATCH, AuthQuery::Privilege::AUTH});
{AuthQuery::Privilege::MATCH, AuthQuery::Privilege::AUTH}, {}, {});
// Verify that all privileges are correctly visited.
check_auth_query(&ast_generator, "GRANT CREATE TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::CREATE});
{AuthQuery::Privilege::CREATE}, {}, {});
check_auth_query(&ast_generator, "GRANT DELETE TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::DELETE});
{AuthQuery::Privilege::DELETE}, {}, {});
check_auth_query(&ast_generator, "GRANT MERGE TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MERGE});
{AuthQuery::Privilege::MERGE}, {}, {});
check_auth_query(&ast_generator, "GRANT SET TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::SET});
{AuthQuery::Privilege::SET}, {}, {});
check_auth_query(&ast_generator, "GRANT REMOVE TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::REMOVE});
{AuthQuery::Privilege::REMOVE}, {}, {});
check_auth_query(&ast_generator, "GRANT INDEX TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::INDEX});
{AuthQuery::Privilege::INDEX}, {}, {});
check_auth_query(&ast_generator, "GRANT STATS TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::STATS});
{AuthQuery::Privilege::STATS}, {}, {});
check_auth_query(&ast_generator, "GRANT AUTH TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::AUTH});
{AuthQuery::Privilege::AUTH}, {}, {});
check_auth_query(&ast_generator, "GRANT CONSTRAINT TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::CONSTRAINT});
{AuthQuery::Privilege::CONSTRAINT}, {}, {});
check_auth_query(&ast_generator, "GRANT DUMP TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::DUMP});
{AuthQuery::Privilege::DUMP}, {}, {});
check_auth_query(&ast_generator, "GRANT REPLICATION TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::REPLICATION});
{AuthQuery::Privilege::REPLICATION}, {}, {});
check_auth_query(&ast_generator, "GRANT DURABILITY TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::DURABILITY});
{AuthQuery::Privilege::DURABILITY}, {}, {});
check_auth_query(&ast_generator, "GRANT READ_FILE TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::READ_FILE});
{AuthQuery::Privilege::READ_FILE}, {}, {});
check_auth_query(&ast_generator, "GRANT FREE_MEMORY TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::FREE_MEMORY});
{AuthQuery::Privilege::FREE_MEMORY}, {}, {});
check_auth_query(&ast_generator, "GRANT TRIGGER TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::TRIGGER});
{AuthQuery::Privilege::TRIGGER}, {}, {});
check_auth_query(&ast_generator, "GRANT CONFIG TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::CONFIG});
{AuthQuery::Privilege::CONFIG}, {}, {});
check_auth_query(&ast_generator, "GRANT STREAM TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::STREAM});
{AuthQuery::Privilege::STREAM}, {}, {});
check_auth_query(&ast_generator, "GRANT WEBSOCKET TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::WEBSOCKET});
{AuthQuery::Privilege::WEBSOCKET}, {}, {});
check_auth_query(&ast_generator, "GRANT MODULE_READ TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MODULE_READ});
{AuthQuery::Privilege::MODULE_READ}, {}, {});
check_auth_query(&ast_generator, "GRANT MODULE_WRITE TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MODULE_WRITE});
{AuthQuery::Privilege::MODULE_WRITE}, {}, {});
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> label_privileges{};
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> edge_type_privileges{};
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"*"}}}});
check_auth_query(&ast_generator, "GRANT READ ON LABELS * TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user",
{}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::UPDATE}, {{"*"}}}});
check_auth_query(&ast_generator, "GRANT UPDATE ON LABELS * TO user", AuthQuery::Action::GRANT_PRIVILEGE, "", "",
"user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE}, {{"*"}}}});
check_auth_query(&ast_generator, "GRANT CREATE_DELETE ON LABELS * TO user", AuthQuery::Action::GRANT_PRIVILEGE, "",
"", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"Label1"}, {"Label2"}}}});
check_auth_query(&ast_generator, "GRANT READ ON LABELS :Label1, :Label2 TO user", AuthQuery::Action::GRANT_PRIVILEGE,
"", "", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::UPDATE}, {{"Label1"}, {"Label2"}}}});
check_auth_query(&ast_generator, "GRANT UPDATE ON LABELS :Label1, :Label2 TO user",
AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE}, {{"Label1"}, {"Label2"}}}});
check_auth_query(&ast_generator, "GRANT CREATE_DELETE ON LABELS :Label1, :Label2 TO user",
AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"Label1"}, {"Label2"}}},
{{AuthQuery::FineGrainedPrivilege::UPDATE}, {{"Label3"}}}});
check_auth_query(&ast_generator, "GRANT READ ON LABELS :Label1, :Label2, UPDATE ON LABELS :Label3 TO user",
AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"Label1"}, {"Label2"}}}});
edge_type_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"Edge1"}, {"Edge2"}, {"Edge3"}}}});
check_auth_query(&ast_generator,
"GRANT READ ON LABELS :Label1, :Label2, READ ON EDGE_TYPES :Edge1, :Edge2, :Edge3 TO user",
AuthQuery::Action::GRANT_PRIVILEGE, "", "", "user", {}, {}, label_privileges, edge_type_privileges);
label_privileges.clear();
edge_type_privileges.clear();
}
TEST_P(CypherMainVisitorTest, DenyPrivilege) {
@ -2223,36 +2280,83 @@ TEST_P(CypherMainVisitorTest, DenyPrivilege) {
ASSERT_THROW(ast_generator.ParseQuery("DENY MATCH, TO user"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("DENY MATCH, BLABLA TO user"), SyntaxException);
check_auth_query(&ast_generator, "DENY MATCH TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MATCH});
{AuthQuery::Privilege::MATCH}, {}, {});
check_auth_query(&ast_generator, "DENY MATCH, AUTH TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MATCH, AuthQuery::Privilege::AUTH});
{AuthQuery::Privilege::MATCH, AuthQuery::Privilege::AUTH}, {}, {});
// Verify that all privileges are correctly visited.
check_auth_query(&ast_generator, "DENY CREATE TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::CREATE});
{AuthQuery::Privilege::CREATE}, {}, {});
check_auth_query(&ast_generator, "DENY DELETE TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::DELETE});
{AuthQuery::Privilege::DELETE}, {}, {});
check_auth_query(&ast_generator, "DENY MERGE TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MERGE});
{AuthQuery::Privilege::MERGE}, {}, {});
check_auth_query(&ast_generator, "DENY SET TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::SET});
{AuthQuery::Privilege::SET}, {}, {});
check_auth_query(&ast_generator, "DENY REMOVE TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::REMOVE});
{AuthQuery::Privilege::REMOVE}, {}, {});
check_auth_query(&ast_generator, "DENY INDEX TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::INDEX});
{AuthQuery::Privilege::INDEX}, {}, {});
check_auth_query(&ast_generator, "DENY STATS TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::STATS});
{AuthQuery::Privilege::STATS}, {}, {});
check_auth_query(&ast_generator, "DENY AUTH TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::AUTH});
{AuthQuery::Privilege::AUTH}, {}, {});
check_auth_query(&ast_generator, "DENY CONSTRAINT TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::CONSTRAINT});
{AuthQuery::Privilege::CONSTRAINT}, {}, {});
check_auth_query(&ast_generator, "DENY DUMP TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::DUMP});
{AuthQuery::Privilege::DUMP}, {}, {});
check_auth_query(&ast_generator, "DENY WEBSOCKET TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::WEBSOCKET});
{AuthQuery::Privilege::WEBSOCKET}, {}, {});
check_auth_query(&ast_generator, "DENY MODULE_READ TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MODULE_READ});
{AuthQuery::Privilege::MODULE_READ}, {}, {});
check_auth_query(&ast_generator, "DENY MODULE_WRITE TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MODULE_WRITE});
{AuthQuery::Privilege::MODULE_WRITE}, {}, {});
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> label_privileges{};
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> edge_type_privileges{};
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"*"}}}});
check_auth_query(&ast_generator, "DENY READ ON LABELS * TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user",
{}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::UPDATE}, {{"*"}}}});
check_auth_query(&ast_generator, "DENY UPDATE ON LABELS * TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "", "user",
{}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE}, {{"*"}}}});
check_auth_query(&ast_generator, "DENY CREATE_DELETE ON LABELS * TO user", AuthQuery::Action::DENY_PRIVILEGE, "", "",
"user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"Label1"}, {"Label2"}}}});
check_auth_query(&ast_generator, "DENY READ ON LABELS :Label1, :Label2 TO user", AuthQuery::Action::DENY_PRIVILEGE,
"", "", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::UPDATE}, {{"Label1"}, {"Label2"}}}});
check_auth_query(&ast_generator, "DENY UPDATE ON LABELS :Label1, :Label2 TO user", AuthQuery::Action::DENY_PRIVILEGE,
"", "", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE}, {{"Label1"}, {"Label2"}}}});
check_auth_query(&ast_generator, "DENY CREATE_DELETE ON LABELS :Label1, :Label2 TO user",
AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"Label1"}, {"Label2"}}},
{{AuthQuery::FineGrainedPrivilege::UPDATE}, {{"Label3"}}}});
check_auth_query(&ast_generator, "DENY READ ON LABELS :Label1, :Label2, UPDATE ON LABELS :Label3 TO user",
AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"Label1"}, {"Label2"}}}});
edge_type_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::READ}, {{"Edge1"}, {"Edge2"}, {"Edge3"}}}});
check_auth_query(&ast_generator,
"DENY READ ON LABELS :Label1, :Label2, READ ON EDGE_TYPES :Edge1, :Edge2, :Edge3 TO user",
AuthQuery::Action::DENY_PRIVILEGE, "", "", "user", {}, {}, label_privileges, edge_type_privileges);
label_privileges.clear();
edge_type_privileges.clear();
}
TEST_P(CypherMainVisitorTest, RevokePrivilege) {
@ -2263,52 +2367,75 @@ TEST_P(CypherMainVisitorTest, RevokePrivilege) {
ASSERT_THROW(ast_generator.ParseQuery("REVOKE MATCH, FROM user"), SyntaxException);
ASSERT_THROW(ast_generator.ParseQuery("REVOKE MATCH, BLABLA FROM user"), SyntaxException);
check_auth_query(&ast_generator, "REVOKE MATCH FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MATCH});
{AuthQuery::Privilege::MATCH}, {}, {});
check_auth_query(&ast_generator, "REVOKE MATCH, AUTH FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user",
{}, {AuthQuery::Privilege::MATCH, AuthQuery::Privilege::AUTH});
{}, {AuthQuery::Privilege::MATCH, AuthQuery::Privilege::AUTH}, {}, {});
check_auth_query(&ast_generator, "REVOKE ALL PRIVILEGES FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "",
"user", {}, kPrivilegesAll);
"user", {}, kPrivilegesAll, {}, {});
// Verify that all privileges are correctly visited.
check_auth_query(&ast_generator, "REVOKE CREATE FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::CREATE});
{AuthQuery::Privilege::CREATE}, {}, {});
check_auth_query(&ast_generator, "REVOKE DELETE FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::DELETE});
{AuthQuery::Privilege::DELETE}, {}, {});
check_auth_query(&ast_generator, "REVOKE MERGE FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::MERGE});
{AuthQuery::Privilege::MERGE}, {}, {});
check_auth_query(&ast_generator, "REVOKE SET FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::SET});
{AuthQuery::Privilege::SET}, {}, {});
check_auth_query(&ast_generator, "REVOKE REMOVE FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::REMOVE});
{AuthQuery::Privilege::REMOVE}, {}, {});
check_auth_query(&ast_generator, "REVOKE INDEX FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::INDEX});
{AuthQuery::Privilege::INDEX}, {}, {});
check_auth_query(&ast_generator, "REVOKE STATS FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::STATS});
{AuthQuery::Privilege::STATS}, {}, {});
check_auth_query(&ast_generator, "REVOKE AUTH FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::AUTH});
{AuthQuery::Privilege::AUTH}, {}, {});
check_auth_query(&ast_generator, "REVOKE CONSTRAINT FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user",
{}, {AuthQuery::Privilege::CONSTRAINT});
{}, {AuthQuery::Privilege::CONSTRAINT}, {}, {});
check_auth_query(&ast_generator, "REVOKE DUMP FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{AuthQuery::Privilege::DUMP});
{AuthQuery::Privilege::DUMP}, {}, {});
check_auth_query(&ast_generator, "REVOKE WEBSOCKET FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user",
{}, {AuthQuery::Privilege::WEBSOCKET});
{}, {AuthQuery::Privilege::WEBSOCKET}, {}, {});
check_auth_query(&ast_generator, "REVOKE MODULE_READ FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user",
{}, {AuthQuery::Privilege::MODULE_READ});
{}, {AuthQuery::Privilege::MODULE_READ}, {}, {});
check_auth_query(&ast_generator, "REVOKE MODULE_WRITE FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user",
{}, {AuthQuery::Privilege::MODULE_WRITE});
{}, {AuthQuery::Privilege::MODULE_WRITE}, {}, {});
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> label_privileges{};
std::vector<std::unordered_map<AuthQuery::FineGrainedPrivilege, std::vector<std::string>>> edge_type_privileges{};
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE}, {{"*"}}}});
check_auth_query(&ast_generator, "REVOKE LABELS * FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {},
{}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE}, {{"Label1"}, {"Label2"}}}});
check_auth_query(&ast_generator, "REVOKE LABELS :Label1, :Label2 FROM user", AuthQuery::Action::REVOKE_PRIVILEGE, "",
"", "user", {}, {}, label_privileges, {});
label_privileges.clear();
label_privileges.push_back({{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE}, {{"Label1"}, {"Label2"}}}});
edge_type_privileges.push_back(
{{{AuthQuery::FineGrainedPrivilege::CREATE_DELETE}, {{"Edge1"}, {"Edge2"}, {"Edge3"}}}});
check_auth_query(&ast_generator, "REVOKE LABELS :Label1, :Label2, EDGE_TYPES :Edge1, :Edge2, :Edge3 FROM user",
AuthQuery::Action::REVOKE_PRIVILEGE, "", "", "user", {}, {}, label_privileges, edge_type_privileges);
label_privileges.clear();
edge_type_privileges.clear();
}
TEST_P(CypherMainVisitorTest, ShowPrivileges) {
auto &ast_generator = *GetParam();
ASSERT_THROW(ast_generator.ParseQuery("SHOW PRIVILEGES FOR"), SyntaxException);
check_auth_query(&ast_generator, "SHOW PRIVILEGES FOR user", AuthQuery::Action::SHOW_PRIVILEGES, "", "", "user", {},
{});
{}, {}, {});
ASSERT_THROW(ast_generator.ParseQuery("SHOW PRIVILEGES FOR user1, user2"), SyntaxException);
}
TEST_P(CypherMainVisitorTest, ShowRoleForUser) {
auto &ast_generator = *GetParam();
ASSERT_THROW(ast_generator.ParseQuery("SHOW ROLE FOR "), SyntaxException);
check_auth_query(&ast_generator, "SHOW ROLE FOR user", AuthQuery::Action::SHOW_ROLE_FOR_USER, "user", "", "", {}, {});
check_auth_query(&ast_generator, "SHOW ROLE FOR user", AuthQuery::Action::SHOW_ROLE_FOR_USER, "user", "", "", {}, {},
{}, {});
ASSERT_THROW(ast_generator.ParseQuery("SHOW ROLE FOR user1, user2"), SyntaxException);
}
@ -2316,7 +2443,7 @@ TEST_P(CypherMainVisitorTest, ShowUsersForRole) {
auto &ast_generator = *GetParam();
ASSERT_THROW(ast_generator.ParseQuery("SHOW USERS FOR "), SyntaxException);
check_auth_query(&ast_generator, "SHOW USERS FOR role", AuthQuery::Action::SHOW_USERS_FOR_ROLE, "", "role", "", {},
{});
{}, {}, {});
ASSERT_THROW(ast_generator.ParseQuery("SHOW USERS FOR role1, role2"), SyntaxException);
}

View File

@ -427,11 +427,12 @@ TEST_F(ExpandFixture, ExpandWithEdgeFiltering) {
auto user = memgraph::auth::User("test");
user.fine_grained_access_handler().edge_type_permissions().Grant("Edge",
memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().edge_type_permissions().Grant(
"Edge", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
user.fine_grained_access_handler().edge_type_permissions().Deny("edge_type_test",
memgraph::auth::LabelPermission::READ);
user.fine_grained_access_handler().label_permissions().Grant("*", memgraph::auth::LabelPermission::CREATE_DELETE);
memgraph::auth::FineGrainedPermission::READ);
user.fine_grained_access_handler().label_permissions().Grant("*",
memgraph::auth::FineGrainedPermission::CREATE_DELETE);
memgraph::storage::EdgeTypeId edge_type_test{db.NameToEdgeType("edge_type_test")};
ASSERT_TRUE(dba.InsertEdge(&v1, &v2, edge_type_test).HasValue());
@ -450,8 +451,8 @@ TEST_F(ExpandFixture, ExpandWithEdgeFiltering) {
EXPECT_EQ(2, test_expand(user, EdgeAtom::Direction::IN, memgraph::storage::View::OLD));
EXPECT_EQ(4, test_expand(user, EdgeAtom::Direction::BOTH, memgraph::storage::View::OLD));
user.fine_grained_access_handler().edge_type_permissions().Grant("edge_type_test",
memgraph::auth::LabelPermission::CREATE_DELETE);
user.fine_grained_access_handler().edge_type_permissions().Grant(
"edge_type_test", memgraph::auth::FineGrainedPermission::CREATE_DELETE);
EXPECT_EQ(4, test_expand(user, EdgeAtom::Direction::OUT, memgraph::storage::View::OLD));
EXPECT_EQ(4, test_expand(user, EdgeAtom::Direction::IN, memgraph::storage::View::OLD));

View File

@ -11,6 +11,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <unordered_map>
#include "query/frontend/ast/ast.hpp"
#include "query/frontend/ast/ast_visitor.hpp"
@ -98,8 +99,11 @@ TEST_F(TestPrivilegeExtractor, CreateIndex) {
}
TEST_F(TestPrivilegeExtractor, AuthQuery) {
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>>>{};
auto *query = AUTH_QUERY(AuthQuery::Action::CREATE_ROLE, "", "role", "", nullptr, std::vector<AuthQuery::Privilege>{},
std::vector<std::string>{}, std::vector<std::string>{});
label_privileges, edge_type_privileges);
EXPECT_THAT(GetRequiredPrivileges(query), UnorderedElementsAre(AuthQuery::Privilege::AUTH));
}