Merge pull request #976 from cli/auth-from-env
Respect GITHUB_TOKEN environment variable
This commit is contained in:
commit
968e17625e
8 changed files with 60 additions and 46 deletions
18
api/queries_user.go
Normal file
18
api/queries_user.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/shurcooL/githubv4"
|
||||
)
|
||||
|
||||
func CurrentLoginName(client *Client) (string, error) {
|
||||
var query struct {
|
||||
Viewer struct {
|
||||
Login string
|
||||
}
|
||||
}
|
||||
v4 := githubv4.NewClient(client.http)
|
||||
err := v4.Query(context.Background(), &query, nil)
|
||||
return query.Viewer.Login, err
|
||||
}
|
||||
|
|
@ -172,7 +172,7 @@ func issueStatus(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
currentUser, err := ctx.AuthLogin()
|
||||
currentUser, err := api.CurrentLoginName(apiClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ func TestIssueStatus(t *testing.T) {
|
|||
initBlankContext("", "OWNER/REPO", "master")
|
||||
http := initFakeHTTP()
|
||||
http.StubRepoResponse("OWNER", "REPO")
|
||||
http.Register(
|
||||
httpmock.GraphQL(`\bviewer\b`),
|
||||
httpmock.StringResponse(`{"data":{"viewer":{"login":"octocat"}}}`))
|
||||
|
||||
jsonFile, _ := os.Open("../test/fixtures/issueStatus.json")
|
||||
defer jsonFile.Close()
|
||||
|
|
@ -49,6 +52,9 @@ func TestIssueStatus_blankSlate(t *testing.T) {
|
|||
initBlankContext("", "OWNER/REPO", "master")
|
||||
http := initFakeHTTP()
|
||||
http.StubRepoResponse("OWNER", "REPO")
|
||||
http.Register(
|
||||
httpmock.GraphQL(`\bviewer\b`),
|
||||
httpmock.StringResponse(`{"data":{"viewer":{"login":"octocat"}}}`))
|
||||
|
||||
http.StubResponse(200, bytes.NewBufferString(`
|
||||
{ "data": { "repository": {
|
||||
|
|
@ -86,6 +92,9 @@ func TestIssueStatus_disabledIssues(t *testing.T) {
|
|||
initBlankContext("", "OWNER/REPO", "master")
|
||||
http := initFakeHTTP()
|
||||
http.StubRepoResponse("OWNER", "REPO")
|
||||
http.Register(
|
||||
httpmock.GraphQL(`\bviewer\b`),
|
||||
httpmock.StringResponse(`{"data":{"viewer":{"login":"octocat"}}}`))
|
||||
|
||||
http.StubResponse(200, bytes.NewBufferString(`
|
||||
{ "data": { "repository": {
|
||||
|
|
|
|||
|
|
@ -108,11 +108,6 @@ func prStatus(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
currentUser, err := ctx.AuthLogin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
baseRepo, err := determineBaseRepo(apiClient, cmd, ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -125,6 +120,8 @@ func prStatus(cmd *cobra.Command, args []string) error {
|
|||
return fmt.Errorf("could not query for pull request for current branch: %w", err)
|
||||
}
|
||||
|
||||
// the `@me` macro is available because the API lookup is ElasticSearch-based
|
||||
currentUser := "@me"
|
||||
prPayload, err := api.PullRequests(apiClient, baseRepo, currentPRNumber, currentPRHeadRef, currentUser)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -101,6 +101,9 @@ var initContext = func() context.Context {
|
|||
if repo := os.Getenv("GH_REPO"); repo != "" {
|
||||
ctx.SetBaseRepo(repo)
|
||||
}
|
||||
if token := os.Getenv("GITHUB_TOKEN"); token != "" {
|
||||
ctx.SetAuthToken(token)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
|
|
@ -113,11 +116,15 @@ func BasicClient() (*api.Client, error) {
|
|||
}
|
||||
opts = append(opts, api.AddHeader("User-Agent", fmt.Sprintf("GitHub CLI %s", Version)))
|
||||
|
||||
if c, err := config.ParseDefaultConfig(); err == nil {
|
||||
if token, _ := c.Get(defaultHostname, "oauth_token"); token != "" {
|
||||
opts = append(opts, api.AddHeader("Authorization", fmt.Sprintf("token %s", token)))
|
||||
token := os.Getenv("GITHUB_TOKEN")
|
||||
if token == "" {
|
||||
if c, err := config.ParseDefaultConfig(); err == nil {
|
||||
token, _ = c.Get(defaultHostname, "oauth_token")
|
||||
}
|
||||
}
|
||||
if token != "" {
|
||||
opts = append(opts, api.AddHeader("Authorization", fmt.Sprintf("token %s", token)))
|
||||
}
|
||||
return api.NewClient(opts...), nil
|
||||
}
|
||||
|
||||
|
|
@ -145,8 +152,12 @@ var apiClientForContext = func(ctx context.Context) (*api.Client, error) {
|
|||
return fmt.Sprintf("token %s", token)
|
||||
}
|
||||
|
||||
tokenFromEnv := func() bool {
|
||||
return os.Getenv("GITHUB_TOKEN") == token
|
||||
}
|
||||
|
||||
checkScopesFunc := func(appID string) error {
|
||||
if config.IsGitHubApp(appID) && utils.IsTerminal(os.Stdin) && utils.IsTerminal(os.Stderr) {
|
||||
if config.IsGitHubApp(appID) && !tokenFromEnv() && utils.IsTerminal(os.Stdin) && utils.IsTerminal(os.Stderr) {
|
||||
newToken, loginHandle, err := config.AuthFlow("Notice: additional authorization required")
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -168,7 +179,11 @@ var apiClientForContext = func(ctx context.Context) (*api.Client, error) {
|
|||
} else {
|
||||
fmt.Fprintln(os.Stderr, "Warning: gh now requires the `read:org` OAuth scope.")
|
||||
fmt.Fprintln(os.Stderr, "Visit https://github.com/settings/tokens and edit your token to enable `read:org`")
|
||||
fmt.Fprintln(os.Stderr, "or generate a new token and paste it via `gh config set -h github.com oauth_token MYTOKEN`")
|
||||
if tokenFromEnv() {
|
||||
fmt.Fprintln(os.Stderr, "or generate a new token for the GITHUB_TOKEN environment variable")
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, "or generate a new token and paste it via `gh config set -h github.com oauth_token MYTOKEN`")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -194,7 +209,9 @@ var ensureScopes = func(ctx context.Context, client *api.Client, wantedScopes ..
|
|||
return client, nil
|
||||
}
|
||||
|
||||
if config.IsGitHubApp(appID) && utils.IsTerminal(os.Stdin) && utils.IsTerminal(os.Stderr) {
|
||||
tokenFromEnv := len(os.Getenv("GITHUB_TOKEN")) > 0
|
||||
|
||||
if config.IsGitHubApp(appID) && !tokenFromEnv && utils.IsTerminal(os.Stdin) && utils.IsTerminal(os.Stderr) {
|
||||
newToken, loginHandle, err := config.AuthFlow("Notice: additional authorization required")
|
||||
if err != nil {
|
||||
return client, err
|
||||
|
|
@ -219,9 +236,13 @@ var ensureScopes = func(ctx context.Context, client *api.Client, wantedScopes ..
|
|||
|
||||
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("Warning: gh now requires %s OAuth scopes.", 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`")
|
||||
if tokenFromEnv {
|
||||
fmt.Fprintln(os.Stderr, "or generate a new token for the GITHUB_TOKEN environment variable")
|
||||
} else {
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ func NewBlank() *blankContext {
|
|||
// A Context implementation that queries the filesystem
|
||||
type blankContext struct {
|
||||
authToken string
|
||||
authLogin string
|
||||
branch string
|
||||
baseRepo ghrepo.Interface
|
||||
remotes Remotes
|
||||
|
|
@ -39,14 +38,6 @@ func (c *blankContext) SetAuthToken(t string) {
|
|||
c.authToken = t
|
||||
}
|
||||
|
||||
func (c *blankContext) SetAuthLogin(login string) {
|
||||
c.authLogin = login
|
||||
}
|
||||
|
||||
func (c *blankContext) AuthLogin() (string, error) {
|
||||
return c.authLogin, nil
|
||||
}
|
||||
|
||||
func (c *blankContext) Branch() (string, error) {
|
||||
if c.branch == "" {
|
||||
return "", fmt.Errorf("branch was not initialized")
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ const defaultHostname = "github.com"
|
|||
type Context interface {
|
||||
AuthToken() (string, error)
|
||||
SetAuthToken(string)
|
||||
AuthLogin() (string, error)
|
||||
Branch() (string, error)
|
||||
SetBranch(string)
|
||||
Remotes() (Remotes, error)
|
||||
|
|
@ -195,20 +194,6 @@ func (c *fsContext) SetAuthToken(t string) {
|
|||
c.authToken = t
|
||||
}
|
||||
|
||||
func (c *fsContext) AuthLogin() (string, error) {
|
||||
config, err := c.Config()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
login, err := config.Get(defaultHostname, "user")
|
||||
if login == "" || err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return login, nil
|
||||
}
|
||||
|
||||
func (c *fsContext) Branch() (string, error) {
|
||||
if c.branch != "" {
|
||||
return c.branch, nil
|
||||
|
|
|
|||
|
|
@ -116,14 +116,7 @@ func setupConfigFile(filename string) (Config, error) {
|
|||
|
||||
func getViewer(token string) (string, error) {
|
||||
http := api.NewClient(api.AddHeader("Authorization", fmt.Sprintf("token %s", token)))
|
||||
|
||||
response := struct {
|
||||
Viewer struct {
|
||||
Login string
|
||||
}
|
||||
}{}
|
||||
err := http.GraphQL("{ viewer { login } }", nil, &response)
|
||||
return response.Viewer.Login, err
|
||||
return api.CurrentLoginName(http)
|
||||
}
|
||||
|
||||
func waitForEnter(r io.Reader) error {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue