callback_handler.go: test when state missing a needed param

Signed-off-by: Andrew Keesler <akeesler@vmware.com>
This commit is contained in:
Andrew Keesler 2020-11-19 08:51:23 -05:00
parent ffdb7fa795
commit 63b8c6e4b2
No known key found for this signature in database
GPG Key ID: 27CE0444346F9413
2 changed files with 45 additions and 5 deletions

View File

@ -36,14 +36,14 @@ func NewHandler(idpListGetter oidc.IDPListGetter, oauthHelper fosite.OAuth2Provi
downstreamAuthParams, err := url.ParseQuery(state.AuthParams)
if err != nil {
return httperr.New(http.StatusBadRequest, "error reading state's downstream auth params")
return httperr.New(http.StatusBadRequest, "error reading state downstream auth params")
}
// Recreate enough of the original authorize request so we can pass it to NewAuthorizeRequest().
reconstitutedAuthRequest := &http.Request{Form: downstreamAuthParams}
authorizeRequester, err := oauthHelper.NewAuthorizeRequest(r.Context(), reconstitutedAuthRequest)
if err != nil {
panic(err) // TODO
return httperr.New(http.StatusBadRequest, "error using state downstream auth params")
}
// TODO: grant the openid scope only if it was requested, similar to what we did in auth_handler.go

View File

@ -83,7 +83,7 @@ func TestCallbackEndpoint(t *testing.T) {
happyDownstreamState := "some-downstream-state"
happyOriginalRequestParams := url.Values{
happyOriginalRequestParamsQuery := url.Values{
"response_type": []string{"code"},
"scope": []string{"openid profile email"},
"client_id": []string{"pinniped-cli"},
@ -92,7 +92,8 @@ func TestCallbackEndpoint(t *testing.T) {
"code_challenge": []string{"some-challenge"},
"code_challenge_method": []string{"S256"},
"redirect_uri": []string{downstreamRedirectURI},
}.Encode()
}
happyOriginalRequestParams := happyOriginalRequestParamsQuery.Encode()
happyCSRF := "test-csrf"
happyPKCE := "test-pkce"
happyNonce := "test-nonce"
@ -142,6 +143,17 @@ func TestCallbackEndpoint(t *testing.T) {
)
require.NoError(t, err)
missingClientIDState, err := happyStateCodec.Encode("s",
testutil.ExpectedUpstreamStateParamFormat{
P: shallowCopyQueryExceptFor(happyOriginalRequestParamsQuery, "client_id").Encode(),
N: happyNonce,
C: happyCSRF,
K: happyPKCE,
V: happyStateVersion,
},
)
require.NoError(t, err)
encodedIncomingCookieCSRFValue, err := happyCookieCodec.Encode("csrf", happyCSRF)
require.NoError(t, err)
happyCSRFCookie := "__Host-pinniped-csrf=" + encodedIncomingCookieCSRFValue
@ -243,7 +255,16 @@ func TestCallbackEndpoint(t *testing.T) {
path: newRequestPath().WithState(wrongDownstreamAuthParamsState).String(),
csrfCookie: happyCSRFCookie,
wantStatus: http.StatusBadRequest,
wantBody: "Bad Request: error reading state's downstream auth params\n",
wantBody: "Bad Request: error reading state downstream auth params\n",
},
{
name: "state's downstream auth params are missing required value (e.g., client_id)",
idpListGetter: testutil.NewIDPListGetter(upstreamOIDCIdentityProvider),
method: http.MethodGet,
path: newRequestPath().WithState(missingClientIDState).String(),
csrfCookie: happyCSRFCookie,
wantStatus: http.StatusBadRequest,
wantBody: "Bad Request: error using state downstream auth params\n",
},
{
name: "the UpstreamOIDCProvider CRD has been deleted",
@ -388,3 +409,22 @@ func (r *requestPath) String() string {
}
return path + params.Encode()
}
func shallowCopyQueryExceptFor(query url.Values, keys ...string) url.Values {
copied := url.Values{}
for key, value := range query {
if !contains(keys, key) {
copied[key] = value
}
}
return copied
}
func contains(haystack []string, needle string) bool {
for _, hay := range haystack {
if hay == needle {
return true
}
}
return false
}