MCPcopy Index your code
hub / github.com/git-bug/git-bug / pollGithubForAuthorization

Function pollGithubForAuthorization

bridge/github/config.go:267–319  ·  view source on GitHub ↗
(deviceCode string, intervalSec int64)

Source from the content-addressed store, hash-verified

265}
266
267func pollGithubForAuthorization(deviceCode string, intervalSec int64) (string, error) {
268 params := url.Values{}
269 params.Set("client_id", githubClientID)
270 params.Set("device_code", deviceCode)
271 params.Set("grant_type", "urn:ietf:params:oauth:grant-type:device_code") // fixed by RFC 8628
272 client := &http.Client{
273 Timeout: defaultTimeout,
274 }
275 interval := time.Duration(intervalSec * 1100) // milliseconds, add 10% margin
276
277 for {
278 resp, err := client.PostForm("https://github.com/login/oauth/access_token", params)
279 if err != nil {
280 return "", errors.Wrap(err, "error polling the Github API")
281 }
282 if resp.StatusCode != http.StatusOK {
283 _ = resp.Body.Close()
284 return "", fmt.Errorf("unexpected response status code %d from Github API", resp.StatusCode)
285 }
286
287 data, err := io.ReadAll(resp.Body)
288 if err != nil {
289 _ = resp.Body.Close()
290 return "", errors.Wrap(err, "error polling the Github API")
291 }
292 _ = resp.Body.Close()
293
294 values, err := url.ParseQuery(string(data))
295 if err != nil {
296 return "", errors.Wrap(err, "error decoding Github API response")
297 }
298
299 if token := values.Get("access_token"); token != "" {
300 return token, nil
301 }
302
303 switch apiError := values.Get("error"); apiError {
304 case "slow_down":
305 interval += 5500 // add 5 seconds (RFC 8628), plus some margin
306 time.Sleep(interval * time.Millisecond)
307 continue
308 case "authorization_pending":
309 time.Sleep(interval * time.Millisecond)
310 continue
311 case "":
312 return "", errors.New("unexpected response from Github API")
313 default:
314 // apiError should equal one of: "expired_token", "unsupported_grant_type",
315 // "incorrect_client_credentials", "incorrect_device_code", or "access_denied"
316 return "", fmt.Errorf("error creating token: %v, %v", apiError, values.Get("error_description"))
317 }
318 }
319}
320
321func promptTokenOptions(repo repository.RepoKeyring, login, owner, project string) (auth.Credential, error) {
322 creds, err := auth.List(repo,

Callers 1

requestTokenFunction · 0.85

Calls 6

SetMethod · 0.80
ErrorfMethod · 0.80
GetMethod · 0.80
CloseMethod · 0.65
ReadAllMethod · 0.65
NewMethod · 0.45

Tested by

no test coverage detected