Skip to content

Commit

Permalink
Merge pull request #54 from ZipoChan/master
Browse files Browse the repository at this point in the history
feat: add enforce functions with convenient interface.
  • Loading branch information
divy9881 authored Jul 7, 2020
2 parents 8f4c866 + 96572fa commit d1840a0
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 2 deletions.
64 changes: 63 additions & 1 deletion casbin/enforcer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,10 +441,72 @@ void Enforcer :: BuildIncrementalRoleLinks(policy_op op, string p_type, vector<v

// Enforce decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
bool Enforcer :: Enforce(Scope scope) {
return this->enforce("", scope);
return this->EnforceWithMatcher("", scope);
}

// 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 EnforceWithMatcher("", 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 EnforceWithMatcher("", 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) {
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<string, string> 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);
}

// 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::EnforceWithMatcher(string matcher, string sub, string obj, string act) {
return this->EnforceWithMatcher(matcher, { 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::EnforceWithMatcher(string matcher, string sub, string dom, string obj, string act) {
return this->EnforceWithMatcher(matcher, { sub,dom,obj,act });
}

// 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<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(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, unordered_map<string, string> params) {
Scope scope = InitializeScope();
PushObject(scope, "r");

for (auto r : params) {
PushStringPropToObject(scope, "r", r.second, r.first);
}

return this->enforce(matcher, scope);
}
18 changes: 17 additions & 1 deletion casbin/enforcer.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,25 @@ 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 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);
// 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<string,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);

// Enforce with three params, decides whether a "subject" can access a "object" with the operation "action", input parameters are usually: (sub, obj, act).
bool EnforceWithMatcher(string matcher, 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 EnforceWithMatcher(string matcher, string sub, string dom, string obj, string act);
// 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<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, unordered_map<string, string> params);

/*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
135 changes: 135 additions & 0 deletions test/test_enforcer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#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, vector<string> params, bool res) {
Assert::AreEqual(res, e->Enforce(params));
}

void TestEnforce(Enforcer* e, unordered_map<string,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(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);
}

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

0 comments on commit d1840a0

Please sign in to comment.