MCPcopy Index your code
hub / github.com/coder/coder / ProcessAuthorize

Function ProcessAuthorize

coderd/oauth2provider/authorize.go:188–285  ·  view source on GitHub ↗

ProcessAuthorize handles POST /oauth2/authorize requests to process the user's authorization decision and generate an authorization code.

(db database.Store)

Source from the content-addressed store, hash-verified

186// ProcessAuthorize handles POST /oauth2/authorize requests to process the user's authorization decision
187// and generate an authorization code.
188func ProcessAuthorize(db database.Store) http.HandlerFunc {
189 return func(rw http.ResponseWriter, r *http.Request) {
190 ctx := r.Context()
191 apiKey := httpmw.APIKey(r)
192 app := httpmw.OAuth2ProviderApp(r)
193
194 callbackURL, err := url.Parse(app.CallbackURL)
195 if err != nil {
196 httpapi.WriteOAuth2Error(r.Context(), rw, http.StatusInternalServerError, codersdk.OAuth2ErrorCodeServerError, "Failed to validate query parameters")
197 return
198 }
199
200 params, _, err := extractAuthorizeParams(r, callbackURL)
201 if err != nil {
202 httpapi.WriteOAuth2Error(ctx, rw, http.StatusBadRequest, codersdk.OAuth2ErrorCodeInvalidRequest, err.Error())
203 return
204 }
205
206 // OAuth 2.1 removes the implicit grant. Only
207 // authorization code flow is supported.
208 if params.responseType != codersdk.OAuth2ProviderResponseTypeCode {
209 httpapi.WriteOAuth2Error(ctx, rw, http.StatusBadRequest,
210 codersdk.OAuth2ErrorCodeUnsupportedResponseType,
211 "Only response_type=code is supported")
212 return
213 }
214
215 // code_challenge is required (enforced by RequiredNotEmpty above),
216 // but default the method to S256 if omitted.
217 if params.codeChallengeMethod == "" {
218 params.codeChallengeMethod = string(codersdk.OAuth2PKCECodeChallengeMethodS256)
219 }
220 if err := codersdk.ValidatePKCECodeChallengeMethod(params.codeChallengeMethod); err != nil {
221 httpapi.WriteOAuth2Error(ctx, rw, http.StatusBadRequest, codersdk.OAuth2ErrorCodeInvalidRequest, err.Error())
222 return
223 }
224
225 // TODO: Ignoring scope for now, but should look into implementing.
226 code, err := GenerateSecret()
227 if err != nil {
228 httpapi.WriteOAuth2Error(r.Context(), rw, http.StatusInternalServerError, codersdk.OAuth2ErrorCodeServerError, "Failed to generate OAuth2 app authorization code")
229 return
230 }
231 err = db.InTx(func(tx database.Store) error {
232 // Delete any previous codes.
233 err = tx.DeleteOAuth2ProviderAppCodesByAppAndUserID(ctx, database.DeleteOAuth2ProviderAppCodesByAppAndUserIDParams{
234 AppID: app.ID,
235 UserID: apiKey.UserID,
236 })
237 if err != nil && !errors.Is(err, sql.ErrNoRows) {
238 return xerrors.Errorf("delete oauth2 app codes: %w", err)
239 }
240
241 // Insert the new code.
242 _, err = tx.InsertOAuth2ProviderAppCode(ctx, database.InsertOAuth2ProviderAppCodeParams{
243 ID: uuid.New(),
244 CreatedAt: dbtime.Now(),
245 // TODO: Configurable expiration? Ten minutes matches GitHub.

Callers 1

Calls 15

APIKeyFunction · 0.92
OAuth2ProviderAppFunction · 0.92
WriteOAuth2ErrorFunction · 0.92
NowFunction · 0.92
extractAuthorizeParamsFunction · 0.85
hashOAuth2StateFunction · 0.85
DurationMethod · 0.80
EncodeMethod · 0.80
GenerateSecretFunction · 0.70
ContextMethod · 0.65
ParseMethod · 0.65

Tested by

no test coverage detected