diff --git a/internal/cmd/commands/accountscmd/funcs.go b/internal/cmd/commands/accountscmd/funcs.go index 0758a8244..5cefc5b51 100644 --- a/internal/cmd/commands/accountscmd/funcs.go +++ b/internal/cmd/commands/accountscmd/funcs.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/boundary/api" "github.com/hashicorp/boundary/api/accounts" "github.com/hashicorp/boundary/internal/cmd/base" + "github.com/hashicorp/go-secure-stdlib/parseutil" "github.com/hashicorp/go-secure-stdlib/password" "github.com/hashicorp/go-secure-stdlib/strutil" ) @@ -116,59 +117,92 @@ func extraFlagsFuncImpl(c *Command, _ *base.FlagSets, f *base.FlagSet) { } func extraFlagsHandlingFuncImpl(c *Command, _ *base.FlagSets, opts *[]accounts.Option) bool { - if strutil.StrListContains(flagsMap[c.Func], "password") && c.flagPassword == "" { - fmt.Print("Password is not set as flag, please enter it now (will be hidden): ") - value, err := password.Read(os.Stdin) - fmt.Print("\n") - if err != nil { - c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) - return false + if strutil.StrListContains(flagsMap[c.Func], "password") { + switch c.flagPassword { + case "": + fmt.Print("Password is not set as flag, please enter it now (will be hidden): ") + value, err := password.Read(os.Stdin) + fmt.Print("\n") + if err != nil { + c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) + return false + } + fmt.Print("Please enter it one more time for confirmation: ") + confirmation, err := password.Read(os.Stdin) + fmt.Print("\n") + if err != nil { + c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) + return false + } + if strings.TrimSpace(value) != strings.TrimSpace(confirmation) { + c.UI.Error("Entered password and confirmation value did not match.") + return false + } + c.flagPassword = strings.TrimSpace(value) + + default: + password, err := parseutil.ParsePath(c.flagPassword) + if err != nil && err.Error() != parseutil.ErrNotAUrl.Error() { + c.UI.Error(fmt.Sprintf("Error parsing password flag: %v", err)) + return false + } + c.flagPassword = password } - fmt.Print("Please enter it one more time for confirmation: ") - confirmation, err := password.Read(os.Stdin) - fmt.Print("\n") - if err != nil { - c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) - return false - } - if strings.TrimSpace(value) != strings.TrimSpace(confirmation) { - c.UI.Error("Entered password and confirmation value did not match.") - return false - } - c.flagPassword = strings.TrimSpace(value) } - if strutil.StrListContains(flagsMap[c.Func], "current-password") && c.flagCurrentPassword == "" { - fmt.Print("Current password is not set as flag, please enter it now (will be hidden): ") - value, err := password.Read(os.Stdin) - fmt.Print("\n") - if err != nil { - c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) - return false + if strutil.StrListContains(flagsMap[c.Func], "current-password") { + switch c.flagCurrentPassword { + case "": + fmt.Print("Current password is not set as flag, please enter it now (will be hidden): ") + value, err := password.Read(os.Stdin) + fmt.Print("\n") + if err != nil { + c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) + return false + } + fmt.Print("Please enter it one more time for confirmation: ") + c.flagCurrentPassword = strings.TrimSpace(value) + + default: + password, err := parseutil.ParsePath(c.flagCurrentPassword) + if err != nil && err.Error() != parseutil.ErrNotAUrl.Error() { + c.UI.Error(fmt.Sprintf("Error parsing current password flag: %v", err)) + return false + } + c.flagCurrentPassword = password } - fmt.Print("Please enter it one more time for confirmation: ") - confirmation, err := password.Read(os.Stdin) - fmt.Print("\n") - if err != nil { - c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) - return false - } - if strings.TrimSpace(value) != strings.TrimSpace(confirmation) { - c.UI.Error("Entered password and confirmation value did not match.") - return false - } - c.flagCurrentPassword = strings.TrimSpace(value) } - if strutil.StrListContains(flagsMap[c.Func], "new-password") && c.flagNewPassword == "" { - fmt.Print("New password is not set as flag, please enter it now (will be hidden): ") - value, err := password.Read(os.Stdin) - fmt.Print("\n") - if err != nil { - c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) - return false + if strutil.StrListContains(flagsMap[c.Func], "new-password") { + switch c.flagNewPassword { + case "": + fmt.Print("New password is not set as flag, please enter it now (will be hidden): ") + value, err := password.Read(os.Stdin) + fmt.Print("\n") + if err != nil { + c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) + return false + } + confirmation, err := password.Read(os.Stdin) + fmt.Print("\n") + if err != nil { + c.UI.Error(fmt.Sprintf("An error occurred attempting to read the password. The raw error message is shown below but usually this is because you attempted to pipe a value into the command or you are executing outside of a terminal (TTY). The raw error was:\n\n%s", err.Error())) + return false + } + if strings.TrimSpace(value) != strings.TrimSpace(confirmation) { + c.UI.Error("Entered password and confirmation value did not match.") + return false + } + c.flagNewPassword = strings.TrimSpace(value) + + default: + password, err := parseutil.ParsePath(c.flagNewPassword) + if err != nil && err.Error() != parseutil.ErrNotAUrl.Error() { + c.UI.Error(fmt.Sprintf("Error parsing new password flag: %v", err)) + return false + } + c.flagNewPassword = password } - c.flagNewPassword = strings.TrimSpace(value) } return true diff --git a/internal/cmd/commands/accountscmd/password_funcs.go b/internal/cmd/commands/accountscmd/password_funcs.go index 165d9da79..617614cb2 100644 --- a/internal/cmd/commands/accountscmd/password_funcs.go +++ b/internal/cmd/commands/accountscmd/password_funcs.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/boundary/api/accounts" "github.com/hashicorp/boundary/internal/cmd/base" + "github.com/hashicorp/go-secure-stdlib/parseutil" "github.com/hashicorp/go-secure-stdlib/password" "github.com/hashicorp/go-secure-stdlib/strutil" ) @@ -72,7 +73,7 @@ func extraPasswordFlagsFuncImpl(c *PasswordCommand, set *base.FlagSets, f *base. f.StringVar(&base.StringVar{ Name: "password", Target: &c.flagPassword, - Usage: "The password for the account. If not specified, the command will prompt for the password to be entered in a non-echoing way.", + Usage: "The password for the account. If blank, the command will prompt for the password to be entered interactively in a non-echoing way. Otherwise, this can refer to a file on disk (file://) from which a password will be read; an env var (env://) from which the password will be read; or a string containing the password.", }) } } @@ -114,8 +115,14 @@ func extraPasswordFlagsHandlingFuncImpl(c *PasswordCommand, _ *base.FlagSets, op return false } *opts = append(*opts, accounts.WithPasswordAccountPassword(strings.TrimSpace(value))) + default: - *opts = append(*opts, accounts.WithPasswordAccountPassword(c.flagPassword)) + password, err := parseutil.ParsePath(c.flagPassword) + if err != nil && err.Error() != parseutil.ErrNotAUrl.Error() { + c.UI.Error(fmt.Sprintf("Error parsing password flag: %v", err)) + return false + } + *opts = append(*opts, accounts.WithPasswordAccountPassword(password)) } } diff --git a/internal/cmd/commands/authenticate/password.go b/internal/cmd/commands/authenticate/password.go index 6e14b07cd..f9f91414f 100644 --- a/internal/cmd/commands/authenticate/password.go +++ b/internal/cmd/commands/authenticate/password.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/boundary/api" "github.com/hashicorp/boundary/api/authmethods" "github.com/hashicorp/boundary/internal/cmd/base" + "github.com/hashicorp/go-secure-stdlib/parseutil" "github.com/hashicorp/go-secure-stdlib/password" "github.com/mitchellh/cli" "github.com/mitchellh/go-wordwrap" @@ -56,21 +57,21 @@ func (c *PasswordCommand) Flags() *base.FlagSets { Name: "login-name", Target: &c.flagLoginName, EnvVar: envLoginName, - Usage: "The login name corresponding to an account within the given auth method", + Usage: "The login name corresponding to an account within the given auth method.", }) f.StringVar(&base.StringVar{ Name: "password", Target: &c.flagPassword, EnvVar: envPassword, - Usage: "The password associated with the login name", + Usage: "The password associated with the login name. If blank, the command will prompt for the password to be entered interactively in a non-echoing way. Otherwise, this can refer to a file on disk (file://) from which a password will be read; an env var (env://) from which the password will be read; or a string containing the password.", }) f.StringVar(&base.StringVar{ Name: "auth-method-id", EnvVar: "BOUNDARY_AUTH_METHOD_ID", Target: &c.FlagAuthMethodId, - Usage: "The auth-method resource to use for the operation", + Usage: "The auth-method resource to use for the operation.", }) return set @@ -101,7 +102,8 @@ func (c *PasswordCommand) Run(args []string) int { return base.CommandUserError } - if c.flagPassword == "" { + switch c.flagPassword { + case "": fmt.Print("Password is not set as flag or in env, please enter it now (will be hidden): ") value, err := password.Read(os.Stdin) fmt.Print("\n") @@ -110,6 +112,14 @@ func (c *PasswordCommand) Run(args []string) int { return base.CommandUserError } c.flagPassword = strings.TrimSpace(value) + + default: + password, err := parseutil.ParsePath(c.flagPassword) + if err != nil && err.Error() != parseutil.ErrNotAUrl.Error() { + c.UI.Error(fmt.Sprintf("Error parsing password flag: %v", err)) + return base.CommandUserError + } + c.flagPassword = password } client, err := c.Client(base.WithNoTokenScope(), base.WithNoTokenValue())