Skip to content

Commit d1840a0

Browse files
authored
Merge pull request #54 from ZipoChan/master
feat: add enforce functions with convenient interface.
2 parents 8f4c866 + 96572fa commit d1840a0

File tree

5 files changed

+219
-2
lines changed

5 files changed

+219
-2
lines changed

casbin/enforcer.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,10 +441,72 @@ void Enforcer :: BuildIncrementalRoleLinks(policy_op op, string p_type, vector<v
441441

442442
// Enforce decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
443443
bool Enforcer :: Enforce(Scope scope) {
444-
return this->enforce("", scope);
444+
return this->EnforceWithMatcher("", scope);
445+
}
446+
447+
// Enforce with three params, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
448+
bool Enforcer::Enforce(string sub, string obj, string act) {
449+
return EnforceWithMatcher("", sub, obj, act);
450+
}
451+
452+
// 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).
453+
bool Enforcer::Enforce(string sub, string dom, string obj, string act) {
454+
return EnforceWithMatcher("", sub, dom, obj, act);
455+
}
456+
457+
// Enforce with a vector param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
458+
bool Enforcer::Enforce(vector<string> params) {
459+
return this->EnforceWithMatcher("", params);
460+
}
461+
462+
// Enforce with a map param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
463+
bool Enforcer::Enforce(unordered_map<string, string> params) {
464+
return this->EnforceWithMatcher("", params);
445465
}
446466

447467
// 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 "".
448468
bool Enforcer :: EnforceWithMatcher(string matcher, Scope scope) {
469+
return this->enforce(matcher, scope);
470+
}
471+
472+
// Enforce with three params, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
473+
bool Enforcer::EnforceWithMatcher(string matcher, string sub, string obj, string act) {
474+
return this->EnforceWithMatcher(matcher, { sub,obj,act });
475+
}
476+
477+
// 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).
478+
bool Enforcer::EnforceWithMatcher(string matcher, string sub, string dom, string obj, string act) {
479+
return this->EnforceWithMatcher(matcher, { sub,dom,obj,act });
480+
}
481+
482+
// 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 "".
483+
bool Enforcer::EnforceWithMatcher(string matcher, vector<string> params) {
484+
vector <string> r_tokens = this->model->m["r"].assertion_map["r"]->tokens;
485+
486+
int r_cnt = r_tokens.size();
487+
int cnt = params.size();
488+
489+
if (cnt != r_cnt)
490+
return false;
491+
492+
Scope scope = InitializeScope();
493+
PushObject(scope, "r");
494+
495+
for (int i = 0; i < cnt; i++) {
496+
PushStringPropToObject(scope, "r", params[i], r_tokens[i].substr(2, r_tokens[i].size() - 2));
497+
}
498+
499+
return this->enforce(matcher, scope);
500+
}
501+
502+
// 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 "".
503+
bool Enforcer::EnforceWithMatcher(string matcher, unordered_map<string, string> params) {
504+
Scope scope = InitializeScope();
505+
PushObject(scope, "r");
506+
507+
for (auto r : params) {
508+
PushStringPropToObject(scope, "r", r.second, r.first);
509+
}
510+
449511
return this->enforce(matcher, scope);
450512
}

casbin/enforcer.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,25 @@ class Enforcer : public IEnforcer{
147147
void BuildIncrementalRoleLinks(policy_op op, string p_type, vector<vector<string>> rules);
148148
// Enforce decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
149149
bool Enforce(Scope scope);
150+
// Enforce with three params, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
151+
bool Enforce(string sub, string obj, string act);
152+
// 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).
153+
bool Enforce(string sub, string dom, string obj, string act);
154+
// Enforce with a vector param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
155+
bool Enforce(vector<string> params);
156+
// Enforce with a map param,decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
157+
bool Enforce(unordered_map<string,string> params);
150158
// 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 "".
151159
bool EnforceWithMatcher(string matcher, Scope scope);
152-
160+
// Enforce with three params, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
161+
bool EnforceWithMatcher(string matcher, string sub, string obj, string act);
162+
// 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).
163+
bool EnforceWithMatcher(string matcher, string sub, string dom, string obj, string act);
164+
// 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 "".
165+
bool EnforceWithMatcher(string matcher, vector<string> params);
166+
// 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 "".
167+
bool EnforceWithMatcher(string matcher, unordered_map<string, string> params);
168+
153169
/*Management API member functions.*/
154170
vector<string> GetAllSubjects();
155171
vector<string> GetAllNamedSubjects(string ptype);

test/test.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167
</ClCompile>
168168
<ClCompile Include="test_built_in_functions.cpp" />
169169
<ClCompile Include="test_config.cpp" />
170+
<ClCompile Include="test_enforcer.cpp" />
170171
<ClCompile Include="test_model.cpp" />
171172
<ClCompile Include="test_model_enforcer.cpp" />
172173
<ClCompile Include="test_role_manager.cpp" />

test/test.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
<ClCompile Include="test_model_enforcer.cpp">
3737
<Filter>Source Files</Filter>
3838
</ClCompile>
39+
<ClCompile Include="test_enforcer.cpp">
40+
<Filter>Source Files</Filter>
41+
</ClCompile>
3942
</ItemGroup>
4043
<ItemGroup>
4144
<ClInclude Include="pch.h">

test/test_enforcer.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#pragma once
2+
3+
#include "pch.h"
4+
5+
#include <direct.h>
6+
#include <algorithm>
7+
8+
#include <enforcer.h>
9+
#include <persist.h>
10+
#include <rbac.h>
11+
#include <util.h>
12+
13+
using namespace std;
14+
15+
namespace test_enforcer
16+
{
17+
TEST_CLASS(TestEnforcer)
18+
{
19+
public:
20+
21+
string filePath(string filepath) {
22+
char* root = _getcwd(NULL, 0);
23+
string rootStr = string(root);
24+
25+
vector <string> directories = Split(rootStr, "\\", -1);
26+
vector<string>::iterator it = find(directories.begin(), directories.end(), "x64");
27+
vector <string> left{ *(it - 1) };
28+
it = find_end(directories.begin(), directories.end(), left.begin(), left.end());
29+
int index = int(directories.size() + (it - directories.end()));
30+
31+
vector <string> finalDirectories(directories.begin(), directories.begin() + index + 1);
32+
33+
vector<string> userD = Split(filepath, "/", -1);
34+
for (int i = 1; i < userD.size(); i++)
35+
finalDirectories.push_back(userD[i]);
36+
37+
string filepath1 = finalDirectories[0];
38+
for (int i = 1; i < finalDirectories.size(); i++)
39+
filepath1 = filepath1 + "/" + finalDirectories[i];
40+
return filepath1;
41+
}
42+
43+
void TestEnforce(Enforcer* e, string sub, string dom, string obj, string act, bool res) {
44+
Assert::AreEqual(res, e->Enforce(sub, dom, obj, act));
45+
}
46+
47+
void TestEnforce(Enforcer* e, string sub, string obj, string act, bool res) {
48+
Assert::AreEqual(res, e->Enforce(sub, obj, act));
49+
}
50+
51+
void TestEnforce(Enforcer* e, vector<string> params, bool res) {
52+
Assert::AreEqual(res, e->Enforce(params));
53+
}
54+
55+
void TestEnforce(Enforcer* e, unordered_map<string,string> params, bool res) {
56+
Assert::AreEqual(res, e->Enforce(params));
57+
}
58+
59+
60+
TEST_METHOD(TestFourParams) {
61+
string model = filePath("../examples/rbac_with_domains_model.conf");
62+
string policy = filePath("../examples/rbac_with_domains_policy.csv");
63+
Enforcer* e = Enforcer::NewEnforcer(model, policy);
64+
65+
TestEnforce(e, "alice", "domain1", "data1", "read", true);
66+
TestEnforce(e, "alice", "domain1", "data1", "write", true);
67+
TestEnforce(e, "alice", "domain1", "data2", "read", false);
68+
TestEnforce(e, "alice", "domain1", "data2", "write", false);
69+
TestEnforce(e, "bob", "domain2", "data1", "read", false);
70+
TestEnforce(e, "bob", "domain2", "data1", "write", false);
71+
TestEnforce(e, "bob", "domain2", "data2", "read", true);
72+
TestEnforce(e, "bob", "domain2", "data2", "write", true);
73+
}
74+
75+
TEST_METHOD(TestThreeParams) {
76+
string model = filePath("../examples/basic_model_without_spaces.conf");
77+
string policy = filePath("../examples/basic_policy.csv");
78+
Enforcer* e = Enforcer::NewEnforcer(model, policy);
79+
80+
TestEnforce(e, { "alice", "data1", "read" }, true);
81+
TestEnforce(e, { "alice", "data1", "write" }, false);
82+
TestEnforce(e, { "alice", "data2", "read" }, false);
83+
TestEnforce(e, { "alice", "data2", "write" }, false);
84+
TestEnforce(e, { "bob", "data1", "read" }, false);
85+
TestEnforce(e, { "bob", "data1", "write" }, false);
86+
TestEnforce(e, { "bob", "data2", "read" }, false);
87+
TestEnforce(e, { "bob", "data2", "write" }, true);
88+
}
89+
90+
TEST_METHOD(TestVectorParams) {
91+
string model = filePath("../examples/basic_model_without_spaces.conf");
92+
string policy = filePath("../examples/basic_policy.csv");
93+
Enforcer* e = Enforcer::NewEnforcer(model, policy);
94+
95+
TestEnforce(e, { "alice", "data1", "read" }, true);
96+
TestEnforce(e, { "alice", "data1", "write" }, false);
97+
TestEnforce(e, {"alice", "data2", "read" }, false);
98+
TestEnforce(e, {"alice", "data2", "write" }, false);
99+
TestEnforce(e, {"bob", "data1", "read" }, false);
100+
TestEnforce(e, {"bob", "data1", "write" }, false);
101+
TestEnforce(e, {"bob", "data2", "read" }, false);
102+
TestEnforce(e, {"bob", "data2", "write" }, true);
103+
}
104+
105+
TEST_METHOD(TestMapParams) {
106+
string model = filePath("../examples/basic_model_without_spaces.conf");
107+
string policy = filePath("../examples/basic_policy.csv");
108+
Enforcer* e = Enforcer::NewEnforcer(model, policy);
109+
110+
unordered_map<string, string> params = { {"sub","alice"},{"obj","data1"},{"act","read"} };
111+
TestEnforce(e, params, true);
112+
113+
params = { {"sub","alice"},{"obj","data1"},{"act","write"} };
114+
TestEnforce(e, params, false);
115+
116+
params = { {"sub","alice"},{"obj","data2"},{"act","read"} };
117+
TestEnforce(e, params, false);
118+
119+
params = { {"sub","alice"},{"obj","data2"},{"act","write"} };
120+
TestEnforce(e, params, false);
121+
122+
params = { {"sub","bob"},{"obj","data1"},{"act","read"} };
123+
TestEnforce(e, params, false);
124+
125+
params = { {"sub","bob"},{"obj","data1"},{"act","write"} };
126+
TestEnforce(e, params, false);
127+
128+
params = { {"sub","bob"},{"obj","data2"},{"act","read"} };
129+
TestEnforce(e, params, false);
130+
131+
params = { {"sub","bob"},{"obj","data2"},{"act","write"} };
132+
TestEnforce(e, params, true);
133+
}
134+
};
135+
}

0 commit comments

Comments
 (0)