github.com/tsuna/docker@v1.7.0-rc3/api/client/login.go (about) 1 package client 2 3 import ( 4 "bufio" 5 "encoding/json" 6 "fmt" 7 "io" 8 "os" 9 "strings" 10 11 "github.com/docker/docker/api/types" 12 "github.com/docker/docker/cliconfig" 13 flag "github.com/docker/docker/pkg/mflag" 14 "github.com/docker/docker/pkg/term" 15 "github.com/docker/docker/registry" 16 ) 17 18 // CmdLogin logs in or registers a user to a Docker registry service. 19 // 20 // If no server is specified, the user will be logged into or registered to the registry's index server. 21 // 22 // Usage: docker login SERVER 23 func (cli *DockerCli) CmdLogin(args ...string) error { 24 cmd := cli.Subcmd("login", "[SERVER]", "Register or log in to a Docker registry server, if no server is\nspecified \""+registry.IndexServerAddress()+"\" is the default.", true) 25 cmd.Require(flag.Max, 1) 26 27 var username, password, email string 28 29 cmd.StringVar(&username, []string{"u", "-username"}, "", "Username") 30 cmd.StringVar(&password, []string{"p", "-password"}, "", "Password") 31 cmd.StringVar(&email, []string{"e", "-email"}, "", "Email") 32 33 cmd.ParseFlags(args, true) 34 35 serverAddress := registry.IndexServerAddress() 36 if len(cmd.Args()) > 0 { 37 serverAddress = cmd.Arg(0) 38 } 39 40 promptDefault := func(prompt string, configDefault string) { 41 if configDefault == "" { 42 fmt.Fprintf(cli.out, "%s: ", prompt) 43 } else { 44 fmt.Fprintf(cli.out, "%s (%s): ", prompt, configDefault) 45 } 46 } 47 48 readInput := func(in io.Reader, out io.Writer) string { 49 reader := bufio.NewReader(in) 50 line, _, err := reader.ReadLine() 51 if err != nil { 52 fmt.Fprintln(out, err.Error()) 53 os.Exit(1) 54 } 55 return string(line) 56 } 57 58 authconfig, ok := cli.configFile.AuthConfigs[serverAddress] 59 if !ok { 60 authconfig = cliconfig.AuthConfig{} 61 } 62 63 if username == "" { 64 promptDefault("Username", authconfig.Username) 65 username = readInput(cli.in, cli.out) 66 username = strings.Trim(username, " ") 67 if username == "" { 68 username = authconfig.Username 69 } 70 } 71 // Assume that a different username means they may not want to use 72 // the password or email from the config file, so prompt them 73 if username != authconfig.Username { 74 if password == "" { 75 oldState, err := term.SaveState(cli.inFd) 76 if err != nil { 77 return err 78 } 79 fmt.Fprintf(cli.out, "Password: ") 80 term.DisableEcho(cli.inFd, oldState) 81 82 password = readInput(cli.in, cli.out) 83 fmt.Fprint(cli.out, "\n") 84 85 term.RestoreTerminal(cli.inFd, oldState) 86 if password == "" { 87 return fmt.Errorf("Error : Password Required") 88 } 89 } 90 91 if email == "" { 92 promptDefault("Email", authconfig.Email) 93 email = readInput(cli.in, cli.out) 94 if email == "" { 95 email = authconfig.Email 96 } 97 } 98 } else { 99 // However, if they don't override the username use the 100 // password or email from the cmd line if specified. IOW, allow 101 // then to change/override them. And if not specified, just 102 // use what's in the config file 103 if password == "" { 104 password = authconfig.Password 105 } 106 if email == "" { 107 email = authconfig.Email 108 } 109 } 110 authconfig.Username = username 111 authconfig.Password = password 112 authconfig.Email = email 113 authconfig.ServerAddress = serverAddress 114 cli.configFile.AuthConfigs[serverAddress] = authconfig 115 116 stream, statusCode, err := cli.call("POST", "/auth", cli.configFile.AuthConfigs[serverAddress], nil) 117 if statusCode == 401 { 118 delete(cli.configFile.AuthConfigs, serverAddress) 119 if err2 := cli.configFile.Save(); err2 != nil { 120 fmt.Fprintf(cli.out, "WARNING: could not save config file: %v\n", err2) 121 } 122 return err 123 } 124 if err != nil { 125 return err 126 } 127 128 var response types.AuthResponse 129 if err := json.NewDecoder(stream).Decode(&response); err != nil { 130 // Upon error, remove entry 131 delete(cli.configFile.AuthConfigs, serverAddress) 132 return err 133 } 134 135 if err := cli.configFile.Save(); err != nil { 136 return fmt.Errorf("Error saving config file: %v", err) 137 } 138 fmt.Fprintf(cli.out, "WARNING: login credentials saved in %s\n", cli.configFile.Filename()) 139 140 if response.Status != "" { 141 fmt.Fprintf(cli.out, "%s\n", response.Status) 142 } 143 return nil 144 }