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

Method refreshTokenWithRetry

coderd/externalauth/externalauth.go:395–441  ·  view source on GitHub ↗

refreshTokenWithRetry exchanges the refresh token for a new access token, retrying with exponential backoff on transient failures. Permanent failures (as classified by isFailedRefresh) and the no-op case where no refresh token is set bypass the retry loop so a doomed refresh is not repeatedly attemp

(ctx context.Context, existingToken *oauth2.Token)

Source from the content-addressed store, hash-verified

393// refresh token is set bypass the retry loop so a doomed refresh is not
394// repeatedly attempted.
395func (c *Config) refreshTokenWithRetry(ctx context.Context, existingToken *oauth2.Token) (*oauth2.Token, error) {
396 // Without a refresh token the oauth2 library short-circuits with
397 // "token expired and refresh token is not set". No retry can recover
398 // from that, so make a single attempt and return.
399 if existingToken.RefreshToken == "" {
400 return c.TokenSource(ctx, existingToken).Token()
401 }
402
403 initial := c.RefreshRetryInitialBackoff
404 if initial <= 0 {
405 initial = defaultRefreshRetryInitialBackoff
406 }
407 maximum := c.RefreshRetryMaxBackoff
408 if maximum <= 0 {
409 maximum = defaultRefreshRetryMaxBackoff
410 }
411 total := c.RefreshRetryTimeout
412 if total <= 0 {
413 total = defaultRefreshRetryTimeout
414 }
415
416 retryCtx, retryCancel := context.WithTimeout(ctx, total)
417 defer retryCancel()
418 backoff := retry.New(initial, maximum)
419
420 var (
421 token *oauth2.Token
422 err error
423 )
424 for {
425 token, err = c.TokenSource(ctx, existingToken).Token()
426 if err == nil || isFailedRefresh(existingToken, err) {
427 return token, err
428 }
429 // Bail out before waiting if the retry budget is already gone.
430 // retry.Wait selects between time.After(delay) and ctx.Done(); when
431 // delay is zero and the context is already canceled the two cases
432 // race nondeterministically, which would cause an unwanted extra
433 // refresh attempt with a near-zero budget (notably in tests).
434 if retryCtx.Err() != nil {
435 return token, err
436 }
437 if !backoff.Wait(retryCtx) {
438 return token, err
439 }
440 }
441}
442
443// ValidateToken checks if the Git token provided is valid.
444// The user is optionally returned if the provider supports it.

Callers 1

RefreshTokenMethod · 0.95

Calls 6

TokenSourceMethod · 0.95
isFailedRefreshFunction · 0.85
ErrMethod · 0.80
TokenMethod · 0.65
NewMethod · 0.65
WaitMethod · 0.65

Tested by

no test coverage detected