From 7b74ddbe8478bbf901685cea7826d96f042c142e Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 14 May 2025 17:05:41 -0600 Subject: feat: provider a fallback provider that defaults to hard-coded paths --- pkg/oidc/oidc.go | 7 +------ pkg/oidc/oidc_test.go | 8 +++++++- pkg/oidc/provider.go | 27 +++++++++++++++++++++++++++ pkg/oidc/test_server.go | 5 +++-- 4 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 pkg/oidc/provider.go (limited to 'pkg') diff --git a/pkg/oidc/oidc.go b/pkg/oidc/oidc.go index 5ff8c28..6ec1005 100644 --- a/pkg/oidc/oidc.go +++ b/pkg/oidc/oidc.go @@ -13,12 +13,7 @@ type OpenID struct { OIDCConfig *oidc.Config } -func New(ctx context.Context, issuer string, clientID, clientSecret, callbackURL string) (*OpenID, error) { - provider, err := oidc.NewProvider(ctx, issuer) - if err != nil { - return nil, err - } - +func New(ctx context.Context, provider *oidc.Provider, clientID, clientSecret, callbackURL string) (*OpenID, error) { return &OpenID{ Provider: provider, Config: &oauth2.Config{ diff --git a/pkg/oidc/oidc_test.go b/pkg/oidc/oidc_test.go index 47a58ba..bb040a2 100644 --- a/pkg/oidc/oidc_test.go +++ b/pkg/oidc/oidc_test.go @@ -13,7 +13,13 @@ func TestOpenID(t *testing.T) { defer srv.Close() t.Run("GET /.well-known/openid-configuration", func(t *testing.T) { - openID, err := New(context.Background(), srv.Issuer(), "client_id", "client_secret", "https://example.com/oauth/callback") + openID, err := New( + context.Background(), + srv.Provider, + srv.MockOIDC.ClientID, + srv.MockOIDC.ClientSecret, + "https://example.com/oauth/callback", + ) require.NoError(t, err) assert.Equal(t, srv.AuthorizationEndpoint(), openID.Provider.Endpoint().AuthURL) diff --git a/pkg/oidc/provider.go b/pkg/oidc/provider.go new file mode 100644 index 0000000..31f7577 --- /dev/null +++ b/pkg/oidc/provider.go @@ -0,0 +1,27 @@ +package oidc + +import ( + "context" + + "github.com/coreos/go-oidc/v3/oidc" +) + +func NewProvider(ctx context.Context, issuer string, report func(error)) *oidc.Provider { + provider, err := oidc.NewProvider(ctx, issuer) + if err == nil { + return provider + } + + report(err) + + config := &oidc.ProviderConfig{ + IssuerURL: issuer, + AuthURL: issuer + "/oauth/authorize", + TokenURL: issuer + "/oauth/token", + DeviceAuthURL: "", + UserInfoURL: issuer + "/oauth/userinfo", + JWKSURL: issuer + "/oauth/disovery/keys", + Algorithms: []string{"RS256"}, + } + return config.NewProvider(ctx) +} diff --git a/pkg/oidc/test_server.go b/pkg/oidc/test_server.go index 5a25549..198076c 100644 --- a/pkg/oidc/test_server.go +++ b/pkg/oidc/test_server.go @@ -30,8 +30,9 @@ func NewTestServer(t *testing.T) *TestServer { }) }) - provider, err := oidc.NewProvider(t.Context(), srv.Issuer()) - require.NoError(t, err) + provider := NewProvider(t.Context(), srv.Issuer(), func(err error) { + require.NoError(t, err) + }) config := &oauth2.Config{ ClientID: srv.Config().ClientID, -- cgit v1.2.3 From 4a090d42089ded8ce38be51d08776131a6dd2e05 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 14 May 2025 17:14:12 -0600 Subject: refactor: remove unnecessary params from ctor --- app/controllers/sessions/controller_test.go | 4 +--- app/controllers/sessions/service_test.go | 4 +--- app/init.go | 12 +----------- app/middleware/id_token_test.go | 17 +---------------- pkg/oidc/oidc.go | 4 ++-- pkg/oidc/oidc_test.go | 7 ++----- 6 files changed, 8 insertions(+), 40 deletions(-) (limited to 'pkg') diff --git a/app/controllers/sessions/controller_test.go b/app/controllers/sessions/controller_test.go index 73a373f..3e7f662 100644 --- a/app/controllers/sessions/controller_test.go +++ b/app/controllers/sessions/controller_test.go @@ -24,14 +24,12 @@ func TestSessions(t *testing.T) { clientID := srv.MockOIDC.Config().ClientID clientSecret := srv.MockOIDC.Config().ClientSecret - cfg, err := oidc.New( - t.Context(), + cfg := oidc.New( srv.Provider, clientID, clientSecret, "callback_url", ) - require.NoError(t, err) controller := New(cfg, http.DefaultClient) mux := http.NewServeMux() controller.MountTo(mux) diff --git a/app/controllers/sessions/service_test.go b/app/controllers/sessions/service_test.go index c98488a..05baa2f 100644 --- a/app/controllers/sessions/service_test.go +++ b/app/controllers/sessions/service_test.go @@ -20,14 +20,12 @@ func TestService(t *testing.T) { clientID := srv.MockOIDC.Config().ClientID clientSecret := srv.MockOIDC.Config().ClientSecret - cfg, err := oidc.New( - t.Context(), + cfg := oidc.New( srv.Provider, clientID, clientSecret, "/session/callback", ) - require.NoError(t, err) svc := NewService(cfg, http.DefaultClient) t.Run("Exchange", func(t *testing.T) { diff --git a/app/init.go b/app/init.go index 959048b..8de5461 100644 --- a/app/init.go +++ b/app/init.go @@ -7,7 +7,6 @@ import ( xoidc "github.com/coreos/go-oidc/v3/oidc" "github.com/rs/zerolog" - "github.com/xlgmokha/x/pkg/env" "github.com/xlgmokha/x/pkg/ioc" "github.com/xlgmokha/x/pkg/log" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/cfg" @@ -58,21 +57,12 @@ func init() { }) }) ioc.RegisterSingleton[*oidc.OpenID](ioc.Default, func() *oidc.OpenID { - ctx := context.WithValue(context.Background(), oauth2.HTTPClient, ioc.MustResolve[*http.Client](ioc.Default)) - item, err := oidc.New( - ctx, + return oidc.New( ioc.MustResolve[*xoidc.Provider](ioc.Default), cfg.OAuthClientID, cfg.OAuthClientSecret, cfg.OAuthRedirectURL, ) - if err != nil { - ioc.MustResolve[*zerolog.Logger](ioc.Default).Err(err).Send() - if env.Fetch("APP_ENV", "") == "test" { - os.Exit(1) - } - } - return item }) ioc.Register[*sessions.Controller](ioc.Default, func() *sessions.Controller { return sessions.New( diff --git a/app/middleware/id_token_test.go b/app/middleware/id_token_test.go index 3df9a7d..b363d2c 100644 --- a/app/middleware/id_token_test.go +++ b/app/middleware/id_token_test.go @@ -1,38 +1,23 @@ package middleware import ( - "context" "net/http" - "os" "testing" "github.com/oauth2-proxy/mockoidc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/xlgmokha/x/pkg/log" "github.com/xlgmokha/x/pkg/test" xcfg "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/app/cfg" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/oidc" "gitlab.com/gitlab-org/software-supply-chain-security/authorization/sparkled/pkg/web" - "golang.org/x/oauth2" ) func TestIDToken(t *testing.T) { srv := oidc.NewTestServer(t) defer srv.Close() - client := &http.Client{Transport: &web.Transport{Logger: log.New(os.Stdout, log.Fields{})}} - cfg := srv.MockOIDC.Config() - ctx := context.WithValue(t.Context(), oauth2.HTTPClient, client) - openID, err := oidc.New( - ctx, - srv.Provider, - cfg.ClientID, - cfg.ClientSecret, - "https://example.com/oauth/callback", - ) - require.NoError(t, err) - + openID := oidc.New(srv.Provider, srv.MockOIDC.ClientID, srv.MockOIDC.ClientSecret, "https://example.com/oauth/callback") middleware := IDToken(openID, IDTokenFromSessionCookie) t.Run("when an active session cookie is provided", func(t *testing.T) { diff --git a/pkg/oidc/oidc.go b/pkg/oidc/oidc.go index 6ec1005..4704f63 100644 --- a/pkg/oidc/oidc.go +++ b/pkg/oidc/oidc.go @@ -13,7 +13,7 @@ type OpenID struct { OIDCConfig *oidc.Config } -func New(ctx context.Context, provider *oidc.Provider, clientID, clientSecret, callbackURL string) (*OpenID, error) { +func New(provider *oidc.Provider, clientID, clientSecret, callbackURL string) *OpenID { return &OpenID{ Provider: provider, Config: &oauth2.Config{ @@ -26,7 +26,7 @@ func New(ctx context.Context, provider *oidc.Provider, clientID, clientSecret, c OIDCConfig: &oidc.Config{ ClientID: clientID, }, - }, nil + } } func (o *OpenID) ValidateIDToken(ctx context.Context, rawIDToken RawToken) (*IDToken, error) { diff --git a/pkg/oidc/oidc_test.go b/pkg/oidc/oidc_test.go index bb040a2..a3dc7e4 100644 --- a/pkg/oidc/oidc_test.go +++ b/pkg/oidc/oidc_test.go @@ -1,11 +1,9 @@ package oidc import ( - "context" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestOpenID(t *testing.T) { @@ -13,15 +11,14 @@ func TestOpenID(t *testing.T) { defer srv.Close() t.Run("GET /.well-known/openid-configuration", func(t *testing.T) { - openID, err := New( - context.Background(), + openID := New( srv.Provider, srv.MockOIDC.ClientID, srv.MockOIDC.ClientSecret, "https://example.com/oauth/callback", ) - require.NoError(t, err) assert.Equal(t, srv.AuthorizationEndpoint(), openID.Provider.Endpoint().AuthURL) + assert.Equal(t, srv.TokenEndpoint(), openID.Provider.Endpoint().TokenURL) }) } -- cgit v1.2.3 From 3a53366bf3c476497163c8e8a0b3fbe7bd40c869 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 14 May 2025 17:29:08 -0600 Subject: test: invline variable --- pkg/oidc/test_server.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'pkg') diff --git a/pkg/oidc/test_server.go b/pkg/oidc/test_server.go index 198076c..92bfe57 100644 --- a/pkg/oidc/test_server.go +++ b/pkg/oidc/test_server.go @@ -34,17 +34,15 @@ func NewTestServer(t *testing.T) *TestServer { require.NoError(t, err) }) - config := &oauth2.Config{ - ClientID: srv.Config().ClientID, - ClientSecret: srv.Config().ClientSecret, - RedirectURL: "https://example.com/oauth/callback", - Endpoint: provider.Endpoint(), - Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, - } - return &TestServer{ srv, - config, + &oauth2.Config{ + ClientID: srv.MockOIDC.ClientID, + ClientSecret: srv.MockOIDC.ClientSecret, + RedirectURL: "https://example.com/oauth/callback", + Endpoint: provider.Endpoint(), + Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, + }, provider, t, } -- cgit v1.2.3 From 7797dffa1412ca0e5a0ba95eb8aa39cddce8d10e Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 14 May 2025 17:32:29 -0600 Subject: fix: delegate to client_* directly --- pkg/oidc/test_server.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'pkg') diff --git a/pkg/oidc/test_server.go b/pkg/oidc/test_server.go index 92bfe57..81b37ca 100644 --- a/pkg/oidc/test_server.go +++ b/pkg/oidc/test_server.go @@ -37,8 +37,8 @@ func NewTestServer(t *testing.T) *TestServer { return &TestServer{ srv, &oauth2.Config{ - ClientID: srv.MockOIDC.ClientID, - ClientSecret: srv.MockOIDC.ClientSecret, + ClientID: srv.ClientID, + ClientSecret: srv.ClientSecret, RedirectURL: "https://example.com/oauth/callback", Endpoint: provider.Endpoint(), Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, -- cgit v1.2.3