2022-08-05 16:08:48 -04:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
2023-02-02 17:15:17 -08:00
2021-02-23 19:06:39 -05:00
package accountscmd
import (
2022-08-05 16:08:48 -04:00
"errors"
2021-02-23 19:06:39 -05:00
"fmt"
"os"
"strings"
"github.com/hashicorp/boundary/api/accounts"
"github.com/hashicorp/boundary/internal/cmd/base"
2022-08-05 13:21:46 -04:00
"github.com/hashicorp/go-secure-stdlib/parseutil"
2021-07-14 17:38:52 -07:00
"github.com/hashicorp/go-secure-stdlib/password"
2021-07-14 17:37:40 -07:00
"github.com/hashicorp/go-secure-stdlib/strutil"
2021-02-23 19:06:39 -05:00
)
func init () {
extraPasswordActionsFlagsMapFunc = extraPasswordActionsFlagsMapFuncImpl
extraPasswordFlagsFunc = extraPasswordFlagsFuncImpl
extraPasswordFlagsHandlingFunc = extraPasswordFlagsHandlingFuncImpl
}
func extraPasswordActionsFlagsMapFuncImpl () map [ string ][] string {
return map [ string ][] string {
"create" : { "login-name" , "password" },
"update" : { "login-name" },
}
}
type extraPasswordCmdVars struct {
flagLoginName string
flagPassword string
}
func ( c * PasswordCommand ) extraPasswordHelpFunc ( helpMap map [ string ] func () string ) string {
var helpStr string
switch c . Func {
case "create" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary accounts create password [options] [args]" ,
"" ,
" Create a password-type account. Example:" ,
"" ,
` $ boundary accounts create password -login-name prodops -description "Password account for ProdOps"` ,
"" ,
"" ,
})
case "update" :
helpStr = base . WrapForHelpText ([] string {
"Usage: boundary accounts update password [options] [args]" ,
"" ,
" Update a password-type account given its ID. Example:" ,
"" ,
2021-06-08 11:31:58 -05:00
` $ boundary accounts update password -id acctpw_1234567890 -name "devops" -description "Password account for DevOps"` ,
2021-02-23 19:06:39 -05:00
"" ,
"" ,
})
}
return helpStr + c . Flags (). Help ()
}
2024-02-13 10:54:48 -05:00
func extraPasswordFlagsFuncImpl ( c * PasswordCommand , set * base . FlagSets , _ * base . FlagSet ) {
f := set . NewFlagSet ( "Password Account Options" )
2021-02-23 19:06:39 -05:00
for _ , name := range flagsPasswordMap [ c . Func ] {
switch name {
case "login-name" :
f . StringVar ( & base . StringVar {
Name : "login-name" ,
Target : & c . flagLoginName ,
Usage : "The login name for the account" ,
})
case "password" :
f . StringVar ( & base . StringVar {
Name : "password" ,
Target : & c . flagPassword ,
2022-08-05 16:08:48 -04:00
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 or an env var (env://) from which the password will be read." ,
2021-02-23 19:06:39 -05:00
})
}
}
}
2021-04-08 20:54:32 -04:00
func extraPasswordFlagsHandlingFuncImpl ( c * PasswordCommand , _ * base . FlagSets , opts * [] accounts . Option ) bool {
2021-02-23 19:06:39 -05:00
if c . Func == "create" && c . flagLoginName == "" {
c . UI . Error ( "Login Name must be passed in via -login-name" )
2021-03-04 20:05:17 -05:00
return false
2021-02-23 19:06:39 -05:00
}
switch c . flagLoginName {
case "" :
case "null" :
* opts = append ( * opts , accounts . DefaultPasswordAccountLoginName ())
default :
* opts = append ( * opts , accounts . WithPasswordAccountLoginName ( c . flagLoginName ))
}
if strutil . StrListContains ( flagsPasswordMap [ c . Func ], "password" ) {
switch c . flagPassword {
case "" :
2022-08-05 19:27:14 -04:00
fmt . Print ( "Please enter the password (it will be hidden): " )
2021-02-23 19:06:39 -05:00
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 ()))
2021-03-04 20:05:17 -05:00
return false
2021-02-23 19:06:39 -05:00
}
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 ()))
2021-03-04 20:05:17 -05:00
return false
2021-02-23 19:06:39 -05:00
}
if strings . TrimSpace ( value ) != strings . TrimSpace ( confirmation ) {
c . UI . Error ( "Entered password and confirmation value did not match." )
2021-03-04 20:05:17 -05:00
return false
2021-02-23 19:06:39 -05:00
}
* opts = append ( * opts , accounts . WithPasswordAccountPassword ( strings . TrimSpace ( value )))
2022-08-05 13:21:46 -04:00
2021-02-23 19:06:39 -05:00
default :
2022-08-05 16:08:48 -04:00
password , err := parseutil . MustParsePath ( c . flagPassword )
switch {
case err == nil :
case errors . Is ( err , parseutil . ErrNotParsed ):
c . UI . Error ( "Password flag must be used with env:// or file:// syntax or left empty for an interactive prompt" )
return false
default :
2022-08-05 13:21:46 -04:00
c . UI . Error ( fmt . Sprintf ( "Error parsing password flag: %v" , err ))
return false
}
* opts = append ( * opts , accounts . WithPasswordAccountPassword ( password ))
2021-02-23 19:06:39 -05:00
}
}
2021-03-04 20:05:17 -05:00
return true
2021-02-23 19:06:39 -05:00
}