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

Method oAuthCallback

internal/api/external_oauth.go:60–147  ·  view source on GitHub ↗
(ctx context.Context, r *http.Request, providerType string)

Source from the content-addressed store, hash-verified

58}
59
60func (a *API) oAuthCallback(ctx context.Context, r *http.Request, providerType string) (*OAuthProviderData, error) {
61 db := a.db.WithContext(ctx)
62
63 var rq url.Values
64 if err := r.ParseForm(); r.Method == http.MethodPost && err == nil {
65 rq = r.Form
66 } else {
67 rq = r.URL.Query()
68 }
69
70 extError := rq.Get("error")
71 if extError != "" {
72 return nil, apierrors.NewOAuthError(extError, rq.Get("error_description"))
73 }
74
75 oauthCode := rq.Get("code")
76 if oauthCode == "" {
77 return nil, apierrors.NewBadRequestError(apierrors.ErrorCodeBadOAuthCallback, "OAuth callback with missing authorization code missing")
78 }
79
80 oauthProvider, _, err := a.OAuthProvider(ctx, providerType)
81 if err != nil {
82 return nil, apierrors.NewBadRequestError(apierrors.ErrorCodeOAuthProviderNotSupported, "Unsupported provider: %+v", err).WithInternalError(err)
83 }
84
85 log := observability.GetLogEntry(r).Entry
86
87 var oauthClientState *models.OAuthClientState
88 // if there's a non-empty OAuthClientStateID we perform PKCE Flow for the external provider
89 if oauthClientStateID := getOAuthClientStateID(ctx); oauthClientStateID != uuid.Nil {
90 oauthClientState, err = models.FindAndDeleteOAuthClientStateByID(db, oauthClientStateID)
91 if models.IsNotFoundError(err) {
92 return nil, apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeOAuthClientStateNotFound, "OAuth state not found").WithInternalError(err)
93 } else if err != nil {
94 return nil, apierrors.NewInternalServerError("Failed to find OAuth state").WithInternalError(err)
95 }
96
97 if oauthClientState.ProviderType != providerType {
98 return nil, apierrors.NewBadRequestError(apierrors.ErrorCodeOAuthInvalidState, "OAuth provider mismatch")
99 }
100
101 if oauthClientState.IsExpired() {
102 return nil, apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeOAuthClientStateExpired, "OAuth state expired")
103 }
104 }
105
106 if oauthProvider.RequiresPKCE() && oauthClientState == nil {
107 return nil, apierrors.NewBadRequestError(apierrors.ErrorCodeOAuthInvalidState, "OAuth PKCE code verifier missing")
108 }
109
110 log.WithFields(logrus.Fields{
111 "provider": providerType,
112 "code": oauthCode,
113 }).Debug("Exchanging OAuth code")
114
115 var tokenOpts []oauth2.AuthCodeOption
116 if oauthClientState != nil {
117 tokenOpts = append(tokenOpts, oauth2.VerifierOption(*oauthClientState.CodeVerifier))

Callers 1

handleOAuthCallbackMethod · 0.95

Calls 15

OAuthProviderMethod · 0.95
IsExpiredMethod · 0.95
NewOAuthErrorFunction · 0.92
NewBadRequestErrorFunction · 0.92
GetLogEntryFunction · 0.92
IsNotFoundErrorFunction · 0.92
NewInternalServerErrorFunction · 0.92
getOAuthClientStateIDFunction · 0.85
WithContextMethod · 0.80
ParseUserMethod · 0.80

Tested by

no test coverage detected