nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: casbin/casbin
Pull request #194 (2019-01-11 19:57:22)

fix escapeAssertion bug
As already discussed here: #192 



Patch:
diff --git a/util/util.go b/util/util.go
index 4ce033d..2893eb4 100644
--- a/util/util.go
+++ b/util/util.go
@@ -15,14 +15,21 @@
 package util
 
 import (
+	"regexp"
 	"sort"
 	"strings"
 )
 
 // EscapeAssertion escapes the dots in the assertion, because the expression evaluation doesn't support such variable names.
 func EscapeAssertion(s string) string {
-	s = strings.Replace(s, "r.", "r_", -1)
-	s = strings.Replace(s, "p.", "p_", -1)
+	//Replace the first dot, because it can't be recognized by the regexp.
+	if (strings.HasPrefix(s, "r") || strings.HasPrefix(s, "p")) {
+		s = strings.Replace(s, ".", "_",1)
+	}
+	var regex = regexp.MustCompile(`(\|| |=|\)|\(|&|<|>|,|\+|-|!|\*|\/)(r|p)\.`)
+	s = regex.ReplaceAllStringFunc(s, func(m string) string {
+		return strings.Replace(m, ".", "_", 1)
+	})
 	return s
 }
 


Test patch:
diff --git a/util/util_test.go b/util/util_test.go
index 555a95e..9986f11 100644
--- a/util/util_test.go
+++ b/util/util_test.go
@@ -18,6 +18,32 @@ import (
 	"testing"
 )
 
