Rework pkg/rbac with new resource index struct

This commit is contained in:
Tomaž Jerman
2022-06-09 15:14:34 +02:00
parent a68ddf1f2a
commit 0466ffeebc
5 changed files with 57 additions and 12 deletions
+4 -2
View File
@@ -82,8 +82,10 @@ func benchmarkMatchResource(b *testing.B, c int) {
b.StartTimer()
for n := 0; n < b.N; n++ {
matchResource("corteza::test/a/1/1/1", "corteza::test/a/1/1/1")
matchResource("corteza::test/a/*/*/1", "corteza::test/a/1/1/1")
for i := 0; i < c; i++ {
matchResource("corteza::test/a/1/1/1", "corteza::test/a/1/1/1")
matchResource("corteza::test/a/*/*/1", "corteza::test/a/1/1/1")
}
}
b.StopTimer()
+29 -4
View File
@@ -2,6 +2,9 @@ package rbac
import (
"fmt"
"strings"
"github.com/cortezaproject/corteza-server/pkg/resource"
)
type (
@@ -17,10 +20,19 @@ type (
RuleSet []*Rule
ruleIndexWrap struct {
index *resource.IndexNode
rules RuleSet
}
// OptRuleSet RBAC rule index (operation / role ID / rules)
OptRuleSet map[string]map[uint64]RuleSet
OptRuleSet map[string]map[uint64]*ruleIndexWrap
)
func (r Rule) Clone() *Rule {
return &r
}
func (r Rule) String() string {
return fmt.Sprintf("%s %d to %s on %s", r.Access, r.RoleID, r.Operation, r.Resource)
}
@@ -29,19 +41,32 @@ func indexRules(rules []*Rule) OptRuleSet {
i := make(OptRuleSet)
for _, r := range rules {
if i[r.Operation] == nil {
i[r.Operation] = make(map[uint64]RuleSet)
i[r.Operation] = make(map[uint64]*ruleIndexWrap)
}
if i[r.Operation][r.RoleID] == nil {
i[r.Operation][r.RoleID] = RuleSet{}
i[r.Operation][r.RoleID] = &ruleIndexWrap{
index: resource.NewIndex(),
}
}
i[r.Operation][r.RoleID] = append(i[r.Operation][r.RoleID], r)
i[r.Operation][r.RoleID].index.Add(r, r.IndexPath()...)
i[r.Operation][r.RoleID].rules = append(i[r.Operation][r.RoleID].rules, r)
}
return i
}
func (r Rule) IndexPath() (out [][]string) {
pts := strings.Split(r.Resource, pathSep)
for _, p := range pts {
out = append(out, []string{p})
}
return
}
func (set RuleSet) Len() int { return len(set) }
func (set RuleSet) Swap(i, j int) { set[i], set[j] = set[j], set[i] }
func (set RuleSet) Less(i, j int) bool {
+17 -1
View File
@@ -2,6 +2,7 @@ package rbac
import (
"sort"
"strings"
)
func check(indexedRules OptRuleSet, rolesByKind partRoles, op, res string) Access {
@@ -44,7 +45,11 @@ func check(indexedRules OptRuleSet, rolesByKind partRoles, op, res string) Acces
if !rolesByKind[kind][roleID] {
continue
}
rules = append(rules, r...)
aux := r.index.Collect(resourceToIndexPath(res)...)
for _, a := range aux {
rules = append(rules, a.(*Rule))
}
}
access := checkRulesByResource(rules, op, res)
@@ -89,3 +94,14 @@ func member(r partRoles, k roleKind) bool {
return false
}
// utility to get the resource index path from the resource identifier
func resourceToIndexPath(r string) (out [][]string) {
pts := strings.Split(r, pathSep)
for _, pt := range pts {
out = append(out, []string{pt})
}
return
}
+6 -4
View File
@@ -105,9 +105,11 @@ func benchmarkCheck(b *testing.B, c int) {
for i := 0; i < cap(rules); i++ {
rules = append(rules, &Rule{
RoleID: uint64(rand.Int31n(50)),
Resource: fmt.Sprintf("res-%d", rand.Int31n(1000)),
Operation: fmt.Sprintf("op-%d", rand.Int31n(100)),
// one over because interval is [a, b)
// lowered others to make the cases more resource intensive
RoleID: uint64(rand.Int31n(10)),
Resource: fmt.Sprintf("res-%d", rand.Int31n(10)),
Operation: fmt.Sprintf("op-%d", rand.Int31n(5)),
Access: Access(rand.Int31n(2)),
})
}
@@ -117,7 +119,7 @@ func benchmarkCheck(b *testing.B, c int) {
b.StartTimer()
for n := 0; n < b.N; n++ {
check(iRules, pr, "res-0", "op-0")
check(iRules, pr, "op-0", "res-0")
}
b.StopTimer()
+1 -1
View File
@@ -279,7 +279,7 @@ func (svc service) String() (out string) {
for _, byRole := range svc.indexed {
for _, rr := range byRole {
for _, r := range rr {
for _, r := range rr.rules {
out += fmt.Sprintf(tpl, r.Access, r.Operation, role(r.RoleID), r.Resource)
}
}