[E129-MG < T1004-MG] Expand cypher with more granular label permissions (#500)
* 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:
parent
b489ac7cff
commit
05f120b7d4
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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*
|
||||
*/
|
||||
|
@ -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 ;
|
||||
|
||||
|
@ -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 ;
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
|
@ -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;")
|
||||
|
||||
|
@ -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: []
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user