+func testEscapeAssertion(t *testing.T, s string, res string) {
+	t.Helper()
+	myRes := EscapeAssertion(s)
+	t.Logf("%s: %s", s, myRes)
+
+	if myRes != res {
+		t.Errorf("%s: %s, supposed to be %s", s, myRes, res)
+	}
+}
+
+func TestEscapeAssertion(t *testing.T) {
+	testEscapeAssertion(t, "r.attr.value == p.attr", "r_attr.value == p_attr")
+	testEscapeAssertion(t, "r.attp.value || p.attr", "r_attp.value || p_attr")
+	testEscapeAssertion(t, "r.attp.value &&p.attr", "r_attp.value &&p_attr")
+	testEscapeAssertion(t, "r.attp.value >p.attr", "r_attp.value >p_attr")
+	testEscapeAssertion(t, "r.attp.value <p.attr", "r_attp.value <p_attr")
+	testEscapeAssertion(t, "r.attp.value +p.attr", "r_attp.value +p_attr")
+	testEscapeAssertion(t, "r.attp.value -p.attr", "r_attp.value -p_attr")
+	testEscapeAssertion(t, "r.attp.value *p.attr", "r_attp.value *p_attr")
+	testEscapeAssertion(t, "r.attp.value /p.attr", "r_attp.value /p_attr")
+	testEscapeAssertion(t, "!r.attp.value /p.attr", "!r_attp.value /p_attr")
+	testEscapeAssertion(t, "g(r.sub, p.sub) == p.attr", "g(r_sub, p_sub) == p_attr")
+	testEscapeAssertion(t, "g(r.sub,p.sub) == p.attr", "g(r_sub,p_sub) == p_attr")
+	testEscapeAssertion(t, "(r.attp.value || p.attr)p.u", "(r_attp.value || p_attr)p_u")
+}
+
 func testRemoveComments(t *testing.T, s string, res string) {
 	t.Helper()
 	myRes := RemoveComments(s)
Repository: casbin/casbin
Pull request #361 (2020-02-13 16:33:01)

Fix syntax errors on multiline config sentences
- The actual code strips the multiline char but sometimes
it leads to syntax errors because not compatible chars may
result appended.


Patch:
diff --git a/config/config.go b/config/config.go
index 5398edf..4a2a5c6 100644
--- a/config/config.go
+++ b/config/config.go
@@ -149,6 +149,7 @@ func (c *Config) parseBuffer(buf *bufio.Reader) error {
 			var p []byte
 			if bytes.HasSuffix(line, DEFAULT_MULTI_LINE_SEPARATOR) {
 				p = bytes.TrimSpace(line[:len(line)-1])
+				p = append(p, " "...)
 			} else {
 				p = line
 				canWrite = true


Test patch:
diff --git a/config/config_test.go b/config/config_test.go
index f0f3158..3e10c5c 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -63,15 +63,15 @@ func TestGet(t *testing.T) {
 
 	config.Set("other::key1", "test key")
 
-	if v := config.String("multi1::name"); v != "r.sub==p.sub&&r.obj==p.obj" {
+	if v := config.String("multi1::name"); v != "r.sub==p.sub && r.obj==p.obj" {
 		t.Errorf("Get failure: expected different value for multi1::name (expected: [%#v] got: [%#v])", "r.sub==p.sub&&r.obj==p.obj", v)
 	}
 
-	if v := config.String("multi2::name"); v != "r.sub==p.sub&&r.obj==p.obj" {
+	if v := config.String("multi2::name"); v != "r.sub==p.sub && r.obj==p.obj" {
 		t.Errorf("Get failure: expected different value for multi2::name (expected: [%#v] got: [%#v])", "r.sub==p.sub&&r.obj==p.obj", v)
 	}
 
-	if v := config.String("multi3::name"); v != "r.sub==p.sub&&r.obj==p.obj" {
+	if v := config.String("multi3::name"); v != "r.sub==p.sub && r.obj==p.obj" {
 		t.Errorf("Get failure: expected different value for multi3::name (expected: [%#v] got: [%#v])", "r.sub==p.sub&&r.obj==p.obj", v)
 	}
 
@@ -79,7 +79,7 @@ func TestGet(t *testing.T) {
 		t.Errorf("Get failure: expected different value for multi4::name (expected: [%#v] got: [%#v])", "", v)
 	}
 
-	if v := config.String("multi5::name"); v != "r.sub==p.sub&&r.obj==p.obj" {
+	if v := config.String("multi5::name"); v != "r.sub==p.sub && r.obj==p.obj" {
 		t.Errorf("Get failure: expected different value for multi5::name (expected: [%#v] got: [%#v])", "r.sub==p.sub&&r.obj==p.obj", v)
 	}
 }
diff --git a/config/testdata/testini.ini b/config/testdata/testini.ini
index 733e544..58946c2 100644
--- a/config/testdata/testini.ini
+++ b/config/testdata/testini.ini
@@ -26,15 +26,15 @@ math.f64 = 64.1
 # multi-line test
 [multi1]
 name = r.sub==p.sub \
-   &&r.obj==p.obj\
+   && r.obj==p.obj\
    \
 [multi2]
 name = r.sub==p.sub \
-   &&r.obj==p.obj
+   && r.obj==p.obj
 
 [multi3]
 name = r.sub==p.sub \
-   &&r.obj==p.obj
+   && r.obj==p.obj
 
 [multi4]
 name = \
@@ -43,5 +43,5 @@ name = \
 
 [multi5]
 name = r.sub==p.sub \
-   &&r.obj==p.obj\
-   \
\ No newline at end of file
+   && r.obj==p.obj\
+   \
Repository: casbin/casbin
Pull request #362 (2020-02-16 18:06:46)

Go idomatic stopping goroutine for auto load policy
Goroutine which is handling auto load policy is immediately exited after user requested to stop it, instead of sleeping.

After I commited, I realized maybe one issue?
StopAutoLoadPolicy will be blocking operation if there is no running auto load, can be solved again adding bool flag. But why user would want stop auto load policy if he didn't start it before.


Patch:
diff --git a/enforcer_synced.go b/enforcer_synced.go
index d2251cc..2c694de 100644
--- a/enforcer_synced.go
+++ b/enforcer_synced.go
@@ -26,8 +26,9 @@ import (
 // SyncedEnforcer wraps Enforcer and provides synchronized access
 type SyncedEnforcer struct {
 	*Enforcer
-	m        sync.RWMutex
-	autoLoad bool
+	m               sync.RWMutex
+	stopAutoLoad    chan struct{}
+	autoLoadRunning bool
 }
 
 // NewSyncedEnforcer creates a synchronized enforcer via file or DB.
@@ -39,35 +40,46 @@ func NewSyncedEnforcer(params ...interface{}) (*SyncedEnforcer, error) {
 		return nil, err
 	}
 
-	e.autoLoad = false
+	e.stopAutoLoad = make(chan struct{}, 1)
 	return e, nil
 }
 
 // StartAutoLoadPolicy starts a go routine that will every specified duration call LoadPolicy
 func (e *SyncedEnforcer) StartAutoLoadPolicy(d time.Duration) {
-	e.autoLoad = true
+	// Don't start another goroutine if there is already one running
+	if e.autoLoadRunning {
+		return
+	}
+	e.autoLoadRunning = true
+	ticker := time.NewTicker(d)
 	go func() {
+		defer func() {
+			ticker.Stop()
+			e.autoLoadRunning = false
+		}()
 		n := 1
 		log.Print("Start automatically load policy")
 		for {
-			if !e.autoLoad {
+			select {
+			case <-ticker.C:
+				// error intentionally ignored
+				_ = e.LoadPolicy()
+				// Uncomment this line to see when the policy is loaded.
+				// log.Print("Load policy for time: ", n)
+				n++
+			case <-e.stopAutoLoad:
 				log.Print("Stop automatically load policy")
-				break
+				return
 			}
-
-			// error intentionally ignored
-			e.LoadPolicy()
-			// Uncomment this line to see when the policy is loaded.
-			// log.Print("Load policy for time: ", n)
-			n++
-			time.Sleep(d)
 		}
 	}()
 }
 
 // StopAutoLoadPolicy causes the go routine to exit.
 func (e *SyncedEnforcer) StopAutoLoadPolicy() {
-	e.autoLoad = false
+	if e.autoLoadRunning {
+		e.stopAutoLoad <- struct{}{}
+	}
 }
 
 // SetWatcher sets the current watcher.


Test patch:
diff --git a/enforcer_synced_test.go b/enforcer_synced_test.go
index 19d18ec..16c07e9 100644
--- a/enforcer_synced_test.go
+++ b/enforcer_synced_test.go
@@ -43,3 +43,17 @@ func TestSync(t *testing.T) {
 	// Stop the reloading policy periodically.
 	e.StopAutoLoadPolicy()
 }
+
+func TestStopAutoLoadPolicy(t *testing.T) {
+	e, _ := NewSyncedEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
+	e.StartAutoLoadPolicy(5 * time.Millisecond)
+	if !e.autoLoadRunning {
+		t.Error("auto load is not running")
+	}
+	e.StopAutoLoadPolicy()
+	// Need a moment, to exit goroutine
+	time.Sleep(10 * time.Millisecond)
+	if e.autoLoadRunning {
+		t.Error("auto load is still running")
+	}
+}
Repository: casbin/casbin
Pull request #364 (2020-02-20 10:31:50)

fix(rbac_api.go): DeleteUser should remove Policies + Grouping Policies
Previously it just removed Grouping policies. Now it shares same implementation as DeleteRole
casbin/node-casbin#118


Patch:
diff --git a/rbac_api.go b/rbac_api.go
index 62071a8..2961f08 100644
--- a/rbac_api.go
+++ b/rbac_api.go
@@ -70,10 +70,18 @@ func (e *Enforcer) DeleteRolesForUser(user string) (bool, error) {
 // DeleteUser deletes a user.
 // Returns false if the user does not exist (aka not affected).
 func (e *Enforcer) DeleteUser(user string) (bool, error) {
-	return e.RemoveFilteredGroupingPolicy(0, user)
+	var err error
+	res1, err := e.RemoveFilteredGroupingPolicy(0, user)
+	if err != nil {
+		return res1, err
+	}
+
+	res2, err := e.RemoveFilteredPolicy(0, user)
+	return res1 || res2, err
 }
 
 // DeleteRole deletes a role.
+// Returns false if the role does not exist (aka not affected).
 func (e *Enforcer) DeleteRole(role string) (bool, error) {
 	var err error
 	res1, err := e.RemoveFilteredGroupingPolicy(1, role)


Test patch:
diff --git a/rbac_api_test.go b/rbac_api_test.go
index 67b915d..8b4d1ff 100644
--- a/rbac_api_test.go
+++ b/rbac_api_test.go
@@ -104,7 +104,7 @@ func TestRoleAPI(t *testing.T) {
 
 	e.AddRoleForUser("alice", "data2_admin")
 
-	testEnforce(t, e, "alice", "data1", "read", true)
+	testEnforce(t, e, "alice", "data1", "read", false)
 	testEnforce(t, e, "alice", "data1", "write", false)
 	testEnforce(t, e, "alice", "data2", "read", true)
 	testEnforce(t, e, "alice", "data2", "write", true)
@@ -115,7 +115,7 @@ func TestRoleAPI(t *testing.T) {
 
 	e.DeleteRole("data2_admin")
 
-	testEnforce(t, e, "alice", "data1", "read", true)
+	testEnforce(t, e, "alice", "data1", "read", false)
 	testEnforce(t, e, "alice", "data1", "write", false)
 	testEnforce(t, e, "alice", "data2", "read", false)
 	testEnforce(t, e, "alice", "data2", "write", false)
Repository: casbin/casbin
Pull request #443 (2020-04-30 05:58:29)

Fix GetImplicitUsersForPermission
Fix: https://github.com/casbin/casbin/issues/442


Patch:
diff --git a/rbac_api.go b/rbac_api.go
index 2961f08..cdbfb23 100644
--- a/rbac_api.go
+++ b/rbac_api.go
@@ -210,13 +210,15 @@ func (e *Enforcer) GetImplicitPermissionsForUser(user string, domain ...string)
 // GetImplicitUsersForPermission("data1", "read") will get: ["alice", "bob"].
 // Note: only users will be returned, roles (2nd arg in "g") will be excluded.
 func (e *Enforcer) GetImplicitUsersForPermission(permission ...string) ([]string, error) {
-	subjects := e.GetAllSubjects()
-	roles := e.GetAllRoles()
+	pSubjects := e.GetAllSubjects()
+	gInherit := e.model.GetValuesForFieldInPolicyAllTypes("g", 1)
+	gSubjects := e.model.GetValuesForFieldInPolicyAllTypes("g", 0)
 
-	users := util.SetSubtract(subjects, roles)
+	subjects := append(pSubjects, gSubjects...)
+	util.ArrayRemoveDuplicates(&subjects)
 
 	res := []string{}
-	for _, user := range users {
+	for _, user := range subjects {
 		req := util.JoinSliceAny(user, permission...)
 		allowed, err := e.Enforce(req...)
 		if err != nil {
@@ -228,5 +230,7 @@ func (e *Enforcer) GetImplicitUsersForPermission(permission ...string) ([]string
 		}
 	}
 
+	res = util.SetSubtract(res, gInherit)
+
 	return res, nil
 }


Test patch:
diff --git a/rbac_api_test.go b/rbac_api_test.go
index 8b4d1ff..48ec8cc 100644
--- a/rbac_api_test.go
+++ b/rbac_api_test.go
@@ -16,6 +16,7 @@ package casbin
 
 import (
 	defaultrolemanager "github.com/casbin/casbin/v2/rbac/default-role-manager"
+	"sort"
 	"testing"
 
 	"github.com/casbin/casbin/v2/errors"
@@ -271,6 +272,9 @@ func testGetImplicitUsers(t *testing.T, e *Enforcer, res []string, permission ..
 	myRes, _ := e.GetImplicitUsersForPermission(permission...)
 	t.Log("Implicit users for permission: ", permission, ": ", myRes)
 
+	sort.Strings(res)
+	sort.Strings(myRes)
+
 	if !util.ArrayEquals(res, myRes) {
 		t.Error("Implicit users for permission: ", permission, ": ", myRes, ", supposed to be ", res)
 	}
@@ -283,4 +287,10 @@ func TestImplicitUserAPI(t *testing.T) {
 	testGetImplicitUsers(t, e, []string{"alice"}, "data1", "write")
 	testGetImplicitUsers(t, e, []string{"alice"}, "data2", "read")
 	testGetImplicitUsers(t, e, []string{"alice", "bob"}, "data2", "write")
+
+	e.ClearPolicy()
+	e.AddPolicy("admin", "data1", "read")
+	e.AddPolicy("bob", "data1", "read")
+	e.AddGroupingPolicy("alice", "admin")
+	testGetImplicitUsers(t, e, []string{"alice", "bob"}, "data1", "read")
 }
Repository: casbin/casbin
Pull request #454 (2020-05-10 12:17:28)

feat: add AddRolesForUser
add AddRolesForUser

coveralls: 
[![Coverage Status](https://coveralls.io/builds/30681339/badge)](https://coveralls.io/builds/30681339)

Coverage decreased (-0.3%) to 73.658% when pulling **e8e800f555ed2086b30ee9078d6a091e251e03b8 on gadelkareem:master** into **70601688b8f11a66c5c507bff5bba9fd0d0b8f45 on casbin:master**.

nodece: @gadelkareem Please add test cases and fix CI error.
hsluoyz: @gadelkareem fix Semantic Pull Request
gadelkareem: @hsluoyz title and commit added. Not sure why it is not fixed yet.
hsluoyz: Replace your previous commits.

Patch:
diff --git a/rbac_api.go b/rbac_api.go
index cdbfb23..8e2d298 100644
--- a/rbac_api.go
+++ b/rbac_api.go
@@ -55,6 +55,22 @@ func (e *Enforcer) AddRoleForUser(user string, role string) (bool, error) {
 	return e.AddGroupingPolicy(user, role)
 }
 
+// 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
+}
+
 // DeleteRoleForUser deletes a role for a user.
 // Returns false if the user does not have the role (aka not affected).
 func (e *Enforcer) DeleteRoleForUser(user string, role string) (bool, error) {


Test patch:
diff --git a/rbac_api_test.go b/rbac_api_test.go
index 48ec8cc..7bdc5f1 100644
--- a/rbac_api_test.go
+++ b/rbac_api_test.go
@@ -126,6 +126,16 @@ func TestRoleAPI(t *testing.T) {
 	testEnforce(t, e, "bob", "data2", "write", true)
 }
 
+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"})
+	testEnforce(t, e, "alice", "data1", "read", true)
+	testEnforce(t, e, "alice", "data2", "read", true)
+	testEnforce(t, e, "alice", "data2", "write", true)
+}
+
 func testGetPermissions(t *testing.T, e *Enforcer, name string, res [][]string) {
 	t.Helper()
 	myRes := e.GetPermissionsForUser(name)
Repository: casbin/casbin
Pull request #526 (2020-07-15 13:34:17)

fix: duplicated policies inside rules to add
Signed-off-by: Cheng JIANG <jiang.cheng@vip.163.com>

close: #517 

coveralls: 
[![Coverage Status](https://coveralls.io/builds/32084544/badge)](https://coveralls.io/builds/32084544)

Coverage increased (+0.07%) to 74.496% when pulling **a14ef52ef4d2d7ac70614001775a44b3a7136652 on GopherJ:fix-dup** into **b2d6dacf6bbaf7d59dc4d13a067baeaf5e6aaf92 on casbin:master**.


Patch:
diff --git a/model/policy.go b/model/policy.go
index fe5c10a..7f8caaa 100644
--- a/model/policy.go
+++ b/model/policy.go
@@ -31,7 +31,7 @@ const (
 	PolicyRemove
 )
 
-var DefaultSep = ","
+const DefaultSep = ","
 
 // BuildIncrementalRoleLinks provides incremental build the role inheritance relations.
 func (model Model) BuildIncrementalRoleLinks(rm rbac.RoleManager, op PolicyOp, sec string, ptype string, rules [][]string) error {
@@ -130,8 +130,13 @@ func (model Model) AddPolicy(sec string, ptype string, rule []string) {
 // AddPolicies adds policy rules to the model.
 func (model Model) AddPolicies(sec string, ptype string, rules [][]string) {
 	for _, rule := range rules {
+		hashKey := strings.Join(rule, DefaultSep)
+		_, ok := model[sec][ptype].PolicyMap[hashKey]
+		if ok {
+			continue
+		}
 		model[sec][ptype].Policy = append(model[sec][ptype].Policy, rule)
-		model[sec][ptype].PolicyMap[strings.Join(rule, DefaultSep)] = len(model[sec][ptype].Policy) - 1
+		model[sec][ptype].PolicyMap[hashKey] = len(model[sec][ptype].Policy) - 1
 	}
 }
 
@@ -187,7 +192,7 @@ func (model Model) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int
 			if firstIndex == -1 {
 				firstIndex = index
 			}
-			delete(model[sec][ptype].PolicyMap, strings.Join(rule, ","))
+			delete(model[sec][ptype].PolicyMap, strings.Join(rule, DefaultSep))
 			effects = append(effects, rule)
 			res = true
 		} else {
diff --git a/util/util.go b/util/util.go
index 7e48ff1..f625c1b 100644
--- a/util/util.go
+++ b/util/util.go
@@ -20,7 +20,7 @@ import (
 	"strings"
 )
 
-var evalReg *regexp.Regexp = regexp.MustCompile(`\beval\((?P<rule>[^),]*)\)`)
+var evalReg *regexp.Regexp = regexp.MustCompile(`\beval\((?P<rule>[^)]*)\)`)
 
 // EscapeAssertion escapes the dots in the assertion, because the expression evaluation doesn't support such variable names.
 func EscapeAssertion(s string) string {


Test patch:
diff --git a/management_api_test.go b/management_api_test.go
index db945aa..9e11c7b 100644
--- a/management_api_test.go
+++ b/management_api_test.go
@@ -155,9 +155,13 @@ func TestModifyPolicyAPI(t *testing.T) {
 	e.AddPolicy("eve", "data3", "read")
 
 	rules := [][]string{
+		{"jack", "data4", "read"},
+		{"jack", "data4", "read"},
 		{"jack", "data4", "read"},
 		{"katy", "data4", "write"},
 		{"leyo", "data4", "read"},
+		{"katy", "data4", "write"},
+		{"katy", "data4", "write"},
 		{"ham", "data4", "write"},
 	}
Repository: casbin/casbin
Pull request #594 (2020-09-09 11:08:00)

fix: modify IsAutoLoadingRunning function name

nodece: @c1dx please fix the enforcer_interface.
c1dx: > @c1dx please fix the enforcer_interface.

IsAutoLoadingRunning not the method of IEnforcer interface

Patch:
diff --git a/enforcer_synced.go b/enforcer_synced.go
index 2bed382..52f03f9 100644
--- a/enforcer_synced.go
+++ b/enforcer_synced.go
@@ -46,15 +46,15 @@ func NewSyncedEnforcer(params ...interface{}) (*SyncedEnforcer, error) {
 	return e, nil
 }
 
-// IsAudoLoadingRunning check if SyncedEnforcer is auto loading policies
-func (e *SyncedEnforcer) IsAudoLoadingRunning() bool {
+// IsAutoLoadingRunning check if SyncedEnforcer is auto loading policies
+func (e *SyncedEnforcer) IsAutoLoadingRunning() bool {
 	return atomic.LoadInt32(&(e.autoLoadRunning)) != 0
 }
 
 // StartAutoLoadPolicy starts a go routine that will every specified duration call LoadPolicy
 func (e *SyncedEnforcer) StartAutoLoadPolicy(d time.Duration) {
 	// Don't start another goroutine if there is already one running
-	if e.IsAudoLoadingRunning() {
+	if e.IsAutoLoadingRunning() {
 		return
 	}
 	atomic.StoreInt32(&(e.autoLoadRunning), int32(1))
@@ -84,7 +84,7 @@ func (e *SyncedEnforcer) StartAutoLoadPolicy(d time.Duration) {
 
 // StopAutoLoadPolicy causes the go routine to exit.
 func (e *SyncedEnforcer) StopAutoLoadPolicy() {
-	if e.IsAudoLoadingRunning() {
+	if e.IsAutoLoadingRunning() {
 		e.stopAutoLoad <- struct{}{}
 	}
 }


Test patch:
diff --git a/enforcer_synced_test.go b/enforcer_synced_test.go
index 14ccb13..4377869 100644
--- a/enforcer_synced_test.go
+++ b/enforcer_synced_test.go
@@ -47,13 +47,13 @@ func TestSync(t *testing.T) {
 func TestStopAutoLoadPolicy(t *testing.T) {
 	e, _ := NewSyncedEnforcer("examples/basic_model.conf", "examples/basic_policy.csv")
 	e.StartAutoLoadPolicy(5 * time.Millisecond)
-	if !e.IsAudoLoadingRunning() {
+	if !e.IsAutoLoadingRunning() {
 		t.Error("auto load is not running")
 	}
 	e.StopAutoLoadPolicy()
 	// Need a moment, to exit goroutine
 	time.Sleep(10 * time.Millisecond)
-	if e.IsAudoLoadingRunning() {
+	if e.IsAutoLoadingRunning() {
 		t.Error("auto load is still running")
 	}
 }
Repository: casbin/casbin
Pull request #736 (2021-03-12 11:26:32)

fix: Unable to add domain matching func
This branch fixes casbin/casbin#735

The problem in the code was that the `defaultrolemanager.NewRoleManager` constructor method signature defines a `rbac.RoleManager` instead of a `*RoleManager`.

As side effect, this also involved the import of `rbac`, which is of no use in the `defaultrolemanager` package.

The important aspect to take care of, in fact, is that `defaultrolemanager.RoleManager` adheres to the `rbac.RoleManager`.
This is granted by the language itself.

This modification allows to avoid the type casting.


Patch:
diff --git a/rbac/default-role-manager/role_manager.go b/rbac/default-role-manager/role_manager.go
index 8fe7150..9fc4eed 100644
--- a/rbac/default-role-manager/role_manager.go
+++ b/rbac/default-role-manager/role_manager.go
@@ -21,7 +21,6 @@ import (
 
 	"github.com/casbin/casbin/v2/errors"
 	"github.com/casbin/casbin/v2/log"
-	"github.com/casbin/casbin/v2/rbac"
 	"github.com/casbin/casbin/v2/util"
 )
 
@@ -45,7 +44,7 @@ type RoleManager struct {
 
 // NewRoleManager is the constructor for creating an instance of the
 // default RoleManager implementation.
-func NewRoleManager(maxHierarchyLevel int) rbac.RoleManager {
+func NewRoleManager(maxHierarchyLevel int) *RoleManager {
 	rm := RoleManager{}
 	rm.roles = &Roles{sync.Map{}}
 	rm.domains = make(map[string]struct{})


Test patch:
diff --git a/rbac/default-role-manager/role_manager_test.go b/rbac/default-role-manager/role_manager_test.go
index 8dd4bea..b290bc6 100644
--- a/rbac/default-role-manager/role_manager_test.go
+++ b/rbac/default-role-manager/role_manager_test.go
@@ -233,7 +233,7 @@ func TestClear(t *testing.T) {
 
 func TestDomainPatternRole(t *testing.T) {
 	rm := NewRoleManager(10)
-	rm.(*RoleManager).AddDomainMatchingFunc("keyMatch2", util.KeyMatch2)
+	rm.AddDomainMatchingFunc("keyMatch2", util.KeyMatch2)
 
 	_ = rm.AddLink("u1", "g1", "domain1")
 	_ = rm.AddLink("u2", "g1", "domain2")
@@ -263,8 +263,8 @@ func TestDomainPatternRole(t *testing.T) {
 
 func TestAllMatchingFunc(t *testing.T) {
 	rm := NewRoleManager(10)
-	rm.(*RoleManager).AddMatchingFunc("keyMatch2", util.KeyMatch2)
-	rm.(*RoleManager).AddDomainMatchingFunc("keyMatch2", util.KeyMatch2)
+	rm.AddMatchingFunc("keyMatch2", util.KeyMatch2)
+	rm.AddDomainMatchingFunc("keyMatch2", util.KeyMatch2)
 
 	_ = rm.AddLink("/book/:id", "book_group", "*")
 	// Current role inheritance tree after deleting the links:
@@ -277,7 +277,7 @@ func TestAllMatchingFunc(t *testing.T) {
 
 func TestMatchingFuncOrder(t *testing.T) {
 	rm := NewRoleManager(10)
-	rm.(*RoleManager).AddMatchingFunc("regexMatch", util.RegexMatch)
+	rm.AddMatchingFunc("regexMatch", util.RegexMatch)
 
 	_ = rm.AddLink("g\\d+", "root")
 	_ = rm.AddLink("u1", "g1")