myxce/src/frontend/apiserver/controllers/rbac_check_test.go

219 lines
4.8 KiB
Go

package controllers
import (
"apiserver/store"
"apiserver/utils"
"os"
"path/filepath"
"testing"
"go.uber.org/zap"
)
func resetRBACState() {
rbacConfig = RBACConfig{}
store.InitStores()
utils.Log = zap.NewNop()
}
func writeTestYAML(t *testing.T, content string) string {
t.Helper()
dir := t.TempDir()
path := filepath.Join(dir, "rbac.yaml")
if err := os.WriteFile(path, []byte(content), 0644); err != nil {
t.Fatalf("write test yaml: %v", err)
}
return path
}
func TestLoadRBACConfig_RolesPopulated(t *testing.T) {
resetRBACState()
yaml := `
permissions:
- queue:view
- job:view
roles:
basic_user:
permissions:
- action: queue:view
domain:
- type: all
- action: job:view
domain:
- type: self
operator:
permissions:
- action: host:view
domain:
- type: all
`
path := writeTestYAML(t, yaml)
if err := LoadRBACConfig(path); err != nil {
t.Fatalf("LoadRBACConfig: %v", err)
}
// Verify roles exist in store
if !store.Roles.Has("basic_user") {
t.Error("store should contain basic_user role")
}
if !store.Roles.Has("operator") {
t.Error("store should contain operator role")
}
// Verify basic_user permissions
perms := store.GetRolePermissions("basic_user")
if len(perms) != 2 {
t.Errorf("basic_user permissions count = %d, want 2", len(perms))
}
found := false
for _, p := range perms {
if p.Action == "queue:view" && p.DomainType == "all" {
found = true
}
}
if !found {
t.Error("basic_user should have queue:view with domain all")
}
}
func TestLoadRBACConfig_UserRoleMappings(t *testing.T) {
resetRBACState()
yaml := `
permissions:
- queue:view
roles:
basic_user:
permissions:
- action: queue:view
domain:
- type: all
users:
alice:
roles:
- name: basic_user
domain:
- type: all
bob:
roles:
- name: basic_user
domain:
- type: all
`
path := writeTestYAML(t, yaml)
if err := LoadRBACConfig(path); err != nil {
t.Fatalf("LoadRBACConfig: %v", err)
}
roles := store.GetUserRoleNames("alice")
if len(roles) != 1 || roles[0] != "basic_user" {
t.Errorf("alice roles = %v, want [basic_user]", roles)
}
roles = store.GetUserRoleNames("bob")
if len(roles) != 1 || roles[0] != "basic_user" {
t.Errorf("bob roles = %v, want [basic_user]", roles)
}
roles = store.GetUserRoleNames("unknown")
if len(roles) != 0 {
t.Errorf("unknown user roles = %v, want empty", roles)
}
}
func TestLoadRBACConfig_RoleIncludes(t *testing.T) {
resetRBACState()
yaml := `
permissions:
- queue:view
- job:view
- queue:control
roles:
basic_user:
permissions:
- action: queue:view
domain:
- type: all
- action: job:view
domain:
- type: self
queue_admin:
includes:
- basic_user
permissions:
- action: queue:control
domain:
- type: self
`
path := writeTestYAML(t, yaml)
if err := LoadRBACConfig(path); err != nil {
t.Fatalf("LoadRBACConfig: %v", err)
}
// queue_admin should have its own permissions + inherited basic_user permissions
perms := store.GetRolePermissions("queue_admin")
if len(perms) < 3 {
t.Errorf("queue_admin permissions count = %d, want >= 3 (own + inherited)", len(perms))
}
// Verify inherited queue:view is present
foundQueueView := false
foundQueueControl := false
for _, p := range perms {
if p.Action == "queue:view" {
foundQueueView = true
}
if p.Action == "queue:control" {
foundQueueControl = true
}
}
if !foundQueueView {
t.Error("queue_admin should inherit queue:view from basic_user")
}
if !foundQueueControl {
t.Error("queue_admin should have its own queue:control")
}
}
func TestLoadRBACConfig_EmptyRoles(t *testing.T) {
resetRBACState()
yaml := `
permissions:
- queue:view
roles:
empty_role: {}
`
path := writeTestYAML(t, yaml)
if err := LoadRBACConfig(path); err != nil {
t.Fatalf("LoadRBACConfig: %v", err)
}
if !store.Roles.Has("empty_role") {
t.Error("store should contain empty_role even with no permissions")
}
perms := store.GetRolePermissions("empty_role")
if len(perms) != 0 {
t.Errorf("empty_role permissions = %v, want empty", perms)
}
}
func TestLoadRBACConfig_FileNotFound(t *testing.T) {
resetRBACState()
err := LoadRBACConfig("/nonexistent/path/rbac.yaml")
if err == nil {
t.Error("expected error for nonexistent file")
}
}
// TestNoMockRBACMaps ensures the hardcoded mock group/queue maps have been removed.
// This is a compile-time check — if the vars exist, this test won't compile.
func TestNoMockRBACMaps(t *testing.T) {
// If hostGroupMap, userGroupMap, or queueMap still exist as package-level vars,
// the build will fail with "declared and not used" or similar.
// This test documents the intent: those vars must not exist.
t.Log("mock RBAC maps removed — OK")
}