| 217 | } |
| 218 | |
| 219 | func requestUserVerificationCode(scope string) (*githRespT, error) { |
| 220 | params := url.Values{} |
| 221 | params.Set("client_id", githubClientID) |
| 222 | params.Set("scope", scope) |
| 223 | client := &http.Client{ |
| 224 | Timeout: defaultTimeout, |
| 225 | } |
| 226 | |
| 227 | resp, err := client.PostForm("https://github.com/login/device/code", params) |
| 228 | if err != nil { |
| 229 | return nil, errors.Wrap(err, "error requesting user verification code") |
| 230 | } |
| 231 | defer resp.Body.Close() |
| 232 | if resp.StatusCode != http.StatusOK { |
| 233 | return nil, fmt.Errorf("unexpected response status code %d from Github API", resp.StatusCode) |
| 234 | } |
| 235 | |
| 236 | data, err := io.ReadAll(resp.Body) |
| 237 | if err != nil { |
| 238 | return nil, errors.Wrap(err, "error requesting user verification code") |
| 239 | } |
| 240 | |
| 241 | vals, err := url.ParseQuery(string(data)) |
| 242 | if err != nil { |
| 243 | return nil, errors.Wrap(err, "error decoding Github API response") |
| 244 | } |
| 245 | |
| 246 | interval, err := strconv.ParseInt(vals.Get("interval"), 10, 64) // base 10, bitSize 64 |
| 247 | if err != nil { |
| 248 | return nil, errors.Wrap(err, "Error parsing integer received from Github API") |
| 249 | } |
| 250 | |
| 251 | return &githRespT{ |
| 252 | uri: vals.Get("verification_uri"), |
| 253 | userCode: vals.Get("user_code"), |
| 254 | deviceCode: vals.Get("device_code"), |
| 255 | interval: interval, |
| 256 | }, nil |
| 257 | } |
| 258 | |
| 259 | func promptUserToGoToBrowser(url, userCode string) { |
| 260 | fmt.Println("Please visit the following Github URL in a browser and enter your user authentication code.") |