oauth2-proxy/oauthproxy_lazy_test.go

98 lines
3.0 KiB
Go

package main
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/util/ptr"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/validation"
"github.com/oauth2-proxy/oauth2-proxy/v7/providers"
. "github.com/onsi/gomega"
)
// newLazyPendingProxy builds a proxy whose OIDC issuer is unreachable with lazy
// discovery enabled. Start is not called, so background discovery never runs and
// the provider stays not-ready for the duration of the test.
func newLazyPendingProxy(g *WithT) *OAuthProxy {
opts := baseTestOptions()
opts.Providers[0].Type = "oidc"
opts.Providers[0].OIDCConfig = options.OIDCOptions{
IssuerURL: "http://127.0.0.1:1/realms/test",
SkipDiscovery: ptr.To(false),
LazyDiscovery: ptr.To(true),
EmailClaim: options.OIDCEmailClaim,
AudienceClaims: []string{"aud"},
}
g.Expect(validation.Validate(opts)).To(Succeed())
proxy, err := NewOAuthProxy(opts, func(string) bool { return true })
g.Expect(err).ToNot(HaveOccurred())
g.Expect(proxy.providerReady()).To(BeFalse())
return proxy
}
func unreachableOIDCProvider(lazy bool) options.Provider {
return options.Provider{
ID: "test-provider",
Type: "oidc",
ClientID: "client-id",
OIDCConfig: options.OIDCOptions{
IssuerURL: "http://127.0.0.1:1/realms/test",
SkipDiscovery: ptr.To(false),
LazyDiscovery: ptr.To(lazy),
},
}
}
func TestSetupProviderLazyFallback(t *testing.T) {
g := NewWithT(t)
// setupProvider does not start the background loop (Start does), so there is
// no goroutine to cancel here.
provider, err := setupProvider(unreachableOIDCProvider(true))
g.Expect(err).ToNot(HaveOccurred())
lazy, ok := provider.(*providers.LazyProvider)
g.Expect(ok).To(BeTrue(), "expected a LazyProvider when discovery fails and lazy discovery is enabled")
g.Expect(lazy.Ready()).To(BeFalse())
}
func TestSetupProviderWithoutLazyFailsFast(t *testing.T) {
g := NewWithT(t)
_, err := setupProvider(unreachableOIDCProvider(false))
g.Expect(err).To(HaveOccurred())
}
// TestReadyEndpointOKWhenProviderNotReady ensures /ready stays healthy under
// lazy discovery so the pod remains in load-balancer rotation while discovery
// is still pending.
func TestReadyEndpointOKWhenProviderNotReady(t *testing.T) {
g := NewWithT(t)
proxy := newLazyPendingProxy(g)
rw := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/ready", nil)
proxy.ServeHTTP(rw, req)
g.Expect(rw.Code).To(Equal(http.StatusOK))
}
// TestOAuthStartUnavailableWhenProviderNotReady ensures the OAuth2 login flow
// returns 503 (rather than a silent self-redirect loop) while lazy discovery is
// still pending.
func TestOAuthStartUnavailableWhenProviderNotReady(t *testing.T) {
g := NewWithT(t)
proxy := newLazyPendingProxy(g)
rw := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/oauth2/start", nil)
proxy.ServeHTTP(rw, req)
g.Expect(rw.Code).To(Equal(http.StatusServiceUnavailable))
}