package rbac import "testing" // build sets up an RBAC store with the given roles, then assigns them all to // user "u". func build(t *testing.T, roles ...Role) *RBAC { t.Helper() r := New() for _, role := range roles { r.DefineRole(role) r.AssignRole("u", role.Name) } return r } func TestCan(t *testing.T) { admin := Role{Name: "admin", ModuleGrants: map[string][]Permission{Wildcard: {All}}} reader := Role{Name: "reader", ModuleGrants: map[string][]Permission{Wildcard: {Read}}} sysWrite := Role{Name: "sysw", ModuleGrants: map[string][]Permission{"system": {Read, Write}}} tests := []struct { name string role Role module string perm Permission want bool }{ {"wildcard module + wildcard perm", admin, "system", Root, true}, {"wildcard module + wildcard perm, other module", admin, "services", Write, true}, {"wildcard module, read only, read", reader, "anything", Read, true}, {"wildcard module, read only, write denied", reader, "anything", Write, false}, {"exact module exact perm", sysWrite, "system", Write, true}, {"exact module missing perm", sysWrite, "system", Root, false}, {"exact module, different module denied", sysWrite, "services", Read, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { r := build(t, tt.role) if got := r.Can("u", tt.module, tt.perm); got != tt.want { t.Errorf("Can(u, %q, %q) = %v, want %v", tt.module, tt.perm, got, tt.want) } }) } } func TestCanNoRolesDenied(t *testing.T) { r := New() if r.Can("nobody", "system", Read) { t.Fatal("user with no roles was granted access") } } func TestCanAssignedUndefinedRoleSkipped(t *testing.T) { r := New() r.AssignRole("u", "ghost") // never defined if r.Can("u", "system", Read) { t.Fatal("undefined role granted access") } } func TestCanUnionOfRoles(t *testing.T) { r := build(t, Role{Name: "a", ModuleGrants: map[string][]Permission{"system": {Read}}}, Role{Name: "b", ModuleGrants: map[string][]Permission{"services": {Write}}}, ) if !r.Can("u", "system", Read) || !r.Can("u", "services", Write) { t.Fatal("union of roles not honored") } if r.Can("u", "system", Write) { t.Fatal("permission leaked across modules") } } func TestRoleExists(t *testing.T) { r := New() r.DefineRole(Role{Name: "x"}) if !r.RoleExists("x") { t.Error("defined role reported missing") } if r.RoleExists("y") { t.Error("undefined role reported present") } }