Skip to content

Commit

Permalink
feat: add enforce functions with convenient interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
ZipoChan committed Jul 6, 2020
1 parent 8f4c866 commit 346af07
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 1 deletion.
34 changes: 34 additions & 0 deletions casbin/enforcer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,40 @@ bool Enforcer :: Enforce(Scope scope) {
return this->enforce("", 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 });
}

// Enforce with three params, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
bool Enforcer::Enforce(string sub, string obj, string act) {
return Enforce({sub,obj,act});
}

// 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 Enforcer::Enforce(string sub, string dom, string obj, string act) {
return Enforce({ sub,dom,obj,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<string> params) {
vector <string> r_tokens = this->model->m["r"].assertion_map["r"]->tokens;

int r_cnt = r_tokens.size();
int cnt = params.size();

if (cnt != r_cnt)
return false;

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));
}

return this->enforce("", 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) {
return this->enforce(matcher, scope);
Expand Down
10 changes: 9 additions & 1 deletion casbin/enforcer.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,17 @@ class Enforcer : public IEnforcer{
void BuildIncrementalRoleLinks(policy_op op, string p_type, vector<vector<string>> rules);
// Enforce decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
bool Enforce(Scope scope);
// Enforce with two params, decides whether a "subject" can do the operation "action", input parameters are usually: (sub, act).
bool Enforce(string sub, string act);
// Enforce with three params, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
bool Enforce(string sub, string obj, string act);
// 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<string> 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);

/*Management API member functions.*/
vector<string> GetAllSubjects();
vector<string> GetAllNamedSubjects(string ptype);
Expand Down
1 change: 1 addition & 0 deletions test/test.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
</ClCompile>
<ClCompile Include="test_built_in_functions.cpp" />
<ClCompile Include="test_config.cpp" />
<ClCompile Include="test_enforcer.cpp" />
<ClCompile Include="test_model.cpp" />
<ClCompile Include="test_model_enforcer.cpp" />
<ClCompile Include="test_role_manager.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions test/test.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
<ClCompile Include="test_model_enforcer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="test_enforcer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
Expand Down
116 changes: 116 additions & 0 deletions test/test_enforcer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#pragma once

#include "pch.h"

#include <direct.h>
#include <algorithm>

#include <enforcer.h>
#include <persist.h>
#include <rbac.h>
#include <util.h>

using namespace std;

namespace test_enforcer
{
TEST_CLASS(TestEnforcer)
{
public:

string filePath(string filepath) {
char* root = _getcwd(NULL, 0);
string rootStr = string(root);

vector <string> directories = Split(rootStr, "\\", -1);
vector<string>::iterator it = find(directories.begin(), directories.end(), "x64");
vector <string> left{ *(it - 1) };
it = find_end(directories.begin(), directories.end(), left.begin(), left.end());
int index = int(directories.size() + (it - directories.end()));

vector <string> finalDirectories(directories.begin(), directories.begin() + index + 1);

vector<string> 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));
}

void TestEnforce(Enforcer* e, string sub, string obj, string act, bool res) {
Assert::AreEqual(res, e->Enforce(sub, obj, act));
}

void TestEnforce(Enforcer* e, string sub, string act, bool res) {
Assert::AreEqual(res, e->Enforce(sub, act));
}

void TestEnforce(Enforcer* e, vector<string> params, bool res) {
Assert::AreEqual(res, e->Enforce(params));
}


TEST_METHOD(TestFourParams) {
string model = filePath("../examples/rbac_with_domains_model.conf");
string policy = filePath("../examples/rbac_with_domains_policy.csv");
Enforcer* e = Enforcer::NewEnforcer(model, policy);

TestEnforce(e, "alice", "domain1", "data1", "read", true);
TestEnforce(e, "alice", "domain1", "data1", "write", true);
TestEnforce(e, "alice", "domain1", "data2", "read", false);
TestEnforce(e, "alice", "domain1", "data2", "write", false);
TestEnforce(e, "bob", "domain2", "data1", "read", false);
TestEnforce(e, "bob", "domain2", "data1", "write", false);
TestEnforce(e, "bob", "domain2", "data2", "read", true);
TestEnforce(e, "bob", "domain2", "data2", "write", true);
}

TEST_METHOD(TestThreeParams) {
string model = filePath("../examples/basic_model_without_spaces.conf");
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);
}

TEST_METHOD(TestTwoParams) {
string model = filePath("../examples/basic_without_users_model.conf");
string policy = filePath("../examples/basic_without_users_policy.csv");
Enforcer* e = Enforcer::NewEnforcer(model, policy);

TestEnforce(e, "data1", "read", true);
TestEnforce(e, "data1", "write", false);
TestEnforce(e, "data2", "read", false);
TestEnforce(e, "data2", "write", true);
}

TEST_METHOD(TestVectorParams) {
string model = filePath("../examples/basic_model_without_spaces.conf");
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);
}
};
}

0 comments on commit 346af07

Please sign in to comment.