github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/client/cli/user/user.go (about) 1 // Package user handles the user cli command 2 package user 3 4 import ( 5 "errors" 6 "fmt" 7 "strings" 8 "syscall" 9 10 "github.com/tickoalcantara12/micro/v3/client/cli/token" 11 "github.com/tickoalcantara12/micro/v3/client/cli/util" 12 "github.com/tickoalcantara12/micro/v3/cmd" 13 pb "github.com/tickoalcantara12/micro/v3/proto/auth" 14 "github.com/tickoalcantara12/micro/v3/service/auth" 15 "github.com/tickoalcantara12/micro/v3/service/client" 16 "github.com/tickoalcantara12/micro/v3/service/context" 17 "github.com/tickoalcantara12/micro/v3/util/config" 18 "github.com/urfave/cli/v2" 19 "golang.org/x/crypto/ssh/terminal" 20 ) 21 22 func init() { 23 cmd.Register( 24 &cli.Command{ 25 Name: "user", 26 Usage: "Print the current logged in user", 27 Action: user, 28 Subcommands: []*cli.Command{ 29 // config as a sub command, 30 { 31 Name: "config", 32 Usage: "{set, get, delete} [key] [value]", 33 Description: "Manage user related config like id, token, namespace, etc", 34 Action: current, 35 Subcommands: config.Commands, 36 }, 37 { 38 Name: "token", 39 Usage: "Get the current user token", 40 Action: getToken, 41 }, 42 { 43 Name: "namespace", 44 Usage: "Get the current namespace", 45 Action: getNamespace, 46 Subcommands: []*cli.Command{ 47 { 48 Name: "set", 49 Usage: "Set namespace in the current environment", 50 Action: setNamespace, 51 }, 52 }, 53 }, 54 { 55 Name: "set", 56 Usage: "Set various user based properties, eg. password", 57 Subcommands: []*cli.Command{ 58 { 59 Name: "password", 60 Usage: "Set password", 61 Action: changePassword, 62 Flags: []cli.Flag{ 63 &cli.StringFlag{ 64 Name: "email", 65 Usage: "Email to use for password change", 66 }, 67 &cli.StringFlag{ 68 Name: "old-password", 69 Usage: "Existing password, the one that is used currently.", 70 }, 71 &cli.StringFlag{ 72 Name: "new-password", 73 Usage: "New password you want to set.", 74 }, 75 }, 76 }, 77 }, 78 }, 79 }, 80 }, 81 ) 82 } 83 84 // get current user settings 85 func changePassword(ctx *cli.Context) error { 86 email := ctx.String("email") 87 if len(email) == 0 { 88 token, err := token.Get(ctx) 89 if err != nil { 90 return err 91 } 92 93 // Inspect the token 94 acc, err := auth.Inspect(token.AccessToken) 95 if err != nil { 96 fmt.Println("You are not logged in") 97 return err 98 } 99 email = acc.ID 100 } 101 102 oldPassword := ctx.String("old-password") 103 newPassword := ctx.String("new-password") 104 105 if len(oldPassword) == 0 { 106 fmt.Print("Enter current password: ") 107 bytePw, _ := terminal.ReadPassword(int(syscall.Stdin)) 108 pw := string(bytePw) 109 pw = strings.TrimSpace(pw) 110 fmt.Println() 111 oldPassword = pw 112 } 113 114 if len(newPassword) == 0 { 115 for { 116 fmt.Print("Enter a new password: ") 117 bytePw, _ := terminal.ReadPassword(int(syscall.Stdin)) 118 pw := string(bytePw) 119 pw = strings.TrimSpace(pw) 120 fmt.Println() 121 122 fmt.Print("Verify your password: ") 123 bytePwVer, _ := terminal.ReadPassword(int(syscall.Stdin)) 124 pwVer := string(bytePwVer) 125 pwVer = strings.TrimSpace(pwVer) 126 fmt.Println() 127 128 if pw != pwVer { 129 fmt.Println("Passwords do not match. Please try again.") 130 continue 131 } 132 newPassword = pw 133 break 134 } 135 } 136 ns, err := currNamespace(ctx) 137 if err != nil { 138 return err 139 } 140 141 accountService := pb.NewAccountsService("auth", client.DefaultClient) 142 _, err = accountService.ChangeSecret(context.DefaultContext, &pb.ChangeSecretRequest{ 143 Id: email, 144 OldSecret: oldPassword, 145 NewSecret: newPassword, 146 Options: &pb.Options{Namespace: ns}, 147 }, client.WithAuthToken()) 148 return err 149 } 150 151 // get current user settings 152 func current(ctx *cli.Context) error { 153 env, err := util.GetEnv(ctx) 154 if err != nil { 155 return err 156 } 157 envName := env.Name 158 if len(envName) == 0 { 159 envName = "n/a" 160 } 161 162 ns, err := config.Get(config.Path("namespaces", env.Name, "current")) 163 if err != nil || len(ns) == 0 { 164 ns = "n/a" 165 } 166 167 token, err := token.Get(ctx) 168 if err != nil { 169 return err 170 } 171 172 gitcreds, err := config.Get(config.Path("git", "credentials")) 173 if err != nil { 174 return err 175 } 176 if len(gitcreds) > 0 { 177 gitcreds = "[hidden]" 178 } else { 179 gitcreds = "n/a" 180 } 181 182 id := "n/a" 183 184 // Inspect the token 185 acc, err := auth.Inspect(token.AccessToken) 186 if err == nil { 187 id = acc.Name 188 if len(id) == 0 { 189 id = acc.ID 190 } 191 } 192 193 baseURL, _ := config.Get(config.Path("git", env.Name, "baseurl")) 194 if len(baseURL) == 0 { 195 baseURL, _ = config.Get(config.Path("git", "baseurl")) 196 } 197 if len(baseURL) == 0 { 198 baseURL = "n/a" 199 } 200 201 fmt.Println("user:", id) 202 fmt.Println("namespace:", ns) 203 fmt.Println("environment:", envName) 204 fmt.Println("git.credentials:", gitcreds) 205 fmt.Println("git.baseurl:", baseURL) 206 return nil 207 } 208 209 // get token for current env 210 func getToken(ctx *cli.Context) error { 211 token, err := token.Get(ctx) 212 if err != nil { 213 return err 214 } 215 fmt.Println(token.AccessToken) 216 return nil 217 } 218 219 // get namespace in current env 220 func getNamespace(ctx *cli.Context) error { 221 namespace, err := currNamespace(ctx) 222 if err != nil { 223 return err 224 } 225 fmt.Println(namespace) 226 return nil 227 } 228 229 func currNamespace(ctx *cli.Context) (string, error) { 230 env, err := config.Get("env") 231 if err != nil { 232 return "", err 233 } 234 namespace, err := config.Get(config.Path("namespaces", env, "current")) 235 if err != nil { 236 return "", err 237 } 238 return namespace, nil 239 } 240 241 // set namespace in current env 242 func setNamespace(ctx *cli.Context) error { 243 if len(ctx.Args().First()) == 0 { 244 return errors.New("No namespace specified") 245 } 246 env, err := config.Get("env") 247 if err != nil { 248 return err 249 } 250 return config.Set(config.Path("namespaces", env, "current"), ctx.Args().First()) 251 } 252 253 // user returns info about the logged in user 254 func user(ctx *cli.Context) error { 255 256 notLoggedIn := errors.New("You are not logged in") 257 // Get the token from micro config 258 token, err := token.Get(ctx) 259 if err != nil { 260 return notLoggedIn 261 } 262 263 // Inspect the token 264 acc, err := auth.Inspect(token.AccessToken) 265 if err != nil { 266 return err 267 } 268 // backward compatibility 269 user := acc.Name 270 if len(user) == 0 { 271 user = acc.ID 272 } 273 fmt.Println(user) 274 return nil 275 }