package oidc import ( "reflect" "testing" "git.ryuvia.com/niklas/terdut-server/internal/config" ) func testCfg() config.OIDC { return config.OIDC{ AllowedGroups: []string{"terdut-users"}, AdminGroup: "terdut-admins", } } func TestComputeGrants(t *testing.T) { tests := []struct { name string groups []string want Grants }{ { name: "not in an allowed group is refused", groups: []string{"sre", "terdut-admins"}, want: Grants{Admitted: false}, }, { name: "allowed but no grants", groups: []string{"terdut-users"}, want: Grants{Admitted: true}, }, { name: "admin group grants admin", groups: []string{"terdut-users", "terdut-admins"}, want: Grants{Admitted: true, Admin: true}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := ComputeGrants(testCfg(), tt.groups) if !reflect.DeepEqual(got, tt.want) { t.Errorf("got %+v, want %+v", got, tt.want) } }) } } func TestComputeGrants_NoAllowedGroupsAdmitsEveryone(t *testing.T) { cfg := testCfg() cfg.AllowedGroups = nil if g := ComputeGrants(cfg, nil); !g.Admitted { t.Error("with no allowed groups configured, everybody the provider authenticates is admitted") } } // testTeamGroups is one SRE team keyed off two groups (a member group and a // higher owner group) and one Platform team keyed off a member group only — // the same shape the old global TERDUT_OIDC_GROUP_MAPPINGS example used. func testTeamGroups() []TeamGroup { return []TeamGroup{ {TeamID: 1, MemberGroup: "sre", OwnerGroup: "sre-leads"}, {TeamID: 2, MemberGroup: "platform"}, } } func TestComputeTeamGrants(t *testing.T) { tests := []struct { name string teamGroups []TeamGroup groups []string want map[int64]string }{ { name: "no matching group grants nothing", teamGroups: testTeamGroups(), groups: []string{"terdut-users"}, want: map[int64]string{}, }, { name: "member group grants member", teamGroups: testTeamGroups(), groups: []string{"sre"}, want: map[int64]string{1: roleMember}, }, { name: "owner group grants owner", teamGroups: testTeamGroups(), groups: []string{"sre-leads"}, want: map[int64]string{1: roleOwner}, }, { name: "in both of a team's groups, owner wins", teamGroups: testTeamGroups(), groups: []string{"sre", "sre-leads"}, want: map[int64]string{1: roleOwner}, }, { name: "several teams from several groups", teamGroups: testTeamGroups(), groups: []string{"sre", "platform"}, want: map[int64]string{1: roleMember, 2: roleMember}, }, { name: "two teams may share a group", teamGroups: []TeamGroup{ {TeamID: 1, MemberGroup: "sre"}, {TeamID: 2, MemberGroup: "sre"}, }, groups: []string{"sre"}, want: map[int64]string{1: roleMember, 2: roleMember}, }, { name: "a team with neither field set is never granted", teamGroups: []TeamGroup{{TeamID: 1}}, groups: []string{"sre", "sre-leads", "platform"}, want: map[int64]string{}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := ComputeTeamGrants(tt.teamGroups, tt.groups) if !reflect.DeepEqual(got, tt.want) { t.Errorf("got %+v, want %+v", got, tt.want) } }) } } func TestStringList(t *testing.T) { if got := stringList([]any{"a", "", 3, "b"}); !reflect.DeepEqual(got, []string{"a", "b"}) { t.Errorf("list: %v", got) } if got := stringList("solo"); !reflect.DeepEqual(got, []string{"solo"}) { t.Errorf("single string: %v", got) } if got := stringList(nil); got != nil { t.Errorf("nil: %v", got) } }