From d225288ab3b9224861a7a750aab03e52468017d5 Mon Sep 17 00:00:00 2001 From: Caleb Doxsey Date: Tue, 7 May 2024 16:45:39 -0600 Subject: [PATCH] core/identity: dynamic authenticator registration (#5105) --- authenticate/config.go | 2 +- authenticate/handlers.go | 4 +- authenticate/handlers_test.go | 4 +- authenticate/identity.go | 4 +- authenticate/state.go | 2 +- config/options.go | 4 +- config/options_test.go | 2 +- config/policy.go | 2 +- databroker/cache.go | 6 +- internal/authenticateflow/authenticateflow.go | 2 +- internal/authenticateflow/identityprofile.go | 4 +- internal/authenticateflow/stateful.go | 4 +- internal/authenticateflow/stateful_test.go | 2 +- internal/authenticateflow/stateless.go | 2 +- internal/identity/providers.go | 74 ----------------- pkg/grpc/session/session.go | 2 +- pkg/grpc/user/user.go | 2 +- {internal => pkg}/identity/claims.go | 0 {internal => pkg}/identity/claims_test.go | 0 .../identity/identity/identity.go | 0 .../identity/legacymanager/config.go | 0 .../identity/legacymanager/data.go | 2 +- .../identity/legacymanager/data_test.go | 0 .../identity/legacymanager/manager.go | 2 +- .../identity/legacymanager/manager_test.go | 2 +- .../identity/legacymanager/misc.go | 0 .../identity/legacymanager/sync.go | 0 {internal => pkg}/identity/manager/config.go | 0 {internal => pkg}/identity/manager/data.go | 2 +- .../identity/manager/data_test.go | 0 .../identity/manager/datastore.go | 0 .../identity/manager/datastore_test.go | 0 {internal => pkg}/identity/manager/manager.go | 2 +- .../identity/manager/manager_test.go | 2 +- {internal => pkg}/identity/manager/misc.go | 0 .../identity/manager/schedulers.go | 0 .../identity/manager/schedulers_test.go | 0 {internal => pkg}/identity/manager/sync.go | 0 {internal => pkg}/identity/mock_provider.go | 2 +- .../identity/oauth/apple/apple.go | 6 +- .../identity/oauth/github/github.go | 8 +- {internal => pkg}/identity/oauth/options.go | 0 .../identity/oidc/auth0/auth0.go | 4 +- .../identity/oidc/auth0/auth0_test.go | 2 +- .../identity/oidc/azure/microsoft.go | 4 +- .../identity/oidc/azure/microsoft_test.go | 2 +- .../identity/oidc/cognito/cognito.go | 4 +- .../identity/oidc/cognito/cognito_test.go | 2 +- {internal => pkg}/identity/oidc/config.go | 0 {internal => pkg}/identity/oidc/errors.go | 0 .../identity/oidc/gitlab/gitlab.go | 4 +- .../identity/oidc/google/google.go | 4 +- .../identity/oidc/google/google_test.go | 2 +- {internal => pkg}/identity/oidc/oidc.go | 4 +- {internal => pkg}/identity/oidc/oidc_test.go | 2 +- {internal => pkg}/identity/oidc/okta/okta.go | 4 +- .../identity/oidc/onelogin/onelogin.go | 4 +- {internal => pkg}/identity/oidc/ping/ping.go | 4 +- {internal => pkg}/identity/oidc/refresh.go | 0 .../identity/oidc/refresh_test.go | 0 {internal => pkg}/identity/oidc/userinfo.go | 0 .../identity/oidc/userinfo_test.go | 0 pkg/identity/providers.go | 80 +++++++++++++++++++ 63 files changed, 141 insertions(+), 135 deletions(-) delete mode 100644 internal/identity/providers.go rename {internal => pkg}/identity/claims.go (100%) rename {internal => pkg}/identity/claims_test.go (100%) rename {internal => pkg}/identity/identity/identity.go (100%) rename {internal => pkg}/identity/legacymanager/config.go (100%) rename {internal => pkg}/identity/legacymanager/data.go (99%) rename {internal => pkg}/identity/legacymanager/data_test.go (100%) rename {internal => pkg}/identity/legacymanager/manager.go (99%) rename {internal => pkg}/identity/legacymanager/manager_test.go (99%) rename {internal => pkg}/identity/legacymanager/misc.go (100%) rename {internal => pkg}/identity/legacymanager/sync.go (100%) rename {internal => pkg}/identity/manager/config.go (100%) rename {internal => pkg}/identity/manager/data.go (98%) rename {internal => pkg}/identity/manager/data_test.go (100%) rename {internal => pkg}/identity/manager/datastore.go (100%) rename {internal => pkg}/identity/manager/datastore_test.go (100%) rename {internal => pkg}/identity/manager/manager.go (99%) rename {internal => pkg}/identity/manager/manager_test.go (91%) rename {internal => pkg}/identity/manager/misc.go (100%) rename {internal => pkg}/identity/manager/schedulers.go (100%) rename {internal => pkg}/identity/manager/schedulers_test.go (100%) rename {internal => pkg}/identity/manager/sync.go (100%) rename {internal => pkg}/identity/mock_provider.go (96%) rename {internal => pkg}/identity/oauth/apple/apple.go (96%) rename {internal => pkg}/identity/oauth/github/github.go (97%) rename {internal => pkg}/identity/oauth/options.go (100%) rename {internal => pkg}/identity/oidc/auth0/auth0.go (94%) rename {internal => pkg}/identity/oidc/auth0/auth0_test.go (96%) rename {internal => pkg}/identity/oidc/azure/microsoft.go (96%) rename {internal => pkg}/identity/oidc/azure/microsoft_test.go (90%) rename {internal => pkg}/identity/oidc/cognito/cognito.go (95%) rename {internal => pkg}/identity/oidc/cognito/cognito_test.go (97%) rename {internal => pkg}/identity/oidc/config.go (100%) rename {internal => pkg}/identity/oidc/errors.go (100%) rename {internal => pkg}/identity/oidc/gitlab/gitlab.go (89%) rename {internal => pkg}/identity/oidc/google/google.go (94%) rename {internal => pkg}/identity/oidc/google/google_test.go (90%) rename {internal => pkg}/identity/oidc/oidc.go (98%) rename {internal => pkg}/identity/oidc/oidc_test.go (96%) rename {internal => pkg}/identity/oidc/okta/okta.go (86%) rename {internal => pkg}/identity/oidc/onelogin/onelogin.go (91%) rename {internal => pkg}/identity/oidc/ping/ping.go (86%) rename {internal => pkg}/identity/oidc/refresh.go (100%) rename {internal => pkg}/identity/oidc/refresh_test.go (100%) rename {internal => pkg}/identity/oidc/userinfo.go (100%) rename {internal => pkg}/identity/oidc/userinfo_test.go (100%) create mode 100644 pkg/identity/providers.go diff --git a/authenticate/config.go b/authenticate/config.go index 3e6afcb4c..ef293808b 100644 --- a/authenticate/config.go +++ b/authenticate/config.go @@ -3,8 +3,8 @@ package authenticate import ( "github.com/pomerium/pomerium/authenticate/events" "github.com/pomerium/pomerium/config" - "github.com/pomerium/pomerium/internal/identity" identitypb "github.com/pomerium/pomerium/pkg/grpc/identity" + "github.com/pomerium/pomerium/pkg/identity" ) type authenticateConfig struct { diff --git a/authenticate/handlers.go b/authenticate/handlers.go index ba05175cc..ceaa721f5 100644 --- a/authenticate/handlers.go +++ b/authenticate/handlers.go @@ -18,14 +18,14 @@ import ( "github.com/pomerium/pomerium/internal/authenticateflow" "github.com/pomerium/pomerium/internal/handlers" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity" - "github.com/pomerium/pomerium/internal/identity/oidc" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/middleware" "github.com/pomerium/pomerium/internal/sessions" "github.com/pomerium/pomerium/internal/telemetry/trace" "github.com/pomerium/pomerium/internal/urlutil" "github.com/pomerium/pomerium/pkg/cryptutil" + "github.com/pomerium/pomerium/pkg/identity" + "github.com/pomerium/pomerium/pkg/identity/oidc" ) // Handler returns the authenticate service's handler chain. diff --git a/authenticate/handlers_test.go b/authenticate/handlers_test.go index a40c3b9e3..c8f5342a5 100644 --- a/authenticate/handlers_test.go +++ b/authenticate/handlers_test.go @@ -28,8 +28,6 @@ import ( "github.com/pomerium/pomerium/internal/encoding/mock" "github.com/pomerium/pomerium/internal/handlers" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity" - "github.com/pomerium/pomerium/internal/identity/oidc" "github.com/pomerium/pomerium/internal/sessions" mstore "github.com/pomerium/pomerium/internal/sessions/mock" "github.com/pomerium/pomerium/internal/testutil" @@ -37,6 +35,8 @@ import ( "github.com/pomerium/pomerium/pkg/cryptutil" configproto "github.com/pomerium/pomerium/pkg/grpc/config" "github.com/pomerium/pomerium/pkg/grpc/databroker" + "github.com/pomerium/pomerium/pkg/identity" + "github.com/pomerium/pomerium/pkg/identity/oidc" ) func testAuthenticate() *Authenticate { diff --git a/authenticate/identity.go b/authenticate/identity.go index 05c30c325..8ea432e15 100644 --- a/authenticate/identity.go +++ b/authenticate/identity.go @@ -2,9 +2,9 @@ package authenticate import ( "github.com/pomerium/pomerium/config" - "github.com/pomerium/pomerium/internal/identity" - "github.com/pomerium/pomerium/internal/identity/oauth" "github.com/pomerium/pomerium/internal/urlutil" + "github.com/pomerium/pomerium/pkg/identity" + "github.com/pomerium/pomerium/pkg/identity/oauth" ) func defaultGetIdentityProvider(options *config.Options, idpID string) (identity.Authenticator, error) { diff --git a/authenticate/state.go b/authenticate/state.go index cd9476962..b7e79681d 100644 --- a/authenticate/state.go +++ b/authenticate/state.go @@ -15,11 +15,11 @@ import ( "github.com/pomerium/pomerium/internal/encoding" "github.com/pomerium/pomerium/internal/encoding/jws" "github.com/pomerium/pomerium/internal/handlers" - "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/internal/sessions" "github.com/pomerium/pomerium/internal/sessions/cookie" "github.com/pomerium/pomerium/internal/urlutil" "github.com/pomerium/pomerium/pkg/cryptutil" + "github.com/pomerium/pomerium/pkg/identity" ) type flow interface { diff --git a/config/options.go b/config/options.go index 2784cf23f..ef8abef4c 100644 --- a/config/options.go +++ b/config/options.go @@ -27,8 +27,6 @@ import ( "github.com/pomerium/pomerium/internal/atomicutil" "github.com/pomerium/pomerium/internal/hashutil" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity/oauth" - "github.com/pomerium/pomerium/internal/identity/oauth/apple" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/sets" "github.com/pomerium/pomerium/internal/telemetry" @@ -38,6 +36,8 @@ import ( "github.com/pomerium/pomerium/pkg/grpc/config" "github.com/pomerium/pomerium/pkg/grpc/crypt" "github.com/pomerium/pomerium/pkg/hpke" + "github.com/pomerium/pomerium/pkg/identity/oauth" + "github.com/pomerium/pomerium/pkg/identity/oauth/apple" ) // DisableHeaderKey is the key used to check whether to disable setting header diff --git a/config/options_test.go b/config/options_test.go index 61ca9191d..c1da27587 100644 --- a/config/options_test.go +++ b/config/options_test.go @@ -25,9 +25,9 @@ import ( "google.golang.org/protobuf/proto" "github.com/pomerium/csrf" - "github.com/pomerium/pomerium/internal/identity/oauth/apple" "github.com/pomerium/pomerium/pkg/cryptutil" "github.com/pomerium/pomerium/pkg/grpc/config" + "github.com/pomerium/pomerium/pkg/identity/oauth/apple" ) var cmpOptIgnoreUnexported = cmpopts.IgnoreUnexported(Options{}, Policy{}) diff --git a/config/policy.go b/config/policy.go index 8ce9930b5..5182b6e20 100644 --- a/config/policy.go +++ b/config/policy.go @@ -17,11 +17,11 @@ import ( "google.golang.org/protobuf/types/known/durationpb" "github.com/pomerium/pomerium/internal/hashutil" - "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/urlutil" "github.com/pomerium/pomerium/pkg/cryptutil" configpb "github.com/pomerium/pomerium/pkg/grpc/config" + "github.com/pomerium/pomerium/pkg/identity" ) // Policy contains route specific configuration and access settings. diff --git a/databroker/cache.go b/databroker/cache.go index f3559e835..79c40c7f2 100644 --- a/databroker/cache.go +++ b/databroker/cache.go @@ -17,9 +17,6 @@ import ( "github.com/pomerium/pomerium/config" "github.com/pomerium/pomerium/internal/atomicutil" "github.com/pomerium/pomerium/internal/events" - "github.com/pomerium/pomerium/internal/identity" - "github.com/pomerium/pomerium/internal/identity/legacymanager" - "github.com/pomerium/pomerium/internal/identity/manager" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/telemetry" "github.com/pomerium/pomerium/internal/version" @@ -28,6 +25,9 @@ import ( "github.com/pomerium/pomerium/pkg/grpc/databroker" "github.com/pomerium/pomerium/pkg/grpc/registry" "github.com/pomerium/pomerium/pkg/grpcutil" + "github.com/pomerium/pomerium/pkg/identity" + "github.com/pomerium/pomerium/pkg/identity/legacymanager" + "github.com/pomerium/pomerium/pkg/identity/manager" ) // DataBroker represents the databroker service. The databroker service is a simple interface diff --git a/internal/authenticateflow/authenticateflow.go b/internal/authenticateflow/authenticateflow.go index 7c12c4ac5..24ad95c73 100644 --- a/internal/authenticateflow/authenticateflow.go +++ b/internal/authenticateflow/authenticateflow.go @@ -8,9 +8,9 @@ import ( "google.golang.org/protobuf/types/known/structpb" - "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/pkg/grpc" "github.com/pomerium/pomerium/pkg/grpc/user" + "github.com/pomerium/pomerium/pkg/identity" ) var outboundGRPCConnection = new(grpc.CachedOutboundGRPClientConn) diff --git a/internal/authenticateflow/identityprofile.go b/internal/authenticateflow/identityprofile.go index d22c8c60e..8cac72e18 100644 --- a/internal/authenticateflow/identityprofile.go +++ b/internal/authenticateflow/identityprofile.go @@ -15,13 +15,13 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity" - "github.com/pomerium/pomerium/internal/identity/manager" "github.com/pomerium/pomerium/internal/sessions" "github.com/pomerium/pomerium/internal/urlutil" "github.com/pomerium/pomerium/pkg/cryptutil" identitypb "github.com/pomerium/pomerium/pkg/grpc/identity" "github.com/pomerium/pomerium/pkg/grpc/session" + "github.com/pomerium/pomerium/pkg/identity" + "github.com/pomerium/pomerium/pkg/identity/manager" ) // An "identity profile" is an alternative to a session, used in the stateless diff --git a/internal/authenticateflow/stateful.go b/internal/authenticateflow/stateful.go index 1c671da73..a7b27762d 100644 --- a/internal/authenticateflow/stateful.go +++ b/internal/authenticateflow/stateful.go @@ -17,8 +17,6 @@ import ( "github.com/pomerium/pomerium/internal/encoding/jws" "github.com/pomerium/pomerium/internal/handlers" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity" - "github.com/pomerium/pomerium/internal/identity/manager" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/sessions" "github.com/pomerium/pomerium/internal/urlutil" @@ -28,6 +26,8 @@ import ( "github.com/pomerium/pomerium/pkg/grpc/session" "github.com/pomerium/pomerium/pkg/grpc/user" "github.com/pomerium/pomerium/pkg/grpcutil" + "github.com/pomerium/pomerium/pkg/identity" + "github.com/pomerium/pomerium/pkg/identity/manager" ) // Stateful implements the stateful authentication flow. In this flow, the diff --git a/internal/authenticateflow/stateful_test.go b/internal/authenticateflow/stateful_test.go index eeb340fc6..d6edd5a43 100644 --- a/internal/authenticateflow/stateful_test.go +++ b/internal/authenticateflow/stateful_test.go @@ -23,7 +23,6 @@ import ( "github.com/pomerium/pomerium/config" "github.com/pomerium/pomerium/internal/encoding" "github.com/pomerium/pomerium/internal/encoding/mock" - "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/internal/sessions" mstore "github.com/pomerium/pomerium/internal/sessions/mock" "github.com/pomerium/pomerium/internal/urlutil" @@ -31,6 +30,7 @@ import ( "github.com/pomerium/pomerium/pkg/grpc/databroker" "github.com/pomerium/pomerium/pkg/grpc/databroker/mock_databroker" "github.com/pomerium/pomerium/pkg/grpc/session" + "github.com/pomerium/pomerium/pkg/identity" "github.com/pomerium/pomerium/pkg/protoutil" ) diff --git a/internal/authenticateflow/stateless.go b/internal/authenticateflow/stateless.go index c0175098e..363962937 100644 --- a/internal/authenticateflow/stateless.go +++ b/internal/authenticateflow/stateless.go @@ -18,7 +18,6 @@ import ( "github.com/pomerium/pomerium/internal/encoding/jws" "github.com/pomerium/pomerium/internal/handlers" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/sessions" "github.com/pomerium/pomerium/internal/urlutil" @@ -29,6 +28,7 @@ import ( "github.com/pomerium/pomerium/pkg/grpc/session" "github.com/pomerium/pomerium/pkg/grpc/user" "github.com/pomerium/pomerium/pkg/hpke" + "github.com/pomerium/pomerium/pkg/identity" ) // Stateless implements the stateless authentication flow. In this flow, the diff --git a/internal/identity/providers.go b/internal/identity/providers.go deleted file mode 100644 index 690b04514..000000000 --- a/internal/identity/providers.go +++ /dev/null @@ -1,74 +0,0 @@ -// Package identity provides support for making OpenID Connect (OIDC) -// and OAuth2 authenticated HTTP requests with third party identity providers. -package identity - -import ( - "context" - "fmt" - "net/http" - - "golang.org/x/oauth2" - - "github.com/pomerium/pomerium/internal/identity/identity" - "github.com/pomerium/pomerium/internal/identity/oauth" - "github.com/pomerium/pomerium/internal/identity/oauth/apple" - "github.com/pomerium/pomerium/internal/identity/oauth/github" - "github.com/pomerium/pomerium/internal/identity/oidc" - "github.com/pomerium/pomerium/internal/identity/oidc/auth0" - "github.com/pomerium/pomerium/internal/identity/oidc/azure" - "github.com/pomerium/pomerium/internal/identity/oidc/cognito" - "github.com/pomerium/pomerium/internal/identity/oidc/gitlab" - "github.com/pomerium/pomerium/internal/identity/oidc/google" - "github.com/pomerium/pomerium/internal/identity/oidc/okta" - "github.com/pomerium/pomerium/internal/identity/oidc/onelogin" - "github.com/pomerium/pomerium/internal/identity/oidc/ping" -) - -// Authenticator is an interface representing the ability to authenticate with an identity provider. -type Authenticator interface { - Authenticate(context.Context, string, identity.State) (*oauth2.Token, error) - Refresh(context.Context, *oauth2.Token, identity.State) (*oauth2.Token, error) - Revoke(context.Context, *oauth2.Token) error - Name() string - UpdateUserInfo(ctx context.Context, t *oauth2.Token, v any) error - - SignIn(w http.ResponseWriter, r *http.Request, state string) error - SignOut(w http.ResponseWriter, r *http.Request, idTokenHint, authenticateSignedOutURL, redirectToURL string) error -} - -// NewAuthenticator returns a new identity provider based on its name. -func NewAuthenticator(o oauth.Options) (a Authenticator, err error) { - ctx := context.Background() - switch o.ProviderName { - case apple.Name: - a, err = apple.New(ctx, &o) - case auth0.Name: - a, err = auth0.New(ctx, &o) - case azure.Name: - a, err = azure.New(ctx, &o) - case gitlab.Name: - a, err = gitlab.New(ctx, &o) - case github.Name: - a, err = github.New(ctx, &o) - case google.Name: - a, err = google.New(ctx, &o) - case oidc.Name: - a, err = oidc.New(ctx, &o) - case okta.Name: - a, err = okta.New(ctx, &o) - case onelogin.Name: - a, err = onelogin.New(ctx, &o) - case ping.Name: - a, err = ping.New(ctx, &o) - case cognito.Name: - a, err = cognito.New(ctx, &o) - case "": - return nil, fmt.Errorf("identity: provider is not defined") - default: - return nil, fmt.Errorf("identity: unknown provider: %s", o.ProviderName) - } - if err != nil { - return nil, err - } - return a, nil -} diff --git a/pkg/grpc/session/session.go b/pkg/grpc/session/session.go index 3f839b121..fdd0b43e5 100644 --- a/pkg/grpc/session/session.go +++ b/pkg/grpc/session/session.go @@ -11,8 +11,8 @@ import ( "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/pkg/grpc/databroker" + "github.com/pomerium/pomerium/pkg/identity" "github.com/pomerium/pomerium/pkg/protoutil" "github.com/pomerium/pomerium/pkg/slices" ) diff --git a/pkg/grpc/user/user.go b/pkg/grpc/user/user.go index bd2fd5b53..ecfc80413 100644 --- a/pkg/grpc/user/user.go +++ b/pkg/grpc/user/user.go @@ -9,8 +9,8 @@ import ( "google.golang.org/protobuf/types/known/structpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/pkg/grpc/databroker" + "github.com/pomerium/pomerium/pkg/identity" "github.com/pomerium/pomerium/pkg/slices" ) diff --git a/internal/identity/claims.go b/pkg/identity/claims.go similarity index 100% rename from internal/identity/claims.go rename to pkg/identity/claims.go diff --git a/internal/identity/claims_test.go b/pkg/identity/claims_test.go similarity index 100% rename from internal/identity/claims_test.go rename to pkg/identity/claims_test.go diff --git a/internal/identity/identity/identity.go b/pkg/identity/identity/identity.go similarity index 100% rename from internal/identity/identity/identity.go rename to pkg/identity/identity/identity.go diff --git a/internal/identity/legacymanager/config.go b/pkg/identity/legacymanager/config.go similarity index 100% rename from internal/identity/legacymanager/config.go rename to pkg/identity/legacymanager/config.go diff --git a/internal/identity/legacymanager/data.go b/pkg/identity/legacymanager/data.go similarity index 99% rename from internal/identity/legacymanager/data.go rename to pkg/identity/legacymanager/data.go index 97033b671..cac00687b 100644 --- a/internal/identity/legacymanager/data.go +++ b/pkg/identity/legacymanager/data.go @@ -7,9 +7,9 @@ import ( "github.com/google/btree" "google.golang.org/protobuf/types/known/timestamppb" - "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/pkg/grpc/session" "github.com/pomerium/pomerium/pkg/grpc/user" + "github.com/pomerium/pomerium/pkg/identity" ) const userRefreshInterval = 10 * time.Minute diff --git a/internal/identity/legacymanager/data_test.go b/pkg/identity/legacymanager/data_test.go similarity index 100% rename from internal/identity/legacymanager/data_test.go rename to pkg/identity/legacymanager/data_test.go diff --git a/internal/identity/legacymanager/manager.go b/pkg/identity/legacymanager/manager.go similarity index 99% rename from internal/identity/legacymanager/manager.go rename to pkg/identity/legacymanager/manager.go index 296f414ff..a13e7a68a 100644 --- a/internal/identity/legacymanager/manager.go +++ b/pkg/identity/legacymanager/manager.go @@ -18,7 +18,6 @@ import ( "github.com/pomerium/pomerium/internal/atomicutil" "github.com/pomerium/pomerium/internal/enabler" "github.com/pomerium/pomerium/internal/events" - "github.com/pomerium/pomerium/internal/identity/identity" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/scheduler" "github.com/pomerium/pomerium/internal/telemetry/metrics" @@ -26,6 +25,7 @@ import ( "github.com/pomerium/pomerium/pkg/grpc/session" "github.com/pomerium/pomerium/pkg/grpc/user" "github.com/pomerium/pomerium/pkg/grpcutil" + "github.com/pomerium/pomerium/pkg/identity/identity" metrics_ids "github.com/pomerium/pomerium/pkg/metrics" ) diff --git a/internal/identity/legacymanager/manager_test.go b/pkg/identity/legacymanager/manager_test.go similarity index 99% rename from internal/identity/legacymanager/manager_test.go rename to pkg/identity/legacymanager/manager_test.go index 4536c061a..b8c61bc20 100644 --- a/internal/identity/legacymanager/manager_test.go +++ b/pkg/identity/legacymanager/manager_test.go @@ -17,11 +17,11 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" "github.com/pomerium/pomerium/internal/events" - "github.com/pomerium/pomerium/internal/identity/identity" "github.com/pomerium/pomerium/pkg/grpc/databroker" "github.com/pomerium/pomerium/pkg/grpc/databroker/mock_databroker" "github.com/pomerium/pomerium/pkg/grpc/session" "github.com/pomerium/pomerium/pkg/grpc/user" + "github.com/pomerium/pomerium/pkg/identity/identity" metrics_ids "github.com/pomerium/pomerium/pkg/metrics" "github.com/pomerium/pomerium/pkg/protoutil" ) diff --git a/internal/identity/legacymanager/misc.go b/pkg/identity/legacymanager/misc.go similarity index 100% rename from internal/identity/legacymanager/misc.go rename to pkg/identity/legacymanager/misc.go diff --git a/internal/identity/legacymanager/sync.go b/pkg/identity/legacymanager/sync.go similarity index 100% rename from internal/identity/legacymanager/sync.go rename to pkg/identity/legacymanager/sync.go diff --git a/internal/identity/manager/config.go b/pkg/identity/manager/config.go similarity index 100% rename from internal/identity/manager/config.go rename to pkg/identity/manager/config.go diff --git a/internal/identity/manager/data.go b/pkg/identity/manager/data.go similarity index 98% rename from internal/identity/manager/data.go rename to pkg/identity/manager/data.go index 6aeccbf5d..feca01d0f 100644 --- a/internal/identity/manager/data.go +++ b/pkg/identity/manager/data.go @@ -7,9 +7,9 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" - "github.com/pomerium/pomerium/internal/identity" "github.com/pomerium/pomerium/pkg/grpc/session" "github.com/pomerium/pomerium/pkg/grpc/user" + "github.com/pomerium/pomerium/pkg/identity" ) func nextSessionRefresh( diff --git a/internal/identity/manager/data_test.go b/pkg/identity/manager/data_test.go similarity index 100% rename from internal/identity/manager/data_test.go rename to pkg/identity/manager/data_test.go diff --git a/internal/identity/manager/datastore.go b/pkg/identity/manager/datastore.go similarity index 100% rename from internal/identity/manager/datastore.go rename to pkg/identity/manager/datastore.go diff --git a/internal/identity/manager/datastore_test.go b/pkg/identity/manager/datastore_test.go similarity index 100% rename from internal/identity/manager/datastore_test.go rename to pkg/identity/manager/datastore_test.go diff --git a/internal/identity/manager/manager.go b/pkg/identity/manager/manager.go similarity index 99% rename from internal/identity/manager/manager.go rename to pkg/identity/manager/manager.go index f7bedca6c..e7221b7e0 100644 --- a/internal/identity/manager/manager.go +++ b/pkg/identity/manager/manager.go @@ -18,13 +18,13 @@ import ( "github.com/pomerium/pomerium/internal/atomicutil" "github.com/pomerium/pomerium/internal/enabler" "github.com/pomerium/pomerium/internal/events" - "github.com/pomerium/pomerium/internal/identity/identity" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/telemetry/metrics" "github.com/pomerium/pomerium/pkg/grpc/databroker" "github.com/pomerium/pomerium/pkg/grpc/session" "github.com/pomerium/pomerium/pkg/grpc/user" "github.com/pomerium/pomerium/pkg/grpcutil" + "github.com/pomerium/pomerium/pkg/identity/identity" metrics_ids "github.com/pomerium/pomerium/pkg/metrics" ) diff --git a/internal/identity/manager/manager_test.go b/pkg/identity/manager/manager_test.go similarity index 91% rename from internal/identity/manager/manager_test.go rename to pkg/identity/manager/manager_test.go index f5225b35f..38f49c2a4 100644 --- a/internal/identity/manager/manager_test.go +++ b/pkg/identity/manager/manager_test.go @@ -5,7 +5,7 @@ import ( "golang.org/x/oauth2" - "github.com/pomerium/pomerium/internal/identity/identity" + "github.com/pomerium/pomerium/pkg/identity/identity" ) type mockAuthenticator struct { diff --git a/internal/identity/manager/misc.go b/pkg/identity/manager/misc.go similarity index 100% rename from internal/identity/manager/misc.go rename to pkg/identity/manager/misc.go diff --git a/internal/identity/manager/schedulers.go b/pkg/identity/manager/schedulers.go similarity index 100% rename from internal/identity/manager/schedulers.go rename to pkg/identity/manager/schedulers.go diff --git a/internal/identity/manager/schedulers_test.go b/pkg/identity/manager/schedulers_test.go similarity index 100% rename from internal/identity/manager/schedulers_test.go rename to pkg/identity/manager/schedulers_test.go diff --git a/internal/identity/manager/sync.go b/pkg/identity/manager/sync.go similarity index 100% rename from internal/identity/manager/sync.go rename to pkg/identity/manager/sync.go diff --git a/internal/identity/mock_provider.go b/pkg/identity/mock_provider.go similarity index 96% rename from internal/identity/mock_provider.go rename to pkg/identity/mock_provider.go index 04e744a91..5d376157e 100644 --- a/internal/identity/mock_provider.go +++ b/pkg/identity/mock_provider.go @@ -6,7 +6,7 @@ import ( "golang.org/x/oauth2" - "github.com/pomerium/pomerium/internal/identity/identity" + "github.com/pomerium/pomerium/pkg/identity/identity" ) // MockProvider provides a mocked implementation of the providers interface. diff --git a/internal/identity/oauth/apple/apple.go b/pkg/identity/oauth/apple/apple.go similarity index 96% rename from internal/identity/oauth/apple/apple.go rename to pkg/identity/oauth/apple/apple.go index fe0d0b4ac..ea0807637 100644 --- a/internal/identity/oauth/apple/apple.go +++ b/pkg/identity/oauth/apple/apple.go @@ -16,11 +16,11 @@ import ( "golang.org/x/oauth2" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity/identity" - "github.com/pomerium/pomerium/internal/identity/oauth" - "github.com/pomerium/pomerium/internal/identity/oidc" "github.com/pomerium/pomerium/internal/urlutil" "github.com/pomerium/pomerium/internal/version" + "github.com/pomerium/pomerium/pkg/identity/identity" + "github.com/pomerium/pomerium/pkg/identity/oauth" + "github.com/pomerium/pomerium/pkg/identity/oidc" ) // Name identifies the apple identity provider. diff --git a/internal/identity/oauth/github/github.go b/pkg/identity/oauth/github/github.go similarity index 97% rename from internal/identity/oauth/github/github.go rename to pkg/identity/oauth/github/github.go index 64557a822..7ae0f5c79 100644 --- a/internal/identity/oauth/github/github.go +++ b/pkg/identity/oauth/github/github.go @@ -17,12 +17,12 @@ import ( "golang.org/x/oauth2" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity/identity" - "github.com/pomerium/pomerium/internal/identity/oauth" - "github.com/pomerium/pomerium/internal/identity/oidc" "github.com/pomerium/pomerium/internal/log" "github.com/pomerium/pomerium/internal/urlutil" "github.com/pomerium/pomerium/internal/version" + "github.com/pomerium/pomerium/pkg/identity/identity" + "github.com/pomerium/pomerium/pkg/identity/oauth" + "github.com/pomerium/pomerium/pkg/identity/oidc" ) // Name identifies the GitHub identity provider @@ -36,7 +36,7 @@ const ( emailPath = "/user/emails" // https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps authURL = "/login/oauth/authorize" - tokenURL = "/login/oauth/access_token" + tokenURL = "/login/oauth/access_token" //nolint:gosec // since github doesn't implement oidc, we need this to refresh the user session refreshDeadline = time.Minute * 60 diff --git a/internal/identity/oauth/options.go b/pkg/identity/oauth/options.go similarity index 100% rename from internal/identity/oauth/options.go rename to pkg/identity/oauth/options.go diff --git a/internal/identity/oidc/auth0/auth0.go b/pkg/identity/oidc/auth0/auth0.go similarity index 94% rename from internal/identity/oidc/auth0/auth0.go rename to pkg/identity/oidc/auth0/auth0.go index 3b50ae153..a0ff21c6b 100644 --- a/internal/identity/oidc/auth0/auth0.go +++ b/pkg/identity/oidc/auth0/auth0.go @@ -11,9 +11,9 @@ import ( "strings" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity/oauth" - pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc" "github.com/pomerium/pomerium/internal/urlutil" + "github.com/pomerium/pomerium/pkg/identity/oauth" + pom_oidc "github.com/pomerium/pomerium/pkg/identity/oidc" ) const ( diff --git a/internal/identity/oidc/auth0/auth0_test.go b/pkg/identity/oidc/auth0/auth0_test.go similarity index 96% rename from internal/identity/oidc/auth0/auth0_test.go rename to pkg/identity/oidc/auth0/auth0_test.go index 4cff74415..4b0ed7ebd 100644 --- a/internal/identity/oidc/auth0/auth0_test.go +++ b/pkg/identity/oidc/auth0/auth0_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/pomerium/pomerium/internal/identity/oauth" + "github.com/pomerium/pomerium/pkg/identity/oauth" ) func TestProvider(t *testing.T) { diff --git a/internal/identity/oidc/azure/microsoft.go b/pkg/identity/oidc/azure/microsoft.go similarity index 96% rename from internal/identity/oidc/azure/microsoft.go rename to pkg/identity/oidc/azure/microsoft.go index ea9ab6c1c..1ae77ea15 100644 --- a/internal/identity/oidc/azure/microsoft.go +++ b/pkg/identity/oidc/azure/microsoft.go @@ -14,8 +14,8 @@ import ( go_oidc "github.com/coreos/go-oidc/v3/oidc" "golang.org/x/oauth2" - "github.com/pomerium/pomerium/internal/identity/oauth" - pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc" + "github.com/pomerium/pomerium/pkg/identity/oauth" + pom_oidc "github.com/pomerium/pomerium/pkg/identity/oidc" ) // Name identifies the Azure identity provider diff --git a/internal/identity/oidc/azure/microsoft_test.go b/pkg/identity/oidc/azure/microsoft_test.go similarity index 90% rename from internal/identity/oidc/azure/microsoft_test.go rename to pkg/identity/oidc/azure/microsoft_test.go index efdabafcf..570f465b2 100644 --- a/internal/identity/oidc/azure/microsoft_test.go +++ b/pkg/identity/oidc/azure/microsoft_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/pomerium/pomerium/internal/identity/oauth" + "github.com/pomerium/pomerium/pkg/identity/oauth" ) func TestAuthCodeOptions(t *testing.T) { diff --git a/internal/identity/oidc/cognito/cognito.go b/pkg/identity/oidc/cognito/cognito.go similarity index 95% rename from internal/identity/oidc/cognito/cognito.go rename to pkg/identity/oidc/cognito/cognito.go index e19e87722..38c4d912f 100644 --- a/internal/identity/oidc/cognito/cognito.go +++ b/pkg/identity/oidc/cognito/cognito.go @@ -8,9 +8,9 @@ import ( "net/url" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity/oauth" - pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc" "github.com/pomerium/pomerium/internal/urlutil" + "github.com/pomerium/pomerium/pkg/identity/oauth" + pom_oidc "github.com/pomerium/pomerium/pkg/identity/oidc" ) var defaultScopes = []string{"openid", "email", "profile"} diff --git a/internal/identity/oidc/cognito/cognito_test.go b/pkg/identity/oidc/cognito/cognito_test.go similarity index 97% rename from internal/identity/oidc/cognito/cognito_test.go rename to pkg/identity/oidc/cognito/cognito_test.go index 20ca014c5..bcb3fce46 100644 --- a/internal/identity/oidc/cognito/cognito_test.go +++ b/pkg/identity/oidc/cognito/cognito_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/pomerium/pomerium/internal/identity/oauth" + "github.com/pomerium/pomerium/pkg/identity/oauth" ) func TestProvider(t *testing.T) { diff --git a/internal/identity/oidc/config.go b/pkg/identity/oidc/config.go similarity index 100% rename from internal/identity/oidc/config.go rename to pkg/identity/oidc/config.go diff --git a/internal/identity/oidc/errors.go b/pkg/identity/oidc/errors.go similarity index 100% rename from internal/identity/oidc/errors.go rename to pkg/identity/oidc/errors.go diff --git a/internal/identity/oidc/gitlab/gitlab.go b/pkg/identity/oidc/gitlab/gitlab.go similarity index 89% rename from internal/identity/oidc/gitlab/gitlab.go rename to pkg/identity/oidc/gitlab/gitlab.go index 5a7bb40c2..210338b7f 100644 --- a/internal/identity/oidc/gitlab/gitlab.go +++ b/pkg/identity/oidc/gitlab/gitlab.go @@ -9,8 +9,8 @@ import ( "github.com/coreos/go-oidc/v3/oidc" - "github.com/pomerium/pomerium/internal/identity/oauth" - pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc" + "github.com/pomerium/pomerium/pkg/identity/oauth" + pom_oidc "github.com/pomerium/pomerium/pkg/identity/oidc" ) // Name identifies the GitLab identity provider. diff --git a/internal/identity/oidc/google/google.go b/pkg/identity/oidc/google/google.go similarity index 94% rename from internal/identity/oidc/google/google.go rename to pkg/identity/oidc/google/google.go index 607a26362..4204c4732 100644 --- a/internal/identity/oidc/google/google.go +++ b/pkg/identity/oidc/google/google.go @@ -10,8 +10,8 @@ import ( oidc "github.com/coreos/go-oidc/v3/oidc" - "github.com/pomerium/pomerium/internal/identity/oauth" - pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc" + "github.com/pomerium/pomerium/pkg/identity/oauth" + pom_oidc "github.com/pomerium/pomerium/pkg/identity/oidc" ) const ( diff --git a/internal/identity/oidc/google/google_test.go b/pkg/identity/oidc/google/google_test.go similarity index 90% rename from internal/identity/oidc/google/google_test.go rename to pkg/identity/oidc/google/google_test.go index 4407c94c5..6dd6911a6 100644 --- a/internal/identity/oidc/google/google_test.go +++ b/pkg/identity/oidc/google/google_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/pomerium/pomerium/internal/identity/oauth" + "github.com/pomerium/pomerium/pkg/identity/oauth" ) func TestAuthCodeOptions(t *testing.T) { diff --git a/internal/identity/oidc/oidc.go b/pkg/identity/oidc/oidc.go similarity index 98% rename from internal/identity/oidc/oidc.go rename to pkg/identity/oidc/oidc.go index df93ed1cd..3960e7017 100644 --- a/internal/identity/oidc/oidc.go +++ b/pkg/identity/oidc/oidc.go @@ -16,10 +16,10 @@ import ( "golang.org/x/oauth2" "github.com/pomerium/pomerium/internal/httputil" - "github.com/pomerium/pomerium/internal/identity/identity" - "github.com/pomerium/pomerium/internal/identity/oauth" "github.com/pomerium/pomerium/internal/urlutil" "github.com/pomerium/pomerium/internal/version" + "github.com/pomerium/pomerium/pkg/identity/identity" + "github.com/pomerium/pomerium/pkg/identity/oauth" ) // Name identifies the generic OpenID Connect provider. diff --git a/internal/identity/oidc/oidc_test.go b/pkg/identity/oidc/oidc_test.go similarity index 96% rename from internal/identity/oidc/oidc_test.go rename to pkg/identity/oidc/oidc_test.go index a15601925..222185c26 100644 --- a/internal/identity/oidc/oidc_test.go +++ b/pkg/identity/oidc/oidc_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/oauth2" - "github.com/pomerium/pomerium/internal/identity/oauth" + "github.com/pomerium/pomerium/pkg/identity/oauth" ) func TestRevoke(t *testing.T) { diff --git a/internal/identity/oidc/okta/okta.go b/pkg/identity/oidc/okta/okta.go similarity index 86% rename from internal/identity/oidc/okta/okta.go rename to pkg/identity/oidc/okta/okta.go index 59386eccf..7c7b91c92 100644 --- a/internal/identity/oidc/okta/okta.go +++ b/pkg/identity/oidc/okta/okta.go @@ -7,8 +7,8 @@ import ( "context" "fmt" - "github.com/pomerium/pomerium/internal/identity/oauth" - pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc" + "github.com/pomerium/pomerium/pkg/identity/oauth" + pom_oidc "github.com/pomerium/pomerium/pkg/identity/oidc" ) const ( diff --git a/internal/identity/oidc/onelogin/onelogin.go b/pkg/identity/oidc/onelogin/onelogin.go similarity index 91% rename from internal/identity/oidc/onelogin/onelogin.go rename to pkg/identity/oidc/onelogin/onelogin.go index 1428e953a..ad3a4669d 100644 --- a/internal/identity/oidc/onelogin/onelogin.go +++ b/pkg/identity/oidc/onelogin/onelogin.go @@ -10,8 +10,8 @@ import ( oidc "github.com/coreos/go-oidc/v3/oidc" - "github.com/pomerium/pomerium/internal/identity/oauth" - pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc" + "github.com/pomerium/pomerium/pkg/identity/oauth" + pom_oidc "github.com/pomerium/pomerium/pkg/identity/oidc" ) const ( diff --git a/internal/identity/oidc/ping/ping.go b/pkg/identity/oidc/ping/ping.go similarity index 86% rename from internal/identity/oidc/ping/ping.go rename to pkg/identity/oidc/ping/ping.go index 1bfbc33c3..9cd6aca3f 100644 --- a/internal/identity/oidc/ping/ping.go +++ b/pkg/identity/oidc/ping/ping.go @@ -7,8 +7,8 @@ import ( "context" "fmt" - "github.com/pomerium/pomerium/internal/identity/oauth" - pom_oidc "github.com/pomerium/pomerium/internal/identity/oidc" + "github.com/pomerium/pomerium/pkg/identity/oauth" + pom_oidc "github.com/pomerium/pomerium/pkg/identity/oidc" ) const ( diff --git a/internal/identity/oidc/refresh.go b/pkg/identity/oidc/refresh.go similarity index 100% rename from internal/identity/oidc/refresh.go rename to pkg/identity/oidc/refresh.go diff --git a/internal/identity/oidc/refresh_test.go b/pkg/identity/oidc/refresh_test.go similarity index 100% rename from internal/identity/oidc/refresh_test.go rename to pkg/identity/oidc/refresh_test.go diff --git a/internal/identity/oidc/userinfo.go b/pkg/identity/oidc/userinfo.go similarity index 100% rename from internal/identity/oidc/userinfo.go rename to pkg/identity/oidc/userinfo.go diff --git a/internal/identity/oidc/userinfo_test.go b/pkg/identity/oidc/userinfo_test.go similarity index 100% rename from internal/identity/oidc/userinfo_test.go rename to pkg/identity/oidc/userinfo_test.go diff --git a/pkg/identity/providers.go b/pkg/identity/providers.go new file mode 100644 index 000000000..34b569cc1 --- /dev/null +++ b/pkg/identity/providers.go @@ -0,0 +1,80 @@ +// Package identity provides support for making OpenID Connect (OIDC) +// and OAuth2 authenticated HTTP requests with third party identity providers. +package identity + +import ( + "context" + "fmt" + "net/http" + + "golang.org/x/oauth2" + + "github.com/pomerium/pomerium/pkg/identity/identity" + "github.com/pomerium/pomerium/pkg/identity/oauth" + "github.com/pomerium/pomerium/pkg/identity/oauth/apple" + "github.com/pomerium/pomerium/pkg/identity/oauth/github" + "github.com/pomerium/pomerium/pkg/identity/oidc" + "github.com/pomerium/pomerium/pkg/identity/oidc/auth0" + "github.com/pomerium/pomerium/pkg/identity/oidc/azure" + "github.com/pomerium/pomerium/pkg/identity/oidc/cognito" + "github.com/pomerium/pomerium/pkg/identity/oidc/gitlab" + "github.com/pomerium/pomerium/pkg/identity/oidc/google" + "github.com/pomerium/pomerium/pkg/identity/oidc/okta" + "github.com/pomerium/pomerium/pkg/identity/oidc/onelogin" + "github.com/pomerium/pomerium/pkg/identity/oidc/ping" +) + +// State is the identity state. +type State = identity.State + +// Authenticator is an interface representing the ability to authenticate with an identity provider. +type Authenticator interface { + Authenticate(context.Context, string, State) (*oauth2.Token, error) + Refresh(context.Context, *oauth2.Token, State) (*oauth2.Token, error) + Revoke(context.Context, *oauth2.Token) error + Name() string + UpdateUserInfo(ctx context.Context, t *oauth2.Token, v any) error + + SignIn(w http.ResponseWriter, r *http.Request, state string) error + SignOut(w http.ResponseWriter, r *http.Request, idTokenHint, authenticateSignedOutURL, redirectToURL string) error +} + +// AuthenticatorConstructor makes an Authenticator from the given options. +type AuthenticatorConstructor func(context.Context, *oauth.Options) (Authenticator, error) + +var registry = map[string]AuthenticatorConstructor{} + +// RegisterAuthenticator registers a new Authenticator. +func RegisterAuthenticator(name string, ctor AuthenticatorConstructor) { + registry[name] = ctor +} + +func init() { + RegisterAuthenticator(apple.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return apple.New(ctx, o) }) + RegisterAuthenticator(auth0.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return auth0.New(ctx, o) }) + RegisterAuthenticator(azure.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return azure.New(ctx, o) }) + RegisterAuthenticator(cognito.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return cognito.New(ctx, o) }) + RegisterAuthenticator(github.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return github.New(ctx, o) }) + RegisterAuthenticator(gitlab.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return gitlab.New(ctx, o) }) + RegisterAuthenticator(google.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return google.New(ctx, o) }) + RegisterAuthenticator(oidc.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return oidc.New(ctx, o) }) + RegisterAuthenticator(okta.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return okta.New(ctx, o) }) + RegisterAuthenticator(onelogin.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return onelogin.New(ctx, o) }) + RegisterAuthenticator(ping.Name, func(ctx context.Context, o *oauth.Options) (Authenticator, error) { return ping.New(ctx, o) }) +} + +// NewAuthenticator returns a new identity provider based on its name. +func NewAuthenticator(o oauth.Options) (a Authenticator, err error) { + ctx := context.Background() + + if o.ProviderName == "" { + return nil, fmt.Errorf("identity: provider is not defined") + } + + ctor, ok := registry[o.ProviderName] + if !ok { + return nil, fmt.Errorf("identity: unknown provider: %s", o.ProviderName) + } + + return ctor(ctx, &o) +}