From 8cfc636f78752a7da383f0dffc7b11019fad3d33 Mon Sep 17 00:00:00 2001 From: nodece Date: Sun, 9 Dec 2018 16:44:15 +0800 Subject: [PATCH] Add RESTful support for g --- model_test.go | 11 +++++++++ rbac/default-role-manager/role_manager.go | 28 ++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/model_test.go b/model_test.go index fc812aa8..c732c657 100644 --- a/model_test.go +++ b/model_test.go @@ -273,6 +273,17 @@ func TestRBACModelWithCustomData(t *testing.T) { testEnforce(t, e, "bob", "data2", "write", true) } +func TestRBACModelWithRESTful(t *testing.T) { + e := NewEnforcer("examples/rbac_model.conf", "examples/rbac_policy.csv") + + e.AddGroupingPolicy("/resource/:id", "data2_admin") + + testEnforce(t, e, "/resource/1", "data2", "read", true) + testEnforce(t, e, "/resource/1", "data2", "write", true) + testEnforce(t, e, "/resource/1", "data1", "read", false) + testEnforce(t, e, "/resource/1", "data1", "write", false) +} + type testCustomRoleManager struct{} func NewRoleManager() rbac.RoleManager { diff --git a/rbac/default-role-manager/role_manager.go b/rbac/default-role-manager/role_manager.go index 0a409f64..03df1a34 100644 --- a/rbac/default-role-manager/role_manager.go +++ b/rbac/default-role-manager/role_manager.go @@ -16,16 +16,19 @@ package defaultrolemanager import ( "errors" + "strings" "sync" "github.com/casbin/casbin/log" "github.com/casbin/casbin/rbac" + "github.com/casbin/casbin/util" ) // RoleManager provides a default implementation for the RoleManager interface type RoleManager struct { allRoles *sync.Map maxHierarchyLevel int + restful bool } // NewRoleManager is the constructor for creating an instance of the @@ -38,11 +41,30 @@ func NewRoleManager(maxHierarchyLevel int) rbac.RoleManager { } func (rm *RoleManager) hasRole(name string) bool { - _, ok := rm.allRoles.Load(name) + var ok bool + if rm.restful { + rm.allRoles.Range(func(key, value interface{}) bool { + if util.KeyMatch2(name, key.(string)) { + ok = true + } + return true + }) + } else { + _, ok = rm.allRoles.Load(name) + } + return ok } func (rm *RoleManager) createRole(name string) *Role { + if rm.restful { + rm.allRoles.Range(func(key, value interface{}) bool { + if util.KeyMatch2(name, key.(string)) { + name = key.(string) + } + return true + }) + } role, _ := rm.allRoles.LoadOrStore(name, newRole(name)) return role.(*Role) } @@ -64,6 +86,10 @@ func (rm *RoleManager) AddLink(name1 string, name2 string, domain ...string) err return errors.New("error: domain should be 1 parameter") } + if strings.Contains(name1, "/*") || strings.Contains(name1, "/:") { + rm.restful = true + } + role1 := rm.createRole(name1) role2 := rm.createRole(name2) role1.addRole(role2)