Detect and warn about read:org OAuth scope being missing

This commit is contained in:
Mislav Marohnić 2020-04-15 17:25:15 +02:00
parent 14ce1f99a7
commit 3d566dc5a6
2 changed files with 42 additions and 0 deletions

View file

@ -7,6 +7,7 @@ import (
"io"
"io/ioutil"
"net/http"
"os"
"regexp"
"strings"
@ -63,6 +64,46 @@ func ReplaceTripper(tr http.RoundTripper) ClientOption {
}
}
var issuedScopesWarning bool
// CheckScopes checks whether an OAuth scope is present in a response
func CheckScopes(wantedScope string) ClientOption {
return func(tr http.RoundTripper) http.RoundTripper {
return &funcTripper{roundTrip: func(req *http.Request) (*http.Response, error) {
res, err := tr.RoundTrip(req)
if err != nil || issuedScopesWarning {
return res, err
}
isApp := res.Header.Get("X-Oauth-Client-Id") != ""
hasScopes := strings.Split(res.Header.Get("X-Oauth-Scopes"), ",")
hasWanted := false
for _, s := range hasScopes {
if wantedScope == strings.TrimSpace(s) {
hasWanted = true
break
}
}
if !hasWanted {
fmt.Fprintln(os.Stderr, "Warning: gh now requires the `read:org` OAuth scope.")
// TODO: offer to take the person through the authentication flow again?
// TODO: retry the original request if it was a read?
if isApp {
fmt.Fprintln(os.Stderr, "To re-authenticate, please `rm ~/.config/gh/config.yml` and try again.")
} else {
// the person has pasted a Personal Access Token
fmt.Fprintln(os.Stderr, "Re-generate your token in `rm ~/.config/gh/config.yml` and try again.")
}
issuedScopesWarning = true
}
return res, nil
}}
}
}
type funcTripper struct {
roundTrip func(*http.Request) (*http.Response, error)
}

View file

@ -131,6 +131,7 @@ var apiClientForContext = func(ctx context.Context) (*api.Client, error) {
opts = append(opts, apiVerboseLog())
}
opts = append(opts,
api.CheckScopes("read:org"),
api.AddHeader("Authorization", fmt.Sprintf("token %s", token)),
api.AddHeader("User-Agent", fmt.Sprintf("GitHub CLI %s", Version)),
// antiope-preview: Checks