X Tutup
Skip to content

Commit 7decae7

Browse files
committed
untested first pass on ensureScopes
1 parent 08e9cda commit 7decae7

File tree

3 files changed

+83
-2
lines changed

3 files changed

+83
-2
lines changed

api/client.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,41 @@ func (gr GraphQLErrorResponse) Error() string {
145145
return fmt.Sprintf("graphql error: '%s'", strings.Join(errorMessages, ", "))
146146
}
147147

148+
// Returns whether or not scopes are present, appID, and error
149+
func (c Client) HasScopes(wantedScopes ...string) (bool, string, error) {
150+
url := "https://api.github.com/user"
151+
req, err := http.NewRequest("GET", url, nil)
152+
if err != nil {
153+
return false, "", err
154+
}
155+
156+
req.Header.Set("Content-Type", "application/json; charset=utf-8")
157+
158+
res, err := c.http.Do(req)
159+
if err != nil {
160+
return false, "", err
161+
}
162+
defer res.Body.Close()
163+
164+
appID := res.Header.Get("X-Oauth-Client-Id")
165+
hasScopes := strings.Split(res.Header.Get("X-Oauth-Scopes"), ",")
166+
167+
found := 0
168+
for _, s := range hasScopes {
169+
for _, w := range wantedScopes {
170+
if w == strings.TrimSpace(s) {
171+
found++
172+
}
173+
}
174+
}
175+
176+
if found == len(wantedScopes) {
177+
return true, appID, nil
178+
}
179+
180+
return false, appID, nil
181+
}
182+
148183
// GraphQL performs a GraphQL request and parses the response
149184
func (c Client) GraphQL(query string, variables map[string]interface{}, data interface{}) error {
150185
url := "https://api.github.com/graphql"

command/gist.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ func gistCreate(cmd *cobra.Command, args []string) error {
3434
return err
3535
}
3636

37-
// TODO ??
38-
ok, err := client.EnsureScope("gist")
37+
client, err = ensureScopes(ctx, client, "gist")
38+
if err != nil {
39+
return err
40+
}
3941

4042
description, err := cmd.Flags().GetString("description")
4143
if err != nil {

command/root.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package command
22

33
import (
4+
"errors"
45
"fmt"
56
"io"
67
"os"
@@ -184,6 +185,49 @@ var apiClientForContext = func(ctx context.Context) (*api.Client, error) {
184185
return api.NewClient(opts...), nil
185186
}
186187

188+
func ensureScopes(ctx context.Context, client *api.Client, wantedScopes ...string) (*api.Client, error) {
189+
hasScopes, appID, err := client.HasScopes(wantedScopes...)
190+
if err != nil {
191+
return client, err
192+
}
193+
194+
if hasScopes {
195+
return client, nil
196+
}
197+
198+
if config.IsGitHubApp(appID) && utils.IsTerminal(os.Stdin) && utils.IsTerminal(os.Stderr) {
199+
newToken, loginHandle, err := config.AuthFlow("Notice: additional authorization required")
200+
if err != nil {
201+
return client, err
202+
}
203+
cfg, err := ctx.Config()
204+
if err != nil {
205+
return client, err
206+
}
207+
_ = cfg.Set(defaultHostname, "oauth_token", newToken)
208+
_ = cfg.Set(defaultHostname, "user", loginHandle)
209+
// update config file on disk
210+
err = cfg.Write()
211+
if err != nil {
212+
return client, err
213+
}
214+
// update configuration in memory
215+
config.AuthFlowComplete()
216+
reloadedClient, err := apiClientForContext(ctx)
217+
if err != nil {
218+
return client, err
219+
}
220+
221+
return reloadedClient, nil
222+
} else {
223+
fmt.Fprintln(os.Stderr, fmt.Sprintf("Warning: gh now requires the `%s` OAuth scope(s).", wantedScopes))
224+
fmt.Fprintln(os.Stderr, fmt.Sprintf("Visit https://github.com/settings/tokens and edit your token to enable %s", wantedScopes))
225+
fmt.Fprintln(os.Stderr, "or generate a new token and paste it via `gh config set -h github.com oauth_token MYTOKEN`")
226+
return client, errors.New("Unable to reauthenticate")
227+
}
228+
229+
}
230+
187231
func apiVerboseLog() api.ClientOption {
188232
logTraffic := strings.Contains(os.Getenv("DEBUG"), "api")
189233
colorize := utils.IsTerminal(os.Stderr)

0 commit comments

Comments
 (0)
X Tutup