support auth login --web
This commit is contained in:
parent
5a8df475b9
commit
2345f49ccb
2 changed files with 113 additions and 52 deletions
|
|
@ -24,8 +24,11 @@ type LoginOptions struct {
|
|||
IO *iostreams.IOStreams
|
||||
Config func() (config.Config, error)
|
||||
|
||||
Interactive bool
|
||||
|
||||
Hostname string
|
||||
Token string
|
||||
Web bool
|
||||
}
|
||||
|
||||
func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Command {
|
||||
|
|
@ -51,6 +54,9 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
|
|||
$ gh auth login
|
||||
# => do an interactive setup
|
||||
|
||||
$ gh auth login --web
|
||||
# => open a browser to authenticate and do a non-interactive setup
|
||||
|
||||
$ gh auth login --with-token < mytoken.txt
|
||||
# => read token from mytoken.txt and authenticate against github.com
|
||||
|
||||
|
|
@ -58,6 +64,14 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
|
|||
# => read token from mytoken.txt and authenticate against a GitHub Enterprise Server instance
|
||||
`),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if !opts.IO.CanPrompt() && !(tokenStdin || opts.Web) {
|
||||
return &cmdutil.FlagError{Err: errors.New("--web or --with-token required when not running interactively")}
|
||||
}
|
||||
|
||||
if tokenStdin && opts.Web {
|
||||
return &cmdutil.FlagError{Err: errors.New("specify only one of --web or --with-token")}
|
||||
}
|
||||
|
||||
if tokenStdin {
|
||||
defer opts.IO.In.Close()
|
||||
token, err := ioutil.ReadAll(opts.IO.In)
|
||||
|
|
@ -67,15 +81,8 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
|
|||
opts.Token = strings.TrimSpace(string(token))
|
||||
}
|
||||
|
||||
if opts.Token != "" {
|
||||
// Assume non-interactive if a token is specified
|
||||
if opts.Hostname == "" {
|
||||
opts.Hostname = ghinstance.Default()
|
||||
}
|
||||
} else {
|
||||
if !opts.IO.CanPrompt() {
|
||||
return &cmdutil.FlagError{Err: errors.New("--with-token required when not running interactively")}
|
||||
}
|
||||
if opts.IO.CanPrompt() && opts.Token == "" && !opts.Web {
|
||||
opts.Interactive = true
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("hostname") {
|
||||
|
|
@ -84,6 +91,12 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
|
|||
}
|
||||
}
|
||||
|
||||
if !opts.Interactive {
|
||||
if opts.Hostname == "" {
|
||||
opts.Hostname = ghinstance.Default()
|
||||
}
|
||||
}
|
||||
|
||||
if runF != nil {
|
||||
return runF(opts)
|
||||
}
|
||||
|
|
@ -94,6 +107,7 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
|
|||
|
||||
cmd.Flags().StringVarP(&opts.Hostname, "hostname", "h", "", "The hostname of the GitHub instance to authenticate with")
|
||||
cmd.Flags().BoolVar(&tokenStdin, "with-token", false, "Read token from standard input")
|
||||
cmd.Flags().BoolVarP(&opts.Web, "web", "w", false, "Open a browser to authenticate")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
@ -168,24 +182,26 @@ func loginRun(opts *LoginOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
username, err := api.CurrentLoginName(apiClient, hostname)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error using api: %w", err)
|
||||
}
|
||||
var keepGoing bool
|
||||
err = prompt.SurveyAskOne(&survey.Confirm{
|
||||
Message: fmt.Sprintf(
|
||||
"You're already logged into %s as %s. Do you want to re-authenticate?",
|
||||
hostname,
|
||||
username),
|
||||
Default: false,
|
||||
}, &keepGoing)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not prompt: %w", err)
|
||||
}
|
||||
if opts.Interactive {
|
||||
username, err := api.CurrentLoginName(apiClient, hostname)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error using api: %w", err)
|
||||
}
|
||||
var keepGoing bool
|
||||
err = prompt.SurveyAskOne(&survey.Confirm{
|
||||
Message: fmt.Sprintf(
|
||||
"You're already logged into %s as %s. Do you want to re-authenticate?",
|
||||
hostname,
|
||||
username),
|
||||
Default: false,
|
||||
}, &keepGoing)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not prompt: %w", err)
|
||||
}
|
||||
|
||||
if !keepGoing {
|
||||
return nil
|
||||
if !keepGoing {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -195,15 +211,19 @@ func loginRun(opts *LoginOptions) error {
|
|||
}
|
||||
|
||||
var authMode int
|
||||
err = prompt.SurveyAskOne(&survey.Select{
|
||||
Message: "How would you like to authenticate?",
|
||||
Options: []string{
|
||||
"Login with a web browser",
|
||||
"Paste an authentication token",
|
||||
},
|
||||
}, &authMode)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not prompt: %w", err)
|
||||
if opts.Web {
|
||||
authMode = 0
|
||||
} else {
|
||||
err = prompt.SurveyAskOne(&survey.Select{
|
||||
Message: "How would you like to authenticate?",
|
||||
Options: []string{
|
||||
"Login with a web browser",
|
||||
"Paste an authentication token",
|
||||
},
|
||||
}, &authMode)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not prompt: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if authMode == 0 {
|
||||
|
|
@ -239,19 +259,21 @@ func loginRun(opts *LoginOptions) error {
|
|||
}
|
||||
}
|
||||
|
||||
var gitProtocol string
|
||||
err = prompt.SurveyAskOne(&survey.Select{
|
||||
Message: "Choose default git protocol",
|
||||
Options: []string{
|
||||
"HTTPS",
|
||||
"SSH",
|
||||
},
|
||||
}, &gitProtocol)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not prompt: %w", err)
|
||||
}
|
||||
gitProtocol := "https"
|
||||
if opts.Interactive {
|
||||
err = prompt.SurveyAskOne(&survey.Select{
|
||||
Message: "Choose default git protocol",
|
||||
Options: []string{
|
||||
"HTTPS",
|
||||
"SSH",
|
||||
},
|
||||
}, &gitProtocol)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not prompt: %w", err)
|
||||
}
|
||||
|
||||
gitProtocol = strings.ToLower(gitProtocol)
|
||||
gitProtocol = strings.ToLower(gitProtocol)
|
||||
}
|
||||
|
||||
fmt.Fprintf(opts.IO.ErrOut, "- gh config set -h %s git_protocol %s\n", hostname, gitProtocol)
|
||||
err = cfg.Set(hostname, "git_protocol", gitProtocol)
|
||||
|
|
|
|||
|
|
@ -81,8 +81,9 @@ func Test_NewCmdLogin(t *testing.T) {
|
|||
stdinTTY: true,
|
||||
cli: "--hostname barry.burton",
|
||||
wants: LoginOptions{
|
||||
Hostname: "barry.burton",
|
||||
Token: "",
|
||||
Hostname: "barry.burton",
|
||||
Token: "",
|
||||
Interactive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -90,10 +91,33 @@ func Test_NewCmdLogin(t *testing.T) {
|
|||
stdinTTY: true,
|
||||
cli: "",
|
||||
wants: LoginOptions{
|
||||
Hostname: "",
|
||||
Token: "",
|
||||
Hostname: "",
|
||||
Token: "",
|
||||
Interactive: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tty web",
|
||||
stdinTTY: true,
|
||||
cli: "--web",
|
||||
wants: LoginOptions{
|
||||
Hostname: "github.com",
|
||||
Web: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nontty web",
|
||||
cli: "--web",
|
||||
wants: LoginOptions{
|
||||
Hostname: "github.com",
|
||||
Web: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "web and with-token",
|
||||
cli: "--web --with-token",
|
||||
wantsErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
@ -134,6 +158,8 @@ func Test_NewCmdLogin(t *testing.T) {
|
|||
|
||||
assert.Equal(t, tt.wants.Token, gotOpts.Token)
|
||||
assert.Equal(t, tt.wants.Hostname, gotOpts.Hostname)
|
||||
assert.Equal(t, tt.wants.Web, gotOpts.Web)
|
||||
assert.Equal(t, tt.wants.Interactive, gotOpts.Interactive)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -262,6 +288,9 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
}{
|
||||
{
|
||||
name: "already authenticated",
|
||||
opts: &LoginOptions{
|
||||
Interactive: true,
|
||||
},
|
||||
cfg: func(cfg config.Config) {
|
||||
_ = cfg.Set("github.com", "oauth_token", "ghi789")
|
||||
},
|
||||
|
|
@ -280,7 +309,8 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
{
|
||||
name: "hostname set",
|
||||
opts: &LoginOptions{
|
||||
Hostname: "rebecca.chambers",
|
||||
Hostname: "rebecca.chambers",
|
||||
Interactive: true,
|
||||
},
|
||||
wantHosts: "rebecca.chambers:\n oauth_token: def456\n git_protocol: https\n user: jillv\n",
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
|
|
@ -298,6 +328,9 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
{
|
||||
name: "choose enterprise",
|
||||
wantHosts: "brad.vickers:\n oauth_token: def456\n git_protocol: https\n user: jillv\n",
|
||||
opts: &LoginOptions{
|
||||
Interactive: true,
|
||||
},
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
as.StubOne(1) // host type enterprise
|
||||
as.StubOne("brad.vickers") // hostname
|
||||
|
|
@ -315,6 +348,9 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
{
|
||||
name: "choose github.com",
|
||||
wantHosts: "github.com:\n oauth_token: def456\n git_protocol: https\n user: jillv\n",
|
||||
opts: &LoginOptions{
|
||||
Interactive: true,
|
||||
},
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
as.StubOne(0) // host type github.com
|
||||
as.StubOne(1) // auth mode: token
|
||||
|
|
@ -325,6 +361,9 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
{
|
||||
name: "sets git_protocol",
|
||||
wantHosts: "github.com:\n oauth_token: def456\n git_protocol: ssh\n user: jillv\n",
|
||||
opts: &LoginOptions{
|
||||
Interactive: true,
|
||||
},
|
||||
askStubs: func(as *prompt.AskStubber) {
|
||||
as.StubOne(0) // host type github.com
|
||||
as.StubOne(1) // auth mode: token
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue