add unit tests for oidc.IntrospectionResponse
- Changed UserInfoAddress to pointer in UserInfo and IntrospectionResponse. This was needed to make omitempty work correctly. - Copy or merge maps in IntrospectionResponse GetUserInfo and SetUserInfo
This commit is contained in:
parent
3940b520a8
commit
72a108a33b
8 changed files with 99 additions and 14 deletions
1
go.mod
1
go.mod
|
@ -10,6 +10,7 @@ require (
|
|||
github.com/gorilla/schema v1.2.0
|
||||
github.com/gorilla/securecookie v1.1.1
|
||||
github.com/jeremija/gosubmit v0.2.7
|
||||
github.com/muhlemmer/gu v0.2.0
|
||||
github.com/rs/cors v1.8.3
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
|
|
2
go.sum
2
go.sum
|
@ -123,6 +123,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
|||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/muhlemmer/gu v0.2.0 h1:vnIYZccxWVSPXbCPTuB1J7HWimMeZLlkfDody5qLUEI=
|
||||
github.com/muhlemmer/gu v0.2.0/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package oidc
|
||||
|
||||
import "github.com/muhlemmer/gu"
|
||||
|
||||
type IntrospectionRequest struct {
|
||||
Token string `schema:"token"`
|
||||
}
|
||||
|
@ -26,8 +28,8 @@ type IntrospectionResponse struct {
|
|||
UserInfoEmail
|
||||
UserInfoPhone
|
||||
|
||||
Address UserInfoAddress `json:"address,omitempty"`
|
||||
Claims map[string]any `json:"-"`
|
||||
Address *UserInfoAddress `json:"address,omitempty"`
|
||||
Claims map[string]any `json:"-"`
|
||||
}
|
||||
|
||||
// GetUserInfo copies all user related fields into a new UserInfo.
|
||||
|
@ -38,6 +40,7 @@ func (i *IntrospectionResponse) GetUserInfo() *UserInfo {
|
|||
UserInfoProfile: i.UserInfoProfile,
|
||||
UserInfoEmail: i.UserInfoEmail,
|
||||
UserInfoPhone: i.UserInfoPhone,
|
||||
Claims: gu.MapCopy(i.Claims),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,20 +48,25 @@ func (i *IntrospectionResponse) GetUserInfo() *UserInfo {
|
|||
// into the IntroSpectionResponse.
|
||||
func (i *IntrospectionResponse) SetUserInfo(u *UserInfo) {
|
||||
i.Subject = u.Subject
|
||||
i.Username = i.PreferredUsername
|
||||
i.Username = u.PreferredUsername
|
||||
i.Address = u.Address
|
||||
i.UserInfoProfile = u.UserInfoProfile
|
||||
i.UserInfoEmail = u.UserInfoEmail
|
||||
i.UserInfoPhone = u.UserInfoPhone
|
||||
if i.Claims == nil {
|
||||
i.Claims = gu.MapCopy(u.Claims)
|
||||
} else {
|
||||
gu.MapMerge(u.Claims, i.Claims)
|
||||
}
|
||||
}
|
||||
|
||||
// introspectionResponseAlias prevents loops on the JSON methods
|
||||
type introspectionResponseAlias IntrospectionResponse
|
||||
|
||||
func (i *IntrospectionResponse) MarshalJSON() ([]byte, error) {
|
||||
//TODO: set the username directly where the IntrospectionResponse is created
|
||||
// a.Username = i.PreferredUsername
|
||||
|
||||
if i.Username == "" {
|
||||
i.Username = i.PreferredUsername
|
||||
}
|
||||
return mergeAndMarshalClaims((*introspectionResponseAlias)(i), i.Claims)
|
||||
}
|
||||
|
||||
|
|
74
pkg/oidc/introspection_test.go
Normal file
74
pkg/oidc/introspection_test.go
Normal file
|
@ -0,0 +1,74 @@
|
|||
package oidc
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestIntrospectionResponse_GetUserInfo(t *testing.T) {
|
||||
got := introspectionResponseData.GetUserInfo()
|
||||
assert.Equal(t, userInfoData, got)
|
||||
}
|
||||
|
||||
func TestIntrospectionResponse_SetUserInfo(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
start *IntrospectionResponse
|
||||
want *IntrospectionResponse
|
||||
}{
|
||||
{
|
||||
|
||||
name: "nil claims",
|
||||
start: &IntrospectionResponse{},
|
||||
want: &IntrospectionResponse{
|
||||
Subject: userInfoData.Subject,
|
||||
Username: userInfoData.PreferredUsername,
|
||||
Address: userInfoData.Address,
|
||||
UserInfoProfile: userInfoData.UserInfoProfile,
|
||||
UserInfoEmail: userInfoData.UserInfoEmail,
|
||||
UserInfoPhone: userInfoData.UserInfoPhone,
|
||||
Claims: userInfoData.Claims,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
name: "merge claims",
|
||||
start: &IntrospectionResponse{
|
||||
Claims: map[string]any{
|
||||
"hello": "world",
|
||||
},
|
||||
},
|
||||
want: &IntrospectionResponse{
|
||||
Subject: userInfoData.Subject,
|
||||
Username: userInfoData.PreferredUsername,
|
||||
Address: userInfoData.Address,
|
||||
UserInfoProfile: userInfoData.UserInfoProfile,
|
||||
UserInfoEmail: userInfoData.UserInfoEmail,
|
||||
UserInfoPhone: userInfoData.UserInfoPhone,
|
||||
Claims: map[string]any{
|
||||
"foo": "bar",
|
||||
"hello": "world",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.start.SetUserInfo(userInfoData)
|
||||
assert.Equal(t, tt.want, tt.start)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntrospectionResponse_MarshalJSON(t *testing.T) {
|
||||
got, err := json.Marshal(&IntrospectionResponse{
|
||||
UserInfoProfile: UserInfoProfile{
|
||||
PreferredUsername: "muhlemmer",
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, string(got), `{"active":false,"username":"muhlemmer","preferred_username":"muhlemmer"}`)
|
||||
}
|
|
@ -113,8 +113,8 @@ type IDTokenClaims struct {
|
|||
UserInfoProfile
|
||||
UserInfoEmail
|
||||
UserInfoPhone
|
||||
Address UserInfoAddress `json:"address,omitempty"`
|
||||
Claims map[string]any `json:"-"`
|
||||
Address *UserInfoAddress `json:"address,omitempty"`
|
||||
Claims map[string]any `json:"-"`
|
||||
}
|
||||
|
||||
// GetAccessTokenHash implements the IDTokenClaims interface
|
||||
|
|
|
@ -96,7 +96,7 @@ var (
|
|||
PhoneNumber: "+1234567890",
|
||||
PhoneNumberVerified: true,
|
||||
},
|
||||
Address: UserInfoAddress{
|
||||
Address: &UserInfoAddress{
|
||||
Formatted: "Sesame street 666\n666-666, Smallvile\nMoon",
|
||||
StreetAddress: "Sesame street 666",
|
||||
Locality: "Smallvile",
|
||||
|
|
|
@ -5,7 +5,7 @@ type UserInfo struct {
|
|||
UserInfoProfile
|
||||
UserInfoEmail
|
||||
UserInfoPhone
|
||||
Address UserInfoAddress `json:"address,omitempty"`
|
||||
Address *UserInfoAddress `json:"address,omitempty"`
|
||||
|
||||
Claims map[string]any `json:"-"`
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
func TestUserInfoMarshal(t *testing.T) {
|
||||
userinfo := &UserInfo{
|
||||
Subject: "test",
|
||||
Address: UserInfoAddress{
|
||||
Address: &UserInfoAddress{
|
||||
StreetAddress: "Test 789\nPostfach 2",
|
||||
},
|
||||
UserInfoEmail: UserInfoEmail{
|
||||
|
@ -55,7 +55,7 @@ func TestUserInfoEmailVerifiedUnmarshal(t *testing.T) {
|
|||
}, uie)
|
||||
})
|
||||
|
||||
t.Run("unmarsha email_verified from json string true", func(t *testing.T) {
|
||||
t.Run("unmarshal email_verified from json string true", func(t *testing.T) {
|
||||
jsonBool := []byte(`{"email": "my@email.com", "email_verified": "true"}`)
|
||||
|
||||
var uie UserInfoEmail
|
||||
|
@ -68,7 +68,7 @@ func TestUserInfoEmailVerifiedUnmarshal(t *testing.T) {
|
|||
}, uie)
|
||||
})
|
||||
|
||||
t.Run("unmarsha email_verified from json bool false", func(t *testing.T) {
|
||||
t.Run("unmarshal email_verified from json bool false", func(t *testing.T) {
|
||||
jsonBool := []byte(`{"email": "my@email.com", "email_verified": false}`)
|
||||
|
||||
var uie UserInfoEmail
|
||||
|
@ -81,7 +81,7 @@ func TestUserInfoEmailVerifiedUnmarshal(t *testing.T) {
|
|||
}, uie)
|
||||
})
|
||||
|
||||
t.Run("unmarsha email_verified from json string false", func(t *testing.T) {
|
||||
t.Run("unmarshal email_verified from json string false", func(t *testing.T) {
|
||||
jsonBool := []byte(`{"email": "my@email.com", "email_verified": "false"}`)
|
||||
|
||||
var uie UserInfoEmail
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue