Merge remote-tracking branch 'upstream/main' into callback-endpoint
This commit is contained in:
commit
25bbd28527
@ -11,6 +11,8 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -26,78 +28,124 @@ import (
|
||||
)
|
||||
|
||||
func TestSupervisorLogin(t *testing.T) {
|
||||
t.Skip("waiting on new callback path logic to get merged in from the callback endpoint work")
|
||||
|
||||
env := library.IntegrationEnv(t)
|
||||
client := library.NewSupervisorClientset(t)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
// Create downstream OIDC provider (i.e., update supervisor with OIDC provider).
|
||||
scheme := "http"
|
||||
addr := env.SupervisorHTTPAddress
|
||||
caBundle := ""
|
||||
path := "/some/path"
|
||||
issuer := fmt.Sprintf("https://%s%s", addr, path)
|
||||
_, _ = requireCreatingOIDCProviderCausesDiscoveryEndpointsToAppear(
|
||||
ctx,
|
||||
t,
|
||||
scheme,
|
||||
addr,
|
||||
caBundle,
|
||||
issuer,
|
||||
client,
|
||||
)
|
||||
|
||||
// Create HTTP client.
|
||||
httpClient := newHTTPClient(t, caBundle, nil)
|
||||
httpClient.CheckRedirect = func(_ *http.Request, _ []*http.Request) error {
|
||||
// Don't follow any redirects right now, since we simply want to validate that our auth endpoint
|
||||
// redirects us.
|
||||
return http.ErrUseLastResponse
|
||||
tests := []struct {
|
||||
Scheme string
|
||||
Address string
|
||||
CABundle string
|
||||
}{
|
||||
{Scheme: "http", Address: env.SupervisorHTTPAddress},
|
||||
{Scheme: "https", Address: env.SupervisorHTTPSIngressAddress, CABundle: env.SupervisorHTTPSIngressCABundle},
|
||||
}
|
||||
|
||||
// Declare the downstream auth endpoint url we will use.
|
||||
downstreamAuthURL := makeDownstreamAuthURL(t, scheme, addr, path)
|
||||
for _, test := range tests {
|
||||
scheme := test.Scheme
|
||||
addr := test.Address
|
||||
caBundle := test.CABundle
|
||||
|
||||
// Make request to auth endpoint - should fail, since we have no upstreams.
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, downstreamAuthURL, nil)
|
||||
require.NoError(t, err)
|
||||
rsp, err := httpClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer rsp.Body.Close()
|
||||
require.Equal(t, http.StatusUnprocessableEntity, rsp.StatusCode)
|
||||
if addr == "" {
|
||||
// Both cases are not required, so when one is empty skip it.
|
||||
continue
|
||||
}
|
||||
|
||||
// Create upstream OIDC provider.
|
||||
spec := idpv1alpha1.UpstreamOIDCProviderSpec{
|
||||
Issuer: env.SupervisorTestUpstream.Issuer,
|
||||
TLS: &idpv1alpha1.TLSSpec{
|
||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorTestUpstream.CABundle)),
|
||||
},
|
||||
Client: idpv1alpha1.OIDCClient{
|
||||
SecretName: makeTestClientCredsSecret(t, env.SupervisorTestUpstream.ClientID, env.SupervisorTestUpstream.ClientSecret).Name,
|
||||
},
|
||||
// Create downstream OIDC provider (i.e., update supervisor with OIDC provider).
|
||||
path := getDownstreamIssuerPathFromUpstreamRedirectURI(t, env.SupervisorTestUpstream.CallbackURL)
|
||||
issuer := fmt.Sprintf("https://%s%s", addr, path)
|
||||
_, _ = requireCreatingOIDCProviderCausesDiscoveryEndpointsToAppear(
|
||||
ctx,
|
||||
t,
|
||||
scheme,
|
||||
addr,
|
||||
caBundle,
|
||||
issuer,
|
||||
client,
|
||||
)
|
||||
|
||||
// Create HTTP client.
|
||||
httpClient := newHTTPClient(t, caBundle, nil)
|
||||
httpClient.CheckRedirect = func(_ *http.Request, _ []*http.Request) error {
|
||||
// Don't follow any redirects right now, since we simply want to validate that our auth endpoint
|
||||
// redirects us.
|
||||
return http.ErrUseLastResponse
|
||||
}
|
||||
|
||||
// Declare the downstream auth endpoint url we will use.
|
||||
downstreamAuthURL := makeDownstreamAuthURL(t, scheme, addr, path)
|
||||
|
||||
// Make request to auth endpoint - should fail, since we have no upstreams.
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, downstreamAuthURL, nil)
|
||||
require.NoError(t, err)
|
||||
rsp, err := httpClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer rsp.Body.Close()
|
||||
require.Equal(t, http.StatusUnprocessableEntity, rsp.StatusCode)
|
||||
|
||||
// Create upstream OIDC provider.
|
||||
spec := idpv1alpha1.UpstreamOIDCProviderSpec{
|
||||
Issuer: env.SupervisorTestUpstream.Issuer,
|
||||
TLS: &idpv1alpha1.TLSSpec{
|
||||
CertificateAuthorityData: base64.StdEncoding.EncodeToString([]byte(env.SupervisorTestUpstream.CABundle)),
|
||||
},
|
||||
Client: idpv1alpha1.OIDCClient{
|
||||
SecretName: makeTestClientCredsSecret(t, env.SupervisorTestUpstream.ClientID, env.SupervisorTestUpstream.ClientSecret).Name,
|
||||
},
|
||||
}
|
||||
upstream := makeTestUpstream(t, spec, idpv1alpha1.PhaseReady)
|
||||
|
||||
// Make request to authorize endpoint - should pass, since we now have an upstream.
|
||||
req, err = http.NewRequestWithContext(ctx, http.MethodGet, downstreamAuthURL, nil)
|
||||
require.NoError(t, err)
|
||||
rsp, err = httpClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer rsp.Body.Close()
|
||||
require.Equal(t, http.StatusFound, rsp.StatusCode)
|
||||
requireValidRedirectLocation(
|
||||
ctx,
|
||||
t,
|
||||
upstream.Spec.Issuer,
|
||||
env.SupervisorTestUpstream.ClientID,
|
||||
env.SupervisorTestUpstream.CallbackURL,
|
||||
rsp.Header.Get("Location"),
|
||||
)
|
||||
}
|
||||
upstream := makeTestUpstream(t, spec, idpv1alpha1.PhaseReady)
|
||||
|
||||
upstreamRedirectURI := fmt.Sprintf("https://%s/some/path/callback/%s", env.SupervisorHTTPAddress, upstream.Name)
|
||||
|
||||
// Make request to authorize endpoint - should pass, since we now have an upstream.
|
||||
req, err = http.NewRequestWithContext(ctx, http.MethodGet, downstreamAuthURL, nil)
|
||||
require.NoError(t, err)
|
||||
rsp, err = httpClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer rsp.Body.Close()
|
||||
require.Equal(t, http.StatusFound, rsp.StatusCode)
|
||||
requireValidRedirectLocation(
|
||||
ctx,
|
||||
t,
|
||||
upstream.Spec.Issuer,
|
||||
env.SupervisorTestUpstream.ClientID,
|
||||
upstreamRedirectURI,
|
||||
rsp.Header.Get("Location"),
|
||||
)
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
func getDownstreamIssuerPathFromUpstreamRedirectURI(t *testing.T, upstreamRedirectURI string) string {
|
||||
// We need to construct the downstream issuer path from the upstream redirect URI since the two
|
||||
// are related, and the upstream redirect URI is supplied via a static test environment
|
||||
// variable. The upstream redirect URI should be something like
|
||||
// https://supervisor.com/some/supervisor/path/callback
|
||||
// and therefore the downstream issuer should be something like
|
||||
// https://supervisor.com/some/supervisor/path
|
||||
// since the /callback endpoint is placed at the root of the downstream issuer path.
|
||||
upstreamRedirectURL, err := url.Parse(upstreamRedirectURI)
|
||||
require.NoError(t, err)
|
||||
|
||||
redirectURIPathWithoutLastSegment, lastUpstreamRedirectURIPathSegment := path.Split(upstreamRedirectURL.Path)
|
||||
require.Equalf(
|
||||
t,
|
||||
"callback",
|
||||
lastUpstreamRedirectURIPathSegment,
|
||||
"expected upstream redirect URI (%q) to follow supervisor callback path conventions (i.e., end in /callback)",
|
||||
upstreamRedirectURI,
|
||||
)
|
||||
|
||||
if strings.HasSuffix(redirectURIPathWithoutLastSegment, "/") {
|
||||
redirectURIPathWithoutLastSegment = redirectURIPathWithoutLastSegment[:len(redirectURIPathWithoutLastSegment)-1]
|
||||
}
|
||||
|
||||
return redirectURIPathWithoutLastSegment
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
func makeDownstreamAuthURL(t *testing.T, scheme, addr, path string) string {
|
||||
t.Helper()
|
||||
downstreamOAuth2Config := oauth2.Config{
|
||||
@ -119,6 +167,7 @@ func makeDownstreamAuthURL(t *testing.T, scheme, addr, path string) string {
|
||||
)
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
func generateAuthRequestParams(t *testing.T) (state.State, nonce.Nonce, pkce.Code) {
|
||||
t.Helper()
|
||||
state, err := state.Generate()
|
||||
@ -130,6 +179,7 @@ func generateAuthRequestParams(t *testing.T) (state.State, nonce.Nonce, pkce.Cod
|
||||
return state, nonce, pkce
|
||||
}
|
||||
|
||||
//nolint:unused
|
||||
func requireValidRedirectLocation(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
|
Loading…
Reference in New Issue
Block a user