diff --git a/casbin/enforcer.cpp b/casbin/enforcer.cpp index ebceddf9..a93ce95d 100644 --- a/casbin/enforcer.cpp +++ b/casbin/enforcer.cpp @@ -446,7 +446,8 @@ bool Enforcer :: Enforce(Scope scope) { // Enforce with two params, decides whether a "subject" can do the operation "action", input parameters are usually: (sub, act). bool Enforcer::Enforce(string sub, string act) { - return Enforce({ sub,act }); + vector v = { sub, act }; + return Enforce(v); } // Enforce with three params, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act). @@ -461,6 +462,20 @@ bool Enforcer::Enforce(string sub, string dom, string obj, string act) { // Enforce with a vector param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act). bool Enforcer::Enforce(vector params) { + return this->EnforceWithMatcher("", params); +} + +// Enforce with a map param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act). +bool Enforcer::Enforce(unordered_map params) { + return this->EnforceWithMatcher("", params); +} + +// EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "". +bool Enforcer :: EnforceWithMatcher(string matcher, Scope scope) { + return this->enforce(matcher, scope); +} +// EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "". +bool Enforcer::EnforceWithMatcher(string matcher, vector params) { vector r_tokens = this->model->m["r"].assertion_map["r"]->tokens; int r_cnt = r_tokens.size(); @@ -471,14 +486,21 @@ bool Enforcer::Enforce(vector params) { Scope scope = InitializeScope(); PushObject(scope, "r"); + for (int i = 0; i < cnt; i++) { - PushStringPropToObject(scope, "r", params[i] , r_tokens[i].substr(2,r_tokens[i].size()-2)); + PushStringPropToObject(scope, "r", params[i], r_tokens[i].substr(2, r_tokens[i].size() - 2)); } - return this->enforce("", scope); + return this->enforce(matcher, scope); } - // EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "". -bool Enforcer :: EnforceWithMatcher(string matcher, Scope scope) { +bool Enforcer::EnforceWithMatcher(string matcher, unordered_map params) { + Scope scope = InitializeScope(); + PushObject(scope, "r"); + + for (auto r : params) { + PushStringPropToObject(scope, "r", r.second, r.first); + } + return this->enforce(matcher, scope); } \ No newline at end of file diff --git a/casbin/enforcer.h b/casbin/enforcer.h index 95ee8a1d..c8a73b7f 100644 --- a/casbin/enforcer.h +++ b/casbin/enforcer.h @@ -154,9 +154,15 @@ class Enforcer : public IEnforcer{ // Enforce with four params, decides whether a "subject" can access a "object" with the operation "action" in the domain "dom", input parameters are usually: (sub, dom, obj,act). bool Enforce(string sub, string dom, string obj, string act); // Enforce with a vector param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act). - bool Enforce(vector params); + bool Enforce(vector params); + // Enforce with a map param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act). + bool Enforce(unordered_map params); // EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "". bool EnforceWithMatcher(string matcher, Scope scope); + // EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "". + bool EnforceWithMatcher(string matcher, vector params); + // EnforceWithMatcher use a custom matcher to decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (matcher, sub, obj, act), use model matcher by default when matcher is "". + bool EnforceWithMatcher(string matcher, unordered_map params); /*Management API member functions.*/ vector GetAllSubjects(); diff --git a/test/test_enforcer.cpp b/test/test_enforcer.cpp index 59f60aee..ab7909d6 100644 --- a/test/test_enforcer.cpp +++ b/test/test_enforcer.cpp @@ -56,6 +56,10 @@ namespace test_enforcer Assert::AreEqual(res, e->Enforce(params)); } + void TestEnforce(Enforcer* e, unordered_map params, bool res) { + Assert::AreEqual(res, e->Enforce(params)); + } + TEST_METHOD(TestFourParams) { string model = filePath("../examples/rbac_with_domains_model.conf"); @@ -77,14 +81,14 @@ namespace test_enforcer string policy = filePath("../examples/basic_policy.csv"); Enforcer* e = Enforcer::NewEnforcer(model, policy); - TestEnforce(e, "alice", "data1", "read", true); - TestEnforce(e, "alice", "data1", "write", false); - TestEnforce(e, "alice", "data2", "read", false); - TestEnforce(e, "alice", "data2", "write", false); - TestEnforce(e, "bob", "data1", "read", false); - TestEnforce(e, "bob", "data1", "write", false); - TestEnforce(e, "bob", "data2", "read", false); - TestEnforce(e, "bob", "data2", "write", true); + TestEnforce(e, { "alice", "data1", "read" }, true); + TestEnforce(e, { "alice", "data1", "write" }, false); + TestEnforce(e, { "alice", "data2", "read" }, false); + TestEnforce(e, { "alice", "data2", "write" }, false); + TestEnforce(e, { "bob", "data1", "read" }, false); + TestEnforce(e, { "bob", "data1", "write" }, false); + TestEnforce(e, { "bob", "data2", "read" }, false); + TestEnforce(e, { "bob", "data2", "write" }, true); } TEST_METHOD(TestTwoParams) { @@ -112,5 +116,35 @@ namespace test_enforcer TestEnforce(e, {"bob", "data2", "read" }, false); TestEnforce(e, {"bob", "data2", "write" }, true); } + + TEST_METHOD(TestMapParams) { + string model = filePath("../examples/basic_model_without_spaces.conf"); + string policy = filePath("../examples/basic_policy.csv"); + Enforcer* e = Enforcer::NewEnforcer(model, policy); + + unordered_map params = { {"sub","alice"},{"obj","data1"},{"act","read"} }; + TestEnforce(e, params, true); + + params = { {"sub","alice"},{"obj","data1"},{"act","write"} }; + TestEnforce(e, params, false); + + params = { {"sub","alice"},{"obj","data2"},{"act","read"} }; + TestEnforce(e, params, false); + + params = { {"sub","alice"},{"obj","data2"},{"act","write"} }; + TestEnforce(e, params, false); + + params = { {"sub","bob"},{"obj","data1"},{"act","read"} }; + TestEnforce(e, params, false); + + params = { {"sub","bob"},{"obj","data1"},{"act","write"} }; + TestEnforce(e, params, false); + + params = { {"sub","bob"},{"obj","data2"},{"act","read"} }; + TestEnforce(e, params, false); + + params = { {"sub","bob"},{"obj","data2"},{"act","write"} }; + TestEnforce(e, params, true); + } }; } \ No newline at end of file