Browse Source

Merge pull request #19793 from calavera/full_login_prompt

Always prompt for a password when asking for credentials.
Vincent Demeester 9 năm trước cách đây
mục cha
commit
6c6729ef5b
2 tập tin đã thay đổi với 80 bổ sung75 xóa
  1. 76 73
      api/client/login.go
  2. 4 2
      api/client/utils.go

+ 76 - 73
api/client/login.go

@@ -25,11 +25,9 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
 	cmd := Cli.Subcmd("login", []string{"[SERVER]"}, Cli.DockerCommands["login"].Description+".\nIf no server is specified \""+registry.IndexServer+"\" is the default.", true)
 	cmd := Cli.Subcmd("login", []string{"[SERVER]"}, Cli.DockerCommands["login"].Description+".\nIf no server is specified \""+registry.IndexServer+"\" is the default.", true)
 	cmd.Require(flag.Max, 1)
 	cmd.Require(flag.Max, 1)
 
 
-	var username, password, email string
-
-	cmd.StringVar(&username, []string{"u", "-username"}, "", "Username")
-	cmd.StringVar(&password, []string{"p", "-password"}, "", "Password")
-	cmd.StringVar(&email, []string{"e", "-email"}, "", "Email")
+	flUser := cmd.String([]string{"u", "-username"}, "", "Username")
+	flPassword := cmd.String([]string{"p", "-password"}, "", "Password")
+	flEmail := cmd.String([]string{"e", "-email"}, "", "Email")
 
 
 	cmd.ParseFlags(args, true)
 	cmd.ParseFlags(args, true)
 
 
@@ -43,101 +41,106 @@ func (cli *DockerCli) CmdLogin(args ...string) error {
 		serverAddress = cmd.Arg(0)
 		serverAddress = cmd.Arg(0)
 	}
 	}
 
 
-	promptDefault := func(prompt string, configDefault string) {
-		if configDefault == "" {
-			fmt.Fprintf(cli.out, "%s: ", prompt)
-		} else {
-			fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault)
-		}
+	authConfig, err := cli.configureAuth(*flUser, *flPassword, *flEmail, serverAddress)
+	if err != nil {
+		return err
 	}
 	}
 
 
-	readInput := func(in io.Reader, out io.Writer) string {
-		reader := bufio.NewReader(in)
-		line, _, err := reader.ReadLine()
-		if err != nil {
-			fmt.Fprintln(out, err.Error())
-			os.Exit(1)
+	response, err := cli.client.RegistryLogin(authConfig)
+	if err != nil {
+		if client.IsErrUnauthorized(err) {
+			delete(cli.configFile.AuthConfigs, serverAddress)
+			if err2 := cli.configFile.Save(); err2 != nil {
+				fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2)
+			}
 		}
 		}
-		return string(line)
+		return err
 	}
 	}
 
 
