untested first pass on ensureScopes

This commit is contained in:
vilmibm 2020-05-15 16:40:13 -05:00
parent 08e9cdaee1
commit 7decae71fc
3 changed files with 83 additions and 2 deletions

View file

@ -145,6 +145,41 @@ func (gr GraphQLErrorResponse) Error() string {
return fmt.Sprintf("graphql error: '%s'", strings.Join(errorMessages, ", "))
}
// Returns whether or not scopes are present, appID, and error
func (c Client) HasScopes(wantedScopes ...string) (bool, string, error) {
url := "https://api.github.com/user"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return false, "", err
}
req.Header.Set("Content-Type", "application/json; charset=utf-8")
res, err := c.http.Do(req)
if err != nil {
return false, "", err
}
defer res.Body.Close()
appID := res.Header.Get("X-Oauth-Client-Id")
hasScopes := strings.Split(res.Header.Get("X-Oauth-Scopes"), ",")
found := 0
for _, s := range hasScopes {
for _, w := range wantedScopes {
if w == strings.TrimSpace(s) {
found++
}
}
}
if found == len(wantedScopes) {
return true, appID, nil
}
return false, appID, nil
}
// GraphQL performs a GraphQL request and parses the response
func (c Client) GraphQL(query string, variables map[string]interface{}, data interface{}) error {
url := "https://api.github.com/graphql"

View file

@ -34,8 +34,10 @@ func gistCreate(cmd *cobra.Command, args []string) error {
return err
}
// TODO ??
ok, err := client.EnsureScope("gist")
client, err = ensureScopes(ctx, client, "gist")
if err != nil {
return err
}
description, err := cmd.Flags().GetString("description")
if err != nil {

View file

@ -1,6 +1,7 @@
package command
import (
"errors"
"fmt"
"io"
"os"
@ -184,6 +185,49 @@ var apiClientForContext = func(ctx context.Context) (*api.Client, error) {
return api.NewClient(opts...), nil
}
func ensureScopes(ctx context.Context, client *api.Client, wantedScopes ...string) (*api.Client, error) {
hasScopes, appID, err := client.HasScopes(wantedScopes...)
if err != nil {
return client, err
}
if hasScopes {
return client, nil
}
if config.IsGitHubApp(appID) && utils.IsTerminal(os.Stdin) && utils.IsTerminal(os.Stderr) {
newToken, loginHandle, err := config.AuthFlow("Notice: additional authorization required")
if err != nil {
return client, err
}
cfg, err := ctx.Config()
if err != nil {
return client, err
}
_ = cfg.Set(defaultHostname, "oauth_token", newToken)
_ = cfg.Set(defaultHostname, "user", loginHandle)
// update config file on disk
err = cfg.Write()
if err != nil {
return client, err
}
// update configuration in memory
config.AuthFlowComplete()
reloadedClient, err := apiClientForContext(ctx)
if err != nil {
return client, err
}
return reloadedClient, nil
} else {
fmt.Fprintln(os.Stderr, fmt.Sprintf("Warning: gh now requires the `%s` OAuth scope(s).", wantedScopes))
fmt.Fprintln(os.Stderr, fmt.Sprintf("Visit https://github.com/settings/tokens and edit your token to enable %s", wantedScopes))
fmt.Fprintln(os.Stderr, "or generate a new token and paste it via `gh config set -h github.com oauth_token MYTOKEN`")
return client, errors.New("Unable to reauthenticate")
}
}
func apiVerboseLog() api.ClientOption {
logTraffic := strings.Contains(os.Getenv("DEBUG"), "api")
colorize := utils.IsTerminal(os.Stderr)