From 5e271b7be7ba5add4132cc8181a12493dc089373 Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Sat, 11 Jul 2020 23:06:44 +0530 Subject: [PATCH 01/13] fix: GetFilteredPolicy() inner loop variable. Signed-off-by: DivyPatel9881 --- casbin/model/model.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/casbin/model/model.cpp b/casbin/model/model.cpp index e2c8e604..110e868e 100644 --- a/casbin/model/model.cpp +++ b/casbin/model/model.cpp @@ -209,8 +209,8 @@ vector> Model :: GetFilteredPolicy(string sec, string p_type, int vector> policy(m[sec].assertion_map[p_type]->policy); for(int i = 0 ; i < policy.size() ; i++){ bool matched = true; - for(int i = 0 ; i < field_values.size() ; i++){ - if(field_values[i] != "" && (policy[i])[field_index + i] != field_values[i] ){ + for(int j = 0 ; j < field_values.size() ; j++){ + if(field_values[j] != "" && (policy[i])[field_index + j] != field_values[j] ){ matched = false; break; } From 925ca24b03d5c6116f84054abe244ab1995ae8c3 Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Sun, 12 Jul 2020 01:54:23 +0530 Subject: [PATCH 02/13] fix: add domain as a parameter. Signed-off-by: DivyPatel9881 --- casbin/enforcer.h | 4 ++-- casbin/enforcer_interface.h | 4 ++-- casbin/rbac_api.cpp | 9 ++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/casbin/enforcer.h b/casbin/enforcer.h index 789c7e3f..56e17a77 100644 --- a/casbin/enforcer.h +++ b/casbin/enforcer.h @@ -210,8 +210,8 @@ class Enforcer : public IEnforcer{ void AddFunction(string name, Function function, Index nargs); /*RBAC API member functions.*/ - vector GetRolesForUser(string name); - vector GetUsersForRole(string name); + vector GetRolesForUser(string name, vector domain); + vector GetUsersForRole(string name, vector domain); bool HasRoleForUser(string name, string role); bool AddRoleForUser(string user, string role); bool AddPermissionForUser(string user, vector permission); diff --git a/casbin/enforcer_interface.h b/casbin/enforcer_interface.h index 0175a6ba..849f7fe4 100644 --- a/casbin/enforcer_interface.h +++ b/casbin/enforcer_interface.h @@ -60,8 +60,8 @@ class IEnforcer { virtual bool EnforceWithMatcher(string matcher, Scope scope) = 0; /* RBAC API */ - virtual vector GetRolesForUser(string name) = 0; - virtual vector GetUsersForRole(string name) = 0; + virtual vector GetRolesForUser(string name, vector domain) = 0; + virtual vector GetUsersForRole(string name, vector domain) = 0; virtual bool HasRoleForUser(string name, string role) = 0; virtual bool AddRoleForUser(string user, string role) = 0; virtual bool AddPermissionForUser(string user, vector permission) = 0; diff --git a/casbin/rbac_api.cpp b/casbin/rbac_api.cpp index a28fdb45..ac34355d 100644 --- a/casbin/rbac_api.cpp +++ b/casbin/rbac_api.cpp @@ -23,22 +23,21 @@ #include "./util/util.h" // GetRolesForUser gets the roles that a user has. -vector Enforcer :: GetRolesForUser(string name) { - vector domain; +vector Enforcer :: GetRolesForUser(string name, vector domain) { vector res = this->model->m["g"].assertion_map["g"]->rm->GetRoles(name, domain); return res; } // GetUsersForRole gets the users that has a role. -vector Enforcer :: GetUsersForRole(string name) { - vector domain; +vector Enforcer :: GetUsersForRole(string name, vector domain) { vector res = this->model->m["g"].assertion_map["g"]->rm->GetUsers(name, domain); return res; } // HasRoleForUser determines whether a user has a role. bool Enforcer :: HasRoleForUser(string name, string role) { - vector roles = this->GetRolesForUser(name); + vector domain; + vector roles = this->GetRolesForUser(name, domain); bool has_role = false; for (int i = 0 ; i < roles.size() ; i++) { From 6e9a7295b70c9b746f4ec84701b9d8b6db37e77f Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Sun, 12 Jul 2020 01:55:10 +0530 Subject: [PATCH 03/13] fix: normal cast to dynamic_cast. Signed-off-by: DivyPatel9881 --- casbin/internal_api.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/casbin/internal_api.cpp b/casbin/internal_api.cpp index efb67b44..43383033 100644 --- a/casbin/internal_api.cpp +++ b/casbin/internal_api.cpp @@ -65,8 +65,11 @@ bool Enforcer :: addPolicies(string sec, string p_type, vector> r this->BuildIncrementalRoleLinks(policy_add, p_type, rules); if (this->adapter != NULL && this->auto_save) { - void* adapter = this->adapter; - ((BatchAdapter *)adapter)->AddPolicies(sec, p_type, rules); + try { + dynamic_cast(this->adapter)->AddPolicies(sec, p_type, rules); + } + catch(UnsupportedOperationException e) { + } } if (this->watcher != NULL && this->auto_notify_watcher) @@ -116,8 +119,11 @@ bool Enforcer :: removePolicies(string sec, string p_type, vector this->BuildIncrementalRoleLinks(policy_add, p_type, rules); if (this->adapter != NULL && this->auto_save) { - void* adapter = this->adapter; - ((BatchAdapter *)adapter)->RemovePolicies(sec, p_type, rules); + try{ + dynamic_cast(this->adapter)->RemovePolicies(sec, p_type, rules); + } + catch(UnsupportedOperationException e){ + } } if (this->watcher != NULL && this->auto_notify_watcher) From 3325cdbd7dc6556248d55018ca07532a73e302d2 Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Sun, 12 Jul 2020 01:56:05 +0530 Subject: [PATCH 04/13] fix: buildIncrementalRoleLinks and if condition negate. Signed-off-by: DivyPatel9881 --- casbin/model/assertion.cpp | 5 +++-- casbin/rbac/default_role_manager.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/casbin/model/assertion.cpp b/casbin/model/assertion.cpp index b583f45c..464ef546 100644 --- a/casbin/model/assertion.cpp +++ b/casbin/model/assertion.cpp @@ -30,8 +30,8 @@ void Assertion :: BuildIncrementalRoleLinks(RoleManager* rm, policy_op op, vecto if (char_count < 2) throw IllegalArgumentException("the number of \"_\" in role definition should be at least 2"); - for(int i = 0 ; i < this->policy.size() ; i++){ - vector rule = this->policy[i]; + for(int i = 0 ; i < rules.size() ; i++){ + vector rule = rules[i]; if (rule.size() < char_count) throw IllegalArgumentException("grouping policy elements do not meet role definition"); @@ -43,6 +43,7 @@ void Assertion :: BuildIncrementalRoleLinks(RoleManager* rm, policy_op op, vecto switch(op) { case policy_op :: policy_add: this->rm->AddLink(rule[0], rule[1], domain); + break; case policy_op :: policy_remove: this->rm->DeleteLink(rule[0], rule[1], domain); } diff --git a/casbin/rbac/default_role_manager.cpp b/casbin/rbac/default_role_manager.cpp index 6f09536d..58c8d622 100644 --- a/casbin/rbac/default_role_manager.cpp +++ b/casbin/rbac/default_role_manager.cpp @@ -254,7 +254,7 @@ vector DefaultRoleManager :: GetUsers(string name, vector domain else if (domain.size() > 1) throw CasbinRBACException("error: domain should be 1 parameter"); - if (this->HasRole(name)) + if (!this->HasRole(name)) throw CasbinRBACException("error: name does not exist"); vector names; From 253ab240932aadbdd557235b1504e0709bcece75 Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Sun, 12 Jul 2020 02:00:13 +0530 Subject: [PATCH 05/13] feat: add management api tests and fix enforcer warnings. Signed-off-by: DivyPatel9881 --- casbin/enforcer.cpp | 4 +- casbin/model/assertion.cpp | 2 +- test/test.vcxproj | 1 + test/test.vcxproj.filters | 3 + test/test_management_api.cpp | 285 +++++++++++++++++++++++++++++++++++ 5 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 test/test_management_api.cpp diff --git a/casbin/enforcer.cpp b/casbin/enforcer.cpp index 6205bc72..26c5c23c 100644 --- a/casbin/enforcer.cpp +++ b/casbin/enforcer.cpp @@ -483,8 +483,8 @@ bool Enforcer::EnforceWithMatcher(string matcher, string sub, string dom, string bool Enforcer::EnforceWithMatcher(string matcher, vector params) { vector r_tokens = this->model->m["r"].assertion_map["r"]->tokens; - int r_cnt = r_tokens.size(); - int cnt = params.size(); + int r_cnt = int(r_tokens.size()); + int cnt = int(params.size()); if (cnt != r_cnt) return false; diff --git a/casbin/model/assertion.cpp b/casbin/model/assertion.cpp index 464ef546..ade15f2d 100644 --- a/casbin/model/assertion.cpp +++ b/casbin/model/assertion.cpp @@ -77,5 +77,5 @@ void Assertion :: BuildRoleLinks(RoleManager* rm) { // LogUtil :: LogPrint("Role links for: " + Key); - this->rm->PrintRoles(); + //this->rm->PrintRoles(); } \ No newline at end of file diff --git a/test/test.vcxproj b/test/test.vcxproj index 277f9779..9ea8e002 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -168,6 +168,7 @@ + diff --git a/test/test.vcxproj.filters b/test/test.vcxproj.filters index 39d8390e..49da0fa1 100644 --- a/test/test.vcxproj.filters +++ b/test/test.vcxproj.filters @@ -39,6 +39,9 @@ Source Files + + Source Files + diff --git a/test/test_management_api.cpp b/test/test_management_api.cpp new file mode 100644 index 00000000..46074518 --- /dev/null +++ b/test/test_management_api.cpp @@ -0,0 +1,285 @@ +#pragma once + +#include "pch.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace std; + +namespace test_management_api +{ + TEST_CLASS(TestManagementAPI) + { + public: + + string basic_example; + Config* basic_config; + + TEST_METHOD_INITIALIZE(InitializeBasicConfig) { + basic_example = filePath("../examples/basic_model.conf"); + basic_config = Config::NewConfig(basic_example); + } + + string filePath(string filepath) { + char* root = _getcwd(NULL, 0); + string rootStr = string(root); + + vector directories = Split(rootStr, "\\", -1); + vector::iterator it = find(directories.begin(), directories.end(), "x64"); + vector left{ *(it - 1) }; + it = find_end(directories.begin(), directories.end(), left.begin(), left.end()); + int index = int(directories.size() + (it - directories.end())); + + vector finalDirectories(directories.begin(), directories.begin() + index + 1); + + vector userD = Split(filepath, "/", -1); + for (int i = 1; i < userD.size(); i++) + finalDirectories.push_back(userD[i]); + + string filepath1 = finalDirectories[0]; + for (int i = 1; i < finalDirectories.size(); i++) + filepath1 = filepath1 + "/" + finalDirectories[i]; + return filepath1; + } + + TEST_METHOD(TestGetList) { + string model = filePath("../examples/rbac_model.conf"); + string policy = filePath("../examples/rbac_policy.csv"); + Enforcer* e = Enforcer :: NewEnforcer(model, policy); + + Assert::IsTrue(ArrayEquals(vector{ "alice", "bob", "data2_admin" }, e->GetAllSubjects())); + Assert::IsTrue(ArrayEquals(vector{ "data1", "data2" }, e->GetAllObjects())); + Assert::IsTrue(ArrayEquals(vector{ "read", "write" }, e->GetAllActions())); + Assert::IsTrue(ArrayEquals(vector{ "data2_admin" }, e->GetAllRoles())); + } + + void TestGetPolicy(Enforcer* e, vector> res) { + vector> my_res; + my_res = e->GetPolicy(); + + int count = 0; + for (int i = 0; i < my_res.size(); i++) { + for (int j = 0; j < res.size(); j++) { + if (ArrayEquals(my_res[i], res[j])) + count++; + } + } + + if (count == res.size()) + Assert::IsTrue(true); + } + + void TestGetFilteredPolicy(Enforcer* e, int field_index, vector> res, vector field_values) { + vector> my_res = e->GetFilteredPolicy(field_index, field_values); + for (int i = 0; i < res.size(); i++) { + Assert::IsTrue(ArrayEquals(my_res[i], res[i])); + } + } + + void TestGetGroupingPolicy(Enforcer* e, vector> res) { + vector> my_res = e->GetGroupingPolicy(); + + for (int i = 0; i < my_res.size(); i++) { + Assert::IsTrue(ArrayEquals(my_res[i], res[i])); + } + } + + void TestGetFilteredGroupingPolicy(Enforcer* e, int field_index, vector> res, vector field_values) { + vector> my_res = e->GetFilteredGroupingPolicy(field_index, field_values); + + for (int i = 0; i < my_res.size(); i++) { + Assert::IsTrue(ArrayEquals(my_res[i], res[i])); + } + } + + void TestHasPolicy(Enforcer* e, vector policy, bool res) { + bool my_res = e->HasPolicy(policy); + Assert::AreEqual(res, my_res); + } + + void TestHasGroupingPolicy(Enforcer* e, vector policy, bool res) { + bool my_res = e->HasGroupingPolicy(policy); + Assert::AreEqual(res, my_res); + } + + TEST_METHOD(TestGetPolicyAPI) { + string model = filePath("../examples/rbac_model.conf"); + string policy = filePath("../examples/rbac_policy.csv"); + Enforcer* e = Enforcer::NewEnforcer(model, policy); + + TestGetPolicy(e, vector>{ + {"alice", "data1", "read"}, + { "bob", "data2", "write" }, + { "data2_admin", "data2", "read" }, + { "data2_admin", "data2", "write" }}); + + TestGetFilteredPolicy(e, 0, vector>{ {"alice", "data1", "read"} }, vector{"alice"}); + TestGetFilteredPolicy(e, 0, vector>{ {"bob", "data2", "write"}}, vector{"bob"}); + TestGetFilteredPolicy(e, 0, vector>{ {"data2_admin", "data2", "read"}, { "data2_admin", "data2", "write" }}, vector{"data2_admin"}); + TestGetFilteredPolicy(e, 1, vector>{ {"alice", "data1", "read"}}, vector{"data1"}); + TestGetFilteredPolicy(e, 1, vector>{ {"bob", "data2", "write"}, { "data2_admin", "data2", "read" }, { "data2_admin", "data2", "write" }}, vector{"data2"}); + TestGetFilteredPolicy(e, 2, vector>{ {"alice", "data1", "read"}, { "data2_admin", "data2", "read" }}, vector{"read"}); + TestGetFilteredPolicy(e, 2, vector>{ {"bob", "data2", "write"}, { "data2_admin", "data2", "write" }}, vector{"write"}); + + TestGetFilteredPolicy(e, 0, vector>{ {"data2_admin", "data2", "read"}, { "data2_admin", "data2", "write" }}, vector{"data2_admin", "data2"}); + // Note: "" (empty string) in fieldValues means matching all values. + TestGetFilteredPolicy(e, 0, vector>{ {"data2_admin", "data2", "read"}}, vector{"data2_admin", "", "read"}); + TestGetFilteredPolicy(e, 1, vector>{ {"bob", "data2", "write"}, { "data2_admin", "data2", "write" }}, vector{"data2", "write"}); + + TestHasPolicy(e, vector{"alice", "data1", "read"}, true); + TestHasPolicy(e, vector{"bob", "data2", "write"}, true); + TestHasPolicy(e, vector{"alice", "data2", "read"}, false); + TestHasPolicy(e, vector{"bob", "data3", "write"}, false); + + TestGetGroupingPolicy(e, vector>{ {"alice", "data2_admin"}}); + + TestGetFilteredGroupingPolicy(e, 0, vector>{ {"alice", "data2_admin"}}, vector < string>{"alice"}); + TestGetFilteredGroupingPolicy(e, 0, vector>{}, vector < string>{"bob"}); + TestGetFilteredGroupingPolicy(e, 1, vector>{}, vector{"data1_admin"}); + TestGetFilteredGroupingPolicy(e, 1, vector>{ {"alice", "data2_admin"}}, vector{"data2_admin"}); + // Note: "" (empty string) in fieldValues means matching all values. + TestGetFilteredGroupingPolicy(e, 0, vector>{ {"alice", "data2_admin"}}, vector{"", "data2_admin"}); + + TestHasGroupingPolicy(e, vector{"alice", "data2_admin"}, true); + TestHasGroupingPolicy(e, vector{"bob", "data2_admin"}, false); + } + + + TEST_METHOD(TestModifyPolicyAPI) { + string model = filePath("../examples/rbac_model.conf"); + string policy = filePath("../examples/rbac_policy.csv"); + Adapter* adapter = BatchFileAdapter::NewAdapter(policy); + Enforcer* e = Enforcer::NewEnforcer(model, adapter); + + TestGetPolicy(e, vector>{ + {"alice", "data1", "read"}, + { "bob", "data2", "write" }, + { "data2_admin", "data2", "read" }, + { "data2_admin", "data2", "write" }}); + + e->RemovePolicy(vector{"alice", "data1", "read"}); + e->RemovePolicy(vector{"bob", "data2", "write"}); + e->RemovePolicy(vector{"alice", "data1", "read"}); + e->AddPolicy(vector{"eve", "data3", "read"}); + e->AddPolicy(vector{"eve", "data3", "read"}); + + vector>rules{ + {"jack", "data4", "read"}, + {"katy", "data4", "write"}, + {"leyo", "data4", "read"}, + {"ham", "data4", "write"}, + }; + + e->AddPolicies(rules); + e->AddPolicies(rules); + + TestGetPolicy(e, vector>{ + {"data2_admin", "data2", "read"}, + { "data2_admin", "data2", "write" }, + { "eve", "data3", "read" }, + { "jack", "data4", "read" }, + { "katy", "data4", "write" }, + { "leyo", "data4", "read" }, + { "ham", "data4", "write" }}); + + e->RemovePolicies(rules); + e->RemovePolicies(rules); + + vectornamed_policy{ "eve", "data3", "read" }; + e->RemoveNamedPolicy("p", named_policy); + e->AddNamedPolicy("p", named_policy); + + TestGetPolicy(e, vector>{ + {"data2_admin", "data2", "read"}, + { "data2_admin", "data2", "write" }, + { "eve", "data3", "read" }}); + + e->RemoveFilteredPolicy(1, vector{"data2"}); + + TestGetPolicy(e, vector>{ {"eve", "data3", "read"}}); + } + + TEST_METHOD(TestModifyGroupingPolicyAPI) { + string model = filePath("../examples/rbac_model.conf"); + string policy = filePath("../examples/rbac_policy.csv"); + Adapter* adapter = BatchFileAdapter::NewAdapter(policy); + Enforcer* e = Enforcer::NewEnforcer(model, adapter); + + Assert::IsTrue(ArrayEquals(vector{"data2_admin"}, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("bob", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("eve", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("non_exist", vector{}))); + + e->RemoveGroupingPolicy(vector{"alice", "data2_admin"}); + e->AddGroupingPolicy(vector{"bob", "data1_admin"}); + e->AddGroupingPolicy(vector{"eve", "data3_admin"}); + + vector> grouping_rules{ + {"ham", "data4_admin"}, + {"jack", "data5_admin"}, + }; + + e->AddGroupingPolicies(grouping_rules); + Assert::IsTrue(ArrayEquals(vector{"data4_admin"}, e->GetRolesForUser("ham", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"data5_admin"}, e->GetRolesForUser("jack", vector{}))); + e->RemoveGroupingPolicies(grouping_rules); + + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice", vector{}))); + vector named_grouping_policy{ "alice", "data2_admin" }; + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice", vector{}))); + e->AddNamedGroupingPolicy("g", named_grouping_policy); + Assert::IsTrue(ArrayEquals(vector{"data2_admin"}, e->GetRolesForUser("alice", vector{}))); + e->RemoveNamedGroupingPolicy("g", named_grouping_policy); + + e->AddNamedGroupingPolicies("g", grouping_rules); + e->AddNamedGroupingPolicies("g", grouping_rules); + Assert::IsTrue(ArrayEquals(vector{"data4_admin"}, e->GetRolesForUser("ham", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"data5_admin"}, e->GetRolesForUser("jack", vector{}))); + e->RemoveNamedGroupingPolicies("g", grouping_rules); + e->RemoveNamedGroupingPolicies("g", grouping_rules); + + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"data1_admin"}, e->GetRolesForUser("bob", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"data3_admin"}, e->GetRolesForUser("eve", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("non_exist", vector{}))); + + Assert::IsTrue(ArrayEquals(vector{"bob"}, e->GetUsersForRole("data1_admin", vector{}))); + try { + e->GetUsersForRole("data2_admin", vector{}); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + Assert::IsTrue(ArrayEquals(vector{"eve"}, e->GetUsersForRole("data3_admin", vector{}))); + + e->RemoveFilteredGroupingPolicy(0, vector{"bob"}); + + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("bob", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"data3_admin"}, e->GetRolesForUser("eve", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("non_exist", vector{}))); + + try { + e->GetUsersForRole("data1_admin", vector{}); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + try { + e->GetUsersForRole("data2_admin", vector{}); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + Assert::IsTrue(ArrayEquals(vector{"eve"}, e->GetUsersForRole("data3_admin", vector{}))); + } + }; +} \ No newline at end of file From 3d27e01f3b7b87c57a1579d62b43a24f3489edac Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Sun, 12 Jul 2020 02:18:59 +0530 Subject: [PATCH 06/13] fix: filePath function removal. Signed-off-by: DivyPatel9881 --- test/test_config.cpp | 24 +---------- test/test_enforcer.cpp | 38 ++++------------- test/test_management_api.cpp | 46 ++++----------------- test/test_model.cpp | 24 +---------- test/test_model_enforcer.cpp | 80 +++++++++++++----------------------- 5 files changed, 47 insertions(+), 165 deletions(-) diff --git a/test/test_config.cpp b/test/test_config.cpp index 3535dc52..adf77091 100644 --- a/test/test_config.cpp +++ b/test/test_config.cpp @@ -19,32 +19,10 @@ namespace test_config Config* config; TEST_METHOD_INITIALIZE(InitializeConfig) { - string filepath = filePath("/casbin/config/testdata/testini.ini"); + string filepath = "../../casbin/config/testdata/testini.ini"; config = Config::NewConfig(filepath); } - string filePath(string filepath) { - char* root = _getcwd(NULL, 0); - string rootStr = string(root); - - vector directories = Split(rootStr, "\\", -1); - vector::iterator it = find(directories.begin(), directories.end(), "x64"); - vector left{ *(it-1) }; - it = find_end(directories.begin(), directories.end(), left.begin(), left.end()); - int index = int(directories.size() + (it - directories.end())); - - vector finalDirectories(directories.begin(), directories.begin() + index + 1); - - vector userD = Split(filepath, "/", -1); - for (int i = 1; i < userD.size(); i++) - finalDirectories.push_back(userD[i]); - - string filepath1 = finalDirectories[0]; - for (int i = 1; i < finalDirectories.size(); i++) - filepath1 = filepath1 + "/" + finalDirectories[i]; - return filepath1; - } - TEST_METHOD(TestDebug) { Assert::IsTrue(config->GetBool("debug")); } diff --git a/test/test_enforcer.cpp b/test/test_enforcer.cpp index 6cdddff8..c6f84a49 100644 --- a/test/test_enforcer.cpp +++ b/test/test_enforcer.cpp @@ -18,28 +18,6 @@ namespace test_enforcer { public: - string filePath(string filepath) { - char* root = _getcwd(NULL, 0); - string rootStr = string(root); - - vector directories = Split(rootStr, "\\", -1); - vector::iterator it = find(directories.begin(), directories.end(), "x64"); - vector left{ *(it - 1) }; - it = find_end(directories.begin(), directories.end(), left.begin(), left.end()); - int index = int(directories.size() + (it - directories.end())); - - vector finalDirectories(directories.begin(), directories.begin() + index + 1); - - vector userD = Split(filepath, "/", -1); - for (int i = 1; i < userD.size(); i++) - finalDirectories.push_back(userD[i]); - - string filepath1 = finalDirectories[0]; - for (int i = 1; i < finalDirectories.size(); i++) - filepath1 = filepath1 + "/" + finalDirectories[i]; - return filepath1; - } - void TestEnforce(Enforcer* e, string sub, string dom, string obj, string act, bool res) { Assert::AreEqual(res, e->Enforce(sub, dom, obj, act)); } @@ -58,8 +36,8 @@ namespace test_enforcer TEST_METHOD(TestFourParams) { - string model = filePath("../examples/rbac_with_domains_model.conf"); - string policy = filePath("../examples/rbac_with_domains_policy.csv"); + string model = "../../examples/rbac_with_domains_model.conf"; + string policy = "../../examples/rbac_with_domains_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); TestEnforce(e, "alice", "domain1", "data1", "read", true); @@ -73,8 +51,8 @@ namespace test_enforcer } TEST_METHOD(TestThreeParams) { - string model = filePath("../examples/basic_model_without_spaces.conf"); - string policy = filePath("../examples/basic_policy.csv"); + string model = "../../examples/basic_model_without_spaces.conf"; + string policy = "../../examples/basic_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); TestEnforce(e, { "alice", "data1", "read" }, true); @@ -88,8 +66,8 @@ namespace test_enforcer } TEST_METHOD(TestVectorParams) { - string model = filePath("../examples/basic_model_without_spaces.conf"); - string policy = filePath("../examples/basic_policy.csv"); + string model = "../../examples/basic_model_without_spaces.conf"; + string policy = "../../examples/basic_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); TestEnforce(e, { "alice", "data1", "read" }, true); @@ -103,8 +81,8 @@ namespace test_enforcer } TEST_METHOD(TestMapParams) { - string model = filePath("../examples/basic_model_without_spaces.conf"); - string policy = filePath("../examples/basic_policy.csv"); + string model = "../../examples/basic_model_without_spaces.conf"; + string policy = "../../examples/basic_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); unordered_map params = { {"sub","alice"},{"obj","data1"},{"act","read"} }; diff --git a/test/test_management_api.cpp b/test/test_management_api.cpp index 46074518..afd168ef 100644 --- a/test/test_management_api.cpp +++ b/test/test_management_api.cpp @@ -20,39 +20,9 @@ namespace test_management_api { public: - string basic_example; - Config* basic_config; - - TEST_METHOD_INITIALIZE(InitializeBasicConfig) { - basic_example = filePath("../examples/basic_model.conf"); - basic_config = Config::NewConfig(basic_example); - } - - string filePath(string filepath) { - char* root = _getcwd(NULL, 0); - string rootStr = string(root); - - vector directories = Split(rootStr, "\\", -1); - vector::iterator it = find(directories.begin(), directories.end(), "x64"); - vector left{ *(it - 1) }; - it = find_end(directories.begin(), directories.end(), left.begin(), left.end()); - int index = int(directories.size() + (it - directories.end())); - - vector finalDirectories(directories.begin(), directories.begin() + index + 1); - - vector userD = Split(filepath, "/", -1); - for (int i = 1; i < userD.size(); i++) - finalDirectories.push_back(userD[i]); - - string filepath1 = finalDirectories[0]; - for (int i = 1; i < finalDirectories.size(); i++) - filepath1 = filepath1 + "/" + finalDirectories[i]; - return filepath1; - } - TEST_METHOD(TestGetList) { - string model = filePath("../examples/rbac_model.conf"); - string policy = filePath("../examples/rbac_policy.csv"); + string model = "../../examples/rbac_model.conf"; + string policy = "../../examples/rbac_policy.csv"; Enforcer* e = Enforcer :: NewEnforcer(model, policy); Assert::IsTrue(ArrayEquals(vector{ "alice", "bob", "data2_admin" }, e->GetAllSubjects())); @@ -111,8 +81,8 @@ namespace test_management_api } TEST_METHOD(TestGetPolicyAPI) { - string model = filePath("../examples/rbac_model.conf"); - string policy = filePath("../examples/rbac_policy.csv"); + string model = "../../examples/rbac_model.conf"; + string policy = "../../examples/rbac_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); TestGetPolicy(e, vector>{ @@ -154,8 +124,8 @@ namespace test_management_api TEST_METHOD(TestModifyPolicyAPI) { - string model = filePath("../examples/rbac_model.conf"); - string policy = filePath("../examples/rbac_policy.csv"); + string model = "../../examples/rbac_model.conf"; + string policy = "../../examples/rbac_policy.csv"; Adapter* adapter = BatchFileAdapter::NewAdapter(policy); Enforcer* e = Enforcer::NewEnforcer(model, adapter); @@ -208,8 +178,8 @@ namespace test_management_api } TEST_METHOD(TestModifyGroupingPolicyAPI) { - string model = filePath("../examples/rbac_model.conf"); - string policy = filePath("../examples/rbac_policy.csv"); + string model = "../../examples/rbac_model.conf"; + string policy = "../../examples/rbac_policy.csv"; Adapter* adapter = BatchFileAdapter::NewAdapter(policy); Enforcer* e = Enforcer::NewEnforcer(model, adapter); diff --git a/test/test_model.cpp b/test/test_model.cpp index c919e566..f1737371 100644 --- a/test/test_model.cpp +++ b/test/test_model.cpp @@ -23,32 +23,10 @@ namespace test_model Config* basic_config; TEST_METHOD_INITIALIZE(InitializeBasicConfig) { - basic_example = filePath("../examples/basic_model.conf"); + basic_example = "../../examples/basic_model.conf"; basic_config = Config::NewConfig(basic_example); } - string filePath(string filepath) { - char* root = _getcwd(NULL, 0); - string rootStr = string(root); - - vector directories = Split(rootStr, "\\", -1); - vector::iterator it = find(directories.begin(), directories.end(), "x64"); - vector left{ *(it - 1) }; - it = find_end(directories.begin(), directories.end(), left.begin(), left.end()); - int index = int(directories.size() + (it - directories.end())); - - vector finalDirectories(directories.begin(), directories.begin() + index + 1); - - vector userD = Split(filepath, "/", -1); - for (int i = 1; i < userD.size(); i++) - finalDirectories.push_back(userD[i]); - - string filepath1 = finalDirectories[0]; - for (int i = 1; i < finalDirectories.size(); i++) - filepath1 = filepath1 + "/" + finalDirectories[i]; - return filepath1; - } - TEST_METHOD(TestNewModel) { Model* model = Model::NewModel(); Assert::IsNotNull(model); diff --git a/test/test_model_enforcer.cpp b/test/test_model_enforcer.cpp index c280cbf7..5c7a69fd 100644 --- a/test/test_model_enforcer.cpp +++ b/test/test_model_enforcer.cpp @@ -18,28 +18,6 @@ namespace test_model_enforcer { public: - string filePath(string filepath) { - char* root = _getcwd(NULL, 0); - string rootStr = string(root); - - vector directories = Split(rootStr, "\\", -1); - vector::iterator it = find(directories.begin(), directories.end(), "x64"); - vector left{ *(it - 1) }; - it = find_end(directories.begin(), directories.end(), left.begin(), left.end()); - int index = int(directories.size() + (it - directories.end())); - - vector finalDirectories(directories.begin(), directories.begin() + index + 1); - - vector userD = Split(filepath, "/", -1); - for (int i = 1; i < userD.size(); i++) - finalDirectories.push_back(userD[i]); - - string filepath1 = finalDirectories[0]; - for (int i = 1; i < finalDirectories.size(); i++) - filepath1 = filepath1 + "/" + finalDirectories[i]; - return filepath1; - } - Scope InitializeParams(string sub, string obj, string act) { Scope scope = InitializeScope(); PushObject(scope, "r"); @@ -83,8 +61,8 @@ namespace test_model_enforcer } TEST_METHOD(TestBasicModel) { - string model = filePath("../examples/basic_model.conf"); - string policy = filePath("../examples/basic_policy.csv"); + string model = "../../examples/basic_model.conf"; + string policy = "../../examples/basic_policy.csv"; Enforcer* e = Enforcer :: NewEnforcer(model, policy); Scope scope; @@ -108,8 +86,8 @@ namespace test_model_enforcer } TEST_METHOD(TestBasicModelWithoutSpaces) { - string model = filePath("../examples/basic_model_without_spaces.conf"); - string policy = filePath("../examples/basic_policy.csv"); + string model = "../../examples/basic_model_without_spaces.conf"; + string policy = "../../examples/basic_policy.csv"; Enforcer* e = Enforcer :: NewEnforcer(model, policy); Scope scope = InitializeParams("alice", "data1", "read"); @@ -131,7 +109,7 @@ namespace test_model_enforcer } TEST_METHOD(TestBasicModelNoPolicy) { - string model = filePath("../examples/basic_model.conf"); + string model = "../../examples/basic_model.conf"; Enforcer* e = Enforcer :: NewEnforcer(model); Scope scope = InitializeParams("alice", "data1", "read"); @@ -153,8 +131,8 @@ namespace test_model_enforcer } TEST_METHOD(TestBasicModelWithRoot) { - string model = filePath("../examples/basic_with_root_model.conf"); - string policy = filePath("../examples/basic_policy.csv"); + string model = "../../examples/basic_with_root_model.conf"; + string policy = "../../examples/basic_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); Scope scope = InitializeParams("alice", "data1", "read"); @@ -184,7 +162,7 @@ namespace test_model_enforcer } TEST_METHOD(TestBasicModelWithRootNoPolicy) { - string model = filePath("../examples/basic_with_root_model.conf"); + string model = "../../examples/basic_with_root_model.conf"; Enforcer* e = Enforcer::NewEnforcer(model); Scope scope = InitializeParams("alice", "data1", "read"); @@ -214,8 +192,8 @@ namespace test_model_enforcer } TEST_METHOD(TestBasicModelWithoutUsers) { - string model = filePath("../examples/basic_without_users_model.conf"); - string policy = filePath("../examples/basic_without_users_policy.csv"); + string model = "../../examples/basic_without_users_model.conf"; + string policy = "../../examples/basic_without_users_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); Scope scope = InitializeParamsWithoutUsers("data1", "read"); @@ -229,8 +207,8 @@ namespace test_model_enforcer } TEST_METHOD(TestBasicModelWithoutResources) { - string model = filePath("../examples/basic_without_resources_model.conf"); - string policy = filePath("../examples/basic_without_resources_policy.csv"); + string model = "../../examples/basic_without_resources_model.conf"; + string policy = "../../examples/basic_without_resources_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); Scope scope = InitializeParamsWithoutResources("alice", "read"); @@ -244,8 +222,8 @@ namespace test_model_enforcer } TEST_METHOD(TestRBACModel) { - string model = filePath("../examples/rbac_model.conf"); - string policy = filePath("../examples/rbac_policy.csv"); + string model = "../../examples/rbac_model.conf"; + string policy = "../../examples/rbac_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); Scope scope = InitializeParams("alice", "data1", "read"); @@ -267,8 +245,8 @@ namespace test_model_enforcer } TEST_METHOD(TestRBACModelWithResourceRoles) { - string model = filePath("../examples/rbac_with_resource_roles_model.conf"); - string policy = filePath("../examples/rbac_with_resource_roles_policy.csv"); + string model = "../../examples/rbac_with_resource_roles_model.conf"; + string policy = "../../examples/rbac_with_resource_roles_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); Scope scope = InitializeParams("alice", "data1", "read"); @@ -290,8 +268,8 @@ namespace test_model_enforcer } TEST_METHOD(TestRBACModelWithDomains) { - string model = filePath("../examples/rbac_with_domains_model.conf"); - string policy = filePath("../examples/rbac_with_domains_policy.csv"); + string model = "../../examples/rbac_with_domains_model.conf"; + string policy = "../../examples/rbac_with_domains_policy.csv"; Enforcer* e = Enforcer :: NewEnforcer(model, policy); Scope scope = InitializeParamsWithDomains("alice", "domain1", "data1", "read"); @@ -313,7 +291,7 @@ namespace test_model_enforcer } TEST_METHOD(TestRBACModelWithDomainsAtRuntime) { - string model = filePath("../examples/rbac_with_domains_model.conf"); + string model = "../../examples/rbac_with_domains_model.conf"; Enforcer* e = Enforcer::NewEnforcer(model); vector params{ "admin", "domain1", "data1", "read" }; @@ -391,8 +369,8 @@ namespace test_model_enforcer } TEST_METHOD(TestRBACModelWithDomainsAtRuntimeMockAdapter) { - string model = filePath("../examples/rbac_with_domains_model.conf"); - string policy = filePath("../examples/rbac_with_domains_policy.csv"); + string model = "../../examples/rbac_with_domains_model.conf"; + string policy = "../../examples/rbac_with_domains_policy.csv"; Adapter* adapter = FileAdapter :: NewAdapter(policy); Enforcer* e = Enforcer :: NewEnforcer(model, adapter); @@ -420,8 +398,8 @@ namespace test_model_enforcer } TEST_METHOD(TestRBACModelWithDeny) { - string model = filePath("../examples/rbac_with_deny_model.conf"); - string policy = filePath("../examples/rbac_with_deny_policy.csv"); + string model = "../../examples/rbac_with_deny_model.conf"; + string policy = "../../examples/rbac_with_deny_policy.csv"; Enforcer* e = Enforcer :: NewEnforcer(model, policy); Scope scope = InitializeParams("alice", "data1", "read"); @@ -443,8 +421,8 @@ namespace test_model_enforcer } TEST_METHOD(TestRBACModelWithOnlyDeny) { - string model = filePath("../examples/rbac_with_not_deny_model.conf"); - string policy = filePath("../examples/rbac_with_deny_policy.csv"); + string model = "../../examples/rbac_with_not_deny_model.conf"; + string policy = "../../examples/rbac_with_deny_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); Scope scope = InitializeParams("alice", "data2", "write"); @@ -452,8 +430,8 @@ namespace test_model_enforcer } TEST_METHOD(TestRBACModelWithCustomData) { - string model = filePath("../examples/rbac_model.conf"); - string policy = filePath("../examples/rbac_policy.csv"); + string model = "../../examples/rbac_model.conf"; + string policy = "../../examples/rbac_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); // You can add custom data to a grouping policy, Casbin will ignore it. It is only meaningful to the caller. @@ -504,8 +482,8 @@ namespace test_model_enforcer } TEST_METHOD(TestRBACModelWithPattern) { - string model = filePath("../examples/rbac_with_pattern_model.conf"); - string policy = filePath("../examples/rbac_with_pattern_policy.csv"); + string model = "../../examples/rbac_with_pattern_model.conf"; + string policy = "../../examples/rbac_with_pattern_policy.csv"; Enforcer* e = Enforcer::NewEnforcer(model, policy); // Here's a little confusing: the matching function here is not the custom function used in matcher. From f858d19713ae78f7bc756050674d672d988b64f2 Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Sun, 12 Jul 2020 20:06:52 +0530 Subject: [PATCH 07/13] feat: Add GetImplicitUsersForPermission and AddRolesForUser. Signed-off-by: DivyPatel9881 --- casbin/enforcer.h | 1 + casbin/enforcer_interface.h | 1 + casbin/rbac_api.cpp | 39 +++++++++++++++++++++++------------- casbin/util/array_equals.cpp | 4 ++++ 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/casbin/enforcer.h b/casbin/enforcer.h index 56e17a77..5885daab 100644 --- a/casbin/enforcer.h +++ b/casbin/enforcer.h @@ -214,6 +214,7 @@ class Enforcer : public IEnforcer{ vector GetUsersForRole(string name, vector domain); bool HasRoleForUser(string name, string role); bool AddRoleForUser(string user, string role); + bool AddRolesForUser(string user, vector roles); bool AddPermissionForUser(string user, vector permission); bool DeletePermissionForUser(string user, vector permission); bool DeletePermissionsForUser(string user); diff --git a/casbin/enforcer_interface.h b/casbin/enforcer_interface.h index 849f7fe4..6da3b683 100644 --- a/casbin/enforcer_interface.h +++ b/casbin/enforcer_interface.h @@ -64,6 +64,7 @@ class IEnforcer { virtual vector GetUsersForRole(string name, vector domain) = 0; virtual bool HasRoleForUser(string name, string role) = 0; virtual bool AddRoleForUser(string user, string role) = 0; + virtual bool AddRolesForUser(string user, vector roles) = 0; virtual bool AddPermissionForUser(string user, vector permission) = 0; virtual bool DeletePermissionForUser(string user, vector permission) = 0; virtual bool DeletePermissionsForUser(string user) = 0; diff --git a/casbin/rbac_api.cpp b/casbin/rbac_api.cpp index ac34355d..e745e529 100644 --- a/casbin/rbac_api.cpp +++ b/casbin/rbac_api.cpp @@ -57,6 +57,18 @@ bool Enforcer :: AddRoleForUser(string user, string role) { return this->AddGroupingPolicy(params); } +// AddRolesForUser adds roles for a user. +// Returns false if the user already has the roles (aka not affected). +bool Enforcer :: AddRolesForUser(string user, vector roles) { + bool f = false; + for(int i=0;iAddGroupingPolicy({user, roles[i]}); + if(b) + f = true; + } + return f; +} + // DeleteRoleForUser deletes a role for a user. // Returns false if the user does not have the role (aka not affected). bool Enforcer :: DeleteRoleForUser(string user, string role) { @@ -210,24 +222,23 @@ vector> Enforcer :: GetImplicitPermissionsForUser(string user, ve // GetImplicitUsersForPermission("data1", "read") will get: ["alice", "bob"]. // Note: only users will be returned, roles (2nd arg in "g") will be excluded. vector Enforcer :: GetImplicitUsersForPermission(vector permission) { - vector subjects = this->GetAllSubjects(); - vector roles = this->GetAllRoles(); + vector p_subjects = this->GetAllSubjects(); + vector g_inherit = this->model->GetValuesForFieldInPolicyAllTypes("g", 1); + vector g_subjects = this->model->GetValuesForFieldInPolicyAllTypes("g", 0); - vector users = SetSubtract(subjects, roles); + vector subjects(p_subjects); + subjects.insert(subjects.end(), g_subjects.begin(), g_subjects.end()); + ArrayRemoveDuplicates(subjects); vector res; - for (int i = 0 ; i < users.size() ; i++) { - Scope scope = InitializeScope(); - PushObject(scope); - PushStringPropToObject(scope, "r", users[i], "sub"); - PushStringPropToObject(scope, "r", permission[0], "obj"); - PushStringPropToObject(scope, "r", permission[1], "act"); - - bool allowed = this->Enforce(scope); - - if (allowed) - res.push_back(users[i]); + for(int i=0;iEnforce({subjects[i], permission[0], permission[1]}); + + if(allowed) { + res.push_back(subjects[i]); + } } + res = SetSubtract(res, g_inherit); return res; } \ No newline at end of file diff --git a/casbin/util/array_equals.cpp b/casbin/util/array_equals.cpp index 658cffa0..d99a3fb8 100644 --- a/casbin/util/array_equals.cpp +++ b/casbin/util/array_equals.cpp @@ -18,6 +18,8 @@ #include "pch.h" +#include + #include "./util.h" using namespace std; @@ -28,6 +30,8 @@ bool ArrayEquals(vector a, vector b) { return false; } + sort(a.begin(), a.end()); + sort(b.begin(), b.end()); for (int i = 0 ; i < a.size() ; i++) { if (a[i] != b[i]) { return false; From 21b31ad3cf8d1a4ccfefded1196b55b5d521cae0 Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Sun, 12 Jul 2020 20:07:16 +0530 Subject: [PATCH 08/13] feat: Add RBAC API test. Signed-off-by: DivyPatel9881 --- test/test.vcxproj | 1 + test/test.vcxproj.filters | 3 + test/test_rbac_api.cpp | 231 ++++++++++++++++++++++++++++++++++++++ test/test_util.cpp | 2 +- 4 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 test/test_rbac_api.cpp diff --git a/test/test.vcxproj b/test/test.vcxproj index 9ea8e002..33953004 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -171,6 +171,7 @@ + diff --git a/test/test.vcxproj.filters b/test/test.vcxproj.filters index 49da0fa1..6611936f 100644 --- a/test/test.vcxproj.filters +++ b/test/test.vcxproj.filters @@ -42,6 +42,9 @@ Source Files + + Source Files + diff --git a/test/test_rbac_api.cpp b/test/test_rbac_api.cpp new file mode 100644 index 00000000..91023dfd --- /dev/null +++ b/test/test_rbac_api.cpp @@ -0,0 +1,231 @@ +#pragma once + +#include "pch.h" + +#include +#include +#include + +#include +#include +#include + +using namespace std; + +namespace test_rbac_api +{ + TEST_CLASS(TestRBACAPI) + { + public: + + TEST_METHOD(TestRoleAPI) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_model.conf", "../../examples/rbac_policy.csv"); + + Assert::IsTrue(ArrayEquals(vector{ "data2_admin" }, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("non_exist", vector{}))); + + Assert::IsFalse(e->HasRoleForUser("alice", "data1_admin")); + Assert::IsTrue(e->HasRoleForUser("alice", "data2_admin")); + + e->AddRoleForUser("alice", "data1_admin"); + + Assert::IsTrue(ArrayEquals(vector{ "data1_admin", "data2_admin" }, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); + + e->DeleteRoleForUser("alice", "data1_admin"); + + Assert::IsTrue(ArrayEquals(vector{ "data2_admin" }, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); + + e->DeleteRolesForUser("alice"); + + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); + + e->AddRoleForUser("alice", "data1_admin"); + e->DeleteUser("alice"); + + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); + + e->AddRoleForUser("alice", "data2_admin"); + + Assert::IsFalse(e->Enforce({ "alice", "data1", "read" })); + Assert::IsFalse(e->Enforce({ "alice", "data1", "write" })); + Assert::IsTrue(e->Enforce({ "alice", "data2", "read" })); + Assert::IsTrue(e->Enforce({ "alice", "data2", "write" })); + Assert::IsFalse(e->Enforce({ "bob", "data1", "read" })); + Assert::IsFalse(e->Enforce({ "bob", "data1", "write" })); + Assert::IsFalse(e->Enforce({ "bob", "data2", "read" })); + Assert::IsTrue(e->Enforce({ "bob", "data2", "write" })); + + e->DeleteRole("data2_admin"); + + Assert::IsFalse(e->Enforce({ "alice", "data1", "read" })); + Assert::IsFalse(e->Enforce({ "alice", "data1", "write" })); + Assert::IsFalse(e->Enforce({ "alice", "data2", "read" })); + Assert::IsFalse(e->Enforce({ "alice", "data2", "write" })); + Assert::IsFalse(e->Enforce({ "bob", "data1", "read" })); + Assert::IsFalse(e->Enforce({ "bob", "data1", "write" })); + Assert::IsFalse(e->Enforce({ "bob", "data2", "read" })); + Assert::IsTrue(e->Enforce({ "bob", "data2", "write" })); + } + + TEST_METHOD(TestEnforcer_AddRolesForUser) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_model.conf", "../../examples/rbac_policy.csv"); + + e->AddRolesForUser("alice", vector{ "data1_admin", "data2_admin", "data3_admin" }); + Assert::IsTrue(ArrayEquals(vector{ "data1_admin", "data2_admin", "data3_admin" }, e->GetRolesForUser("alice", vector{}))); + + Assert::IsTrue(e->Enforce({ "alice", "data1", "read" })); + Assert::IsTrue(e->Enforce({ "alice", "data2", "read" })); + Assert::IsTrue(e->Enforce({ "alice", "data2", "write" })); + } + + void TestGetPermissions(Enforcer* e, string name, vector> res) { + vector> my_res = e->GetPermissionsForUser(name); + + int count = 0; + for (int i = 0; i < my_res.size(); i++) { + for (int j = 0; j < res.size(); j++) { + if (ArrayEquals(res[j], my_res[i])) { + count += 1; + break; + } + } + } + + Assert::AreEqual(int(res.size()), count); + } + + TEST_METHOD(TestPermissionAPI) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/basic_without_resources_model.conf", "../../examples/basic_without_resources_policy.csv"); + + Assert::IsTrue(e->Enforce(vector{ "alice", "read" })); + Assert::IsFalse(e->Enforce(vector{ "alice", "write" })); + Assert::IsFalse(e->Enforce(vector{ "bob", "read" })); + Assert::IsTrue(e->Enforce(vector{ "bob", "write" })); + + TestGetPermissions(e, "alice", vector>{ {"alice", "read"} }); + TestGetPermissions(e, "bob", vector>{ {"bob", "write"} }); + + Assert::IsTrue(e->HasPermissionForUser("alice", { "read" })); + Assert::IsFalse(e->HasPermissionForUser("alice", { "write" })); + Assert::IsFalse(e->HasPermissionForUser("bob", { "read" })); + Assert::IsTrue(e->HasPermissionForUser("bob", { "write" })); + + e->DeletePermission({ "read" }); + + Assert::IsFalse(e->Enforce(vector{ "alice", "read" })); + Assert::IsFalse(e->Enforce(vector{ "alice", "write" })); + Assert::IsFalse(e->Enforce(vector{ "bob", "read" })); + Assert::IsTrue(e->Enforce(vector{ "bob", "write" })); + + e->AddPermissionForUser("bob", { "read" }); + + Assert::IsFalse(e->Enforce(vector{ "alice", "read" })); + Assert::IsFalse(e->Enforce(vector{ "alice", "write" })); + Assert::IsTrue(e->Enforce(vector{ "bob", "read" })); + Assert::IsTrue(e->Enforce(vector{ "bob", "write" })); + + e->DeletePermissionForUser("bob", { "read" }); + + Assert::IsFalse(e->Enforce(vector{ "alice", "read" })); + Assert::IsFalse(e->Enforce(vector{ "alice", "write" })); + Assert::IsFalse(e->Enforce(vector{ "bob", "read" })); + Assert::IsTrue(e->Enforce(vector{ "bob", "write" })); + + e->DeletePermissionsForUser("bob"); + + Assert::IsFalse(e->Enforce(vector{ "alice", "read" })); + Assert::IsFalse(e->Enforce(vector{ "alice", "write" })); + Assert::IsFalse(e->Enforce(vector{ "bob", "read" })); + Assert::IsFalse(e->Enforce(vector{ "bob", "write" })); + } + + TEST_METHOD(TestImplicitRoleAPI) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_model.conf", "../../examples/rbac_with_hierarchy_policy.csv"); + + TestGetPermissions(e, "alice", vector>{ {"alice", "data1", "read"} }); + TestGetPermissions(e, "bob", vector>{ {"bob", "data2", "write"} }); + + Assert::IsTrue(ArrayEquals(vector{ "admin", "data1_admin", "data2_admin" }, e->GetImplicitRolesForUser("alice", {}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetImplicitRolesForUser("bob", {}))); + + e = Enforcer::NewEnforcer("../../examples/rbac_with_pattern_model.conf", "../../examples/rbac_with_pattern_policy.csv"); + + dynamic_cast(e->GetRoleManager())->AddMatchingFunc(KeyMatch); + + Assert::IsTrue(ArrayEquals(vector{ "/book/1/2/3/4/5", "pen_admin", "/book/*", "book_group" }, e->GetImplicitRolesForUser("cathy", {}))); + Assert::IsTrue(ArrayEquals(vector{ "/book/1/2/3/4/5", "pen_admin" }, e->GetRolesForUser("cathy", vector{}))); + } + + void TestGetImplicitPermissions(Enforcer* e, string name, vector> res) { + vector> my_res = e->GetImplicitPermissionsForUser(name, {}); + + int count = 0; + for (int i = 0; i < my_res.size(); i++) { + for (int j = 0; j < res.size(); j++) { + if (ArrayEquals(res[j], my_res[i])) { + count += 1; + break; + } + } + } + + Assert::AreEqual(int(res.size()), count); + } + + void TestGetImplicitPermissionsWithDomain(Enforcer* e, string name, string domain, vector> res) { + vector> my_res = e->GetImplicitPermissionsForUser(name, { domain }); + + int count = 0; + for (int i = 0; i < my_res.size(); i++) { + for (int j = 0; j < res.size(); j++) { + if (ArrayEquals(res[j], my_res[i])) { + count += 1; + break; + } + } + } + + Assert::AreEqual(int(res.size()), count); + } + + TEST_METHOD(TestImplicitPermissionAPI) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_model.conf", "../../examples/rbac_with_hierarchy_policy.csv"); + + TestGetPermissions(e, "alice", vector>{ {"alice", "data1", "read"} }); + TestGetPermissions(e, "bob", vector>{ {"bob", "data2", "write"} }); + + TestGetImplicitPermissions(e, "alice", vector>{ {"alice", "data1", "read"}, { "data1_admin", "data1", "read" }, { "data1_admin", "data1", "write" }, { "data2_admin", "data2", "read" }, { "data2_admin", "data2", "write" } }); + TestGetImplicitPermissions(e, "bob", vector>{ {"bob", "data2", "write"} }); + } + + TEST_METHOD(TestImplicitPermissionAPIWithDomain) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_with_domains_model.conf", "../../examples/rbac_with_hierarchy_with_domains_policy.csv"); + TestGetImplicitPermissionsWithDomain(e, "alice", "domain1", vector>{ {"alice", "domain1", "data2", "read"}, { "role:reader", "domain1", "data1", "read" }, { "role:writer", "domain1", "data1", "write" } }); + } + + TEST_METHOD(TestImplicitUserAPI) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_model.conf", "../../examples/rbac_with_hierarchy_policy.csv"); + + Assert::IsTrue(ArrayEquals(vector{ "alice" }, e->GetImplicitUsersForPermission({ "data1", "read" }))); + Assert::IsTrue(ArrayEquals(vector{ "alice" }, e->GetImplicitUsersForPermission({ "data1", "write" }))); + Assert::IsTrue(ArrayEquals(vector{ "alice" }, e->GetImplicitUsersForPermission({ "data2", "read" }))); + Assert::IsTrue(ArrayEquals(vector{ "alice", "bob" }, e->GetImplicitUsersForPermission({ "data2", "write" }))); + + e->ClearPolicy(); + e->AddPolicy({ "admin", "data1", "read" }); + e->AddPolicy({ "bob", "data1", "read" }); + e->AddGroupingPolicy({ "alice", "admin" }); + Assert::IsTrue(ArrayEquals(vector{ "alice", "bob" }, e->GetImplicitUsersForPermission({ "data1", "read" }))); + } + }; +} \ No newline at end of file diff --git a/test/test_util.cpp b/test/test_util.cpp index f2a6b96b..13bfec05 100644 --- a/test/test_util.cpp +++ b/test/test_util.cpp @@ -54,7 +54,7 @@ namespace test_util TEST_METHOD(TestArrayEquals) { TestArrayEquals(vector {"a", "b", "c"}, vector {"a", "b", "c"}, true); TestArrayEquals(vector {"a", "b", "c"}, vector {"a", "b"}, false); - TestArrayEquals(vector {"a", "b", "c"}, vector {"a", "c", "b"}, false); + TestArrayEquals(vector {"a", "b", "c"}, vector {"a", "c", "b"}, true); TestArrayEquals(vector {"a", "b", "c"}, vector {}, false); } }; From 50702967a208b7eb5af77b453ffbb53ab4751e40 Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Sun, 12 Jul 2020 21:05:23 +0530 Subject: [PATCH 09/13] feat: Add RBAC API with Domains tests. Signed-off-by: DivyPatel9881 --- test/test.vcxproj | 1 + test/test.vcxproj.filters | 3 + test/test_config.cpp | 3 - test/test_enforcer.cpp | 3 - test/test_management_api.cpp | 4 - test/test_model.cpp | 2 - test/test_model_enforcer.cpp | 3 - test/test_rbac_api.cpp | 4 - test/test_rbac_api_with_domains.cpp | 185 ++++++++++++++++++++++++++++ 9 files changed, 189 insertions(+), 19 deletions(-) create mode 100644 test/test_rbac_api_with_domains.cpp diff --git a/test/test.vcxproj b/test/test.vcxproj index 33953004..a2a151d6 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -172,6 +172,7 @@ + diff --git a/test/test.vcxproj.filters b/test/test.vcxproj.filters index 6611936f..4b5e33f9 100644 --- a/test/test.vcxproj.filters +++ b/test/test.vcxproj.filters @@ -45,6 +45,9 @@ Source Files + + Source Files + diff --git a/test/test_config.cpp b/test/test_config.cpp index adf77091..94faa71f 100644 --- a/test/test_config.cpp +++ b/test/test_config.cpp @@ -2,9 +2,6 @@ #include "pch.h" -#include -#include - #include #include diff --git a/test/test_enforcer.cpp b/test/test_enforcer.cpp index c6f84a49..098d34d7 100644 --- a/test/test_enforcer.cpp +++ b/test/test_enforcer.cpp @@ -2,9 +2,6 @@ #include "pch.h" -#include -#include - #include #include #include diff --git a/test/test_management_api.cpp b/test/test_management_api.cpp index afd168ef..74ffa662 100644 --- a/test/test_management_api.cpp +++ b/test/test_management_api.cpp @@ -2,10 +2,6 @@ #include "pch.h" -#include -#include -#include - #include #include #include diff --git a/test/test_model.cpp b/test/test_model.cpp index f1737371..03b1e5b8 100644 --- a/test/test_model.cpp +++ b/test/test_model.cpp @@ -2,8 +2,6 @@ #include "pch.h" -#include -#include #include #include diff --git a/test/test_model_enforcer.cpp b/test/test_model_enforcer.cpp index 5c7a69fd..8e197a2c 100644 --- a/test/test_model_enforcer.cpp +++ b/test/test_model_enforcer.cpp @@ -2,9 +2,6 @@ #include "pch.h" -#include -#include - #include #include #include diff --git a/test/test_rbac_api.cpp b/test/test_rbac_api.cpp index 91023dfd..17d31d8f 100644 --- a/test/test_rbac_api.cpp +++ b/test/test_rbac_api.cpp @@ -2,10 +2,6 @@ #include "pch.h" -#include -#include -#include - #include #include #include diff --git a/test/test_rbac_api_with_domains.cpp b/test/test_rbac_api_with_domains.cpp new file mode 100644 index 00000000..4846676b --- /dev/null +++ b/test/test_rbac_api_with_domains.cpp @@ -0,0 +1,185 @@ +#pragma once + +#include "pch.h" + +#include +#include +#include +#include + +using namespace std; + +namespace test_rbac_api_with_domains +{ + TEST_CLASS(TestRBACAPIWithDomains) + { + public: + + TEST_METHOD(TestGetImplicitRolesForDomainUser) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_with_domains_model.conf", "../../examples/rbac_with_hierarchy_with_domains_policy.csv"); + + // This is only able to retrieve the first level of roles. + Assert::IsTrue(ArrayEquals({ "role:global_admin" }, e->GetRolesForUserInDomain("alice", { "domain1" }))); + + // Retrieve all inherit roles. It supports domains as well. + Assert::IsTrue(ArrayEquals(vector{"role:global_admin", "role:reader", "role:writer"}, e->GetImplicitRolesForUser("alice", {"domain1"}))); + } + + // TestUserAPIWithDomains: Add by Gordon + TEST_METHOD(TestUserAPIWithDomains) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_with_domains_model.conf", "../../examples/rbac_with_domains_policy.csv"); + + Assert::IsTrue(ArrayEquals({ "alice" }, e->GetUsersForRole("admin", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ "alice" }, e->GetUsersForRoleInDomain("admin", { "domain1" }))); + + try { + e->GetUsersForRole("non_exist", { "domain1" }); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + try { + e->GetUsersForRoleInDomain("non_exist", { "domain1" }); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + + Assert::IsTrue(ArrayEquals({ "bob" }, e->GetUsersForRole("admin", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ "bob" }, e->GetUsersForRoleInDomain("admin", { "domain2" }))); + + try { + e->GetUsersForRole("non_exist", { "domain2" }); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + try { + e->GetUsersForRoleInDomain("non_exist", { "domain2" }); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + + e->DeleteRoleForUserInDomain("alice", "admin", "domain1"); + e->AddRoleForUserInDomain("bob", "admin", "domain1"); + + Assert::IsTrue(ArrayEquals({ "bob" }, e->GetUsersForRole("admin", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ "bob" }, e->GetUsersForRoleInDomain("admin", { "domain1" }))); + + try { + e->GetUsersForRole("non_exist", { "domain1" }); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + try { + e->GetUsersForRoleInDomain("non_exist", { "domain1" }); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + + Assert::IsTrue(ArrayEquals({ "bob" }, e->GetUsersForRole("admin", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ "bob" }, e->GetUsersForRoleInDomain("admin", { "domain2" }))); + + try { + e->GetUsersForRole("non_exist", { "domain2" }); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + try { + e->GetUsersForRoleInDomain("non_exist", { "domain2" }); + } + catch (CasbinRBACException e) { + Assert::IsTrue(true); + } + } + + TEST_METHOD(TestRoleAPIWithDomains) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_with_domains_model.conf", "../../examples/rbac_with_domains_policy.csv"); + + Assert::IsTrue(ArrayEquals({ "admin" }, e->GetRolesForUser("alice", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ "admin" }, e->GetRolesForUserInDomain("alice", { "domain1" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("bob", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("bob", { "domain1" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("admin", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("admin", { "domain1" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("non_exist", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("non_exist", { "domain1" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("alice", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("alice", { "domain2" }))); + + Assert::IsTrue(ArrayEquals({ "admin" }, e->GetRolesForUser("bob", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ "admin" }, e->GetRolesForUserInDomain("bob", { "domain2" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("admin", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("admin", { "domain2" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("non_exist", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("non_exist", { "domain2" }))); + + e->DeleteRoleForUserInDomain("alice", "admin", "domain1"); + e->AddRoleForUserInDomain("bob", "admin", "domain1"); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("alice", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("alice", { "domain1" }))); + + Assert::IsTrue(ArrayEquals({ "admin" }, e->GetRolesForUser("bob", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ "admin" }, e->GetRolesForUserInDomain("bob", { "domain1" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("admin", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("admin", { "domain1" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("non_exist", { "domain1" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("non_exist", { "domain1" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("alice", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("alice", { "domain2" }))); + + Assert::IsTrue(ArrayEquals({ "admin" }, e->GetRolesForUser("bob", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ "admin" }, e->GetRolesForUserInDomain("bob", { "domain2" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("admin", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("admin", { "domain2" }))); + + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUser("non_exist", { "domain2" }))); + Assert::IsTrue(ArrayEquals({ }, e->GetRolesForUserInDomain("non_exist", { "domain2" }))); + } + + void TestGetPermissionsInDomain(Enforcer* e, string name, string domain, vector> res) { + vector> my_res = e->GetPermissionsForUserInDomain(name, { domain }); + + int count = 0; + for (int i = 0; i < my_res.size(); i++) { + for (int j = 0; j < res.size(); j++) { + if (ArrayEquals(res[j], my_res[i])) { + count += 1; + break; + } + } + } + + Assert::AreEqual(int(res.size()), count); + } + + TEST_METHOD(TestPermissionAPIInDomain) { + Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_with_domains_model.conf", "../../examples/rbac_with_domains_policy.csv"); + + TestGetPermissionsInDomain(e, "alice", "domain1", {}); + TestGetPermissionsInDomain(e, "bob", "domain1", {}); + TestGetPermissionsInDomain(e, "admin", "domain1", { {"admin", "domain1", "data1", "read"}, {"admin", "domain1", "data1", "write"} }); + TestGetPermissionsInDomain(e, "non_exist", "domain1", {}); + + TestGetPermissionsInDomain(e, "alice", "domain2", {}); + TestGetPermissionsInDomain(e, "bob", "domain2", {}); + TestGetPermissionsInDomain(e, "admin", "domain2", { {"admin", "domain2", "data2", "read"}, {"admin", "domain2", "data2", "write"} }); + TestGetPermissionsInDomain(e, "non_exist", "domain2", {}); + } + }; +} \ No newline at end of file From 5f80bb57664ac70839cb5cde56dc1bbdd57e601e Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Tue, 14 Jul 2020 13:18:34 +0530 Subject: [PATCH 10/13] fix: Make domain as default argument to make it optional Signed-off-by: DivyPatel9881 --- casbin/enforcer.h | 18 +++++------ casbin/enforcer_interface.h | 8 ++--- casbin/rbac/default_role_manager.h | 10 +++---- test/test_management_api.cpp | 48 +++++++++++++++--------------- test/test_rbac_api.cpp | 44 +++++++++++++-------------- 5 files changed, 64 insertions(+), 64 deletions(-) diff --git a/casbin/enforcer.h b/casbin/enforcer.h index 5885daab..7a8abf4e 100644 --- a/casbin/enforcer.h +++ b/casbin/enforcer.h @@ -210,8 +210,8 @@ class Enforcer : public IEnforcer{ void AddFunction(string name, Function function, Index nargs); /*RBAC API member functions.*/ - vector GetRolesForUser(string name, vector domain); - vector GetUsersForRole(string name, vector domain); + vector GetRolesForUser(string name, vector domain = {}); + vector GetUsersForRole(string name, vector domain = {}); bool HasRoleForUser(string name, string role); bool AddRoleForUser(string user, string role); bool AddRolesForUser(string user, vector roles); @@ -220,8 +220,8 @@ class Enforcer : public IEnforcer{ bool DeletePermissionsForUser(string user); vector> GetPermissionsForUser(string user); bool HasPermissionForUser(string user, vector permission); - vector GetImplicitRolesForUser(string name, vector domain); - vector> GetImplicitPermissionsForUser(string user, vector domain); + vector GetImplicitRolesForUser(string name, vector domain = {}); + vector> GetImplicitPermissionsForUser(string user, vector domain = {}); vector GetImplicitUsersForPermission(vector permission); bool DeleteRoleForUser(string user, string role); bool DeleteRolesForUser(string user); @@ -237,11 +237,11 @@ class Enforcer : public IEnforcer{ bool removeFilteredPolicy(string sec , string ptype , int fieldIndex , vector fieldValues); /* RBAC API with domains.*/ - vector GetUsersForRoleInDomain(string name, string domain); - vector GetRolesForUserInDomain(string name, string domain); - vector> GetPermissionsForUserInDomain(string user, string domain); - bool AddRoleForUserInDomain(string user, string role, string domain); - bool DeleteRoleForUserInDomain(string user, string role, string domain); + vector GetUsersForRoleInDomain(string name, string domain = {}); + vector GetRolesForUserInDomain(string name, string domain = {}); + vector> GetPermissionsForUserInDomain(string user, string domain = {}); + bool AddRoleForUserInDomain(string user, string role, string domain = {}); + bool DeleteRoleForUserInDomain(string user, string role, string domain = {}); }; diff --git a/casbin/enforcer_interface.h b/casbin/enforcer_interface.h index 6da3b683..6f78e54e 100644 --- a/casbin/enforcer_interface.h +++ b/casbin/enforcer_interface.h @@ -60,8 +60,8 @@ class IEnforcer { virtual bool EnforceWithMatcher(string matcher, Scope scope) = 0; /* RBAC API */ - virtual vector GetRolesForUser(string name, vector domain) = 0; - virtual vector GetUsersForRole(string name, vector domain) = 0; + virtual vector GetRolesForUser(string name, vector domain = {}) = 0; + virtual vector GetUsersForRole(string name, vector domain = {}) = 0; virtual bool HasRoleForUser(string name, string role) = 0; virtual bool AddRoleForUser(string user, string role) = 0; virtual bool AddRolesForUser(string user, vector roles) = 0; @@ -70,8 +70,8 @@ class IEnforcer { virtual bool DeletePermissionsForUser(string user) = 0; virtual vector> GetPermissionsForUser(string user) = 0; virtual bool HasPermissionForUser(string user, vector permission) = 0; - virtual vector GetImplicitRolesForUser(string name, vector domain) = 0; - virtual vector> GetImplicitPermissionsForUser(string user, vector domain) = 0; + virtual vector GetImplicitRolesForUser(string name, vector domain = {}) = 0; + virtual vector> GetImplicitPermissionsForUser(string user, vector domain = {}) = 0; virtual vector GetImplicitUsersForPermission(vector permission) = 0; virtual bool DeleteRoleForUser(string user, string role) = 0; virtual bool DeleteRolesForUser(string user) = 0; diff --git a/casbin/rbac/default_role_manager.h b/casbin/rbac/default_role_manager.h index b3c838c7..9f75dc1c 100644 --- a/casbin/rbac/default_role_manager.h +++ b/casbin/rbac/default_role_manager.h @@ -85,28 +85,28 @@ class DefaultRoleManager : public RoleManager { // AddLink adds the inheritance link between role: name1 and role: name2. // aka role: name1 inherits role: name2. // domain is a prefix to the roles. - void AddLink(string name1, string name2, vector domain = vector{}); + void AddLink(string name1, string name2, vector domain = {}); /** * deleteLink deletes the inheritance link between role: name1 and role: name2. * aka role: name1 does not inherit role: name2 any more. * domain is a prefix to the roles. */ - void DeleteLink(string name1, string name2, vector domain = vector{}); + void DeleteLink(string name1, string name2, vector domain = {}); /** * hasLink determines whether role: name1 inherits role: name2. * domain is a prefix to the roles. */ - bool HasLink(string name1, string name2, vector domain = vector{}); + bool HasLink(string name1, string name2, vector domain = {}); /** * getRoles gets the roles that a subject inherits. * domain is a prefix to the roles. */ - vector GetRoles(string name, vector domain = vector{}); + vector GetRoles(string name, vector domain = {}); - vector GetUsers(string name, vector domain = vector{}); + vector GetUsers(string name, vector domain = {}); /** * printRoles prints all the roles to log. diff --git a/test/test_management_api.cpp b/test/test_management_api.cpp index 74ffa662..10c0ba05 100644 --- a/test/test_management_api.cpp +++ b/test/test_management_api.cpp @@ -179,10 +179,10 @@ namespace test_management_api Adapter* adapter = BatchFileAdapter::NewAdapter(policy); Enforcer* e = Enforcer::NewEnforcer(model, adapter); - Assert::IsTrue(ArrayEquals(vector{"data2_admin"}, e->GetRolesForUser("alice", vector{}))); - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("bob", vector{}))); - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("eve", vector{}))); - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("non_exist", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"data2_admin"}, e->GetRolesForUser("alice"))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("bob"))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("eve"))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("non_exist"))); e->RemoveGroupingPolicy(vector{"alice", "data2_admin"}); e->AddGroupingPolicy(vector{"bob", "data1_admin"}); @@ -194,58 +194,58 @@ namespace test_management_api }; e->AddGroupingPolicies(grouping_rules); - Assert::IsTrue(ArrayEquals(vector{"data4_admin"}, e->GetRolesForUser("ham", vector{}))); - Assert::IsTrue(ArrayEquals(vector{"data5_admin"}, e->GetRolesForUser("jack", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"data4_admin"}, e->GetRolesForUser("ham"))); + Assert::IsTrue(ArrayEquals(vector{"data5_admin"}, e->GetRolesForUser("jack"))); e->RemoveGroupingPolicies(grouping_rules); - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice"))); vector named_grouping_policy{ "alice", "data2_admin" }; - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice"))); e->AddNamedGroupingPolicy("g", named_grouping_policy); - Assert::IsTrue(ArrayEquals(vector{"data2_admin"}, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"data2_admin"}, e->GetRolesForUser("alice"))); e->RemoveNamedGroupingPolicy("g", named_grouping_policy); e->AddNamedGroupingPolicies("g", grouping_rules); e->AddNamedGroupingPolicies("g", grouping_rules); - Assert::IsTrue(ArrayEquals(vector{"data4_admin"}, e->GetRolesForUser("ham", vector{}))); - Assert::IsTrue(ArrayEquals(vector{"data5_admin"}, e->GetRolesForUser("jack", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"data4_admin"}, e->GetRolesForUser("ham"))); + Assert::IsTrue(ArrayEquals(vector{"data5_admin"}, e->GetRolesForUser("jack"))); e->RemoveNamedGroupingPolicies("g", grouping_rules); e->RemoveNamedGroupingPolicies("g", grouping_rules); - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice", vector{}))); - Assert::IsTrue(ArrayEquals(vector{"data1_admin"}, e->GetRolesForUser("bob", vector{}))); - Assert::IsTrue(ArrayEquals(vector{"data3_admin"}, e->GetRolesForUser("eve", vector{}))); - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("non_exist", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice"))); + Assert::IsTrue(ArrayEquals(vector{"data1_admin"}, e->GetRolesForUser("bob"))); + Assert::IsTrue(ArrayEquals(vector{"data3_admin"}, e->GetRolesForUser("eve"))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("non_exist"))); - Assert::IsTrue(ArrayEquals(vector{"bob"}, e->GetUsersForRole("data1_admin", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"bob"}, e->GetUsersForRole("data1_admin"))); try { e->GetUsersForRole("data2_admin", vector{}); } catch (CasbinRBACException e) { Assert::IsTrue(true); } - Assert::IsTrue(ArrayEquals(vector{"eve"}, e->GetUsersForRole("data3_admin", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"eve"}, e->GetUsersForRole("data3_admin"))); e->RemoveFilteredGroupingPolicy(0, vector{"bob"}); - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice", vector{}))); - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("bob", vector{}))); - Assert::IsTrue(ArrayEquals(vector{"data3_admin"}, e->GetRolesForUser("eve", vector{}))); - Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("non_exist", vector{}))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("alice"))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("bob"))); + Assert::IsTrue(ArrayEquals(vector{"data3_admin"}, e->GetRolesForUser("eve"))); + Assert::IsTrue(ArrayEquals(vector{}, e->GetRolesForUser("non_exist"))); try { - e->GetUsersForRole("data1_admin", vector{}); + e->GetUsersForRole("data1_admin"); } catch (CasbinRBACException e) { Assert::IsTrue(true); } try { - e->GetUsersForRole("data2_admin", vector{}); + e->GetUsersForRole("data2_admin"); } catch (CasbinRBACException e) { Assert::IsTrue(true); } - Assert::IsTrue(ArrayEquals(vector{"eve"}, e->GetUsersForRole("data3_admin", vector{}))); + Assert::IsTrue(ArrayEquals(vector{"eve"}, e->GetUsersForRole("data3_admin"))); } }; } \ No newline at end of file diff --git a/test/test_rbac_api.cpp b/test/test_rbac_api.cpp index 17d31d8f..2ffff389 100644 --- a/test/test_rbac_api.cpp +++ b/test/test_rbac_api.cpp @@ -17,38 +17,38 @@ namespace test_rbac_api TEST_METHOD(TestRoleAPI) { Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_model.conf", "../../examples/rbac_policy.csv"); - Assert::IsTrue(ArrayEquals(vector{ "data2_admin" }, e->GetRolesForUser("alice", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("non_exist", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ "data2_admin" }, e->GetRolesForUser("alice"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("non_exist"))); Assert::IsFalse(e->HasRoleForUser("alice", "data1_admin")); Assert::IsTrue(e->HasRoleForUser("alice", "data2_admin")); e->AddRoleForUser("alice", "data1_admin"); - Assert::IsTrue(ArrayEquals(vector{ "data1_admin", "data2_admin" }, e->GetRolesForUser("alice", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ "data1_admin", "data2_admin" }, e->GetRolesForUser("alice"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin"))); e->DeleteRoleForUser("alice", "data1_admin"); - Assert::IsTrue(ArrayEquals(vector{ "data2_admin" }, e->GetRolesForUser("alice", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ "data2_admin" }, e->GetRolesForUser("alice"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin"))); e->DeleteRolesForUser("alice"); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("alice", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("alice"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin"))); e->AddRoleForUser("alice", "data1_admin"); e->DeleteUser("alice"); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("alice", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob", vector{}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("alice"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("bob"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetRolesForUser("data2_admin"))); e->AddRoleForUser("alice", "data2_admin"); @@ -77,7 +77,7 @@ namespace test_rbac_api Enforcer* e = Enforcer::NewEnforcer("../../examples/rbac_model.conf", "../../examples/rbac_policy.csv"); e->AddRolesForUser("alice", vector{ "data1_admin", "data2_admin", "data3_admin" }); - Assert::IsTrue(ArrayEquals(vector{ "data1_admin", "data2_admin", "data3_admin" }, e->GetRolesForUser("alice", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ "data1_admin", "data2_admin", "data3_admin" }, e->GetRolesForUser("alice"))); Assert::IsTrue(e->Enforce({ "alice", "data1", "read" })); Assert::IsTrue(e->Enforce({ "alice", "data2", "read" })); @@ -151,19 +151,19 @@ namespace test_rbac_api TestGetPermissions(e, "alice", vector>{ {"alice", "data1", "read"} }); TestGetPermissions(e, "bob", vector>{ {"bob", "data2", "write"} }); - Assert::IsTrue(ArrayEquals(vector{ "admin", "data1_admin", "data2_admin" }, e->GetImplicitRolesForUser("alice", {}))); - Assert::IsTrue(ArrayEquals(vector{ }, e->GetImplicitRolesForUser("bob", {}))); + Assert::IsTrue(ArrayEquals(vector{ "admin", "data1_admin", "data2_admin" }, e->GetImplicitRolesForUser("alice"))); + Assert::IsTrue(ArrayEquals(vector{ }, e->GetImplicitRolesForUser("bob"))); e = Enforcer::NewEnforcer("../../examples/rbac_with_pattern_model.conf", "../../examples/rbac_with_pattern_policy.csv"); dynamic_cast(e->GetRoleManager())->AddMatchingFunc(KeyMatch); - Assert::IsTrue(ArrayEquals(vector{ "/book/1/2/3/4/5", "pen_admin", "/book/*", "book_group" }, e->GetImplicitRolesForUser("cathy", {}))); - Assert::IsTrue(ArrayEquals(vector{ "/book/1/2/3/4/5", "pen_admin" }, e->GetRolesForUser("cathy", vector{}))); + Assert::IsTrue(ArrayEquals(vector{ "/book/1/2/3/4/5", "pen_admin", "/book/*", "book_group" }, e->GetImplicitRolesForUser("cathy"))); + Assert::IsTrue(ArrayEquals(vector{ "/book/1/2/3/4/5", "pen_admin" }, e->GetRolesForUser("cathy"))); } void TestGetImplicitPermissions(Enforcer* e, string name, vector> res) { - vector> my_res = e->GetImplicitPermissionsForUser(name, {}); + vector> my_res = e->GetImplicitPermissionsForUser(name); int count = 0; for (int i = 0; i < my_res.size(); i++) { From 514fa2a21f067a83d3cb1f5bda2b5b9b6c1ab1db Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Tue, 14 Jul 2020 20:50:56 +0530 Subject: [PATCH 11/13] feat: Add Get-Started section. Signed-off-by: DivyPatel9881 --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index d267e0ab..d364cf23 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,37 @@ You can also use the online editor (https://casbin.org/editor/) to write your Ca https://casbin.org/docs/en/tutorials +## Get started + +1. New a Casbin enforcer with a model file and a policy file: + + ```c++ + Enforcer* e = Enforcer :: NewEnforcer("", ""); + ``` + +Note: you can also initialize an enforcer with policy in DB instead of file, see [Policy-persistence](#policy-persistence) section for details. + +2. Add an enforcement hook into your code right before the access happens: + + ```c++ + string sub = "alice"; // the user that wants to access a resource. + string obj = "data1"; // the resource that is going to be accessed. + string act = "read"; // the operation that the user performs on the resource. + + if(e->Enforce({ sub, obj, act })) { + // permit alice to read data1 + } else { + // deny the request, show an error + } + ``` + +3. Besides the static policy file, Casbin also provides API for permission management at run-time. For example, You can get all the roles assigned to a user as below: + + ```c++ + vector roles( e->GetImplicitRolesForUser(sub) ); + ``` + + ## Policy management Casbin provides two sets of APIs to manage permissions: From 6caf08e754c70dfc3b6995102d3ed0116a87c9ee Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Wed, 15 Jul 2020 12:24:30 +0530 Subject: [PATCH 12/13] fix: code formatting. Signed-off-by: DivyPatel9881 --- casbin/internal_api.cpp | 2 +- casbin/model/assertion.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/casbin/internal_api.cpp b/casbin/internal_api.cpp index 43383033..a46f6177 100644 --- a/casbin/internal_api.cpp +++ b/casbin/internal_api.cpp @@ -120,7 +120,7 @@ bool Enforcer :: removePolicies(string sec, string p_type, vector if (this->adapter != NULL && this->auto_save) { try{ - dynamic_cast(this->adapter)->RemovePolicies(sec, p_type, rules); + dynamic_cast(this->adapter)->RemovePolicies(sec, p_type, rules); } catch(UnsupportedOperationException e){ } diff --git a/casbin/model/assertion.cpp b/casbin/model/assertion.cpp index ade15f2d..f856eb48 100644 --- a/casbin/model/assertion.cpp +++ b/casbin/model/assertion.cpp @@ -77,5 +77,5 @@ void Assertion :: BuildRoleLinks(RoleManager* rm) { // LogUtil :: LogPrint("Role links for: " + Key); - //this->rm->PrintRoles(); + // this->rm->PrintRoles(); } \ No newline at end of file From 2bfebf8d0a048c9550cbf98482a3b99bd9920360 Mon Sep 17 00:00:00 2001 From: DivyPatel9881 Date: Wed, 15 Jul 2020 12:30:11 +0530 Subject: [PATCH 13/13] fix: merge conflicts. Signed-off-by: DivyPatel9881 --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d364cf23..b59b61fa 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,13 @@ Casbin-CPP **News**: Are you still worried about how to write the correct Casbin policy? ``Casbin online editor`` is coming to help! Try it at: http://casbin.org/editor/ +## Build Availability on Platforms: +Operating Systems | Availability status +----------------- | ------------------- +Windows (VS C++) | :heavy_check_mark: Available +Linux and MacOS | :wrench: Under-Development + + ![casbin Logo](casbin-logo.png) ## All the languages supported by Casbin: @@ -130,7 +137,6 @@ Note: you can also initialize an enforcer with policy in DB instead of file, see vector roles( e->GetImplicitRolesForUser(sub) ); ``` - ## Policy management Casbin provides two sets of APIs to manage permissions: