DoDeviceAuthorization gets a token from the IDP using the OAuth 2.0 Device Authorization Grant. https://datatracker.ietf.org/doc/html/rfc8628
()
| 861 | // DoDeviceAuthorization gets a token from the IDP using the OAuth 2.0 |
| 862 | // Device Authorization Grant. https://datatracker.ietf.org/doc/html/rfc8628 |
| 863 | func (o *oauth) DoDeviceAuthorization() (*token, error) { |
| 864 | // Identify the Device |
| 865 | data := url.Values{} |
| 866 | data.Set("client_id", o.clientID) |
| 867 | data.Set("client_secret", o.clientSecret) |
| 868 | data.Set("scope", o.scope) |
| 869 | |
| 870 | resp, err := postForm(o.deviceAuthzEndpoint, data) |
| 871 | if err != nil { |
| 872 | return nil, errors.Wrap(err, "http failure to identify device") |
| 873 | } |
| 874 | defer resp.Body.Close() |
| 875 | b, err := io.ReadAll(resp.Body) |
| 876 | if err != nil { |
| 877 | return nil, err |
| 878 | } |
| 879 | |
| 880 | if resp.StatusCode >= 400 { |
| 881 | var e struct { |
| 882 | Error string |
| 883 | } |
| 884 | if err := json.NewDecoder(bytes.NewReader(b)).Decode(&e); err != nil { |
| 885 | return nil, errors.Wrapf(err, "could not parse http body: %s", string(b)) |
| 886 | } |
| 887 | } |
| 888 | |
| 889 | var idr identifyDeviceResponse |
| 890 | if err := json.NewDecoder(bytes.NewReader(b)).Decode(&idr); err != nil { |
| 891 | return nil, errors.Wrap(err, "failure decoding device authz response to JSON") |
| 892 | } |
| 893 | |
| 894 | shouldPrintCode := true |
| 895 | switch { |
| 896 | case idr.VerificationURIComplete != "": |
| 897 | // Prefer VerificationURIComplete if present for user convenience |
| 898 | idr.VerificationURI = idr.VerificationURIComplete |
| 899 | shouldPrintCode = false |
| 900 | case idr.VerificationURI != "": |
| 901 | // do nothing |
| 902 | case idr.VerificationURL != "": |
| 903 | // NOTE this is a hack for Google, because their API returns the attribute |
| 904 | // 'verification_url` rather than `verification_uri`. |
| 905 | idr.VerificationURI = idr.VerificationURL |
| 906 | default: |
| 907 | return nil, errors.Errorf("device code response from server missing 'verification_uri' parameter. http body response: %s", string(b)) |
| 908 | } |
| 909 | |
| 910 | if idr.Interval <= 0 { |
| 911 | idr.Interval = defaultDeviceAuthzInterval |
| 912 | } |
| 913 | |
| 914 | if shouldPrintCode { |
| 915 | fmt.Fprintf(os.Stderr, "Visit %s and enter the code:\n", idr.VerificationURI) |
| 916 | fmt.Fprintln(os.Stderr, idr.UserCode) |
| 917 | } else { |
| 918 | fmt.Fprintf(os.Stderr, "Visit %s:\n", idr.VerificationURI) |
| 919 | } |
| 920 |
no test coverage detected