memgraph/tests/unit/auth_checker.cpp
Boris Taševski 05f120b7d4
[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
2022-08-22 14:11:43 +02:00

182 lines
8.7 KiB
C++

// Copyright 2022 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
// License, and you may not use this file except in compliance with the Business Source License.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "auth/models.hpp"
#include "glue/auth_checker.hpp"
#include "query_plan_common.hpp"
#include "storage/v2/view.hpp"
class FineGrainedAuthCheckerFixture : public testing::Test {
protected:
memgraph::storage::Storage db;
memgraph::storage::Storage::Accessor storage_dba{db.Access()};
memgraph::query::DbAccessor dba{&storage_dba};
// make a V-graph (v3)<-[r2]-(v1)-[r1]->(v2)
memgraph::query::VertexAccessor v1{dba.InsertVertex()};
memgraph::query::VertexAccessor v2{dba.InsertVertex()};
memgraph::query::VertexAccessor v3{dba.InsertVertex()};
memgraph::storage::EdgeTypeId edge_type_one{db.NameToEdgeType("edge_type_1")};
memgraph::storage::EdgeTypeId edge_type_two{db.NameToEdgeType("edge_type_2")};
memgraph::query::EdgeAccessor r1{*dba.InsertEdge(&v1, &v2, edge_type_one)};
memgraph::query::EdgeAccessor r2{*dba.InsertEdge(&v1, &v3, edge_type_one)};
memgraph::query::EdgeAccessor r3{*dba.InsertEdge(&v1, &v2, edge_type_two)};
memgraph::query::EdgeAccessor r4{*dba.InsertEdge(&v1, &v3, edge_type_two)};
void SetUp() override {
ASSERT_TRUE(v1.AddLabel(dba.NameToLabel("l1")).HasValue());
ASSERT_TRUE(v2.AddLabel(dba.NameToLabel("l2")).HasValue());
ASSERT_TRUE(v3.AddLabel(dba.NameToLabel("l3")).HasValue());
dba.AdvanceCommand();
}
};
TEST_F(FineGrainedAuthCheckerFixture, GrantedAllLabels) {
memgraph::auth::User user{"test"};
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));
ASSERT_TRUE(auth_checker.Accept(dba, v1, memgraph::storage::View::OLD));
ASSERT_TRUE(auth_checker.Accept(dba, v2, memgraph::storage::View::NEW));
ASSERT_TRUE(auth_checker.Accept(dba, v2, memgraph::storage::View::OLD));
ASSERT_TRUE(auth_checker.Accept(dba, v3, memgraph::storage::View::NEW));
ASSERT_TRUE(auth_checker.Accept(dba, v3, memgraph::storage::View::OLD));
}
TEST_F(FineGrainedAuthCheckerFixture, GrantedAllEdgeTypes) {
memgraph::auth::User user{"test"};
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));
ASSERT_TRUE(auth_checker.Accept(dba, r2));
ASSERT_TRUE(auth_checker.Accept(dba, r3));
ASSERT_TRUE(auth_checker.Accept(dba, r4));
}
TEST_F(FineGrainedAuthCheckerFixture, DeniedAllLabels) {
memgraph::auth::User user{"test"};
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));
ASSERT_FALSE(auth_checker.Accept(dba, v1, memgraph::storage::View::OLD));
ASSERT_FALSE(auth_checker.Accept(dba, v2, memgraph::storage::View::NEW));
ASSERT_FALSE(auth_checker.Accept(dba, v2, memgraph::storage::View::OLD));
ASSERT_FALSE(auth_checker.Accept(dba, v3, memgraph::storage::View::NEW));
ASSERT_FALSE(auth_checker.Accept(dba, v3, memgraph::storage::View::OLD));
}
TEST_F(FineGrainedAuthCheckerFixture, DeniedAllEdgeTypes) {
memgraph::auth::User user{"test"};
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));
ASSERT_FALSE(auth_checker.Accept(dba, r2));
ASSERT_FALSE(auth_checker.Accept(dba, r3));
ASSERT_FALSE(auth_checker.Accept(dba, r4));
}
TEST_F(FineGrainedAuthCheckerFixture, GrantLabel) {
memgraph::auth::User user{"test"};
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));
ASSERT_TRUE(auth_checker.Accept(dba, v1, memgraph::storage::View::OLD));
}
TEST_F(FineGrainedAuthCheckerFixture, DenyLabel) {
memgraph::auth::User user{"test"};
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));
ASSERT_FALSE(auth_checker.Accept(dba, v3, memgraph::storage::View::OLD));
}
TEST_F(FineGrainedAuthCheckerFixture, GrantAndDenySpecificLabels) {
memgraph::auth::User user{"test"};
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));
ASSERT_TRUE(auth_checker.Accept(dba, v1, memgraph::storage::View::OLD));
ASSERT_TRUE(auth_checker.Accept(dba, v2, memgraph::storage::View::NEW));
ASSERT_TRUE(auth_checker.Accept(dba, v2, memgraph::storage::View::OLD));
ASSERT_FALSE(auth_checker.Accept(dba, v3, memgraph::storage::View::NEW));
ASSERT_FALSE(auth_checker.Accept(dba, v3, memgraph::storage::View::OLD));
}
TEST_F(FineGrainedAuthCheckerFixture, MultipleVertexLabels) {
memgraph::auth::User user{"test"};
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());
dba.AdvanceCommand();
ASSERT_FALSE(auth_checker.Accept(dba, v1, memgraph::storage::View::NEW));
ASSERT_FALSE(auth_checker.Accept(dba, v1, memgraph::storage::View::OLD));
ASSERT_TRUE(auth_checker.Accept(dba, v2, memgraph::storage::View::NEW));
ASSERT_TRUE(auth_checker.Accept(dba, v2, memgraph::storage::View::OLD));
}
TEST_F(FineGrainedAuthCheckerFixture, GrantEdgeType) {
memgraph::auth::User user{"test"};
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));
}
TEST_F(FineGrainedAuthCheckerFixture, DenyEdgeType) {
memgraph::auth::User user{"test"};
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));
}
TEST_F(FineGrainedAuthCheckerFixture, GrantAndDenySpecificEdgeTypes) {
memgraph::auth::User user{"test"};
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));
ASSERT_TRUE(auth_checker.Accept(dba, r2));
ASSERT_FALSE(auth_checker.Accept(dba, r3));
ASSERT_FALSE(auth_checker.Accept(dba, r4));
}