Integration tests call supervisor token endpoint and validate response
Signed-off-by: Aram Price <pricear@vmware.com>
This commit is contained in:
parent
ac19782405
commit
e0b6133bf1
@ -24,6 +24,7 @@ import (
|
|||||||
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/supervisor/config/v1alpha1"
|
configv1alpha1 "go.pinniped.dev/generated/1.19/apis/supervisor/config/v1alpha1"
|
||||||
idpv1alpha1 "go.pinniped.dev/generated/1.19/apis/supervisor/idp/v1alpha1"
|
idpv1alpha1 "go.pinniped.dev/generated/1.19/apis/supervisor/idp/v1alpha1"
|
||||||
"go.pinniped.dev/internal/certauthority"
|
"go.pinniped.dev/internal/certauthority"
|
||||||
|
"go.pinniped.dev/internal/testutil"
|
||||||
"go.pinniped.dev/pkg/oidcclient/nonce"
|
"go.pinniped.dev/pkg/oidcclient/nonce"
|
||||||
"go.pinniped.dev/pkg/oidcclient/pkce"
|
"go.pinniped.dev/pkg/oidcclient/pkce"
|
||||||
"go.pinniped.dev/pkg/oidcclient/state"
|
"go.pinniped.dev/pkg/oidcclient/state"
|
||||||
@ -67,6 +68,7 @@ func TestSupervisorLogin(t *testing.T) {
|
|||||||
return proxyURL, nil
|
return proxyURL, nil
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
oidcHttpClientContext := oidc.ClientContext(ctx, httpClient)
|
||||||
|
|
||||||
// Use the CA to issue a TLS server cert.
|
// Use the CA to issue a TLS server cert.
|
||||||
t.Logf("issuing test certificate")
|
t.Logf("issuing test certificate")
|
||||||
@ -109,7 +111,7 @@ func TestSupervisorLogin(t *testing.T) {
|
|||||||
// Perform OIDC discovery for our downstream.
|
// Perform OIDC discovery for our downstream.
|
||||||
var discovery *oidc.Provider
|
var discovery *oidc.Provider
|
||||||
assert.Eventually(t, func() bool {
|
assert.Eventually(t, func() bool {
|
||||||
discovery, err = oidc.NewProvider(oidc.ClientContext(ctx, httpClient), downstream.Spec.Issuer)
|
discovery, err = oidc.NewProvider(oidcHttpClientContext, downstream.Spec.Issuer)
|
||||||
return err == nil
|
return err == nil
|
||||||
}, 30*time.Second, 200*time.Millisecond)
|
}, 30*time.Second, 200*time.Millisecond)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -158,7 +160,43 @@ func TestSupervisorLogin(t *testing.T) {
|
|||||||
t.Logf("got callback request: %s", library.MaskTokens(callback.URL.String()))
|
t.Logf("got callback request: %s", library.MaskTokens(callback.URL.String()))
|
||||||
require.Equal(t, stateParam.String(), callback.URL.Query().Get("state"))
|
require.Equal(t, stateParam.String(), callback.URL.Query().Get("state"))
|
||||||
require.Equal(t, "openid", callback.URL.Query().Get("scope"))
|
require.Equal(t, "openid", callback.URL.Query().Get("scope"))
|
||||||
require.NotEmpty(t, callback.URL.Query().Get("code"))
|
authcode := callback.URL.Query().Get("code")
|
||||||
|
require.NotEmpty(t, authcode)
|
||||||
|
|
||||||
|
// Call the token endpoint to get tokens.
|
||||||
|
tokenResponse, err := downstreamOAuth2Config.Exchange(oidcHttpClientContext, authcode, pkceParam.Verifier())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify the ID Token.
|
||||||
|
rawIDToken, ok := tokenResponse.Extra("id_token").(string)
|
||||||
|
require.True(t, ok, "expected to get an ID token but did not")
|
||||||
|
var verifier = discovery.Verifier(&oidc.Config{ClientID: downstreamOAuth2Config.ClientID})
|
||||||
|
idToken, err := verifier.Verify(ctx, rawIDToken)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Check the claims of the ID token.
|
||||||
|
expectedSubjectPrefix := env.SupervisorTestUpstream.Issuer + "?sub="
|
||||||
|
require.True(t, strings.HasPrefix(idToken.Subject, expectedSubjectPrefix))
|
||||||
|
require.Greater(t, len(idToken.Subject), len(expectedSubjectPrefix),
|
||||||
|
"the ID token Subject should include the upstream user ID after the upstream issuer name")
|
||||||
|
require.NoError(t, nonceParam.Validate(idToken))
|
||||||
|
testutil.RequireTimeInDelta(t, time.Now().UTC().Add(time.Minute*5), idToken.Expiry, time.Second*30)
|
||||||
|
idTokenClaims := map[string]interface{}{}
|
||||||
|
err = idToken.Claims(&idTokenClaims)
|
||||||
|
require.NoError(t, err)
|
||||||
|
idTokenClaimNames := []string{}
|
||||||
|
for k := range idTokenClaims {
|
||||||
|
idTokenClaimNames = append(idTokenClaimNames, k)
|
||||||
|
}
|
||||||
|
require.ElementsMatch(t, []string{"iss", "exp", "sub", "aud", "auth_time", "iat", "jti", "nonce", "rat"}, idTokenClaimNames)
|
||||||
|
|
||||||
|
// Some light verification of the other tokens that were returned.
|
||||||
|
require.NotEmpty(t, tokenResponse.AccessToken)
|
||||||
|
require.Equal(t, "bearer", tokenResponse.TokenType)
|
||||||
|
require.NotZero(t, tokenResponse.Expiry)
|
||||||
|
testutil.RequireTimeInDelta(t, time.Now().UTC().Add(time.Minute*5), tokenResponse.Expiry, time.Second*30)
|
||||||
|
|
||||||
|
require.Empty(t, tokenResponse.RefreshToken) // for now, until the next user story :)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startLocalCallbackServer(t *testing.T) *localCallbackServer {
|
func startLocalCallbackServer(t *testing.T) *localCallbackServer {
|
||||||
|
Loading…
Reference in New Issue
Block a user