+	if err := cli.configFile.Save(); err != nil {
+		return fmt.Errorf("Error saving config file: %v", err)
+	}
+	fmt.Fprintf(cli.out, "WARNING: login credentials saved in %s\n", cli.configFile.Filename())
+
+	if response.Status != "" {
+		fmt.Fprintf(cli.out, "%s\n", response.Status)
+	}
+	return nil
+}
+
+func (cli *DockerCli) promptWithDefault(prompt string, configDefault string) {
+	if configDefault == "" {
+		fmt.Fprintf(cli.out, "%s: ", prompt)
+	} else {
+		fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault)
+	}
+}
+
+func (cli *DockerCli) configureAuth(flUser, flPassword, flEmail, serverAddress string) (types.AuthConfig, error) {
 	authconfig, ok := cli.configFile.AuthConfigs[serverAddress]
 	authconfig, ok := cli.configFile.AuthConfigs[serverAddress]
 	if !ok {
 	if !ok {
 		authconfig = types.AuthConfig{}
 		authconfig = types.AuthConfig{}
 	}
 	}
 
 
-	if username == "" {
-		promptDefault("Username", authconfig.Username)
-		username = readInput(cli.in, cli.out)
-		username = strings.TrimSpace(username)
-		if username == "" {
-			username = authconfig.Username
+	if flUser == "" {
+		cli.promptWithDefault("Username", authconfig.Username)
+		flUser = readInput(cli.in, cli.out)
+		flUser = strings.TrimSpace(flUser)
+		if flUser == "" {
+			flUser = authconfig.Username
 		}
 		}
 	}
 	}
-	// Assume that a different username means they may not want to use
-	// the password or email from the config file, so prompt them
-	if username != authconfig.Username {
-		if password == "" {
-			oldState, err := term.SaveState(cli.inFd)
-			if err != nil {
-				return err
-			}
-			fmt.Fprintf(cli.out, "Password: ")
-			term.DisableEcho(cli.inFd, oldState)
 
 
-			password = readInput(cli.in, cli.out)
-			fmt.Fprint(cli.out, "\n")
+	if flPassword == "" {
+		oldState, err := term.SaveState(cli.inFd)
+		if err != nil {
+			return authconfig, err
+		}
+		fmt.Fprintf(cli.out, "Password: ")
+		term.DisableEcho(cli.inFd, oldState)
 
 
-			term.RestoreTerminal(cli.inFd, oldState)
-			if password == "" {
-				return fmt.Errorf("Error : Password Required")
-			}
+		flPassword = readInput(cli.in, cli.out)
+		fmt.Fprint(cli.out, "\n")
+
+		term.RestoreTerminal(cli.inFd, oldState)
+		if flPassword == "" {
+			return authconfig, fmt.Errorf("Error : Password Required")
 		}
 		}
+	}
 
 
-		if email == "" {
-			promptDefault("Email", authconfig.Email)
-			email = readInput(cli.in, cli.out)
-			if email == "" {
-				email = authconfig.Email
+	// Assume that a different username means they may not want to use
+	// the email from the config file, so prompt it
+	if flUser != authconfig.Username {
+		if flEmail == "" {
+			cli.promptWithDefault("Email", authconfig.Email)
+			flEmail = readInput(cli.in, cli.out)
+			if flEmail == "" {
+				flEmail = authconfig.Email
 			}
 			}
 		}
 		}
 	} else {
 	} else {
 		// However, if they don't override the username use the
 		// However, if they don't override the username use the
-		// password or email from the cmd line if specified. IOW, allow
+		// email from the cmd line if specified. IOW, allow
 		// then to change/override them.  And if not specified, just
 		// then to change/override them.  And if not specified, just
 		// use what's in the config file
 		// use what's in the config file
-		if password == "" {
-			password = authconfig.Password
-		}
-		if email == "" {
-			email = authconfig.Email
+		if flEmail == "" {
+			flEmail = authconfig.Email
 		}
 		}
 	}
 	}
-	authconfig.Username = username
-	authconfig.Password = password
-	authconfig.Email = email
+	authconfig.Username = flUser
+	authconfig.Password = flPassword
+	authconfig.Email = flEmail
 	authconfig.ServerAddress = serverAddress
 	authconfig.ServerAddress = serverAddress
 	cli.configFile.AuthConfigs[serverAddress] = authconfig
 	cli.configFile.AuthConfigs[serverAddress] = authconfig
+	return authconfig, nil
+}
 
 
-	auth := cli.configFile.AuthConfigs[serverAddress]
-	response, err := cli.client.RegistryLogin(auth)
+func readInput(in io.Reader, out io.Writer) string {
+	reader := bufio.NewReader(in)
+	line, _, err := reader.ReadLine()
 	if err != nil {
 	if err != nil {
-		if client.IsErrUnauthorized(err) {
-			delete(cli.configFile.AuthConfigs, serverAddress)
-			if err2 := cli.configFile.Save(); err2 != nil {
-				fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2)
-			}
-		}
-		return err
-	}
-
-	if err := cli.configFile.Save(); err != nil {
-		return fmt.Errorf("Error saving config file: %v", err)
+		fmt.Fprintln(out, err.Error())
+		os.Exit(1)
 	}
 	}
-	fmt.Fprintf(cli.out, "WARNING: login credentials saved in %s\n", cli.configFile.Filename())
-
-	if response.Status != "" {
-		fmt.Fprintf(cli.out, "%s\n", response.Status)
-	}
-	return nil
+	return string(line)
 }
 }

+ 4 - 2
api/client/utils.go

@@ -38,10 +38,12 @@ func (cli *DockerCli) encodeRegistryAuth(index *registrytypes.IndexInfo) (string
 func (cli *DockerCli) registryAuthenticationPrivilegedFunc(index *registrytypes.IndexInfo, cmdName string) client.RequestPrivilegeFunc {
 func (cli *DockerCli) registryAuthenticationPrivilegedFunc(index *registrytypes.IndexInfo, cmdName string) client.RequestPrivilegeFunc {
 	return func() (string, error) {
 	return func() (string, error) {
 		fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName)
 		fmt.Fprintf(cli.out, "\nPlease login prior to %s:\n", cmdName)
-		if err := cli.CmdLogin(registry.GetAuthConfigKey(index)); err != nil {
+		indexServer := registry.GetAuthConfigKey(index)
+		authConfig, err := cli.configureAuth("", "", "", indexServer)
+		if err != nil {
 			return "", err
 			return "", err
 		}
 		}
-		return cli.encodeRegistryAuth(index)
+		return encodeAuthToBase64(authConfig)
 	}
 	}
 }
 }