diff --git a/casbin/casbin.vcxproj b/casbin/casbin.vcxproj
index e9ee4d5f..ac39d519 100644
--- a/casbin/casbin.vcxproj
+++ b/casbin/casbin.vcxproj
@@ -198,7 +198,6 @@
-
@@ -281,7 +280,6 @@
-
diff --git a/casbin/casbin.vcxproj.filters b/casbin/casbin.vcxproj.filters
index c28bc8c8..65149081 100644
--- a/casbin/casbin.vcxproj.filters
+++ b/casbin/casbin.vcxproj.filters
@@ -216,9 +216,6 @@
Source Files\rbac
-
- Source Files\rbac
-
Source Files\persist\file_adapter
@@ -287,9 +284,6 @@
Header Files\rbac
-
- Header Files\rbac
-
Header Files\rbac
diff --git a/casbin/ip_parser/parser/IP.cpp b/casbin/ip_parser/parser/IP.cpp
index 76766485..800425fe 100644
--- a/casbin/ip_parser/parser/IP.cpp
+++ b/casbin/ip_parser/parser/IP.cpp
@@ -13,15 +13,19 @@ IP :: IP() {
}
IP IP :: Mask(IPMask mask) {
- IPMask mask_2(mask.begin(), mask.begin()+12);
- if(mask.size() == IPv6len && ip.size() == IPv4len && allFF(mask_2)) {
- IPMask mask_3(mask.begin() + 12, mask.end());
- mask = mask_3;
+ if (mask.size() == IPv6len && ip.size() == IPv4len) {
+ IPMask mask_2(mask.begin(), mask.begin() + 12);
+ if (allFF(mask_2)) {
+ IPMask mask_3(mask.begin() + 12, mask.end());
+ mask = mask_3;
+ }
}
- IPMask ip_2(ip.begin(), ip.begin() + 12);
- if(mask.size() == IPv4len && ip.size() == IPv6len && equal(ip_2, v4InV6Prefix)) {
- IPMask ip_3(ip.begin() + 12, ip.end());
- ip = ip_3;
+ if (mask.size() == IPv4len && ip.size() == IPv6len) {
+ IPMask ip_2(ip.begin(), ip.begin() + 12);
+ if (equal(ip_2, v4InV6Prefix)) {
+ IPMask ip_3(ip.begin() + 12, ip.end());
+ ip = ip_3;
+ }
}
unsigned int n = int(ip.size());
if(n != mask.size()) {
diff --git a/casbin/rbac.h b/casbin/rbac.h
index bf6c43b9..b8cbab3f 100644
--- a/casbin/rbac.h
+++ b/casbin/rbac.h
@@ -2,7 +2,6 @@
#define CASBIN_CPP_RBAC
#include "./rbac/default_role_manager.h"
-#include "./rbac/group_role_manager.h"
#include "./rbac/role_manager.h"
#endif
\ No newline at end of file
diff --git a/casbin/rbac/default_role_manager.cpp b/casbin/rbac/default_role_manager.cpp
index 5e48a809..e6c227e6 100644
--- a/casbin/rbac/default_role_manager.cpp
+++ b/casbin/rbac/default_role_manager.cpp
@@ -21,9 +21,9 @@ void Role :: AddRole(Role* role) {
}
void Role :: DeleteRole(Role* role) {
- for (vector :: iterator it = roles.begin() ; it != roles.end() ; it++) {
- if (!(*it)->name.compare(role->name)) {
- roles.erase(it);
+ for (int i = 0; i < roles.size();i++) {
+ if (!roles[i]->name.compare(role->name)) {
+ roles.erase(roles.begin()+i);
}
}
}
diff --git a/casbin/rbac/default_role_manager.h b/casbin/rbac/default_role_manager.h
index 82e74571..136335dd 100644
--- a/casbin/rbac/default_role_manager.h
+++ b/casbin/rbac/default_role_manager.h
@@ -69,28 +69,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);
+ void AddLink(string name1, string name2, vector domain = vector{});
/**
* 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);
+ void DeleteLink(string name1, string name2, vector domain = vector{});
/**
* hasLink determines whether role: name1 inherits role: name2.
* domain is a prefix to the roles.
*/
- bool HasLink(string name1, string name2, vector domain);
+ bool HasLink(string name1, string name2, vector domain = vector{});
/**
* getRoles gets the roles that a subject inherits.
* domain is a prefix to the roles.
*/
- vector GetRoles(string name, vector domain);
+ vector GetRoles(string name, vector domain = vector{});
- vector GetUsers(string name, vector domain);
+ vector GetUsers(string name, vector domain = vector{});
/**
* printRoles prints all the roles to log.
diff --git a/casbin/rbac/group_role_manager.cpp b/casbin/rbac/group_role_manager.cpp
deleted file mode 100644
index 74c44912..00000000
--- a/casbin/rbac/group_role_manager.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-#include "pch.h"
-
-#include "./group_role_manager.h"
-#include "../exception/casbin_rbac_exception.h"
-
-/**
- * GroupRoleManager is the constructor for creating an instance of the
- * GroupRoleManager implementation.
- *
- * @param max_hierarchy_level the maximized allowed RBAC hierarchy level.
- */
-GroupRoleManager* GroupRoleManager :: NewGroupRoleManager(int max_hierarchy_level){
- return (GroupRoleManager*)NewRoleManager(max_hierarchy_level);
-}
-
-/**
- * hasLink determines whether role: name1 inherits role: name2.
- * domain is a prefix to the roles.
- */
-bool GroupRoleManager :: HasLink(string name1, string name2, vector domain) {
- if (DefaultRoleManager :: HasLink(name1, name2, domain)) {
- return true;
- }
- unsigned int domain_length = sizeof(domain) / sizeof(domain[0]);
- // check name1's groups
- if (domain_length == 1) {
- try {
- vector domain1;
- vector groups = DefaultRoleManager :: GetRoles(name1, domain1);
- for (vector :: iterator group = groups.begin() ; group < groups.end() ; group++) {
- if (DefaultRoleManager :: HasLink(*group, name2, domain)) {
- return true;
- }
- }
- } catch (CasbinRBACException ignore) {
- return false;
- }
- }
- return false;
-}
\ No newline at end of file
diff --git a/casbin/rbac/group_role_manager.h b/casbin/rbac/group_role_manager.h
deleted file mode 100644
index c3e935d0..00000000
--- a/casbin/rbac/group_role_manager.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef CASBIN_CPP_RBAC_GROUP_ROLE_MANAGER
-#define CASBIN_CPP_RBAC_GROUP_ROLE_MANAGER
-
-#include "./default_role_manager.h"
-
-/**
- * GroupRoleManager is used for authorization if the user's group is the role who has permission,
- * but the group information is in the default format (policy start with "g") and the role information
- * is in named format (policy start with "g2", "g3", ...).
- * e.g.
- * p, admin, domain1, data1, read
- * g, alice, group1
- * g2, group1, admin, domain1
- *
- * As for the previous example, alice should have the permission to read data1, but if we use the
- * DefaultRoleManager, it will return false.
- * GroupRoleManager is to handle this situation.
- */
-class GroupRoleManager : public DefaultRoleManager {
- public:
- /**
- * GroupRoleManager is the constructor for creating an instance of the
- * GroupRoleManager implementation.
- *
- * @param max_hierarchy_level the maximized allowed RBAC hierarchy level.
- */
- static GroupRoleManager* NewGroupRoleManager(int max_hierarchy_level);
-
- /**
- * hasLink determines whether role: name1 inherits role: name2.
- * domain is a prefix to the roles.
- */
- bool HasLink(string name1, string name2, vector domain);
-};
-
-#endif
\ No newline at end of file
diff --git a/casbin/rbac/role_manager.h b/casbin/rbac/role_manager.h
index 0c90ccd7..2aa71d0e 100644
--- a/casbin/rbac/role_manager.h
+++ b/casbin/rbac/role_manager.h
@@ -6,65 +6,28 @@
using namespace std;
+// RoleManager provides interface to define the operations for managing roles.
class RoleManager {
public:
- /**
- * Clear clears all stored data and resets the role manager to the initial state.
- */
- virtual void Clear() = 0;
-
- /**
- * AddLink adds the inheritance link between two roles. role: name1 and role: name2.
- * domain is a prefix to the roles.
- *
- * @param name1 the first role (or user).
- * @param name2 the second role.
- * @param domain the domain the roles belong to.
- */
- virtual void AddLink(string name1, string name2, vector domain) = 0;
-
- /**
- * DeleteLink deletes the inheritance link between two roles. role: name1 and role: name2.
- * domain is a prefix to the roles.
- *
- * @param name1 the first role (or user).
- * @param name2 the second role.
- * @param domain the domain the roles belong to.
- */
- virtual void DeleteLink(string name1, string name2, vector domain) = 0;
-
- /**
- * hasLink determines whether a link exists between two roles. role: name1 inherits role: name2.
- * domain is a prefix to the roles.
- *
- * @param name1 the first role (or a user).
- * @param name2 the second role.
- * @param domain the domain the roles belong to.
- * @return whether name1 inherits name2 (name1 has role name2).
- */
- virtual bool HasLink(string name1, string name2, vector domain) = 0;
-
- /**
- * GetRoles gets the roles that a user inherits.
- * domain is a prefix to the roles.
- *
- * @param name the user (or a role).
- * @param domain the domain the roles belong to.
- * @return the roles.
- */
- virtual vector GetRoles(string name, vector domain) = 0;
-
- /**
- * GetUsers gets the users that inherits a role.
- * @param name the role.
- * @return the users.
- */
- virtual vector GetUsers(string name, vector domain) = 0;
-
- /**
- * PrintRoles prints all the roles to log.
- */
- virtual void PrintRoles() = 0;
+ // Clear clears all stored data and resets the role manager to the initial state.
+ virtual void Clear() = 0;
+ // AddLink adds the inheritance link between two roles. role: name1 and role: name2.
+ // domain is a prefix to the roles (can be used for other purposes).
+ virtual void AddLink(string name1, string name2, vector domain = vector{}) = 0;
+ // DeleteLink deletes the inheritance link between two roles. role: name1 and role: name2.
+ // domain is a prefix to the roles (can be used for other purposes).
+ virtual void DeleteLink(string name1, string name2, vector domain = vector{}) = 0;
+ // HasLink determines whether a link exists between two roles. role: name1 inherits role: name2.
+ // domain is a prefix to the roles (can be used for other purposes).
+ virtual bool HasLink(string name1, string name2, vector domain = vector{}) = 0;
+ // GetRoles gets the roles that a user inherits.
+ // domain is a prefix to the roles (can be used for other purposes).
+ virtual vector GetRoles(string name, vector domain = vector{}) = 0;
+ // GetUsers gets the users that inherits a role.
+ // domain is a prefix to the users (can be used for other purposes).
+ virtual vector GetUsers(string name, vector domain = vector{}) = 0;
+ // PrintRoles prints all the roles to log.
+ virtual void PrintRoles() = 0;
};
#endif
\ No newline at end of file
diff --git a/casbin/util/built_in_functions.cpp b/casbin/util/built_in_functions.cpp
index fe9edd2c..ffce2f5d 100644
--- a/casbin/util/built_in_functions.cpp
+++ b/casbin/util/built_in_functions.cpp
@@ -43,28 +43,47 @@ ReturnType KeyMatch2(Scope scope) {
string key1 = GetString(scope, 0);
string key2 = GetString(scope, 1);
- vector indexes = FindAllOccurences(key2, "/*");
- for (int i = 0 ; i < indexes.size() ; i++) {
- key1.replace(indexes[i], 2, "/.*");
- }
-
- regex regex_s("(.*):[^/]+(.*)");
- smatch match;
-
- while (true) {
+ vector key1_arr = Split(key1, "/");
+ vector key2_arr = Split(key2, "/");
- if (key2.find("/:") == string::npos)
+ bool res = true;
+ for(int i=0;i= key1_arr.size()){
+ res = false;
break;
-
- if (regex_search(key2, match, regex_s)) {
- for (int i=1; i indexes = FindAllOccurences(key2, "/*");
- for (int i = 0 ; i < indexes.size() ; i++)
- key1.replace(indexes[i], 2, "/.*");
-
- regex regex_s("(.*)\\{[^/]+\\}(.*)");
- smatch match;
+ vector key1_arr = Split(key1, "/");
+ vector key2_arr = Split(key2, "/");
- while (true) {
- if (key2.find("/{") == string::npos)
+ bool res = true;
+ for(int i=0;i= key1_arr.size()){
+ res = false;
break;
-
- if (regex_search(key2, match, regex_s)) {
- for (int i=1; i 0 && index3 != string::npos){
+ if(key1_arr[i]=="" || !key2_arr[i].substr(1, key2_arr[i].length()-2).compare("")){
+ res = false;
+ break;
+ }
+ else
+ continue;
+ }
+ res = false;
+ break;
+ }else
+ continue;
}
- regex regex_s1("^"+key2+"$");
- PushBooleanValue(scope, regex_match(key1, regex_s1));
+ if(key2_arr.size() < key1_arr.size())
+ if(key2_arr[key2_arr.size()-1] != "*")
+ res = false;
+
+ PushBooleanValue(scope, res);
return RETURN_RESULT;
}
@@ -114,13 +156,13 @@ ReturnType IPMatch(Scope scope) {
IP objIP1 = parseIP(ip1);
if (objIP1.isLegal == false)
- IllegalArgumentException("invalid argument: ip1 in IPMatch() function is not an IP address.");
+ throw IllegalArgumentException("invalid argument: ip1 in IPMatch() function is not an IP address.");
CIDR objCIDR = parseCIDR(ip2);
if (objCIDR.ip.isLegal == false) {
IP objIP2 = parseIP(ip2);
if (objIP2.isLegal == false)
- IllegalArgumentException("invalid argument: ip1 in IPMatch() function is not an IP address.");
+ throw IllegalArgumentException("invalid argument: ip1 in IPMatch() function is not an IP address.");
PushBooleanValue(scope, objIP1.Equal(objIP2));
return RETURN_RESULT;
diff --git a/test/test.vcxproj b/test/test.vcxproj
index d08f6b82..cd613c9b 100644
--- a/test/test.vcxproj
+++ b/test/test.vcxproj
@@ -165,8 +165,10 @@
Create
Create
+
+
diff --git a/test/test.vcxproj.filters b/test/test.vcxproj.filters
index 40e42832..01e9d08f 100644
--- a/test/test.vcxproj.filters
+++ b/test/test.vcxproj.filters
@@ -27,6 +27,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
diff --git a/test/test_built_in_functions.cpp b/test/test_built_in_functions.cpp
new file mode 100644
index 00000000..32ead58e
--- /dev/null
+++ b/test/test_built_in_functions.cpp
@@ -0,0 +1,160 @@
+#pragma once
+
+#include "pch.h"
+
+#include
+
+using namespace std;
+
+namespace test_built_in_functions
+{
+ TEST_CLASS(TestBuiltInFunctions)
+ {
+ public:
+ void TestKeyMatch(string key1, string key2, bool res) {
+ Scope scope = InitializeScope();
+ PushStringValue(scope, key1);
+ PushStringValue(scope, key2);
+
+ KeyMatch(scope);
+ bool my_res = GetBoolean(scope);
+
+ Assert::AreEqual(res, my_res);
+ }
+
+ TEST_METHOD(TestKeyMatch) {
+ TestKeyMatch("/foo", "/foo", true);
+ TestKeyMatch("/foo", "/foo*", true);
+ TestKeyMatch("/foo", "/foo/*", false);
+ TestKeyMatch("/foo/bar", "/foo", false);
+ TestKeyMatch("/foo/bar", "/foo*", true);
+ TestKeyMatch("/foo/bar", "/foo/*", true);
+ TestKeyMatch("/foobar", "/foo", false);
+ TestKeyMatch("/foobar", "/foo*", true);
+ TestKeyMatch("/foobar", "/foo/*", false);
+ }
+
+ void TestKeyMatch2(string key1, string key2, bool res) {
+ Scope scope = InitializeScope();
+ PushStringValue(scope, key1);
+ PushStringValue(scope, key2);
+
+ KeyMatch2(scope);
+ bool my_res = GetBoolean(scope);
+
+ Assert::AreEqual(res, my_res);
+ }
+
+ TEST_METHOD(TestKeyMatch2){
+ TestKeyMatch2("/foo", "/foo", true);
+ TestKeyMatch2("/foo", "/foo*", true);
+ TestKeyMatch2("/foo", "/foo/*", false);
+ TestKeyMatch2("/foo/bar", "/foo", false);
+ TestKeyMatch2("/foo/bar", "/foo*", false); // different with KeyMatch.
+ TestKeyMatch2("/foo/bar", "/foo/*", true);
+ TestKeyMatch2("/foobar", "/foo", false);
+ TestKeyMatch2("/foobar", "/foo*", false); // different with KeyMatch.
+ TestKeyMatch2("/foobar", "/foo/*", false);
+
+ TestKeyMatch2("/", "/:resource", false);
+ TestKeyMatch2("/resource1", "/:resource", true);
+ TestKeyMatch2("/myid", "/:id/using/:resId", false);
+ TestKeyMatch2("/myid/using/myresid", "/:id/using/:resId", true);
+
+ TestKeyMatch2("/proxy/myid", "/proxy/:id/*", false);
+ TestKeyMatch2("/proxy/myid/", "/proxy/:id/*", true);
+ TestKeyMatch2("/proxy/myid/res", "/proxy/:id/*", true);
+ TestKeyMatch2("/proxy/myid/res/res2", "/proxy/:id/*", true);
+ TestKeyMatch2("/proxy/myid/res/res2/res3", "/proxy/:id/*", true);
+ TestKeyMatch2("/proxy/", "/proxy/:id/*", false);
+
+ TestKeyMatch2("/alice", "/:id", true);
+ TestKeyMatch2("/alice/all", "/:id/all", true);
+ TestKeyMatch2("/alice", "/:id/all", false);
+ TestKeyMatch2("/alice/all", "/:id", false);
+
+ TestKeyMatch2("/alice/all", "/:/all", false);
+ }
+
+ void TestKeyMatch3(string key1, string key2, bool res) {
+ Scope scope = InitializeScope();
+ PushStringValue(scope, key1);
+ PushStringValue(scope, key2);
+
+ KeyMatch3(scope);
+ bool my_res = GetBoolean(scope);
+
+ Assert::AreEqual(res, my_res);
+ }
+
+ TEST_METHOD(TestKeyMatch3){
+ // keyMatch3() is similar with KeyMatch2(), except using "/proxy/{id}" instead of "/proxy/:id".
+ TestKeyMatch3("/foo", "/foo", true);
+ TestKeyMatch3("/foo", "/foo*", true);
+ TestKeyMatch3("/foo", "/foo/*", false);
+ TestKeyMatch3("/foo/bar", "/foo", false);
+ TestKeyMatch3("/foo/bar", "/foo*", false);
+ TestKeyMatch3("/foo/bar", "/foo/*", true);
+ TestKeyMatch3("/foobar", "/foo", false);
+ TestKeyMatch3("/foobar", "/foo*", false);
+ TestKeyMatch3("/foobar", "/foo/*", false);
+
+ TestKeyMatch3("/", "/{resource}", false);
+ TestKeyMatch3("/resource1", "/{resource}", true);
+ TestKeyMatch3("/myid", "/{id}/using/{resId}", false);
+ TestKeyMatch3("/myid/using/myresid", "/{id}/using/{resId}", true);
+
+ TestKeyMatch3("/proxy/myid", "/proxy/{id}/*", false);
+ TestKeyMatch3("/proxy/myid/", "/proxy/{id}/*", true);
+ TestKeyMatch3("/proxy/myid/res", "/proxy/{id}/*", true);
+ TestKeyMatch3("/proxy/myid/res/res2", "/proxy/{id}/*", true);
+ TestKeyMatch3("/proxy/myid/res/res2/res3", "/proxy/{id}/*", true);
+ TestKeyMatch3("/proxy/", "/proxy/{id}/*", false);
+
+ TestKeyMatch3("/myid/using/myresid", "/{id/using/{resId}", false);
+ }
+
+ void TestRegexMatch(string key1, string key2, bool res) {
+ Scope scope = InitializeScope();
+ PushStringValue(scope, key1);
+ PushStringValue(scope, key2);
+
+ RegexMatch(scope);
+ bool my_res = GetBoolean(scope);
+
+ Assert::AreEqual(res, my_res);
+ }
+
+ TEST_METHOD(TestRegexMatch) {
+ TestRegexMatch("/topic/create", "/topic/create", true);
+ TestRegexMatch("/topic/create/123", "/topic/create", false);
+ TestRegexMatch("/topic/delete", "/topic/create", false);
+ TestRegexMatch("/topic/edit", "/topic/edit/[0-9]+", false);
+ TestRegexMatch("/topic/edit/123", "/topic/edit/[0-9]+", true);
+ TestRegexMatch("/topic/edit/abc", "/topic/edit/[0-9]+", false);
+ TestRegexMatch("/foo/delete/123", "/topic/delete/[0-9]+", false);
+ TestRegexMatch("/topic/delete/0", "/topic/delete/[0-9]+", true);
+ TestRegexMatch("/topic/edit/123s", "/topic/delete/[0-9]+", false);
+ }
+
+ void TestIPMatch(string ip1, string ip2, bool res) {
+ Scope scope = InitializeScope();
+ PushStringValue(scope, ip1);
+ PushStringValue(scope, ip2);
+
+ IPMatch(scope);
+ bool my_res = GetBoolean(scope);
+
+ Assert::AreEqual(res, my_res);
+ }
+
+ TEST_METHOD(TestIPMatch) {
+ TestIPMatch("192.168.2.123", "192.168.2.0/24", true);
+ TestIPMatch("192.168.2.123", "192.168.3.0/24", false);
+ TestIPMatch("192.168.2.123", "192.168.2.0/16", true);
+ TestIPMatch("192.168.2.123", "192.168.2.123/32", true);
+ TestIPMatch("10.0.0.11", "10.0.0.0/8", true);
+ TestIPMatch("11.0.0.123", "10.0.0.0/8", false);
+ }
+ };
+}
\ No newline at end of file
diff --git a/test/test_config.cpp b/test/test_config.cpp
index 31b8dd49..3535dc52 100644
--- a/test/test_config.cpp
+++ b/test/test_config.cpp
@@ -25,7 +25,6 @@ namespace test_config
string filePath(string filepath) {
char* root = _getcwd(NULL, 0);
- Logger::WriteMessage(root);
string rootStr = string(root);
vector directories = Split(rootStr, "\\", -1);
diff --git a/test/test_role_manager.cpp b/test/test_role_manager.cpp
new file mode 100644
index 00000000..5dfafa5e
--- /dev/null
+++ b/test/test_role_manager.cpp
@@ -0,0 +1,183 @@
+#pragma once
+
+#include "pch.h"
+
+#include
+
+using namespace std;
+
+namespace test_role_manager
+{
+ TEST_CLASS(TestRoleManager)
+ {
+ public:
+ void TestRole(RoleManager* rm, string name1, string name2, bool res) {
+ bool my_res = rm->HasLink(name1, name2);
+
+ Assert::AreEqual(res, my_res);
+ }
+
+ void TestDomainRole(RoleManager* rm, string name1, string name2, vector domain, bool res) {
+ bool my_res = rm->HasLink(name1, name2, domain);
+
+ Assert::AreEqual(res, my_res);
+ }
+
+ TEST_METHOD(TestRole) {
+ RoleManager* rm = DefaultRoleManager :: NewRoleManager(3);
+ rm->AddLink("u1", "g1");
+ rm->AddLink("u2", "g1");
+ rm->AddLink("u3", "g2");
+ rm->AddLink("u4", "g2");
+ rm->AddLink("u4", "g3");
+ rm->AddLink("g1", "g3");
+
+ // Current role inheritance tree:
+ // g3 g2
+ // / \ / \
+ // g1 u4 u3
+ // / \
+ // u1 u2
+
+ TestRole(rm, "u1", "g1", true);
+ TestRole(rm, "u1", "g2", false);
+ TestRole(rm, "u1", "g3", true);
+ TestRole(rm, "u2", "g1", true);
+ TestRole(rm, "u2", "g2", false);
+ TestRole(rm, "u2", "g3", true);
+ TestRole(rm, "u3", "g1", false);
+ TestRole(rm, "u3", "g2", true);
+ TestRole(rm, "u3", "g3", false);
+ TestRole(rm, "u4", "g1", false);
+ TestRole(rm, "u4", "g2", true);
+ TestRole(rm, "u4", "g3", true);
+
+ rm->DeleteLink("g1", "g3");
+ rm->DeleteLink("u4", "g2");
+
+ // Current role inheritance tree after deleting the links:
+ // g3 g2
+ // \ \
+ // g1 u4 u3
+ // / \
+ // u1 u2
+
+ TestRole(rm, "u1", "g1", true);
+ TestRole(rm, "u1", "g2", false);
+ TestRole(rm, "u1", "g3", false);
+ TestRole(rm, "u2", "g1", true);
+ TestRole(rm, "u2", "g2", false);
+ TestRole(rm, "u2", "g3", false);
+ TestRole(rm, "u3", "g1", false);
+ TestRole(rm, "u3", "g2", true);
+ TestRole(rm, "u3", "g3", false);
+ TestRole(rm, "u4", "g1", false);
+ TestRole(rm, "u4", "g2", false);
+ TestRole(rm, "u4", "g3", true);
+ }
+
+ TEST_METHOD(TestDomainRole) {
+ RoleManager* rm = DefaultRoleManager :: NewRoleManager(3);
+ vector domain1{ "domain1" };
+ vector domain2{ "domain2" };
+ rm->AddLink("u1", "g1", domain1);
+ rm->AddLink("u2", "g1", domain1);
+ rm->AddLink("u3", "admin", domain2);
+ rm->AddLink("u4", "admin", domain2);
+ rm->AddLink("u4", "admin", domain1);
+ rm->AddLink("g1", "admin", domain1);
+
+ // Current role inheritance tree:
+ // domain1:admin domain2:admin
+ // / \ / \
+ // domain1:g1 u4 u3
+ // / \
+ // u1 u2
+
+ TestDomainRole(rm, "u1", "g1", domain1, true);
+ TestDomainRole(rm, "u1", "g1", domain2, false);
+ TestDomainRole(rm, "u1", "admin", domain1, true);
+ TestDomainRole(rm, "u1", "admin", domain2, false);
+
+ TestDomainRole(rm, "u2", "g1", domain1, true);
+ TestDomainRole(rm, "u2", "g1", domain2, false);
+ TestDomainRole(rm, "u2", "admin", domain1, true);
+ TestDomainRole(rm, "u2", "admin", domain2, false);
+
+ TestDomainRole(rm, "u3", "g1", domain1, false);
+ TestDomainRole(rm, "u3", "g1", domain2, false);
+ TestDomainRole(rm, "u3", "admin", domain1, false);
+ TestDomainRole(rm, "u3", "admin", domain2, true);
+
+ TestDomainRole(rm, "u4", "g1", domain1, false);
+ TestDomainRole(rm, "u4", "g1", domain2, false);
+ TestDomainRole(rm, "u4", "admin", domain1, true);
+ TestDomainRole(rm, "u4", "admin", domain2, true);
+
+ rm->DeleteLink("g1", "admin", domain1);
+ rm->DeleteLink("u4", "admin", domain2);
+
+ // Current role inheritance tree after deleting the links:
+ // domain1:admin domain2:admin
+ // \ \
+ // domain1:g1 u4 u3
+ // / \
+ // u1 u2
+
+ TestDomainRole(rm, "u1", "g1", domain1, true);
+ TestDomainRole(rm, "u1", "g1", domain2, false);
+ TestDomainRole(rm, "u1", "admin", domain1, false);
+ TestDomainRole(rm, "u1", "admin", domain2, false);
+
+ TestDomainRole(rm, "u2", "g1", domain1, true);
+ TestDomainRole(rm, "u2", "g1", domain2, false);
+ TestDomainRole(rm, "u2", "admin", domain1, false);
+ TestDomainRole(rm, "u2", "admin", domain2, false);
+
+ TestDomainRole(rm, "u3", "g1", domain1, false);
+ TestDomainRole(rm, "u3", "g1", domain2, false);
+ TestDomainRole(rm, "u3", "admin", domain1, false);
+ TestDomainRole(rm, "u3", "admin", domain2, true);
+
+ TestDomainRole(rm, "u4", "g1", domain1, false);
+ TestDomainRole(rm, "u4", "g1", domain2, false);
+ TestDomainRole(rm, "u4", "admin", domain1, true);
+ TestDomainRole(rm, "u4", "admin", domain2, false);
+ }
+
+ TEST_METHOD(TestClear) {
+ RoleManager* rm = DefaultRoleManager::NewRoleManager(3);
+ rm->AddLink("u1", "g1");
+ rm->AddLink("u2", "g1");
+ rm->AddLink("u3", "g2");
+ rm->AddLink("u4", "g2");
+ rm->AddLink("u4", "g3");
+ rm->AddLink("g1", "g3");
+
+ // Current role inheritance tree:
+ // g3 g2
+ // / \ / \
+ // g1 u4 u3
+ // / \
+ // u1 u2
+
+ rm->Clear();
+
+ // All data is cleared.
+ // No role inheritance now.
+
+ TestRole(rm, "u1", "g1", false);
+ TestRole(rm, "u1", "g2", false);
+ TestRole(rm, "u1", "g3", false);
+ TestRole(rm, "u2", "g1", false);
+ TestRole(rm, "u2", "g2", false);
+ TestRole(rm, "u2", "g3", false);
+ TestRole(rm, "u3", "g1", false);
+ TestRole(rm, "u3", "g2", false);
+ TestRole(rm, "u3", "g3", false);
+ TestRole(rm, "u4", "g1", false);
+ TestRole(rm, "u4", "g2", false);
+ TestRole(rm, "u4", "g3", false);
+ }
+ };
+}
\ No newline at end of file