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") }