Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
189 lines
4.6 KiB
Go
189 lines
4.6 KiB
Go
package rbac
|
|
|
|
import (
|
|
"sort"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// Test role inheritance
|
|
func TestRuleSet_merge(t *testing.T) {
|
|
var (
|
|
role1 uint64 = 1
|
|
role2 uint64 = 2
|
|
role3 uint64 = 3
|
|
|
|
resService1 = "res1"
|
|
resService2 = "res2"
|
|
opAccess = "access"
|
|
resThing42 = "42"
|
|
resThingWc = "*"
|
|
|
|
sCases = []struct {
|
|
old RuleSet
|
|
new RuleSet
|
|
deletable RuleSet
|
|
updatable RuleSet
|
|
final RuleSet
|
|
}{
|
|
{
|
|
RuleSet{AllowRule(role1, resService1, opAccess)},
|
|
RuleSet{AllowRule(role1, resService1, opAccess)},
|
|
RuleSet{},
|
|
RuleSet{},
|
|
RuleSet{AllowRule(role1, resService1, opAccess)},
|
|
},
|
|
{
|
|
RuleSet{AllowRule(role1, resService1, opAccess)},
|
|
RuleSet{DenyRule(role1, resService1, opAccess)},
|
|
RuleSet{},
|
|
RuleSet{DenyRule(role1, resService1, opAccess)},
|
|
RuleSet{DenyRule(role1, resService1, opAccess)},
|
|
},
|
|
{
|
|
RuleSet{AllowRule(role1, resService1, opAccess)},
|
|
RuleSet{InheritRule(role1, resService1, opAccess)},
|
|
RuleSet{InheritRule(role1, resService1, opAccess)},
|
|
RuleSet{},
|
|
RuleSet{},
|
|
},
|
|
{
|
|
RuleSet{AllowRule(role1, resService1, opAccess)},
|
|
RuleSet{AllowRule(role1, resService1, opAccess)},
|
|
RuleSet{},
|
|
RuleSet{},
|
|
RuleSet{AllowRule(role1, resService1, opAccess)},
|
|
},
|
|
{
|
|
RuleSet{
|
|
AllowRule(role1, resService1, opAccess),
|
|
DenyRule(role2, resService1, opAccess),
|
|
DenyRule(role3, resService2, opAccess),
|
|
AllowRule(role1, resService2, opAccess),
|
|
AllowRule(role2, resThing42, opAccess),
|
|
},
|
|
RuleSet{
|
|
DenyRule(role3, resThingWc, opAccess),
|
|
AllowRule(role1, resService2, opAccess),
|
|
AllowRule(role1, resThing42, opAccess),
|
|
InheritRule(role2, resThing42, opAccess),
|
|
},
|
|
RuleSet{
|
|
InheritRule(role2, resThing42, opAccess),
|
|
},
|
|
RuleSet{
|
|
DenyRule(role3, resThingWc, opAccess),
|
|
AllowRule(role1, resThing42, opAccess),
|
|
},
|
|
RuleSet{
|
|
AllowRule(role1, resService1, opAccess),
|
|
DenyRule(role2, resService1, opAccess),
|
|
DenyRule(role3, resService2, opAccess),
|
|
AllowRule(role1, resService2, opAccess),
|
|
DenyRule(role3, resThingWc, opAccess),
|
|
AllowRule(role1, resThing42, opAccess),
|
|
},
|
|
},
|
|
}
|
|
)
|
|
|
|
for _, sc := range sCases {
|
|
t.Run("", func(t *testing.T) {
|
|
var (
|
|
req = require.New(t)
|
|
|
|
// Apply changed and get update candidates
|
|
mrg = merge(sc.old, sc.new...)
|
|
deletable, updatable, final = flushable(mrg)
|
|
)
|
|
|
|
req.Equal(len(sc.deletable), len(deletable), "rule count for deletable do not match")
|
|
req.Equal(len(sc.updatable), len(updatable), "rule count for updatable do not match")
|
|
req.Equal(len(sc.final), len(final), "rule count for final do not match")
|
|
|
|
// Clear dirty flag so that we do not confuse comparison test
|
|
clear(deletable)
|
|
clear(updatable)
|
|
clear(final)
|
|
|
|
req.Equal(sc.deletable, deletable, "deletable rules do not match")
|
|
req.Equal(sc.updatable, updatable, "updatable rules do not match")
|
|
req.Equal(sc.final, final, "final rules do not match")
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test role inheritance
|
|
func TestRuleSet_sigRoles(t *testing.T) {
|
|
const (
|
|
roleA uint64 = 1
|
|
roleB uint64 = 2
|
|
roleC uint64 = 3
|
|
roleD uint64 = 4
|
|
roleE uint64 = 5
|
|
|
|
opRead = "read"
|
|
opWrite = "write"
|
|
resD = "res:foo:1"
|
|
resI = "res:foo:*"
|
|
)
|
|
|
|
var (
|
|
rr = func(rr ...uint64) []uint64 { return rr }
|
|
sCases = []struct {
|
|
set RuleSet
|
|
arr []uint64
|
|
drr []uint64
|
|
}{
|
|
{
|
|
RuleSet{
|
|
AllowRule(roleA, resD, opRead),
|
|
DenyRule(roleA, resD, opWrite),
|
|
AllowRule(roleB, resI, opRead),
|
|
DenyRule(roleA, resI, opRead),
|
|
DenyRule(roleC, resI, opRead),
|
|
DenyRule(roleD, resI, opRead),
|
|
DenyRule(roleE, resI, opRead),
|
|
DenyRule(roleE, resI, opWrite),
|
|
},
|
|
rr(roleB),
|
|
rr(roleA, roleC, roleD, roleE),
|
|
},
|
|
{
|
|
RuleSet{
|
|
AllowRule(roleA, resD, opRead),
|
|
DenyRule(roleA, resD, opRead),
|
|
},
|
|
rr(),
|
|
rr(roleA),
|
|
},
|
|
{
|
|
RuleSet{
|
|
AllowRule(roleA, resD, opRead),
|
|
DenyRule(roleA, resD, opRead),
|
|
AllowRule(roleA, resI, opRead),
|
|
DenyRule(roleA, resI, opRead),
|
|
},
|
|
rr(),
|
|
rr(roleA),
|
|
},
|
|
}
|
|
)
|
|
|
|
for _, sc := range sCases {
|
|
t.Run("a", func(t *testing.T) {
|
|
req := require.New(t)
|
|
arr, drr := sc.set.sigRoles(resD, opRead)
|
|
|
|
sort.Slice(sc.arr, func(i, j int) bool { return sc.arr[i] < sc.arr[j] })
|
|
sort.Slice(sc.drr, func(i, j int) bool { return sc.drr[i] < sc.drr[j] })
|
|
sort.Slice(arr, func(i, j int) bool { return arr[i] < arr[j] })
|
|
sort.Slice(drr, func(i, j int) bool { return drr[i] < drr[j] })
|
|
|
|
req.Equal(sc.arr, arr)
|
|
req.Equal(sc.drr, drr)
|
|
})
|
|
}
|
|
}
|