MCPcopy Create free account
hub / github.com/couchbase/sync_gateway / handleOIDCCallback

Method handleOIDCCallback

rest/oidc_api.go:133–213  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

131}
132
133func (h *handler) handleOIDCCallback() error {
134 callbackError := h.getQuery(requestParamError)
135 if callbackError != "" {
136 errorDescription := h.getQuery(requestParamErrorDesc)
137 return base.HTTPErrorf(http.StatusUnauthorized, "oidc callback received an error: %v", errorDescription)
138 }
139
140 code := h.getQuery(requestParamCode)
141 if code == "" {
142 return base.HTTPErrorf(http.StatusBadRequest, "Code must be present on oidc callback")
143 }
144
145 providerName := h.getQuery(requestParamProvider)
146 provider, err := h.getOIDCProvider(providerName)
147 if err != nil || provider == nil {
148 return base.HTTPErrorf(http.StatusBadRequest, "Unable to identify provider for callback request")
149 }
150
151 // Validate state parameter to prevent cross-site request forgery (CSRF) when callback state is enabled.
152 if !provider.DisableCallbackState {
153 stateCookie, err := h.rq.Cookie(stateCookieName)
154
155 if err == http.ErrNoCookie || stateCookie == nil {
156 return ErrNoStateCookie
157 }
158
159 if err != nil {
160 base.WarnfCtx(h.ctx(), "Unexpected error attempting to read OIDC state cookie: %v", err)
161 return ErrReadStateCookie
162 }
163
164 stateParam := h.rq.URL.Query().Get(requestParamState)
165 if stateParam != stateCookie.Value {
166 return ErrStateMismatch
167 }
168
169 // Delete the state cookie on successful validation.
170 stateCookie = h.makeStateCookie("", -1)
171 http.SetCookie(h.response, stateCookie)
172 }
173
174 client, err := provider.GetClient(h.ctx(), h.getOIDCCallbackURL)
175 if err != nil {
176 return fmt.Errorf("OIDC initialization error: %w", err)
177 }
178
179 // Converts the authorization code into a token.
180 context := auth.GetOIDCClientContext(provider.InsecureSkipVerify)
181 token, err := client.Config().Exchange(context, code)
182 if err != nil {
183 return base.HTTPErrorf(http.StatusInternalServerError, "Failed to exchange token: %s", err.Error())
184 }
185
186 rawIDToken, ok := token.Extra("id_token").(string)
187 if !ok {
188 return base.HTTPErrorf(http.StatusInternalServerError, "No id_token field in oauth2 token.")
189 }
190 base.InfofCtx(h.ctx(), base.KeyAuth, "Obtained token from Authorization Server: %v", rawIDToken)

Callers

nothing calls this directly

Calls 15

getQueryMethod · 0.95
getOIDCProviderMethod · 0.95
ctxMethod · 0.95
makeStateCookieMethod · 0.95
writeJSONMethod · 0.95
HTTPErrorfFunction · 0.92
WarnfCtxFunction · 0.92
GetOIDCClientContextFunction · 0.92
InfofCtxFunction · 0.92
GetClientMethod · 0.80
ErrorfMethod · 0.80

Tested by

no test coverage detected