Repository: casbin/casbin (go)

Issue:
Problems in role inheritance
I have a problem with role inheritance.
policy like this:
```
p	g1_root	/server/*
g	chen	g1_root
g	shen	g1_root
p	g0_base	/u/info
g	g1_*	 g0_base
g	chen	g1_like_video
```
when chen login in,his roles is:g1_root g1_* g0_base
but what I except is:g1_root g1_likee_video g0_base

Pull request description:
Fix #329

Patch:
diff --git a/examples/rbac_with_pattern_policy.csv b/examples/rbac_with_pattern_policy.csv
index eff87b6..a8c06c7 100644
--- a/examples/rbac_with_pattern_policy.csv
+++ b/examples/rbac_with_pattern_policy.csv
@@ -5,6 +5,11 @@ p, pen_admin, pen_group, GET
 
 g, alice, book_admin
 g, bob, pen_admin
+
+g, /book/*, book_group
+g, cathy, /book/1/2/3/4/5
+g, cathy, pen_admin
+
 g2, /book/:id, book_group
 g2, /pen/:id, pen_group
 
diff --git a/rbac/default-role-manager/role_manager.go b/rbac/default-role-manager/role_manager.go
index 7a67a9d..e203e90 100644
--- a/rbac/default-role-manager/role_manager.go
+++ b/rbac/default-role-manager/role_manager.go
@@ -44,6 +44,9 @@ func NewRoleManager(maxHierarchyLevel int) rbac.RoleManager {
 	return &rm
 }
 
+// e.BuildRoleLinks must be called after AddMatchingFunc().
+//
+// example: e.GetRoleManager().(*defaultrolemanager.RoleManager).AddMatchingFunc('matcher', util.KeyMatch)
 func (rm *RoleManager) AddMatchingFunc(name string, fn MatchingFunc) {
 	rm.hasPattern = true
 	rm.matchingFunc = fn
@@ -66,15 +69,19 @@ func (rm *RoleManager) hasRole(name string) bool {
 }
 
 func (rm *RoleManager) createRole(name string) *Role {
+	role, _ := rm.allRoles.LoadOrStore(name, newRole(name))
+
 	if rm.hasPattern {
 		rm.allRoles.Range(func(key, value interface{}) bool {
-			if rm.matchingFunc(name, key.(string)) {
-				name = key.(string)
+			if rm.matchingFunc(name, key.(string)) && name!=key.(string) {
+				// Add new role to matching role
+				role1, _ := rm.allRoles.LoadOrStore(key.(string), newRole(key.(string)))
+				role.(*Role).addRole(role1.(*Role))
 			}
 			return true
 		})
 	}
-	role, _ := rm.allRoles.LoadOrStore(name, newRole(name))
+
 	return role.(*Role)
 }
 


Test patch:
diff --git a/rbac_api_test.go b/rbac_api_test.go
index 732a439..67b915d 100644
--- a/rbac_api_test.go
+++ b/rbac_api_test.go
@@ -15,6 +15,7 @@
 package casbin
 
 import (
+	defaultrolemanager "github.com/casbin/casbin/v2/rbac/default-role-manager"
 	"testing"
 
 	"github.com/casbin/casbin/v2/errors"
@@ -217,6 +218,17 @@ func TestImplicitRoleAPI(t *testing.T) {
 
 	testGetImplicitRoles(t, e, "alice", []string{"admin", "data1_admin", "data2_admin"})
 	testGetImplicitRoles(t, e, "bob", []string{})
+
+	e, _ = NewEnforcer("examples/rbac_with_pattern_model.conf", "examples/rbac_with_pattern_policy.csv")
+
+	e.GetRoleManager().(*defaultrolemanager.RoleManager).AddMatchingFunc("matcher", util.KeyMatch)
+	err := e.BuildRoleLinks()
+	if err != nil {
+		t.Error(err)
+	}
+
+	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"})
 }
 
 func testGetImplicitPermissions(t *testing.T, e *Enforcer, name string, res [][]string) {