MCPcopy Create free account
hub / github.com/supabase/auth / GetExternalProviderRedirectURL

Method GetExternalProviderRedirectURL

internal/api/external.go:36–128  ·  view source on GitHub ↗

GetExternalProviderRedirectURL returns the URL to start the oauth flow with the corresponding oauth provider

(w http.ResponseWriter, r *http.Request, linkingTargetUser *models.User)

Source from the content-addressed store, hash-verified

34
35// GetExternalProviderRedirectURL returns the URL to start the oauth flow with the corresponding oauth provider
36func (a *API) GetExternalProviderRedirectURL(w http.ResponseWriter, r *http.Request, linkingTargetUser *models.User) (string, error) {
37 ctx := r.Context()
38 db := a.db.WithContext(ctx)
39 config := a.config
40
41 query := r.URL.Query()
42 providerType := query.Get("provider")
43 scopes := query.Get("scopes")
44 codeChallenge := query.Get("code_challenge")
45 codeChallengeMethod := query.Get("code_challenge_method")
46
47 p, pConfig, err := a.Provider(ctx, providerType, scopes)
48 if err != nil {
49 return "", apierrors.NewBadRequestError(apierrors.ErrorCodeValidationFailed, "Unsupported provider: %+v", err).WithInternalError(err)
50 }
51
52 inviteToken := query.Get("invite_token")
53 if inviteToken != "" {
54 _, userErr := models.FindUserByConfirmationToken(db, inviteToken)
55 if userErr != nil {
56 if models.IsNotFoundError(userErr) {
57 return "", apierrors.NewNotFoundError(apierrors.ErrorCodeUserNotFound, "User identified by token not found")
58 }
59 return "", apierrors.NewInternalServerError("Database error finding user").WithInternalError(userErr)
60 }
61 }
62
63 redirectURL := utilities.GetReferrer(r, config)
64 log := observability.GetLogEntry(r).Entry
65 log.WithField("provider", providerType).Info("Redirecting to external provider")
66 if err := validatePKCEParams(codeChallengeMethod, codeChallenge); err != nil {
67 return "", err
68 }
69
70 authUrlParams := make([]oauth2.AuthCodeOption, 0)
71 query.Del("scopes")
72 query.Del("provider")
73 query.Del("code_challenge")
74 query.Del("code_challenge_method")
75 for key := range query {
76 if key == "workos_provider" {
77 // See https://workos.com/docs/reference/sso/authorize/get
78 authUrlParams = append(authUrlParams, oauth2.SetAuthURLParam("provider", query.Get(key)))
79 } else {
80 authUrlParams = append(authUrlParams, oauth2.SetAuthURLParam(key, query.Get(key)))
81 }
82 }
83
84 // Handle OAuthClientState for providers that require PKCE on their end
85 var oauthClientStateID *uuid.UUID
86 if oauthProvider, ok := p.(provider.OAuthProvider); ok && oauthProvider.RequiresPKCE() {
87 codeVerifier := oauth2.GenerateVerifier()
88 oauthClientState := models.NewOAuthClientState(providerType, &codeVerifier)
89 err := db.Create(oauthClientState)
90 if err != nil {
91 return "", err
92 }
93 oauthClientStateID = &oauthClientState.ID

Callers 2

LinkIdentityMethod · 0.95

Calls 15

ProviderMethod · 0.95
NewBadRequestErrorFunction · 0.92
IsNotFoundErrorFunction · 0.92
NewNotFoundErrorFunction · 0.92
NewInternalServerErrorFunction · 0.92
GetReferrerFunction · 0.92
GetLogEntryFunction · 0.92
NewOAuthClientStateFunction · 0.92
NewFlowStateFunction · 0.92
validatePKCEParamsFunction · 0.85
WithContextMethod · 0.80

Tested by

no test coverage detected