Repository: casbin/casbin
Pull request #467 (2020-05-24 13:40:54)

fix: support domain for GetRolesForUser and GetUsersForRole


Patch:
diff --git a/enforcer_interface.go b/enforcer_interface.go
index 016f967..ecccf00 100644
--- a/enforcer_interface.go
+++ b/enforcer_interface.go
@@ -58,8 +58,8 @@ type IEnforcer interface {
 	EnforceExWithMatcher(matcher string, rvals ...interface{}) (bool, []string, error)
 
 	/* RBAC API */
-	GetRolesForUser(name string) ([]string, error)
-	GetUsersForRole(name string) ([]string, error)
+	GetRolesForUser(name string, domain ...string) ([]string, error)
+	GetUsersForRole(name string, domain ...string) ([]string, error)
 	HasRoleForUser(name string, role string) (bool, error)
 	AddRoleForUser(user string, role string) (bool, error)
 	AddPermissionForUser(user string, permission ...string) (bool, error)
diff --git a/rbac_api.go b/rbac_api.go
index 8e2d298..c222dd2 100644
--- a/rbac_api.go
+++ b/rbac_api.go
@@ -21,14 +21,14 @@ import (
 )
 
 // GetRolesForUser gets the roles that a user has.
-func (e *Enforcer) GetRolesForUser(name string) ([]string, error) {
-	res, err := e.model["g"]["g"].RM.GetRoles(name)
+func (e *Enforcer) GetRolesForUser(name string, domain ...string) ([]string, error) {
+	res, err := e.model["g"]["g"].RM.GetRoles(name, domain...)
 	return res, err
 }
 
 // GetUsersForRole gets the users that has a role.
-func (e *Enforcer) GetUsersForRole(name string) ([]string, error) {
-	res, err := e.model["g"]["g"].RM.GetUsers(name)
+func (e *Enforcer) GetUsersForRole(name string, domain ...string) ([]string, error) {
+	res, err := e.model["g"]["g"].RM.GetUsers(name, domain...)
 	return res, err
 }
 
@@ -58,17 +58,17 @@ func (e *Enforcer) AddRoleForUser(user string, role string) (bool, error) {
 // AddRolesForUser adds roles for a user.
 // Returns false if the user already has the roles (aka not affected).
 func (e *Enforcer) AddRolesForUser(user string, roles []string) (bool, error) {
-    f := false
-    for _, r := range roles {
-        b, err := e.AddGroupingPolicy(user, r)
-        if err != nil {
-            return false, err
-        }
-        if b {
-            f = true
-        }
-    }
-    return f, nil
+	f := false
+	for _, r := range roles {
+		b, err := e.AddGroupingPolicy(user, r)
+		if err != nil {
+			return false, err
+		}
+		if b {
+			f = true
+		}
+	}
+	return f, nil
 }
 
 // DeleteRoleForUser deletes a role for a user.


Test patch:
diff --git a/management_api_test.go b/management_api_test.go
index fad5d31..db945aa 100644
--- a/management_api_test.go
+++ b/management_api_test.go
@@ -193,10 +193,10 @@ func TestModifyPolicyAPI(t *testing.T) {
 func TestModifyGroupingPolicyAPI(t *testing.T) {
 	e, _ := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
 
-	testGetRoles(t, e, "alice", []string{"data2_admin"})
-	testGetRoles(t, e, "bob", []string{})
-	testGetRoles(t, e, "eve", []string{})
-	testGetRoles(t, e, "non_exist", []string{})
+	testGetRoles(t, e, []string{"data2_admin"}, "alice")
+	testGetRoles(t, e, []string{}, "bob")
+	testGetRoles(t, e, []string{}, "eve")
+	testGetRoles(t, e, []string{}, "non_exist")
 
 	e.RemoveGroupingPolicy("alice", "data2_admin")
 	e.AddGroupingPolicy("bob", "data1_admin")
@@ -208,41 +208,41 @@ func TestModifyGroupingPolicyAPI(t *testing.T) {
 	}
 
 	e.AddGroupingPolicies(groupingRules)
-	testGetRoles(t, e, "ham", []string{"data4_admin"})
-	testGetRoles(t, e, "jack", []string{"data5_admin"})
+	testGetRoles(t, e, []string{"data4_admin"}, "ham")
+	testGetRoles(t, e, []string{"data5_admin"}, "jack")
 	e.RemoveGroupingPolicies(groupingRules)
 
-	testGetRoles(t, e, "alice", []string{})
+	testGetRoles(t, e, []string{}, "alice")
 	namedGroupingPolicy := []string{"alice", "data2_admin"}
-	testGetRoles(t, e, "alice", []string{})
+	testGetRoles(t, e, []string{}, "alice")
 	e.AddNamedGroupingPolicy("g", namedGroupingPolicy)
-	testGetRoles(t, e, "alice", []string{"data2_admin"})
+	testGetRoles(t, e, []string{"data2_admin"}, "alice")
 	e.RemoveNamedGroupingPolicy("g", namedGroupingPolicy)
 
 	e.AddNamedGroupingPolicies("g", groupingRules)
 	e.AddNamedGroupingPolicies("g", groupingRules)
-	testGetRoles(t, e, "ham", []string{"data4_admin"})
-	testGetRoles(t, e, "jack", []string{"data5_admin"})
+	testGetRoles(t, e, []string{"data4_admin"}, "ham")
+	testGetRoles(t, e, []string{"data5_admin"}, "jack")
 	e.RemoveNamedGroupingPolicies("g", groupingRules)
 	e.RemoveNamedGroupingPolicies("g", groupingRules)
 
-	testGetRoles(t, e, "alice", []string{})
-	testGetRoles(t, e, "bob", []string{"data1_admin"})
-	testGetRoles(t, e, "eve", []string{"data3_admin"})
-	testGetRoles(t, e, "non_exist", []string{})
+	testGetRoles(t, e, []string{}, "alice")
+	testGetRoles(t, e, []string{"data1_admin"}, "bob")
+	testGetRoles(t, e, []string{"data3_admin"}, "eve")
+	testGetRoles(t, e, []string{}, "non_exist")
 
-	testGetUsers(t, e, "data1_admin", []string{"bob"})
-	testGetUsers(t, e, "data2_admin", []string{})
-	testGetUsers(t, e, "data3_admin", []string{"eve"})
+	testGetUsers(t, e, []string{"bob"}, "data1_admin")
+	testGetUsers(t, e, []string{}, "data2_admin")
+	testGetUsers(t, e, []string{"eve"}, "data3_admin")
 
 	e.RemoveFilteredGroupingPolicy(0, "bob")
 
-	testGetRoles(t, e, "alice", []string{})
-	testGetRoles(t, e, "bob", []string{})
-	testGetRoles(t, e, "eve", []string{"data3_admin"})
-	testGetRoles(t, e, "non_exist", []string{})
+	testGetRoles(t, e, []string{}, "alice")
+	testGetRoles(t, e, []string{}, "bob")
+	testGetRoles(t, e, []string{"data3_admin"}, "eve")
+	testGetRoles(t, e, []string{}, "non_exist")
 
-	testGetUsers(t, e, "data1_admin", []string{})
-	testGetUsers(t, e, "data2_admin", []string{})
-	testGetUsers(t, e, "data3_admin", []string{"eve"})
+	testGetUsers(t, e, []string{}, "data1_admin")
+	testGetUsers(t, e, []string{}, "data2_admin")
+	testGetUsers(t, e, []string{"eve"}, "data3_admin")
 }
diff --git a/rbac_api_test.go b/rbac_api_test.go
index 7bdc5f1..76c8577 100644
--- a/rbac_api_test.go
+++ b/rbac_api_test.go
@@ -23,9 +23,9 @@ import (
 	"github.com/casbin/casbin/v2/util"
 )
 
-func testGetRoles(t *testing.T, e *Enforcer, name string, res []string) {
+func testGetRoles(t *testing.T, e *Enforcer, res []string, name string, domain ...string) {
 	t.Helper()
-	myRes, err := e.GetRolesForUser(name)
+	myRes, err := e.GetRolesForUser(name, domain...)
 	if err != nil {
 		t.Error("Roles for ", name, " could not be fetched: ", err.Error())
 	}
@@ -36,9 +36,9 @@ func testGetRoles(t *testing.T, e *Enforcer, name string, res []string) {
 	}
 }
 
-func testGetUsers(t *testing.T, e *Enforcer, name string, res []string) {
+func testGetUsers(t *testing.T, e *Enforcer, res []string, name string, domain ...string) {
 	t.Helper()
-	myRes, err := e.GetUsersForRole(name)
+	myRes, err := e.GetUsersForRole(name, domain...)
 	switch err {
 	case nil:
 		break
@@ -70,38 +70,38 @@ func testHasRole(t *testing.T, e *Enforcer, name string, role string, res bool)
 func TestRoleAPI(t *testing.T) {
 	e, _ := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
 
-	testGetRoles(t, e, "alice", []string{"data2_admin"})
-	testGetRoles(t, e, "bob", []string{})
-	testGetRoles(t, e, "data2_admin", []string{})
-	testGetRoles(t, e, "non_exist", []string{})
+	testGetRoles(t, e, []string{"data2_admin"}, "alice")
+	testGetRoles(t, e, []string{}, "bob")
+	testGetRoles(t, e, []string{}, "data2_admin")
+	testGetRoles(t, e, []string{}, "non_exist")
 
 	testHasRole(t, e, "alice", "data1_admin", false)
 	testHasRole(t, e, "alice", "data2_admin", true)
 
 	e.AddRoleForUser("alice", "data1_admin")
 
-	testGetRoles(t, e, "alice", []string{"data1_admin", "data2_admin"})
-	testGetRoles(t, e, "bob", []string{})
-	testGetRoles(t, e, "data2_admin", []string{})
+	testGetRoles(t, e, []string{"data1_admin", "data2_admin"}, "alice")
+	testGetRoles(t, e, []string{}, "bob")
+	testGetRoles(t, e, []string{}, "data2_admin")
 
 	e.DeleteRoleForUser("alice", "data1_admin")
 
-	testGetRoles(t, e, "alice", []string{"data2_admin"})
-	testGetRoles(t, e, "bob", []string{})
-	testGetRoles(t, e, "data2_admin", []string{})
+	testGetRoles(t, e, []string{"data2_admin"}, "alice")
+	testGetRoles(t, e, []string{}, "bob")
+	testGetRoles(t, e, []string{}, "data2_admin")
 
 	e.DeleteRolesForUser("alice")
 
-	testGetRoles(t, e, "alice", []string{})
-	testGetRoles(t, e, "bob", []string{})
-	testGetRoles(t, e, "data2_admin", []string{})
+	testGetRoles(t, e, []string{}, "alice")
+	testGetRoles(t, e, []string{}, "bob")
+	testGetRoles(t, e, []string{}, "data2_admin")
 
 	e.AddRoleForUser("alice", "data1_admin")
 	e.DeleteUser("alice")
 
-	testGetRoles(t, e, "alice", []string{})
-	testGetRoles(t, e, "bob", []string{})
-	testGetRoles(t, e, "data2_admin", []string{})
+	testGetRoles(t, e, []string{}, "alice")
+	testGetRoles(t, e, []string{}, "bob")
+	testGetRoles(t, e, []string{}, "data2_admin")
 
 	e.AddRoleForUser("alice", "data2_admin")
 
@@ -130,7 +130,7 @@ func TestEnforcer_AddRolesForUser(t *testing.T) {
 	e, _ := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv")
 
 	e.AddRolesForUser("alice", []string{"data1_admin", "data2_admin", "data3_admin"})
-	testGetRoles(t, e, "alice", []string{"data1_admin", "data2_admin", "data3_admin"})
+	testGetRoles(t, e, []string{"data1_admin", "data2_admin", "data3_admin"}, "alice")
 	testEnforce(t, e, "alice", "data1", "read", true)
 	testEnforce(t, e, "alice", "data2", "read", true)
 	testEnforce(t, e, "alice", "data2", "write", true)
@@ -239,7 +239,7 @@ func TestImplicitRoleAPI(t *testing.T) {
 	}
 
 	testGetImplicitRoles(t, e, "cathy", []string{"/book/1/2/3/4/5", "pen_admin", "/book/*", "book_group"})
-	testGetRoles(t, e, "cathy", []string{"/book/1/2/3/4/5", "pen_admin"})
+	testGetRoles(t, e, []string{"/book/1/2/3/4/5", "pen_admin"}, "cathy")
 }
 
 func testGetImplicitPermissions(t *testing.T, e *Enforcer, name string, res [][]string) {
diff --git a/rbac_api_with_domains_test.go b/rbac_api_with_domains_test.go
index ad9642d..e4c10a1 100644
--- a/rbac_api_with_domains_test.go
+++ b/rbac_api_with_domains_test.go
@@ -55,46 +55,86 @@ func TestGetImplicitRolesForDomainUser(t *testing.T) {
 func TestUserAPIWithDomains(t *testing.T) {
 	e, _ := NewEnforcer("examples/rbac_with_domains_model.conf", "examples/rbac_with_domains_policy.csv")
 
+	testGetUsers(t, e, []string{"alice"}, "admin", "domain1")
 	testGetUsersInDomain(t, e, "admin", "domain1", []string{"alice"})
+
+	testGetUsers(t, e, []string{}, "non_exist", "domain1")
 	testGetUsersInDomain(t, e, "non_exist", "domain1", []string{})
 
+	testGetUsers(t, e, []string{"bob"}, "admin", "domain2")
 	testGetUsersInDomain(t, e, "admin", "domain2", []string{"bob"})
+
+	testGetUsers(t, e, []string{}, "non_exist", "domain2")
 	testGetUsersInDomain(t, e, "non_exist", "domain2", []string{})
 
 	e.DeleteRoleForUserInDomain("alice", "admin", "domain1")
 	e.AddRoleForUserInDomain("bob", "admin", "domain1")
 
+	testGetUsers(t, e, []string{"bob"}, "admin", "domain1")
 	testGetUsersInDomain(t, e, "admin", "domain1", []string{"bob"})
+
+	testGetUsers(t, e, []string{}, "non_exist", "domain1")
 	testGetUsersInDomain(t, e, "non_exist", "domain1", []string{})
 
+	testGetUsers(t, e, []string{"bob"}, "admin", "domain2")
 	testGetUsersInDomain(t, e, "admin", "domain2", []string{"bob"})
+
+	testGetUsers(t, e, []string{}, "non_exist", "domain2")
 	testGetUsersInDomain(t, e, "non_exist", "domain2", []string{})
 }
 
 func TestRoleAPIWithDomains(t *testing.T) {
 	e, _ := NewEnforcer("examples/rbac_with_domains_model.conf", "examples/rbac_with_domains_policy.csv")
 
+	testGetRoles(t, e, []string{"admin"}, "alice", "domain1")
 	testGetRolesInDomain(t, e, "alice", "domain1", []string{"admin"})
+
+	testGetRoles(t, e, []string{}, "bob", "domain1")
 	testGetRolesInDomain(t, e, "bob", "domain1", []string{})
+
+	testGetRoles(t, e, []string{}, "admin", "domain1")
 	testGetRolesInDomain(t, e, "admin", "domain1", []string{})
+
+	testGetRoles(t, e, []string{}, "non_exist", "domain1")
 	testGetRolesInDomain(t, e, "non_exist", "domain1", []string{})
 
+	testGetRoles(t, e, []string{}, "alice", "domain2")
 	testGetRolesInDomain(t, e, "alice", "domain2", []string{})
+
+	testGetRoles(t, e, []string{"admin"}, "bob", "domain2")
 	testGetRolesInDomain(t, e, "bob", "domain2", []string{"admin"})
+
+	testGetRoles(t, e, []string{}, "admin", "domain2")
 	testGetRolesInDomain(t, e, "admin", "domain2", []string{})
+
+	testGetRoles(t, e, []string{}, "non_exist", "domain2")
 	testGetRolesInDomain(t, e, "non_exist", "domain2", []string{})
 
 	e.DeleteRoleForUserInDomain("alice", "admin", "domain1")
 	e.AddRoleForUserInDomain("bob", "admin", "domain1")
 
+	testGetRoles(t, e, []string{}, "alice", "domain1")
 	testGetRolesInDomain(t, e, "alice", "domain1", []string{})
+
+	testGetRoles(t, e, []string{"admin"}, "bob", "domain1")
 	testGetRolesInDomain(t, e, "bob", "domain1", []string{"admin"})
+
+	testGetRoles(t, e, []string{}, "admin", "domain1")
 	testGetRolesInDomain(t, e, "admin", "domain1", []string{})
+
+	testGetRoles(t, e, []string{}, "non_exist", "domain1")
 	testGetRolesInDomain(t, e, "non_exist", "domain1", []string{})
 
+	testGetRoles(t, e, []string{}, "alice", "domain2")
 	testGetRolesInDomain(t, e, "alice", "domain2", []string{})
+
+	testGetRoles(t, e, []string{"admin"}, "bob", "domain2")
 	testGetRolesInDomain(t, e, "bob", "domain2", []string{"admin"})
+
+	testGetRoles(t, e, []string{}, "admin", "domain2")
 	testGetRolesInDomain(t, e, "admin", "domain2", []string{})
+
+	testGetRoles(t, e, []string{}, "non_exist", "domain2")
 	testGetRolesInDomain(t, e, "non_exist", "domain2", []string{})
 }