in oauth2/authorization_tokenretriever.go [282:321]
func (ce *TokenRetriever) ExchangeDeviceCode(ctx context.Context, req DeviceCodeExchangeRequest) (*TokenResult, error) {
for {
request, err := ce.newDeviceCodeExchangeRequest(req)
if err != nil {
return nil, err
}
response, err := ce.transport.Do(request)
if err != nil {
return nil, err
}
token, err := ce.handleAuthTokensResponse(response)
if err == nil {
return token, nil
}
terr, ok := err.(*TokenError)
if !ok {
return nil, err
}
switch terr.ErrorCode {
case "expired_token":
// The user has not authorized the device quickly enough, so the device_code has expired.
return nil, fmt.Errorf("the device code has expired")
case "access_denied":
// The user refused to authorize the device
return nil, fmt.Errorf("the device was not authorized")
case "authorization_pending":
// Still waiting for the user to take action
case "slow_down":
// You are polling too fast
}
select {
case <-time.After(req.PollInterval):
continue
case <-ctx.Done():
return nil, errors.New("cancelled")
}
}
}