snapshot of https://github.com/casbin/casbin.git (master, 2026-09-15; blobs > 131072B omitted)
This commit is contained in:
49
rbac/context_role_manager.go
Normal file
49
rbac/context_role_manager.go
Normal file
@@ -0,0 +1,49 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package rbac
|
||||
|
||||
import "context"
|
||||
|
||||
// ContextRoleManager provides a context-aware interface to define the operations for managing roles.
|
||||
// Prefer this over RoleManager interface for context propagation, which is useful for things like handling
|
||||
// request timeouts.
|
||||
type ContextRoleManager interface {
|
||||
RoleManager
|
||||
|
||||
// ClearCtx clears all stored data and resets the role manager to the initial state with context.
|
||||
ClearCtx(ctx context.Context) error
|
||||
// AddLinkCtx adds the inheritance link between two roles. role: name1 and role: name2 with context.
|
||||
// domain is a prefix to the roles (can be used for other purposes).
|
||||
AddLinkCtx(ctx context.Context, name1 string, name2 string, domain ...string) error
|
||||
// DeleteLinkCtx deletes the inheritance link between two roles. role: name1 and role: name2 with context.
|
||||
// domain is a prefix to the roles (can be used for other purposes).
|
||||
DeleteLinkCtx(ctx context.Context, name1 string, name2 string, domain ...string) error
|
||||
// HasLinkCtx determines whether a link exists between two roles. role: name1 inherits role: name2 with context.
|
||||
// domain is a prefix to the roles (can be used for other purposes).
|
||||
HasLinkCtx(ctx context.Context, name1 string, name2 string, domain ...string) (bool, error)
|
||||
// GetRolesCtx gets the roles that a user inherits with context.
|
||||
// domain is a prefix to the roles (can be used for other purposes).
|
||||
GetRolesCtx(ctx context.Context, name string, domain ...string) ([]string, error)
|
||||
// GetUsersCtx gets the users that inherits a role with context.
|
||||
// domain is a prefix to the users (can be used for other purposes).
|
||||
GetUsersCtx(ctx context.Context, name string, domain ...string) ([]string, error)
|
||||
// GetDomainsCtx gets domains that a user has with context.
|
||||
GetDomainsCtx(ctx context.Context, name string) ([]string, error)
|
||||
// GetAllDomainsCtx gets all domains with context.
|
||||
GetAllDomainsCtx(ctx context.Context) ([]string, error)
|
||||
}
|
||||
1252
rbac/default-role-manager/role_manager.go
Normal file
1252
rbac/default-role-manager/role_manager.go
Normal file
File diff suppressed because it is too large
Load Diff
436
rbac/default-role-manager/role_manager_test.go
Normal file
436
rbac/default-role-manager/role_manager_test.go
Normal file
@@ -0,0 +1,436 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package defaultrolemanager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"github.com/casbin/casbin/v3/rbac"
|
||||
"github.com/casbin/casbin/v3/util"
|
||||
)
|
||||
|
||||
func testRole(t *testing.T, rm rbac.RoleManager, name1 string, name2 string, res bool) {
|
||||
t.Helper()
|
||||
myRes, _ := rm.HasLink(name1, name2)
|
||||
t.Logf("%s, %s: %t", name1, name2, myRes)
|
||||
|
||||
if myRes != res {
|
||||
t.Errorf("%s < %s: %t, supposed to be %t", name1, name2, !res, res)
|
||||
}
|
||||
}
|
||||
|
||||
func testDomainRole(t *testing.T, rm rbac.RoleManager, name1 string, name2 string, domain string, res bool) {
|
||||
t.Helper()
|
||||
myRes, _ := rm.HasLink(name1, name2, domain)
|
||||
t.Logf("%s :: %s, %s: %t", domain, name1, name2, myRes)
|
||||
|
||||
if myRes != res {
|
||||
t.Errorf("%s :: %s < %s: %t, supposed to be %t", domain, name1, name2, !res, res)
|
||||
}
|
||||
}
|
||||
|
||||
func testPrintRoles(t *testing.T, rm rbac.RoleManager, name string, res []string) {
|
||||
t.Helper()
|
||||
myRes, _ := rm.GetRoles(name)
|
||||
t.Logf("%s: %s", name, myRes)
|
||||
|
||||
if !util.SetEquals(myRes, res) {
|
||||
t.Errorf("%s: %s, supposed to be %s", name, myRes, res)
|
||||
}
|
||||
}
|
||||
|
||||
func testPrintUsers(t *testing.T, rm rbac.RoleManager, name string, res []string) {
|
||||
t.Helper()
|
||||
myRes, _ := rm.GetUsers(name)
|
||||
t.Logf("%s: %s", name, myRes)
|
||||
|
||||
if !util.SetEquals(myRes, res) {
|
||||
t.Errorf("%s: %s, supposed to be %s", name, myRes, res)
|
||||
}
|
||||
}
|
||||
|
||||
func testPrintRolesWithDomain(t *testing.T, rm rbac.RoleManager, name string, domain string, res []string) {
|
||||
t.Helper()
|
||||
myRes, _ := rm.GetRoles(name, domain)
|
||||
|
||||
if !util.SetEquals(myRes, res) {
|
||||
t.Errorf("%s: %s, supposed to be %s", name, myRes, res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRole(t *testing.T) {
|
||||
rm := 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(t, rm, "u1", "g1", true)
|
||||
testRole(t, rm, "u1", "g2", false)
|
||||
testRole(t, rm, "u1", "g3", true)
|
||||
testRole(t, rm, "u2", "g1", true)
|
||||
testRole(t, rm, "u2", "g2", false)
|
||||
testRole(t, rm, "u2", "g3", true)
|
||||
testRole(t, rm, "u3", "g1", false)
|
||||
testRole(t, rm, "u3", "g2", true)
|
||||
testRole(t, rm, "u3", "g3", false)
|
||||
testRole(t, rm, "u4", "g1", false)
|
||||
testRole(t, rm, "u4", "g2", true)
|
||||
testRole(t, rm, "u4", "g3", true)
|
||||
|
||||
testPrintRoles(t, rm, "u1", []string{"g1"})
|
||||
testPrintRoles(t, rm, "u2", []string{"g1"})
|
||||
testPrintRoles(t, rm, "u3", []string{"g2"})
|
||||
testPrintRoles(t, rm, "u4", []string{"g2", "g3"})
|
||||
testPrintRoles(t, rm, "g1", []string{"g3"})
|
||||
testPrintRoles(t, rm, "g2", []string{})
|
||||
testPrintRoles(t, rm, "g3", []string{})
|
||||
|
||||
_ = rm.DeleteLink("g1", "g3")
|
||||
_ = rm.DeleteLink("u4", "g2")
|
||||
|
||||
// Current role inheritance tree after deleting the links:
|
||||
// g3 g2
|
||||
// \ \
|
||||
// g1 u4 u3
|
||||
// / \
|
||||
// u1 u2
|
||||
|
||||
testRole(t, rm, "u1", "g1", true)
|
||||
testRole(t, rm, "u1", "g2", false)
|
||||
testRole(t, rm, "u1", "g3", false)
|
||||
testRole(t, rm, "u2", "g1", true)
|
||||
testRole(t, rm, "u2", "g2", false)
|
||||
testRole(t, rm, "u2", "g3", false)
|
||||
testRole(t, rm, "u3", "g1", false)
|
||||
testRole(t, rm, "u3", "g2", true)
|
||||
testRole(t, rm, "u3", "g3", false)
|
||||
testRole(t, rm, "u4", "g1", false)
|
||||
testRole(t, rm, "u4", "g2", false)
|
||||
testRole(t, rm, "u4", "g3", true)
|
||||
|
||||
testPrintRoles(t, rm, "u1", []string{"g1"})
|
||||
testPrintRoles(t, rm, "u2", []string{"g1"})
|
||||
testPrintRoles(t, rm, "u3", []string{"g2"})
|
||||
testPrintRoles(t, rm, "u4", []string{"g3"})
|
||||
testPrintRoles(t, rm, "g1", []string{})
|
||||
testPrintRoles(t, rm, "g2", []string{})
|
||||
testPrintRoles(t, rm, "g3", []string{})
|
||||
|
||||
rm = NewRoleManager(3)
|
||||
rm.AddMatchingFunc("keyMatch", util.KeyMatch)
|
||||
|
||||
_ = rm.AddLink("u1", "g1")
|
||||
_ = rm.AddLink("u1", "*")
|
||||
_ = rm.AddLink("u2", "g2")
|
||||
|
||||
// Current role inheritance tree after deleting the links:
|
||||
// g1 g2
|
||||
// \ / \
|
||||
// * u2
|
||||
// |
|
||||
// u1
|
||||
testRole(t, rm, "u1", "g1", true)
|
||||
testRole(t, rm, "u1", "g2", true)
|
||||
testRole(t, rm, "u2", "g2", true)
|
||||
testRole(t, rm, "u2", "g1", false)
|
||||
testPrintRoles(t, rm, "u1", []string{"*", "u1", "u2", "g1", "g2"})
|
||||
testPrintUsers(t, rm, "*", []string{"u1"})
|
||||
}
|
||||
|
||||
func TestDomainRole(t *testing.T) {
|
||||
rm := NewRoleManager(3)
|
||||
_ = 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(t, rm, "u1", "g1", "domain1", true)
|
||||
testDomainRole(t, rm, "u1", "g1", "domain2", false)
|
||||
testDomainRole(t, rm, "u1", "admin", "domain1", true)
|
||||
testDomainRole(t, rm, "u1", "admin", "domain2", false)
|
||||
|
||||
testDomainRole(t, rm, "u2", "g1", "domain1", true)
|
||||
testDomainRole(t, rm, "u2", "g1", "domain2", false)
|
||||
testDomainRole(t, rm, "u2", "admin", "domain1", true)
|
||||
testDomainRole(t, rm, "u2", "admin", "domain2", false)
|
||||
|
||||
testDomainRole(t, rm, "u3", "g1", "domain1", false)
|
||||
testDomainRole(t, rm, "u3", "g1", "domain2", false)
|
||||
testDomainRole(t, rm, "u3", "admin", "domain1", false)
|
||||
testDomainRole(t, rm, "u3", "admin", "domain2", true)
|
||||
|
||||
testDomainRole(t, rm, "u4", "g1", "domain1", false)
|
||||
testDomainRole(t, rm, "u4", "g1", "domain2", false)
|
||||
testDomainRole(t, rm, "u4", "admin", "domain1", true)
|
||||
testDomainRole(t, 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(t, rm, "u1", "g1", "domain1", true)
|
||||
testDomainRole(t, rm, "u1", "g1", "domain2", false)
|
||||
testDomainRole(t, rm, "u1", "admin", "domain1", false)
|
||||
testDomainRole(t, rm, "u1", "admin", "domain2", false)
|
||||
|
||||
testDomainRole(t, rm, "u2", "g1", "domain1", true)
|
||||
testDomainRole(t, rm, "u2", "g1", "domain2", false)
|
||||
testDomainRole(t, rm, "u2", "admin", "domain1", false)
|
||||
testDomainRole(t, rm, "u2", "admin", "domain2", false)
|
||||
|
||||
testDomainRole(t, rm, "u3", "g1", "domain1", false)
|
||||
testDomainRole(t, rm, "u3", "g1", "domain2", false)
|
||||
testDomainRole(t, rm, "u3", "admin", "domain1", false)
|
||||
testDomainRole(t, rm, "u3", "admin", "domain2", true)
|
||||
|
||||
testDomainRole(t, rm, "u4", "g1", "domain1", false)
|
||||
testDomainRole(t, rm, "u4", "g1", "domain2", false)
|
||||
testDomainRole(t, rm, "u4", "admin", "domain1", true)
|
||||
testDomainRole(t, rm, "u4", "admin", "domain2", false)
|
||||
}
|
||||
|
||||
func TestClear(t *testing.T) {
|
||||
rm := 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(t, rm, "u1", "g1", false)
|
||||
testRole(t, rm, "u1", "g2", false)
|
||||
testRole(t, rm, "u1", "g3", false)
|
||||
testRole(t, rm, "u2", "g1", false)
|
||||
testRole(t, rm, "u2", "g2", false)
|
||||
testRole(t, rm, "u2", "g3", false)
|
||||
testRole(t, rm, "u3", "g1", false)
|
||||
testRole(t, rm, "u3", "g2", false)
|
||||
testRole(t, rm, "u3", "g3", false)
|
||||
testRole(t, rm, "u4", "g1", false)
|
||||
testRole(t, rm, "u4", "g2", false)
|
||||
testRole(t, rm, "u4", "g3", false)
|
||||
}
|
||||
|
||||
func TestDomainPatternRole(t *testing.T) {
|
||||
rm := NewRoleManager(10)
|
||||
rm.AddDomainMatchingFunc("keyMatch2", util.KeyMatch2)
|
||||
|
||||
_ = rm.AddLink("u1", "g1", "domain1")
|
||||
_ = rm.AddLink("u2", "g1", "domain2")
|
||||
_ = rm.AddLink("u3", "g1", "*")
|
||||
_ = rm.AddLink("u4", "g2", "domain3")
|
||||
// Current role inheritance tree after deleting the links:
|
||||
// domain1:g1 domain2:g1 domain3:g2
|
||||
// / \ / \ |
|
||||
// domain1:u1 *:g1 domain2:u2 domain3:u4
|
||||
// |
|
||||
// *:u3
|
||||
testDomainRole(t, rm, "u1", "g1", "domain1", true)
|
||||
testDomainRole(t, rm, "u2", "g1", "domain1", false)
|
||||
testDomainRole(t, rm, "u2", "g1", "domain2", true)
|
||||
testDomainRole(t, rm, "u3", "g1", "domain1", true)
|
||||
testDomainRole(t, rm, "u3", "g1", "domain2", true)
|
||||
testDomainRole(t, rm, "u1", "g2", "domain1", false)
|
||||
testDomainRole(t, rm, "u4", "g2", "domain3", true)
|
||||
testDomainRole(t, rm, "u3", "g2", "domain3", false)
|
||||
|
||||
testPrintRolesWithDomain(t, rm, "u3", "domain1", []string{"g1"})
|
||||
testPrintRolesWithDomain(t, rm, "u1", "domain1", []string{"g1"})
|
||||
testPrintRolesWithDomain(t, rm, "u3", "domain2", []string{"g1"})
|
||||
testPrintRolesWithDomain(t, rm, "u1", "domain2", []string{})
|
||||
testPrintRolesWithDomain(t, rm, "u4", "domain3", []string{"g2"})
|
||||
}
|
||||
|
||||
func TestAllMatchingFunc(t *testing.T) {
|
||||
rm := NewRoleManager(10)
|
||||
rm.AddMatchingFunc("keyMatch2", util.KeyMatch2)
|
||||
rm.AddDomainMatchingFunc("keyMatch2", util.KeyMatch2)
|
||||
|
||||
_ = rm.AddLink("/book/:id", "book_group", "*")
|
||||
// Current role inheritance tree after deleting the links:
|
||||
// *:book_group
|
||||
// |
|
||||
// *:/book/:id
|
||||
testDomainRole(t, rm, "/book/1", "book_group", "domain1", true)
|
||||
testDomainRole(t, rm, "/book/2", "book_group", "domain1", true)
|
||||
}
|
||||
|
||||
func TestMatchingFuncOrder(t *testing.T) {
|
||||
rm := NewRoleManager(10)
|
||||
rm.AddMatchingFunc("regexMatch", util.RegexMatch)
|
||||
|
||||
_ = rm.AddLink("g\\d+", "root")
|
||||
_ = rm.AddLink("u1", "g1")
|
||||
testRole(t, rm, "u1", "root", true)
|
||||
|
||||
_ = rm.Clear()
|
||||
|
||||
_ = rm.AddLink("u1", "g1")
|
||||
_ = rm.AddLink("g\\d+", "root")
|
||||
testRole(t, rm, "u1", "root", true)
|
||||
|
||||
_ = rm.Clear()
|
||||
|
||||
_ = rm.AddLink("u1", "g\\d+")
|
||||
testRole(t, rm, "u1", "g1", true)
|
||||
testRole(t, rm, "u1", "g2", true)
|
||||
}
|
||||
|
||||
func TestDomainMatchingFuncWithDifferentDomain(t *testing.T) {
|
||||
rm := NewRoleManager(10)
|
||||
rm.AddDomainMatchingFunc("keyMatch", util.KeyMatch)
|
||||
|
||||
_ = rm.AddLink("alice", "editor", "*")
|
||||
_ = rm.AddLink("editor", "admin", "domain1")
|
||||
|
||||
testDomainRole(t, rm, "alice", "admin", "domain1", true)
|
||||
testDomainRole(t, rm, "alice", "admin", "domain2", false)
|
||||
}
|
||||
|
||||
func TestTemporaryRoles(t *testing.T) {
|
||||
rm := NewRoleManager(10)
|
||||
rm.AddMatchingFunc("regexMatch", util.RegexMatch)
|
||||
|
||||
_ = rm.AddLink("u\\d+", "user")
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
testRole(t, rm, fmt.Sprintf("u%d", i), "user", true)
|
||||
}
|
||||
|
||||
testPrintUsers(t, rm, "user", []string{"u\\d+"})
|
||||
testPrintRoles(t, rm, "u1", []string{"user"})
|
||||
|
||||
_ = rm.AddLink("u1", "manager")
|
||||
|
||||
for i := 10; i < 20; i++ {
|
||||
testRole(t, rm, fmt.Sprintf("u%d", i), "user", true)
|
||||
}
|
||||
|
||||
testPrintUsers(t, rm, "user", []string{"u\\d+", "u1"})
|
||||
testPrintRoles(t, rm, "u1", []string{"user", "manager"})
|
||||
}
|
||||
|
||||
func TestMaxHierarchyLevel(t *testing.T) {
|
||||
rm := NewRoleManager(1)
|
||||
_ = rm.AddLink("level0", "level1")
|
||||
_ = rm.AddLink("level1", "level2")
|
||||
_ = rm.AddLink("level2", "level3")
|
||||
|
||||
testRole(t, rm, "level0", "level0", true)
|
||||
testRole(t, rm, "level0", "level1", true)
|
||||
testRole(t, rm, "level0", "level2", false)
|
||||
testRole(t, rm, "level0", "level3", false)
|
||||
testRole(t, rm, "level1", "level2", true)
|
||||
testRole(t, rm, "level1", "level3", false)
|
||||
|
||||
rm = NewRoleManager(2)
|
||||
_ = rm.AddLink("level0", "level1")
|
||||
_ = rm.AddLink("level1", "level2")
|
||||
_ = rm.AddLink("level2", "level3")
|
||||
|
||||
testRole(t, rm, "level0", "level0", true)
|
||||
testRole(t, rm, "level0", "level1", true)
|
||||
testRole(t, rm, "level0", "level2", true)
|
||||
testRole(t, rm, "level0", "level3", false)
|
||||
testRole(t, rm, "level1", "level2", true)
|
||||
testRole(t, rm, "level1", "level3", true)
|
||||
}
|
||||
|
||||
// TestConcurrentHasLink tests concurrent HasLink calls for race conditions.
|
||||
// This test verifies that concurrent HasLink calls with matching functions
|
||||
// don't produce inconsistent results due to temporary role creation/deletion races.
|
||||
// Regression test for issue #1318.
|
||||
func TestConcurrentHasLink(t *testing.T) {
|
||||
rm := NewRoleManager(10)
|
||||
rm.AddMatchingFunc("keyMatch2", util.KeyMatch2)
|
||||
|
||||
_ = rm.AddLink("alice", "admin")
|
||||
_ = rm.AddLink("admin", "/data/*")
|
||||
|
||||
expected, _ := rm.HasLink("alice", "/data/123")
|
||||
|
||||
const numGoroutines = 20
|
||||
const numIterations = 100
|
||||
|
||||
var inconsistencies int64
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for i := 0; i < numGoroutines; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < numIterations; j++ {
|
||||
result, err := rm.HasLink("alice", "/data/123")
|
||||
if err != nil {
|
||||
t.Errorf("HasLink failed: %v", err)
|
||||
return
|
||||
} else if result != expected {
|
||||
atomic.AddInt64(&inconsistencies, 1)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
if inconsistencies > 0 {
|
||||
t.Errorf("Found %d inconsistencies in %d total operations",
|
||||
inconsistencies, numGoroutines*numIterations)
|
||||
}
|
||||
}
|
||||
83
rbac/role_manager.go
Normal file
83
rbac/role_manager.go
Normal file
@@ -0,0 +1,83 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package rbac
|
||||
|
||||
type MatchingFunc func(arg1 string, arg2 string) bool
|
||||
|
||||
type LinkConditionFunc = func(args ...string) (bool, error)
|
||||
|
||||
// RoleManager provides interface to define the operations for managing roles.
|
||||
type RoleManager interface {
|
||||
// Clear clears all stored data and resets the role manager to the initial state.
|
||||
Clear() error
|
||||
// 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).
|
||||
AddLink(name1 string, name2 string, domain ...string) error
|
||||
// Deprecated: BuildRelationship is no longer required
|
||||
BuildRelationship(name1 string, name2 string, domain ...string) error
|
||||
// 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).
|
||||
DeleteLink(name1 string, name2 string, domain ...string) error
|
||||
// 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).
|
||||
HasLink(name1 string, name2 string, domain ...string) (bool, error)
|
||||
// GetRoles gets the roles that a user inherits.
|
||||
// domain is a prefix to the roles (can be used for other purposes).
|
||||
GetRoles(name string, domain ...string) ([]string, error)
|
||||
// GetUsers gets the users that inherits a role.
|
||||
// domain is a prefix to the users (can be used for other purposes).
|
||||
GetUsers(name string, domain ...string) ([]string, error)
|
||||
// GetImplicitRoles gets the implicit roles that a user inherits, respecting maxHierarchyLevel.
|
||||
// domain is a prefix to the roles (can be used for other purposes).
|
||||
GetImplicitRoles(name string, domain ...string) ([]string, error)
|
||||
// GetImplicitUsers gets the implicit users that inherits a role, respecting maxHierarchyLevel.
|
||||
// domain is a prefix to the users (can be used for other purposes).
|
||||
GetImplicitUsers(name string, domain ...string) ([]string, error)
|
||||
// GetDomains gets domains that a user has
|
||||
GetDomains(name string) ([]string, error)
|
||||
// GetAllDomains gets all domains
|
||||
GetAllDomains() ([]string, error)
|
||||
// PrintRoles prints all the roles to log.
|
||||
PrintRoles() error
|
||||
// Match matches the domain with the pattern
|
||||
Match(str string, pattern string) bool
|
||||
// AddMatchingFunc adds the matching function
|
||||
AddMatchingFunc(name string, fn MatchingFunc)
|
||||
// AddDomainMatchingFunc adds the domain matching function
|
||||
AddDomainMatchingFunc(name string, fn MatchingFunc)
|
||||
// DeleteDomain deletes all data of a domain in the role manager.
|
||||
DeleteDomain(domain string) error
|
||||
}
|
||||
|
||||
// ConditionalRoleManager provides interface to define the operations for managing roles.
|
||||
// Link with conditions is supported.
|
||||
type ConditionalRoleManager interface {
|
||||
RoleManager
|
||||
|
||||
// AddLinkConditionFunc Add condition function fn for Link userName->roleName,
|
||||
// when fn returns true, Link is valid, otherwise invalid
|
||||
AddLinkConditionFunc(userName, roleName string, fn LinkConditionFunc)
|
||||
// SetLinkConditionFuncParams Sets the parameters of the condition function fn for Link userName->roleName
|
||||
SetLinkConditionFuncParams(userName, roleName string, params ...string)
|
||||
// AddDomainLinkConditionFunc Add condition function fn for Link userName-> {roleName, domain},
|
||||
// when fn returns true, Link is valid, otherwise invalid
|
||||
AddDomainLinkConditionFunc(user string, role string, domain string, fn LinkConditionFunc)
|
||||
// SetDomainLinkConditionFuncParams Sets the parameters of the condition function fn
|
||||
// for Link userName->{roleName, domain}
|
||||
SetDomainLinkConditionFuncParams(user string, role string, domain string, params ...string)
|
||||
}
|
||||
Reference in New Issue
Block a user