[E129-MG < T1003-MG] Expand fine grained access checker with more granular permissions (#496)

* 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

* FineGrainedAccessChecker Grant and Deny methods reworked

* removed faulty test addition

* Naming fixes; FineGrainedAccessChecker unit tests introduced

* unnecessary includes removed; minor code improvements

* 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;

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

* unwrapping the iterator fix

* minor spelling fixes
This commit is contained in:
Boris Taševski 2022-08-18 16:59:38 +02:00 committed by GitHub
parent e15576f56c
commit b489ac7cff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 591 additions and 198 deletions

View File

@ -8,10 +8,8 @@
#include "auth/models.hpp"
#include <algorithm>
#include <iterator>
#include <cstdint>
#include <regex>
#include <unordered_set>
#include <gflags/gflags.h>
@ -19,6 +17,7 @@
#include "auth/exceptions.hpp"
#include "utils/cast.hpp"
#include "utils/license.hpp"
#include "utils/logging.hpp"
#include "utils/settings.hpp"
#include "utils/string.hpp"
@ -101,6 +100,24 @@ std::string PermissionLevelToString(PermissionLevel level) {
}
}
FineGrainedAccessPermissions Merge(const FineGrainedAccessPermissions &first,
const FineGrainedAccessPermissions &second) {
std::unordered_map<std::string, uint64_t> permissions{first.GetPermissions()};
std::optional<uint64_t> global_permission;
if (second.GetGlobalPermission().has_value()) {
global_permission = second.GetGlobalPermission().value();
} else if (first.GetGlobalPermission().has_value()) {
global_permission = first.GetGlobalPermission().value();
}
for (const auto &[label_name, permission] : second.GetPermissions()) {
permissions[label_name] = permission;
}
return FineGrainedAccessPermissions(permissions, global_permission);
}
Permissions::Permissions(uint64_t grants, uint64_t denies) {
// The deny bitmask has higher priority than the grant bitmask.
denies_ = denies;
@ -186,96 +203,58 @@ bool operator==(const Permissions &first, const Permissions &second) {
bool operator!=(const Permissions &first, const Permissions &second) { return !(first == second); }
const std::string ASTERISK = "*";
FineGrainedAccessPermissions::FineGrainedAccessPermissions(const std::unordered_map<std::string, uint64_t> &permissions,
const std::optional<uint64_t> &global_permission)
: permissions_(permissions), global_permission_(global_permission) {}
FineGrainedAccessPermissions::FineGrainedAccessPermissions(const std::unordered_set<std::string> &grants,
const std::unordered_set<std::string> &denies)
: grants_(grants), denies_(denies) {}
PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission,
const LabelPermission label_permission) const {
const auto concrete_permission = std::invoke([&]() -> uint64_t {
if (permissions_.contains(permission)) {
return permissions_.at(permission);
}
PermissionLevel FineGrainedAccessPermissions::Has(const std::string &permission) const {
if ((denies_.size() == 1 && denies_.find(ASTERISK) != denies_.end()) || denies_.find(permission) != denies_.end()) {
return PermissionLevel::DENY;
}
if (global_permission_.has_value()) {
return global_permission_.value();
}
if ((grants_.size() == 1 && grants_.find(ASTERISK) != grants_.end()) || grants_.find(permission) != denies_.end()) {
return PermissionLevel::GRANT;
}
return 0;
});
return PermissionLevel::NEUTRAL;
const auto temp_permission = concrete_permission & label_permission;
return temp_permission > 0 ? PermissionLevel::GRANT : PermissionLevel::DENY;
}
void FineGrainedAccessPermissions::Grant(const std::string &permission) {
void FineGrainedAccessPermissions::Grant(const std::string &permission, const LabelPermission label_permission) {
if (permission == ASTERISK) {
grants_.clear();
denies_.clear();
grants_.insert(permission);
return;
}
auto deniedPermissionIter = denies_.find(permission);
if (deniedPermissionIter != denies_.end()) {
denies_.erase(deniedPermissionIter);
}
if (grants_.size() == 1 && grants_.find(ASTERISK) != grants_.end()) {
grants_.erase(ASTERISK);
}
if (grants_.find(permission) == grants_.end()) {
grants_.insert(permission);
global_permission_ = CalculateGrant(label_permission);
} else {
permissions_[permission] |= CalculateGrant(label_permission);
}
}
void FineGrainedAccessPermissions::Revoke(const std::string &permission) {
if (permission == ASTERISK) {
grants_.clear();
denies_.clear();
return;
}
auto deniedPermissionIter = denies_.find(permission);
auto grantedPermissionIter = grants_.find(permission);
if (deniedPermissionIter != denies_.end()) {
denies_.erase(deniedPermissionIter);
}
if (grantedPermissionIter != grants_.end()) {
grants_.erase(grantedPermissionIter);
permissions_.clear();
global_permission_ = std::nullopt;
} else {
permissions_.erase(permission);
}
}
void FineGrainedAccessPermissions::Deny(const std::string &permission) {
void FineGrainedAccessPermissions::Deny(const std::string &permission, const LabelPermission label_permission) {
if (permission == ASTERISK) {
grants_.clear();
denies_.clear();
denies_.insert(permission);
return;
}
auto grantedPermissionIter = grants_.find(permission);
if (grantedPermissionIter != grants_.end()) {
grants_.erase(grantedPermissionIter);
}
if (denies_.size() == 1 && denies_.find(ASTERISK) != denies_.end()) {
denies_.erase(ASTERISK);
}
if (denies_.find(permission) == denies_.end()) {
denies_.insert(permission);
global_permission_ = CalculateDeny(label_permission);
} else {
permissions_[permission] = CalculateDeny(label_permission);
}
}
nlohmann::json FineGrainedAccessPermissions::Serialize() const {
nlohmann::json data = nlohmann::json::object();
data["grants"] = grants_;
data["denies"] = denies_;
data["permissions"] = permissions_;
data["global_permission"] = global_permission_.has_value() ? global_permission_.value() : -1;
return data;
}
@ -284,14 +263,51 @@ FineGrainedAccessPermissions FineGrainedAccessPermissions::Deserialize(const nlo
throw AuthException("Couldn't load permissions data!");
}
return FineGrainedAccessPermissions(data["grants"], data["denies"]);
std::optional<uint64_t> global_permission;
if (data["global_permission"].empty() || data["global_permission"] == -1) {
global_permission = std::nullopt;
} else {
global_permission = data["global_permission"];
}
return FineGrainedAccessPermissions(data["permissions"], global_permission);
}
const std::unordered_set<std::string> &FineGrainedAccessPermissions::grants() const { return grants_; }
const std::unordered_set<std::string> &FineGrainedAccessPermissions::denies() const { return denies_; }
const std::unordered_map<std::string, uint64_t> &FineGrainedAccessPermissions::GetPermissions() const {
return permissions_;
}
const std::optional<uint64_t> &FineGrainedAccessPermissions::GetGlobalPermission() const { return global_permission_; };
uint64_t FineGrainedAccessPermissions::CalculateGrant(LabelPermission label_permission) {
uint64_t shift{1};
uint64_t result{0};
auto uint_label_permission = static_cast<uint64_t>(label_permission);
while (uint_label_permission > 0) {
result |= uint_label_permission;
uint_label_permission >>= shift;
}
return result;
}
uint64_t FineGrainedAccessPermissions::CalculateDeny(LabelPermission 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) {
result |= uint_label_permission;
uint_label_permission <<= shift;
}
return LabelPermissionAll - result;
}
bool operator==(const FineGrainedAccessPermissions &first, const FineGrainedAccessPermissions &second) {
return first.grants() == second.grants() && first.denies() == second.denies();
return first.GetPermissions() == second.GetPermissions() &&
first.GetGlobalPermission() == second.GetGlobalPermission();
}
bool operator!=(const FineGrainedAccessPermissions &first, const FineGrainedAccessPermissions &second) {
@ -321,7 +337,7 @@ FineGrainedAccessHandler FineGrainedAccessHandler::Deserialize(const nlohmann::j
if (!data.is_object()) {
throw AuthException("Couldn't load role data!");
}
if (!data["label_permissions"].is_object() && !data["edge_type_permissions"].is_object()) {
if (!data["label_permissions"].is_object() || !data["edge_type_permissions"].is_object()) {
throw AuthException("Couldn't load label_permissions or edge_type_permissions data!");
}
auto label_permissions = FineGrainedAccessPermissions::Deserialize(data["label_permissions"]);
@ -439,46 +455,16 @@ Permissions User::GetPermissions() const {
FineGrainedAccessPermissions User::GetFineGrainedAccessLabelPermissions() const {
if (role_) {
std::unordered_set<std::string> resultGrants;
std::set_union(fine_grained_access_handler_.label_permissions().grants().begin(),
fine_grained_access_handler_.label_permissions().grants().end(),
role_->fine_grained_access_handler().label_permissions().grants().begin(),
role_->fine_grained_access_handler().label_permissions().grants().end(),
std::inserter(resultGrants, resultGrants.begin()));
std::unordered_set<std::string> resultDenies;
std::set_union(fine_grained_access_handler_.label_permissions().denies().begin(),
fine_grained_access_handler_.label_permissions().denies().end(),
role_->fine_grained_access_handler().label_permissions().denies().begin(),
role_->fine_grained_access_handler().label_permissions().denies().end(),
std::inserter(resultDenies, resultDenies.begin()));
return FineGrainedAccessPermissions(resultGrants, resultDenies);
return Merge(role()->fine_grained_access_handler().label_permissions(),
fine_grained_access_handler_.label_permissions());
}
return fine_grained_access_handler_.label_permissions();
}
FineGrainedAccessPermissions User::GetFineGrainedAccessEdgeTypePermissions() const {
if (role_) {
std::unordered_set<std::string> resultGrants;
std::set_union(fine_grained_access_handler_.edge_type_permissions().grants().begin(),
fine_grained_access_handler_.edge_type_permissions().grants().end(),
role_->fine_grained_access_handler().edge_type_permissions().grants().begin(),
role_->fine_grained_access_handler().edge_type_permissions().grants().end(),
std::inserter(resultGrants, resultGrants.begin()));
std::unordered_set<std::string> resultDenies;
std::set_union(fine_grained_access_handler_.edge_type_permissions().denies().begin(),
fine_grained_access_handler_.edge_type_permissions().denies().end(),
role_->fine_grained_access_handler().edge_type_permissions().denies().begin(),
role_->fine_grained_access_handler().edge_type_permissions().denies().end(),
std::inserter(resultDenies, resultDenies.begin()));
return FineGrainedAccessPermissions(resultGrants, resultDenies);
return Merge(role()->fine_grained_access_handler().edge_type_permissions(),
fine_grained_access_handler_.edge_type_permissions());
}
return fine_grained_access_handler_.edge_type_permissions();
}

View File

@ -10,12 +10,12 @@
#include <optional>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <json/json.hpp>
#include <unordered_set>
namespace memgraph::auth {
const std::string ASTERISK = "*";
// These permissions must have values that are applicable for usage in a
// bitmask.
// clang-format off
@ -44,15 +44,34 @@ enum class Permission : uint64_t {
};
// clang-format on
// clang-format off
enum class LabelPermission : uint64_t {
READ = 1,
EDIT = 1U << 1U,
CREATE_DELETE = 1U << 2U
};
// clang-format on
constexpr inline uint64_t operator|(LabelPermission lhs, LabelPermission 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, LabelPermission 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);
// Function that converts a permission to its string representation.
std::string PermissionToString(Permission permission);
// Class that indicates what permission level the user/role has.
enum class PermissionLevel {
GRANT,
NEUTRAL,
DENY,
};
enum class PermissionLevel : uint8_t { GRANT, NEUTRAL, DENY };
// Function that converts a permission level to its string representation.
std::string PermissionLevelToString(PermissionLevel level);
@ -98,34 +117,36 @@ bool operator!=(const Permissions &first, const Permissions &second);
class FineGrainedAccessPermissions final {
public:
explicit FineGrainedAccessPermissions(const std::unordered_set<std::string> &grants = {},
const std::unordered_set<std::string> &denies = {});
explicit FineGrainedAccessPermissions(const std::unordered_map<std::string, uint64_t> &permissions = {},
const std::optional<uint64_t> &global_permission = std::nullopt);
FineGrainedAccessPermissions(const FineGrainedAccessPermissions &) = default;
FineGrainedAccessPermissions &operator=(const FineGrainedAccessPermissions &) = default;
FineGrainedAccessPermissions(FineGrainedAccessPermissions &&) = default;
FineGrainedAccessPermissions &operator=(FineGrainedAccessPermissions &&) = default;
~FineGrainedAccessPermissions() = default;
PermissionLevel Has(const std::string &permission) const;
PermissionLevel Has(const std::string &permission, LabelPermission label_permission) const;
void Grant(const std::string &permission);
void Grant(const std::string &permission, LabelPermission label_permission);
void Revoke(const std::string &permission);
void Deny(const std::string &permission);
void Deny(const std::string &permission, LabelPermission label_permission);
nlohmann::json Serialize() const;
/// @throw AuthException if unable to deserialize.
static FineGrainedAccessPermissions Deserialize(const nlohmann::json &data);
const std::unordered_set<std::string> &grants() const;
const std::unordered_set<std::string> &denies() const;
const std::unordered_map<std::string, uint64_t> &GetPermissions() const;
const std::optional<uint64_t> &GetGlobalPermission() const;
private:
std::unordered_set<std::string> grants_{};
std::unordered_set<std::string> denies_{};
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);
};
bool operator==(const FineGrainedAccessPermissions &first, const FineGrainedAccessPermissions &second);
@ -252,4 +273,7 @@ class User final {
};
bool operator==(const User &first, const User &second);
FineGrainedAccessPermissions Merge(const FineGrainedAccessPermissions &first,
const FineGrainedAccessPermissions &second);
} // namespace memgraph::auth

View File

@ -21,14 +21,15 @@ 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::PermissionLevel::GRANT;
return user.GetFineGrainedAccessLabelPermissions().Has(
dba.LabelToName(label), memgraph::auth::LabelPermission::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)) ==
return user.GetFineGrainedAccessEdgeTypePermissions().Has(dba.EdgeTypeToName(edgeType),
memgraph::auth::LabelPermission::READ) ==
memgraph::auth::PermissionLevel::GRANT;
}
} // namespace

View File

@ -756,43 +756,57 @@ 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> &edgeTypes) override {
EditPermissions(user_or_role, privileges, labels, edgeTypes, [](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);
});
const std::vector<std::string> &labels, const std::vector<std::string> &edge_types) override {
EditPermissions(
user_or_role, privileges, labels, edge_types,
[](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);
});
}
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> &edgeTypes) override {
EditPermissions(user_or_role, privileges, labels, edgeTypes, [](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);
});
const std::vector<std::string> &labels, const std::vector<std::string> &edge_types) override {
EditPermissions(
user_or_role, privileges, labels, edge_types,
[](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);
});
}
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> &edgeTypes) override {
EditPermissions(user_or_role, privileges, labels, edgeTypes, [](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);
});
const std::vector<std::string> &labels, const std::vector<std::string> &edge_types) override {
EditPermissions(
user_or_role, privileges, labels, edge_types,
[](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); });
}
private:
template <class TEditFun>
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 TEditFun &edit_fun) {
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.");
}
@ -810,25 +824,25 @@ class AuthQueryHandler final : public memgraph::query::AuthQueryHandler {
}
if (user) {
for (const auto &permission : permissions) {
edit_fun(&user->permissions(), permission);
edit_permissions_fun(user->permissions(), permission);
}
for (const auto &label : labels) {
edit_fun(&user->fine_grained_access_handler().label_permissions(), label);
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), label);
}
for (const auto &edgeType : edgeTypes) {
edit_fun(&user->fine_grained_access_handler().edge_type_permissions(), edgeType);
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().edge_type_permissions(), edgeType);
}
locked_auth->SaveUser(*user);
} else {
for (const auto &permission : permissions) {
edit_fun(&role->permissions(), permission);
edit_permissions_fun(role->permissions(), permission);
}
for (const auto &label : labels) {
edit_fun(&user->fine_grained_access_handler().label_permissions(), label);
edit_fine_grained_permissions_fun(user->fine_grained_access_handler().label_permissions(), label);
}
for (const auto &edgeType : edgeTypes) {
edit_fun(&role->fine_grained_access_handler().edge_type_permissions(), edgeType);
edit_fine_grained_permissions_fun(role->fine_grained_access_handler().edge_type_permissions(), edgeType);
}
locked_auth->SaveRole(*role);

View File

@ -13,8 +13,7 @@ import mgp
@mgp.read_proc
def underlying_graph_is_mutable(ctx: mgp.ProcCtx,
object: mgp.Any) -> mgp.Record(mutable=bool):
def underlying_graph_is_mutable(ctx: mgp.ProcCtx, object: mgp.Any) -> mgp.Record(mutable=bool):
return mgp.Record(mutable=object.underlying_graph_is_mutable())

View File

@ -11,6 +11,7 @@
#include <algorithm>
#include <iostream>
#include <optional>
#include <gflags/gflags.h>
#include <gtest/gtest.h>
@ -176,25 +177,29 @@ TEST_F(AuthWithStorage, UserRoleFineGrainedAccessHandler) {
user->GetFineGrainedAccessEdgeTypePermissions());
// Grant one label to user .
user->fine_grained_access_handler().label_permissions().Grant("labelTest");
user->fine_grained_access_handler().label_permissions().Grant("labelTest", LabelPermission::CREATE_DELETE);
// Grant one edge type to user .
user->fine_grained_access_handler().edge_type_permissions().Grant("edgeTypeTest");
user->fine_grained_access_handler().edge_type_permissions().Grant("edgeTypeTest", LabelPermission::CREATE_DELETE);
// Check permissions.
ASSERT_EQ(user->fine_grained_access_handler().label_permissions().Has("labelTest"), PermissionLevel::GRANT);
ASSERT_EQ(user->fine_grained_access_handler().edge_type_permissions().Has("edgeTypeTest"), PermissionLevel::GRANT);
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),
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");
user->fine_grained_access_handler().label_permissions().Deny("labelTest1", LabelPermission::READ);
// Deny one edge type to user .
user->fine_grained_access_handler().edge_type_permissions().Deny("edgeTypeTest1");
user->fine_grained_access_handler().edge_type_permissions().Deny("edgeTypeTest1", LabelPermission::READ);
// Check permissions.
ASSERT_EQ(user->fine_grained_access_handler().label_permissions().Has("labelTest1"), PermissionLevel::DENY);
ASSERT_EQ(user->fine_grained_access_handler().edge_type_permissions().Has("edgeTypeTest1"), PermissionLevel::DENY);
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),
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());
@ -205,25 +210,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");
role->fine_grained_access_handler().edge_type_permissions().Grant("roleEdgeTypeTest");
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);
user->SetRole(*role);
// Check permissions.
{
ASSERT_EQ(user->GetFineGrainedAccessLabelPermissions().Has("roleLabelTest"), PermissionLevel::GRANT);
ASSERT_EQ(user->GetFineGrainedAccessEdgeTypePermissions().Has("roleEdgeTypeTest"), PermissionLevel::GRANT);
ASSERT_EQ(user->GetFineGrainedAccessLabelPermissions().Has("roleLabelTest", LabelPermission::READ),
PermissionLevel::GRANT);
ASSERT_EQ(user->GetFineGrainedAccessEdgeTypePermissions().Has("roleEdgeTypeTest", LabelPermission::READ),
PermissionLevel::GRANT);
}
// Deny label and edge type to role and role to user.
role->fine_grained_access_handler().label_permissions().Deny("roleLabelTest1");
role->fine_grained_access_handler().edge_type_permissions().Deny("roleEdgeTypeTest1");
role->fine_grained_access_handler().label_permissions().Deny("roleLabelTest1", LabelPermission::READ);
role->fine_grained_access_handler().edge_type_permissions().Deny("roleEdgeTypeTest1", LabelPermission::READ);
user->SetRole(*role);
// Check permissions.
{
ASSERT_EQ(user->GetFineGrainedAccessLabelPermissions().Has("roleLabelTest1"), PermissionLevel::DENY);
ASSERT_EQ(user->GetFineGrainedAccessEdgeTypePermissions().Has("roleEdgeTypeTest1"), PermissionLevel::DENY);
ASSERT_EQ(user->GetFineGrainedAccessLabelPermissions().Has("roleLabelTest1", LabelPermission::READ),
PermissionLevel::DENY);
ASSERT_EQ(user->GetFineGrainedAccessEdgeTypePermissions().Has("roleEdgeTypeTest1", LabelPermission::READ),
PermissionLevel::DENY);
}
}
@ -475,6 +484,361 @@ TEST(AuthWithoutStorage, PermissionsMaskTest) {
ASSERT_EQ(p4.denies(), 2);
}
TEST(AuthWithoutStorage, FineGrainedAccessPermissions) {
const std::string any_label = "AnyString";
const std::string check_label = "Label";
const std::string non_check_label = "OtherLabel";
const std::string asterisk = "*";
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
ASSERT_TRUE(fga_permissions1 == fga_permissions2);
}
{
FineGrainedAccessPermissions fga_permissions;
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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(any_label, LabelPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_FALSE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(any_label, LabelPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_FALSE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(any_label, LabelPermission::CREATE_DELETE);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), LabelPermissionAll);
ASSERT_FALSE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Revoke(any_label);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), LabelPermissionAll);
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Revoke(any_label);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Revoke(asterisk);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Revoke(any_label);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), LabelPermission::EDIT | LabelPermission::READ);
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Revoke(any_label);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(any_label, LabelPermission::CREATE_DELETE);
fga_permissions.Revoke(asterisk);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(check_label, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(non_check_label, LabelPermission::CREATE_DELETE);
fga_permissions.Revoke(asterisk);
ASSERT_EQ(fga_permissions.GetGlobalPermission(), std::nullopt);
ASSERT_TRUE(fga_permissions.GetPermissions().empty());
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::EDIT);
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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(asterisk, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(asterisk, LabelPermission::EDIT);
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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Deny(asterisk, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::READ);
fga_permissions.Grant(check_label, LabelPermission::EDIT);
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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::READ);
fga_permissions.Deny(check_label, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::EDIT);
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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, LabelPermission::EDIT);
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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(asterisk, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::EDIT);
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);
}
{
FineGrainedAccessPermissions fga_permissions;
fga_permissions.Grant(asterisk, LabelPermission::CREATE_DELETE);
fga_permissions.Deny(check_label, LabelPermission::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);
}
}
TEST_F(AuthWithStorage, FineGrainedAccessCheckerMerge) {
auto any_label = "AnyString";
auto check_label = "Label";
auto asterisk = "*";
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
fga_permissions1.Grant(asterisk, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
fga_permissions2.Grant(asterisk, LabelPermission::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);
}
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
fga_permissions1.Grant(asterisk, LabelPermission::READ);
fga_permissions2.Grant(asterisk, LabelPermission::EDIT);
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);
}
{
FineGrainedAccessPermissions fga_permissions1, fga_permissions2;
fga_permissions1.Grant(asterisk, LabelPermission::READ);
fga_permissions1.Grant(check_label, LabelPermission::EDIT);
fga_permissions2.Grant(asterisk, LabelPermission::EDIT);
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);
}
{
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);
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);
}
}
TEST(AuthWithoutStorage, UserSerializeDeserialize) {
auto user = User("test");
user.permissions().Grant(Permission::MATCH);

View File

@ -46,7 +46,7 @@ class FineGrainedAuthCheckerFixture : public testing::Test {
TEST_F(FineGrainedAuthCheckerFixture, GrantedAllLabels) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Grant("*");
user.fine_grained_access_handler().label_permissions().Grant("*", memgraph::auth::LabelPermission::CREATE_DELETE);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, v1, memgraph::storage::View::NEW));
@ -59,7 +59,7 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantedAllLabels) {
TEST_F(FineGrainedAuthCheckerFixture, GrantedAllEdgeTypes) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().edge_type_permissions().Grant("*");
user.fine_grained_access_handler().edge_type_permissions().Grant("*", memgraph::auth::LabelPermission::CREATE_DELETE);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, r1));
@ -70,7 +70,7 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantedAllEdgeTypes) {
TEST_F(FineGrainedAuthCheckerFixture, DeniedAllLabels) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Deny("*");
user.fine_grained_access_handler().label_permissions().Deny("*", memgraph::auth::LabelPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_FALSE(auth_checker.Accept(dba, v1, memgraph::storage::View::NEW));
@ -83,7 +83,7 @@ TEST_F(FineGrainedAuthCheckerFixture, DeniedAllLabels) {
TEST_F(FineGrainedAuthCheckerFixture, DeniedAllEdgeTypes) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().edge_type_permissions().Deny("*");
user.fine_grained_access_handler().edge_type_permissions().Deny("*", memgraph::auth::LabelPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_FALSE(auth_checker.Accept(dba, r1));
@ -94,7 +94,7 @@ TEST_F(FineGrainedAuthCheckerFixture, DeniedAllEdgeTypes) {
TEST_F(FineGrainedAuthCheckerFixture, GrantLabel) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Grant("l1");
user.fine_grained_access_handler().label_permissions().Grant("l1", memgraph::auth::LabelPermission::CREATE_DELETE);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, v1, memgraph::storage::View::NEW));
@ -103,7 +103,7 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantLabel) {
TEST_F(FineGrainedAuthCheckerFixture, DenyLabel) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Deny("l3");
user.fine_grained_access_handler().label_permissions().Deny("l3", memgraph::auth::LabelPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_FALSE(auth_checker.Accept(dba, v3, memgraph::storage::View::NEW));
@ -112,9 +112,9 @@ TEST_F(FineGrainedAuthCheckerFixture, DenyLabel) {
TEST_F(FineGrainedAuthCheckerFixture, GrantAndDenySpecificLabels) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Grant("l1");
user.fine_grained_access_handler().label_permissions().Grant("l2");
user.fine_grained_access_handler().label_permissions().Deny("l3");
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);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, v1, memgraph::storage::View::NEW));
@ -127,9 +127,9 @@ TEST_F(FineGrainedAuthCheckerFixture, GrantAndDenySpecificLabels) {
TEST_F(FineGrainedAuthCheckerFixture, MultipleVertexLabels) {
memgraph::auth::User user{"test"};
user.fine_grained_access_handler().label_permissions().Grant("l1");
user.fine_grained_access_handler().label_permissions().Grant("l2");
user.fine_grained_access_handler().label_permissions().Deny("l3");
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);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l3")).HasValue());
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l1")).HasValue());
@ -143,7 +143,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");
user.fine_grained_access_handler().edge_type_permissions().Grant("edge_type_1",
memgraph::auth::LabelPermission::CREATE_DELETE);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, r1));
@ -151,7 +152,7 @@ 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");
user.fine_grained_access_handler().edge_type_permissions().Deny("edge_type_1", memgraph::auth::LabelPermission::READ);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_FALSE(auth_checker.Accept(dba, r1));
@ -159,8 +160,9 @@ 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");
user.fine_grained_access_handler().edge_type_permissions().Deny("edge_type_2");
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);
memgraph::glue::FineGrainedAuthChecker auth_checker{user};
ASSERT_TRUE(auth_checker.Accept(dba, r1));

View File

@ -427,9 +427,11 @@ TEST_F(ExpandFixture, ExpandWithEdgeFiltering) {
auto user = memgraph::auth::User("test");
user.fine_grained_access_handler().edge_type_permissions().Grant("Edge");
user.fine_grained_access_handler().edge_type_permissions().Deny("edge_type_test");
user.fine_grained_access_handler().label_permissions().Grant("*");
user.fine_grained_access_handler().edge_type_permissions().Grant("Edge",
memgraph::auth::LabelPermission::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::storage::EdgeTypeId edge_type_test{db.NameToEdgeType("edge_type_test")};
ASSERT_TRUE(dba.InsertEdge(&v1, &v2, edge_type_test).HasValue());
@ -448,7 +450,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");
user.fine_grained_access_handler().edge_type_permissions().Grant("edge_type_test",
memgraph::auth::LabelPermission::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));