Ctrl K
ComunidadGuías…

pkg/auth/cloud_role_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package auth

import (
	"context"
	"testing"
)

func TestCloudRoleFromGroupsRadarVocabulary(t *testing.T) {
	cases := []struct {
		name   string
		groups []string
		want   CloudRole
	}{
		{"radar canonical", []string{"radar:member", "radar:org:o1", "radar:user:u1"}, RoleMember},
		{"dual-emit picks tier once", []string{"radar:viewer", "radar:org:o1", "cloud:viewer", "cloud:org:o1"}, RoleViewer},
		{"legacy cloud only (old hub)", []string{"cloud:owner", "cloud:org:o1"}, RoleOwner},
		{"idp groups are not tiers", []string{"radar:idp:owner", "radar:idp:member"}, RoleNone},
		{"highest rank wins across vocabularies", []string{"cloud:viewer", "radar:owner"}, RoleOwner},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			if got := CloudRoleFromGroups(tc.groups); got != tc.want {
				t.Errorf("CloudRoleFromGroups(%v) = %q, want %q", tc.groups, got, tc.want)
			}
		})
	}
}

func TestCloudRoleFromGroups(t *testing.T) {
	cases := []struct {
		name   string
		groups []string
		want   CloudRole
	}{
		{"empty groups", nil, RoleNone},
		{"no Radar prefix", []string{"developers", "sre"}, RoleNone},
		{"viewer", []string{"radar:viewer"}, RoleViewer},
		{"member", []string{"radar:member"}, RoleMember},
		{"owner", []string{"radar:owner"}, RoleOwner},
		{"unknown Radar tier", []string{"radar:superuser"}, RoleNone},
		{"viewer + unrelated group", []string{"radar:viewer", "team:platform"}, RoleViewer},
		// Cloud injects multiple radar:* groups (radar:<tier>, radar:org:<id>,
		// radar:user:<id>). Only the tier should drive the role.
		{"multiple Radar groups", []string{"radar:viewer", "radar:org:abc", "radar:user:xyz"}, RoleViewer},
		// If two tiers are present (shouldn't happen in practice), prefer
		// the highest. Defensive: a header-stuffing attempt to downgrade
		// shouldn't succeed by adding a lower-tier alongside.
		{"two tiers — pick highest", []string{"radar:viewer", "radar:owner"}, RoleOwner},
		{"member + viewer", []string{"radar:member", "radar:viewer"}, RoleMember},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			got := CloudRoleFromGroups(tc.groups)
			if got != tc.want {
				t.Errorf("CloudRoleFromGroups(%v) = %q, want %q", tc.groups, got, tc.want)
			}
		})
	}
}

func TestCloudRole_AtLeast(t *testing.T) {
	cases := []struct {
		role CloudRole
		min  CloudRole
		want bool
	}{
		// RoleNone bypasses — non-Cloud deploys must not be gated.
		{RoleNone, RoleViewer, true},
		{RoleNone, RoleMember, true},
		{RoleNone, RoleOwner, true},
		{RoleViewer, RoleViewer, true},
		{RoleViewer, RoleMember, false},
		{RoleViewer, RoleOwner, false},
		{RoleMember, RoleViewer, true},
		{RoleMember, RoleMember, true},
		{RoleMember, RoleOwner, false},
		{RoleOwner, RoleViewer, true},
		{RoleOwner, RoleMember, true},
		{RoleOwner, RoleOwner, true},
	}
	for _, tc := range cases {
		got := tc.role.AtLeast(tc.min)
		if got != tc.want {
			t.Errorf("CloudRole(%q).AtLeast(%q) = %v, want %v", tc.role, tc.min, got, tc.want)
		}
	}
}

func TestCloudRoleFromContext(t *testing.T) {
	t.Run("no user in context", func(t *testing.T) {
		if got := CloudRoleFromContext(context.Background()); got != RoleNone {
			t.Errorf("CloudRoleFromContext(empty) = %q, want RoleNone", got)
		}
	})
	t.Run("user with Cloud groups", func(t *testing.T) {
		ctx := ContextWithUser(context.Background(), &User{
			Username: "alice",
			Groups:   []string{"radar:member", "radar:org:abc"},
		})
		if got := CloudRoleFromContext(ctx); got != RoleMember {
			t.Errorf("CloudRoleFromContext = %q, want member", got)
		}
	})
	t.Run("user without Cloud groups (OSS proxy/oidc)", func(t *testing.T) {
		ctx := ContextWithUser(context.Background(), &User{
			Username: "bob",
			Groups:   []string{"sre", "platform-team"},
		})
		if got := CloudRoleFromContext(ctx); got != RoleNone {
			t.Errorf("CloudRoleFromContext = %q, want RoleNone (no radar: prefix)", got)
		}
	})
}