github.com/hustcat/docker@v1.3.3-0.20160314103604-901c67a8eeab/api/client/login.go (about) 1 package client 2 3 import ( 4 "bufio" 5 "fmt" 6 "io" 7 "os" 8 "runtime" 9 "strings" 10 11 Cli "github.com/docker/docker/cli" 12 "github.com/docker/docker/cliconfig" 13 "github.com/docker/docker/cliconfig/credentials" 14 flag "github.com/docker/docker/pkg/mflag" 15 "github.com/docker/docker/pkg/term" 16 "github.com/docker/engine-api/types" 17 ) 18 19 // CmdLogin logs in a user to a Docker registry service. 20 // 21 // If no server is specified, the user will be logged into or registered to the registry's index server. 22 // 23 // Usage: docker login SERVER 24 func (cli *DockerCli) CmdLogin(args ...string) error { 25 cmd := Cli.Subcmd("login", []string{"[SERVER]"}, Cli.DockerCommands["login"].Description+".\nIf no server is specified, the default is defined by the daemon.", true) 26 cmd.Require(flag.Max, 1) 27 28 flUser := cmd.String([]string{"u", "-username"}, "", "Username") 29 flPassword := cmd.String([]string{"p", "-password"}, "", "Password") 30 31 // Deprecated in 1.11: Should be removed in docker 1.13 32 cmd.String([]string{"#e", "#-email"}, "", "Email") 33 34 cmd.ParseFlags(args, true) 35 36 // On Windows, force the use of the regular OS stdin stream. Fixes #14336/#14210 37 if runtime.GOOS == "windows" { 38 cli.in = os.Stdin 39 } 40 41 var serverAddress string 42 var isDefaultRegistry bool 43 if len(cmd.Args()) > 0 { 44 serverAddress = cmd.Arg(0) 45 } else { 46 serverAddress = cli.electAuthServer() 47 isDefaultRegistry = true 48 } 49 50 authConfig, err := cli.configureAuth(*flUser, *flPassword, serverAddress, isDefaultRegistry) 51 if err != nil { 52 return err 53 } 54 55 response, err := cli.client.RegistryLogin(authConfig) 56 if err != nil { 57 return err 58 } 59 60 if err := storeCredentials(cli.configFile, authConfig); err != nil { 61 return fmt.Errorf("Error saving credentials: %v", err) 62 } 63 64 if response.Status != "" { 65 fmt.Fprintf(cli.out, "%s\n", response.Status) 66 } 67 return nil 68 } 69 70 func (cli *DockerCli) promptWithDefault(prompt string, configDefault string) { 71 if configDefault == "" { 72 fmt.Fprintf(cli.out, "%s: ", prompt) 73 } else { 74 fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault) 75 } 76 } 77 78 func (cli *DockerCli) configureAuth(flUser, flPassword, serverAddress string, isDefaultRegistry bool) (types.AuthConfig, error) { 79 authconfig, err := getCredentials(cli.configFile, serverAddress) 80 if err != nil { 81 return authconfig, err 82 } 83 84 authconfig.Username = strings.TrimSpace(authconfig.Username) 85 86 if flUser = strings.TrimSpace(flUser); flUser == "" { 87 if isDefaultRegistry { 88 // if this is a defauly registry (docker hub), then display the following message. 89 fmt.Fprintln(cli.out, "Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.") 90 } 91 cli.promptWithDefault("Username", authconfig.Username) 92 flUser = readInput(cli.in, cli.out) 93 flUser = strings.TrimSpace(flUser) 94 if flUser == "" { 95 flUser = authconfig.Username 96 } 97 } 98 99 if flUser == "" { 100 return authconfig, fmt.Errorf("Error: Non-null Username Required") 101 } 102 103 if flPassword == "" { 104 oldState, err := term.SaveState(cli.inFd) 105 if err != nil { 106 return authconfig, err 107 } 108 fmt.Fprintf(cli.out, "Password: ") 109 term.DisableEcho(cli.inFd, oldState) 110 111 flPassword = readInput(cli.in, cli.out) 112 fmt.Fprint(cli.out, "\n") 113 114 term.RestoreTerminal(cli.inFd, oldState) 115 if flPassword == "" { 116 return authconfig, fmt.Errorf("Error: Password Required") 117 } 118 } 119 120 authconfig.Username = flUser 121 authconfig.Password = flPassword 122 authconfig.ServerAddress = serverAddress 123 124 return authconfig, nil 125 } 126 127 func readInput(in io.Reader, out io.Writer) string { 128 reader := bufio.NewReader(in) 129 line, _, err := reader.ReadLine() 130 if err != nil { 131 fmt.Fprintln(out, err.Error()) 132 os.Exit(1) 133 } 134 return string(line) 135 } 136 137 // getCredentials loads the user credentials from a credentials store. 138 // The store is determined by the config file settings. 139 func getCredentials(c *cliconfig.ConfigFile, serverAddress string) (types.AuthConfig, error) { 140 s := loadCredentialsStore(c) 141 return s.Get(serverAddress) 142 } 143 144 func getAllCredentials(c *cliconfig.ConfigFile) (map[string]types.AuthConfig, error) { 145 s := loadCredentialsStore(c) 146 return s.GetAll() 147 } 148 149 // storeCredentials saves the user credentials in a credentials store. 150 // The store is determined by the config file settings. 151 func storeCredentials(c *cliconfig.ConfigFile, auth types.AuthConfig) error { 152 s := loadCredentialsStore(c) 153 return s.Store(auth) 154 } 155 156 // eraseCredentials removes the user credentials from a credentials store. 157 // The store is determined by the config file settings. 158 func eraseCredentials(c *cliconfig.ConfigFile, serverAddress string) error { 159 s := loadCredentialsStore(c) 160 return s.Erase(serverAddress) 161 } 162 163 // loadCredentialsStore initializes a new credentials store based 164 // in the settings provided in the configuration file. 165 func loadCredentialsStore(c *cliconfig.ConfigFile) credentials.Store { 166 if c.CredentialsStore != "" { 167 return credentials.NewNativeStore(c) 168 } 169 return credentials.NewFileStore(c) 170 }