From a2a6ca17022958a0c1682fd37bcc7cfa83346a1a Mon Sep 17 00:00:00 2001 From: Martin Norberg Date: Mon, 9 Mar 2026 16:39:49 +0100 Subject: [PATCH 1/2] fix: tolerate string amr claims from external providers --- pkg/oidc/introspection.go | 52 ++++++++++++++++++++++++- pkg/oidc/token.go | 82 ++++++++++++++++++++++++++++++++++++++- pkg/oidc/token_test.go | 15 +++++++ pkg/oidc/types.go | 25 ++++++++++++ pkg/oidc/types_test.go | 44 +++++++++++++++++++++ 5 files changed, 214 insertions(+), 4 deletions(-) diff --git a/pkg/oidc/introspection.go b/pkg/oidc/introspection.go index 1a200ebb..281616ed 100644 --- a/pkg/oidc/introspection.go +++ b/pkg/oidc/introspection.go @@ -1,6 +1,11 @@ package oidc -import "github.com/muhlemmer/gu" +import ( + "encoding/json" + "fmt" + + "github.com/muhlemmer/gu" +) type IntrospectionRequest struct { Token string `schema:"token"` @@ -75,5 +80,48 @@ func (i *IntrospectionResponse) MarshalJSON() ([]byte, error) { } func (i *IntrospectionResponse) UnmarshalJSON(data []byte) error { - return unmarshalJSONMulti(data, (*introspectionResponseAlias)(i), &i.Claims) + var dst struct { + Active bool `json:"active"` + Scope SpaceDelimitedArray `json:"scope,omitempty"` + ClientID string `json:"client_id,omitempty"` + TokenType string `json:"token_type,omitempty"` + Expiration Time `json:"exp,omitempty"` + IssuedAt Time `json:"iat,omitempty"` + AuthTime Time `json:"auth_time,omitempty"` + NotBefore Time `json:"nbf,omitempty"` + Subject string `json:"sub,omitempty"` + Audience Audience `json:"aud,omitempty"` + AuthenticationMethodsReferences authMethodRefs `json:"amr,omitempty"` + Issuer string `json:"iss,omitempty"` + JWTID string `json:"jti,omitempty"` + Username string `json:"username,omitempty"` + Actor *ActorClaims `json:"act,omitempty"` + UserInfoProfile + UserInfoEmail + UserInfoPhone + Address *UserInfoAddress `json:"address,omitempty"` + } + if err := json.Unmarshal(data, &dst); err != nil { + return fmt.Errorf("oidc: %w into %T", err, (*introspectionResponseAlias)(i)) + } + i.Active = dst.Active + i.Scope = dst.Scope + i.ClientID = dst.ClientID + i.TokenType = dst.TokenType + i.Expiration = dst.Expiration + i.IssuedAt = dst.IssuedAt + i.AuthTime = dst.AuthTime + i.NotBefore = dst.NotBefore + i.Subject = dst.Subject + i.Audience = dst.Audience + i.AuthenticationMethodsReferences = []string(dst.AuthenticationMethodsReferences) + i.Issuer = dst.Issuer + i.JWTID = dst.JWTID + i.Username = dst.Username + i.Actor = dst.Actor + i.UserInfoProfile = dst.UserInfoProfile + i.UserInfoEmail = dst.UserInfoEmail + i.UserInfoPhone = dst.UserInfoPhone + i.Address = dst.Address + return unmarshalJSONMulti(data, &i.Claims) } diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index d2b6f6d4..65fee712 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -2,6 +2,7 @@ package oidc import ( "encoding/json" + "fmt" "os" "time" @@ -54,6 +55,51 @@ type TokenClaims struct { SignatureAlg jose.SignatureAlgorithm `json:"-"` } +type tokenClaimsJSON struct { + Issuer string `json:"iss,omitempty"` + Subject string `json:"sub,omitempty"` + Audience Audience `json:"aud,omitempty"` + Expiration Time `json:"exp,omitempty"` + IssuedAt Time `json:"iat,omitempty"` + AuthTime Time `json:"auth_time,omitempty"` + NotBefore Time `json:"nbf,omitempty"` + Nonce string `json:"nonce,omitempty"` + AuthenticationContextClassReference string `json:"acr,omitempty"` + AuthenticationMethodsReferences authMethodRefs `json:"amr,omitempty"` + AuthorizedParty string `json:"azp,omitempty"` + ClientID string `json:"client_id,omitempty"` + JWTID string `json:"jti,omitempty"` + Actor *ActorClaims `json:"act,omitempty"` +} + +func (j tokenClaimsJSON) tokenClaims() TokenClaims { + return TokenClaims{ + Issuer: j.Issuer, + Subject: j.Subject, + Audience: j.Audience, + Expiration: j.Expiration, + IssuedAt: j.IssuedAt, + AuthTime: j.AuthTime, + NotBefore: j.NotBefore, + Nonce: j.Nonce, + AuthenticationContextClassReference: j.AuthenticationContextClassReference, + AuthenticationMethodsReferences: []string(j.AuthenticationMethodsReferences), + AuthorizedParty: j.AuthorizedParty, + ClientID: j.ClientID, + JWTID: j.JWTID, + Actor: j.Actor, + } +} + +func (c *TokenClaims) UnmarshalJSON(data []byte) error { + var dst tokenClaimsJSON + if err := json.Unmarshal(data, &dst); err != nil { + return fmt.Errorf("oidc: %w into %T", err, c) + } + *c = dst.tokenClaims() + return nil +} + func (c *TokenClaims) GetIssuer() string { return c.Issuer } @@ -130,7 +176,16 @@ func (a *AccessTokenClaims) MarshalJSON() ([]byte, error) { } func (a *AccessTokenClaims) UnmarshalJSON(data []byte) error { - return unmarshalJSONMulti(data, (*atcAlias)(a), &a.Claims) + var dst struct { + tokenClaimsJSON + Scopes SpaceDelimitedArray `json:"scope,omitempty"` + } + if err := json.Unmarshal(data, &dst); err != nil { + return fmt.Errorf("oidc: %w into %T", err, (*atcAlias)(a)) + } + a.TokenClaims = dst.tokenClaims() + a.Scopes = dst.Scopes + return unmarshalJSONMulti(data, &a.Claims) } // IDTokenClaims extends TokenClaims by further implementing @@ -204,7 +259,30 @@ func (i *IDTokenClaims) MarshalJSON() ([]byte, error) { } func (i *IDTokenClaims) UnmarshalJSON(data []byte) error { - return unmarshalJSONMulti(data, (*itcAlias)(i), &i.Claims) + var dst struct { + tokenClaimsJSON + NotBefore Time `json:"nbf,omitempty"` + AccessTokenHash string `json:"at_hash,omitempty"` + CodeHash string `json:"c_hash,omitempty"` + SessionID string `json:"sid,omitempty"` + UserInfoProfile + UserInfoEmail + UserInfoPhone + Address *UserInfoAddress `json:"address,omitempty"` + } + if err := json.Unmarshal(data, &dst); err != nil { + return fmt.Errorf("oidc: %w into %T", err, (*itcAlias)(i)) + } + i.TokenClaims = dst.tokenClaims() + i.NotBefore = dst.NotBefore + i.AccessTokenHash = dst.AccessTokenHash + i.CodeHash = dst.CodeHash + i.SessionID = dst.SessionID + i.UserInfoProfile = dst.UserInfoProfile + i.UserInfoEmail = dst.UserInfoEmail + i.UserInfoPhone = dst.UserInfoPhone + i.Address = dst.Address + return unmarshalJSONMulti(data, &i.Claims) } // ActorClaims provides the `act` claims used for impersonation or delegation Token Exchange. diff --git a/pkg/oidc/token_test.go b/pkg/oidc/token_test.go index 621cdbc0..aa1eb354 100644 --- a/pkg/oidc/token_test.go +++ b/pkg/oidc/token_test.go @@ -1,6 +1,7 @@ package oidc import ( + "encoding/json" "testing" "time" @@ -243,6 +244,20 @@ func TestIDTokenClaims_GetUserInfo(t *testing.T) { assert.Equal(t, want, got) } +func TestIDTokenClaims_UnmarshalJSON_StringAMR(t *testing.T) { + var got IDTokenClaims + err := json.Unmarshal([]byte(`{"iss":"zitadel","sub":"hello@me.com","aud":"foo","exp":12345,"iat":12000,"amr":"pwd"}`), &got) + assert.NoError(t, err) + assert.Equal(t, []string{"pwd"}, got.AuthenticationMethodsReferences) +} + +func TestIntrospectionResponse_UnmarshalJSON_StringAMR(t *testing.T) { + var got IntrospectionResponse + err := json.Unmarshal([]byte(`{"active":true,"sub":"hello@me.com","amr":"pwd"}`), &got) + assert.NoError(t, err) + assert.Equal(t, []string{"pwd"}, got.AuthenticationMethodsReferences) +} + func TestNewLogoutTokenClaims(t *testing.T) { want := &LogoutTokenClaims{ Issuer: "zitadel", diff --git a/pkg/oidc/types.go b/pkg/oidc/types.go index 33ad2d5d..6a0ca100 100644 --- a/pkg/oidc/types.go +++ b/pkg/oidc/types.go @@ -35,6 +35,31 @@ func (a *Audience) UnmarshalJSON(text []byte) error { return nil } +type authMethodRefs []string + +func (a *authMethodRefs) UnmarshalJSON(data []byte) error { + var dst any + if err := json.Unmarshal(data, &dst); err != nil { + return fmt.Errorf("oidc amr: %w", err) + } + + switch v := dst.(type) { + case nil: + *a = nil + case string: + *a = authMethodRefs{v} + case []any: + refs, err := gu.AssertInterfaces[string](v) + if err != nil { + return fmt.Errorf("oidc amr: %w", err) + } + *a = refs + default: + return fmt.Errorf("oidc amr: unsupported type: %T", v) + } + return nil +} + type Display string func (d *Display) UnmarshalText(text []byte) error { diff --git a/pkg/oidc/types_test.go b/pkg/oidc/types_test.go index 53a97796..764c19fc 100644 --- a/pkg/oidc/types_test.go +++ b/pkg/oidc/types_test.go @@ -70,6 +70,50 @@ func TestAudience_UnmarshalText(t *testing.T) { } } +func TestAuthMethodRefs_UnmarshalJSON(t *testing.T) { + tests := []struct { + name string + input string + want authMethodRefs + wantErr bool + }{ + { + name: "single auth method", + input: `{"amr":"pwd"}`, + want: authMethodRefs{"pwd"}, + }, + { + name: "multiple auth methods", + input: `{"amr":["pwd","mfa"]}`, + want: authMethodRefs{"pwd", "mfa"}, + }, + { + name: "null", + input: `{"amr":null}`, + }, + { + name: "invalid type", + input: `{"amr":1}`, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var got struct { + AMR authMethodRefs `json:"amr,omitempty"` + } + err := json.Unmarshal([]byte(tt.input), &got) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + assert.Equal(t, tt.want, got.AMR) + }) + } +} + func TestDisplay_UnmarshalText(t *testing.T) { type args struct { text []byte From d52f8be2ee89dfe5a41a17437c8c743c2af13666 Mon Sep 17 00:00:00 2001 From: Martin Norberg Date: Thu, 9 Apr 2026 19:08:44 +0200 Subject: [PATCH 2/2] refactor: use same patterns as audience custom deserializer --- pkg/oidc/introspection.go | 82 ++++++---------------------- pkg/oidc/token.go | 110 ++++++-------------------------------- pkg/oidc/token_test.go | 4 +- pkg/oidc/types.go | 8 +-- pkg/oidc/types_test.go | 10 ++-- 5 files changed, 44 insertions(+), 170 deletions(-) diff --git a/pkg/oidc/introspection.go b/pkg/oidc/introspection.go index 281616ed..28dcde9a 100644 --- a/pkg/oidc/introspection.go +++ b/pkg/oidc/introspection.go @@ -1,11 +1,6 @@ package oidc -import ( - "encoding/json" - "fmt" - - "github.com/muhlemmer/gu" -) +import "github.com/muhlemmer/gu" type IntrospectionRequest struct { Token string `schema:"token"` @@ -21,21 +16,21 @@ type ClientAssertionParams struct { // https://www.rfc-editor.org/rfc/rfc7662.html#section-2.2. // https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims. type IntrospectionResponse struct { - Active bool `json:"active"` - Scope SpaceDelimitedArray `json:"scope,omitempty"` - ClientID string `json:"client_id,omitempty"` - TokenType string `json:"token_type,omitempty"` - Expiration Time `json:"exp,omitempty"` - IssuedAt Time `json:"iat,omitempty"` - AuthTime Time `json:"auth_time,omitempty"` - NotBefore Time `json:"nbf,omitempty"` - Subject string `json:"sub,omitempty"` - Audience Audience `json:"aud,omitempty"` - AuthenticationMethodsReferences []string `json:"amr,omitempty"` - Issuer string `json:"iss,omitempty"` - JWTID string `json:"jti,omitempty"` - Username string `json:"username,omitempty"` - Actor *ActorClaims `json:"act,omitempty"` + Active bool `json:"active"` + Scope SpaceDelimitedArray `json:"scope,omitempty"` + ClientID string `json:"client_id,omitempty"` + TokenType string `json:"token_type,omitempty"` + Expiration Time `json:"exp,omitempty"` + IssuedAt Time `json:"iat,omitempty"` + AuthTime Time `json:"auth_time,omitempty"` + NotBefore Time `json:"nbf,omitempty"` + Subject string `json:"sub,omitempty"` + Audience Audience `json:"aud,omitempty"` + AuthenticationMethodsReferences AuthenticationMethodsReferences `json:"amr,omitempty"` + Issuer string `json:"iss,omitempty"` + JWTID string `json:"jti,omitempty"` + Username string `json:"username,omitempty"` + Actor *ActorClaims `json:"act,omitempty"` UserInfoProfile UserInfoEmail UserInfoPhone @@ -80,48 +75,5 @@ func (i *IntrospectionResponse) MarshalJSON() ([]byte, error) { } func (i *IntrospectionResponse) UnmarshalJSON(data []byte) error { - var dst struct { - Active bool `json:"active"` - Scope SpaceDelimitedArray `json:"scope,omitempty"` - ClientID string `json:"client_id,omitempty"` - TokenType string `json:"token_type,omitempty"` - Expiration Time `json:"exp,omitempty"` - IssuedAt Time `json:"iat,omitempty"` - AuthTime Time `json:"auth_time,omitempty"` - NotBefore Time `json:"nbf,omitempty"` - Subject string `json:"sub,omitempty"` - Audience Audience `json:"aud,omitempty"` - AuthenticationMethodsReferences authMethodRefs `json:"amr,omitempty"` - Issuer string `json:"iss,omitempty"` - JWTID string `json:"jti,omitempty"` - Username string `json:"username,omitempty"` - Actor *ActorClaims `json:"act,omitempty"` - UserInfoProfile - UserInfoEmail - UserInfoPhone - Address *UserInfoAddress `json:"address,omitempty"` - } - if err := json.Unmarshal(data, &dst); err != nil { - return fmt.Errorf("oidc: %w into %T", err, (*introspectionResponseAlias)(i)) - } - i.Active = dst.Active - i.Scope = dst.Scope - i.ClientID = dst.ClientID - i.TokenType = dst.TokenType - i.Expiration = dst.Expiration - i.IssuedAt = dst.IssuedAt - i.AuthTime = dst.AuthTime - i.NotBefore = dst.NotBefore - i.Subject = dst.Subject - i.Audience = dst.Audience - i.AuthenticationMethodsReferences = []string(dst.AuthenticationMethodsReferences) - i.Issuer = dst.Issuer - i.JWTID = dst.JWTID - i.Username = dst.Username - i.Actor = dst.Actor - i.UserInfoProfile = dst.UserInfoProfile - i.UserInfoEmail = dst.UserInfoEmail - i.UserInfoPhone = dst.UserInfoPhone - i.Address = dst.Address - return unmarshalJSONMulti(data, &i.Claims) + return unmarshalJSONMulti(data, (*introspectionResponseAlias)(i), &i.Claims) } diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index 65fee712..e1a0ae93 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -2,7 +2,6 @@ package oidc import ( "encoding/json" - "fmt" "os" "time" @@ -36,70 +35,25 @@ type Tokens[C IDClaims] struct { // TokenClaims implements the Claims interface, // and can be used to extend larger claim types by embedding. type TokenClaims struct { - Issuer string `json:"iss,omitempty"` - Subject string `json:"sub,omitempty"` - Audience Audience `json:"aud,omitempty"` - Expiration Time `json:"exp,omitempty"` - IssuedAt Time `json:"iat,omitempty"` - AuthTime Time `json:"auth_time,omitempty"` - NotBefore Time `json:"nbf,omitempty"` - Nonce string `json:"nonce,omitempty"` - AuthenticationContextClassReference string `json:"acr,omitempty"` - AuthenticationMethodsReferences []string `json:"amr,omitempty"` - AuthorizedParty string `json:"azp,omitempty"` - ClientID string `json:"client_id,omitempty"` - JWTID string `json:"jti,omitempty"` - Actor *ActorClaims `json:"act,omitempty"` + Issuer string `json:"iss,omitempty"` + Subject string `json:"sub,omitempty"` + Audience Audience `json:"aud,omitempty"` + Expiration Time `json:"exp,omitempty"` + IssuedAt Time `json:"iat,omitempty"` + AuthTime Time `json:"auth_time,omitempty"` + NotBefore Time `json:"nbf,omitempty"` + Nonce string `json:"nonce,omitempty"` + AuthenticationContextClassReference string `json:"acr,omitempty"` + AuthenticationMethodsReferences AuthenticationMethodsReferences `json:"amr,omitempty"` + AuthorizedParty string `json:"azp,omitempty"` + ClientID string `json:"client_id,omitempty"` + JWTID string `json:"jti,omitempty"` + Actor *ActorClaims `json:"act,omitempty"` // Additional information set by this framework SignatureAlg jose.SignatureAlgorithm `json:"-"` } -type tokenClaimsJSON struct { - Issuer string `json:"iss,omitempty"` - Subject string `json:"sub,omitempty"` - Audience Audience `json:"aud,omitempty"` - Expiration Time `json:"exp,omitempty"` - IssuedAt Time `json:"iat,omitempty"` - AuthTime Time `json:"auth_time,omitempty"` - NotBefore Time `json:"nbf,omitempty"` - Nonce string `json:"nonce,omitempty"` - AuthenticationContextClassReference string `json:"acr,omitempty"` - AuthenticationMethodsReferences authMethodRefs `json:"amr,omitempty"` - AuthorizedParty string `json:"azp,omitempty"` - ClientID string `json:"client_id,omitempty"` - JWTID string `json:"jti,omitempty"` - Actor *ActorClaims `json:"act,omitempty"` -} - -func (j tokenClaimsJSON) tokenClaims() TokenClaims { - return TokenClaims{ - Issuer: j.Issuer, - Subject: j.Subject, - Audience: j.Audience, - Expiration: j.Expiration, - IssuedAt: j.IssuedAt, - AuthTime: j.AuthTime, - NotBefore: j.NotBefore, - Nonce: j.Nonce, - AuthenticationContextClassReference: j.AuthenticationContextClassReference, - AuthenticationMethodsReferences: []string(j.AuthenticationMethodsReferences), - AuthorizedParty: j.AuthorizedParty, - ClientID: j.ClientID, - JWTID: j.JWTID, - Actor: j.Actor, - } -} - -func (c *TokenClaims) UnmarshalJSON(data []byte) error { - var dst tokenClaimsJSON - if err := json.Unmarshal(data, &dst); err != nil { - return fmt.Errorf("oidc: %w into %T", err, c) - } - *c = dst.tokenClaims() - return nil -} - func (c *TokenClaims) GetIssuer() string { return c.Issuer } @@ -176,16 +130,7 @@ func (a *AccessTokenClaims) MarshalJSON() ([]byte, error) { } func (a *AccessTokenClaims) UnmarshalJSON(data []byte) error { - var dst struct { - tokenClaimsJSON - Scopes SpaceDelimitedArray `json:"scope,omitempty"` - } - if err := json.Unmarshal(data, &dst); err != nil { - return fmt.Errorf("oidc: %w into %T", err, (*atcAlias)(a)) - } - a.TokenClaims = dst.tokenClaims() - a.Scopes = dst.Scopes - return unmarshalJSONMulti(data, &a.Claims) + return unmarshalJSONMulti(data, (*atcAlias)(a), &a.Claims) } // IDTokenClaims extends TokenClaims by further implementing @@ -259,30 +204,7 @@ func (i *IDTokenClaims) MarshalJSON() ([]byte, error) { } func (i *IDTokenClaims) UnmarshalJSON(data []byte) error { - var dst struct { - tokenClaimsJSON - NotBefore Time `json:"nbf,omitempty"` - AccessTokenHash string `json:"at_hash,omitempty"` - CodeHash string `json:"c_hash,omitempty"` - SessionID string `json:"sid,omitempty"` - UserInfoProfile - UserInfoEmail - UserInfoPhone - Address *UserInfoAddress `json:"address,omitempty"` - } - if err := json.Unmarshal(data, &dst); err != nil { - return fmt.Errorf("oidc: %w into %T", err, (*itcAlias)(i)) - } - i.TokenClaims = dst.tokenClaims() - i.NotBefore = dst.NotBefore - i.AccessTokenHash = dst.AccessTokenHash - i.CodeHash = dst.CodeHash - i.SessionID = dst.SessionID - i.UserInfoProfile = dst.UserInfoProfile - i.UserInfoEmail = dst.UserInfoEmail - i.UserInfoPhone = dst.UserInfoPhone - i.Address = dst.Address - return unmarshalJSONMulti(data, &i.Claims) + return unmarshalJSONMulti(data, (*itcAlias)(i), &i.Claims) } // ActorClaims provides the `act` claims used for impersonation or delegation Token Exchange. diff --git a/pkg/oidc/token_test.go b/pkg/oidc/token_test.go index aa1eb354..66da3393 100644 --- a/pkg/oidc/token_test.go +++ b/pkg/oidc/token_test.go @@ -248,14 +248,14 @@ func TestIDTokenClaims_UnmarshalJSON_StringAMR(t *testing.T) { var got IDTokenClaims err := json.Unmarshal([]byte(`{"iss":"zitadel","sub":"hello@me.com","aud":"foo","exp":12345,"iat":12000,"amr":"pwd"}`), &got) assert.NoError(t, err) - assert.Equal(t, []string{"pwd"}, got.AuthenticationMethodsReferences) + assert.Equal(t, AuthenticationMethodsReferences{"pwd"}, got.AuthenticationMethodsReferences) } func TestIntrospectionResponse_UnmarshalJSON_StringAMR(t *testing.T) { var got IntrospectionResponse err := json.Unmarshal([]byte(`{"active":true,"sub":"hello@me.com","amr":"pwd"}`), &got) assert.NoError(t, err) - assert.Equal(t, []string{"pwd"}, got.AuthenticationMethodsReferences) + assert.Equal(t, AuthenticationMethodsReferences{"pwd"}, got.AuthenticationMethodsReferences) } func TestNewLogoutTokenClaims(t *testing.T) { diff --git a/pkg/oidc/types.go b/pkg/oidc/types.go index 6a0ca100..12fddc50 100644 --- a/pkg/oidc/types.go +++ b/pkg/oidc/types.go @@ -35,9 +35,9 @@ func (a *Audience) UnmarshalJSON(text []byte) error { return nil } -type authMethodRefs []string +type AuthenticationMethodsReferences []string -func (a *authMethodRefs) UnmarshalJSON(data []byte) error { +func (a *AuthenticationMethodsReferences) UnmarshalJSON(data []byte) error { var dst any if err := json.Unmarshal(data, &dst); err != nil { return fmt.Errorf("oidc amr: %w", err) @@ -47,13 +47,13 @@ func (a *authMethodRefs) UnmarshalJSON(data []byte) error { case nil: *a = nil case string: - *a = authMethodRefs{v} + *a = AuthenticationMethodsReferences{v} case []any: refs, err := gu.AssertInterfaces[string](v) if err != nil { return fmt.Errorf("oidc amr: %w", err) } - *a = refs + *a = AuthenticationMethodsReferences(refs) default: return fmt.Errorf("oidc amr: unsupported type: %T", v) } diff --git a/pkg/oidc/types_test.go b/pkg/oidc/types_test.go index 764c19fc..7d403c7c 100644 --- a/pkg/oidc/types_test.go +++ b/pkg/oidc/types_test.go @@ -70,22 +70,22 @@ func TestAudience_UnmarshalText(t *testing.T) { } } -func TestAuthMethodRefs_UnmarshalJSON(t *testing.T) { +func TestAuthenticationMethodsReferences_UnmarshalJSON(t *testing.T) { tests := []struct { name string input string - want authMethodRefs + want AuthenticationMethodsReferences wantErr bool }{ { name: "single auth method", input: `{"amr":"pwd"}`, - want: authMethodRefs{"pwd"}, + want: AuthenticationMethodsReferences{"pwd"}, }, { name: "multiple auth methods", input: `{"amr":["pwd","mfa"]}`, - want: authMethodRefs{"pwd", "mfa"}, + want: AuthenticationMethodsReferences{"pwd", "mfa"}, }, { name: "null", @@ -101,7 +101,7 @@ func TestAuthMethodRefs_UnmarshalJSON(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { var got struct { - AMR authMethodRefs `json:"amr,omitempty"` + AMR AuthenticationMethodsReferences `json:"amr,omitempty"` } err := json.Unmarshal([]byte(tt.input), &got) if tt.wantErr {