callback_handler.go: test invalid upstream ID token username/groups

Signed-off-by: Ryan Richard <richardry@vmware.com>
This commit is contained in:
Andrew Keesler 2020-11-19 15:53:21 -05:00 committed by Ryan Richard
parent 83101eefce
commit b49d37ca54
No known key found for this signature in database
GPG Key ID: 27CE0444346F9413
2 changed files with 60 additions and 8 deletions

View File

@ -82,7 +82,11 @@ func NewHandler(
return err return err
} }
groups := getGroupsFromUpstreamIDToken(upstreamIDPConfig, idTokenClaims) groups, err := getGroupsFromUpstreamIDToken(upstreamIDPConfig, idTokenClaims)
if err != nil {
return err
}
openIDSession := makeDownstreamSession(downstreamIssuer, downstreamAuthParams.Get("client_id"), username, groups) openIDSession := makeDownstreamSession(downstreamIssuer, downstreamAuthParams.Get("client_id"), username, groups)
authorizeResponder, err := oauthHelper.NewAuthorizeResponse(r.Context(), authorizeRequester, openIDSession) authorizeResponder, err := oauthHelper.NewAuthorizeResponse(r.Context(), authorizeRequester, openIDSession)
if err != nil { if err != nil {
@ -209,7 +213,13 @@ func getUsernameFromUpstreamIDToken(
username, ok := usernameAsInterface.(string) username, ok := usernameAsInterface.(string)
if !ok { if !ok {
panic("todo bbb") // TODO plog.Warning(
"username claim in upstream ID token has invalid format",
"upstreamName", upstreamIDPConfig.GetName(),
"configuredUsernameClaim", upstreamIDPConfig.GetUsernameClaim(),
"usernameClaim", usernameClaim,
)
return "", httperr.New(http.StatusUnprocessableEntity, "username claim in upstream ID token has invalid format")
} }
return username, nil return username, nil
@ -218,23 +228,35 @@ func getUsernameFromUpstreamIDToken(
func getGroupsFromUpstreamIDToken( func getGroupsFromUpstreamIDToken(
upstreamIDPConfig provider.UpstreamOIDCIdentityProviderI, upstreamIDPConfig provider.UpstreamOIDCIdentityProviderI,
idTokenClaims map[string]interface{}, idTokenClaims map[string]interface{},
) []string { ) ([]string, error) {
groupsClaim := upstreamIDPConfig.GetGroupsClaim() groupsClaim := upstreamIDPConfig.GetGroupsClaim()
if groupsClaim == "" { if groupsClaim == "" {
return nil return nil, nil
} }
groupsAsInterface, ok := idTokenClaims[groupsClaim] groupsAsInterface, ok := idTokenClaims[groupsClaim]
if !ok { if !ok {
panic("todo ccc") // TODO plog.Warning(
"no groups claim in upstream ID token",
"upstreamName", upstreamIDPConfig.GetName(),
"configuredGroupsClaim", upstreamIDPConfig.GetGroupsClaim(),
"groupsClaim", groupsClaim,
)
return nil, httperr.New(http.StatusUnprocessableEntity, "no groups claim in upstream ID token")
} }
groups, ok := groupsAsInterface.([]string) groups, ok := groupsAsInterface.([]string)
if !ok { if !ok {
panic("todo ddd") // TODO plog.Warning(
"groups claim in upstream ID token has invalid format",
"upstreamName", upstreamIDPConfig.GetName(),
"configuredGroupsClaim", upstreamIDPConfig.GetGroupsClaim(),
"groupsClaim", groupsClaim,
)
return nil, httperr.New(http.StatusUnprocessableEntity, "groups claim in upstream ID token has invalid format")
} }
return groups return groups, nil
} }
func makeDownstreamSession(issuer, clientID, username string, groups []string) *openid.DefaultSession { func makeDownstreamSession(issuer, clientID, username string, groups []string) *openid.DefaultSession {

View File

@ -360,6 +360,36 @@ func TestCallbackEndpoint(t *testing.T) {
wantBody: "Unprocessable Entity: no username claim in upstream ID token\n", wantBody: "Unprocessable Entity: no username claim in upstream ID token\n",
wantExchangeAndValidateTokensCall: happyExchangeAndValidateTokensArgs, wantExchangeAndValidateTokensCall: happyExchangeAndValidateTokensArgs,
}, },
{
name: "upstream ID token does not contain requested groups claim",
idp: happyUpstream().WithoutIDTokenClaim(upstreamGroupsClaim).Build(),
method: http.MethodGet,
path: newRequestPath().WithState(happyState).WithCode(happyUpstreamAuthcode).String(),
csrfCookie: happyCSRFCookie,
wantStatus: http.StatusUnprocessableEntity,
wantBody: "Unprocessable Entity: no groups claim in upstream ID token\n",
wantExchangeAndValidateTokensCall: happyExchangeAndValidateTokensArgs,
},
{
name: "upstream ID token contains username claim with weird format",
idp: happyUpstream().WithIDTokenClaim(upstreamUsernameClaim, 42).Build(),
method: http.MethodGet,
path: newRequestPath().WithState(happyState).WithCode(happyUpstreamAuthcode).String(),
csrfCookie: happyCSRFCookie,
wantStatus: http.StatusUnprocessableEntity,
wantBody: "Unprocessable Entity: username claim in upstream ID token has invalid format\n",
wantExchangeAndValidateTokensCall: happyExchangeAndValidateTokensArgs,
},
{
name: "upstream ID token contains groups claim with weird format",
idp: happyUpstream().WithIDTokenClaim(upstreamGroupsClaim, 42).Build(),
method: http.MethodGet,
path: newRequestPath().WithState(happyState).WithCode(happyUpstreamAuthcode).String(),
csrfCookie: happyCSRFCookie,
wantStatus: http.StatusUnprocessableEntity,
wantBody: "Unprocessable Entity: groups claim in upstream ID token has invalid format\n",
wantExchangeAndValidateTokensCall: happyExchangeAndValidateTokensArgs,
},
} }
for _, test := range tests { for _, test := range tests {
test := test test := test
@ -531,7 +561,7 @@ func (u *upstreamOIDCIdentityProviderBuilder) WithoutGroupsClaim() *upstreamOIDC
return u return u
} }
func (u *upstreamOIDCIdentityProviderBuilder) WithIDTokenClaim(name, value string) *upstreamOIDCIdentityProviderBuilder { func (u *upstreamOIDCIdentityProviderBuilder) WithIDTokenClaim(name string, value interface{}) *upstreamOIDCIdentityProviderBuilder {
u.idToken[name] = value u.idToken[name] = value
return u return u
} }