2021-09-17 21:55:24 +00:00
|
|
|
package userprompt
|
2020-07-23 03:10:23 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2020-08-20 17:53:09 +00:00
|
|
|
"os"
|
2020-07-23 03:10:23 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/logrusorgru/aurora"
|
|
|
|
"github.com/manifoldco/promptui"
|
|
|
|
"github.com/pkg/errors"
|
2021-03-02 18:58:40 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/cmd/validator/flags"
|
2021-09-17 21:55:24 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/io/file"
|
|
|
|
"github.com/prysmaticlabs/prysm/io/prompt"
|
2020-10-15 22:31:52 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/validator/keymanager/remote"
|
2020-07-23 03:10:23 +00:00
|
|
|
"github.com/urfave/cli/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2020-09-17 01:34:42 +00:00
|
|
|
// ImportKeysDirPromptText for the import keys cli function.
|
|
|
|
ImportKeysDirPromptText = "Enter the directory or filepath where your keystores to import are located"
|
2021-01-22 23:12:22 +00:00
|
|
|
// DataDirDirPromptText for the validator database directory.
|
|
|
|
DataDirDirPromptText = "Enter the directory of the validator database you would like to use"
|
2021-09-17 21:55:24 +00:00
|
|
|
// SlashingProtectionJSONPromptText for the EIP-3076 slashing protection JSON userprompt.
|
2021-01-22 23:12:22 +00:00
|
|
|
SlashingProtectionJSONPromptText = "Enter the the filepath of your EIP-3076 Slashing Protection JSON from your previously used validator client"
|
2020-09-17 01:34:42 +00:00
|
|
|
// WalletDirPromptText for the wallet.
|
|
|
|
WalletDirPromptText = "Enter a wallet directory"
|
|
|
|
// SelectAccountsDeletePromptText --
|
|
|
|
SelectAccountsDeletePromptText = "Select the account(s) you would like to delete"
|
|
|
|
// SelectAccountsBackupPromptText --
|
|
|
|
SelectAccountsBackupPromptText = "Select the account(s) you wish to backup"
|
|
|
|
// SelectAccountsVoluntaryExitPromptText --
|
|
|
|
SelectAccountsVoluntaryExitPromptText = "Select the account(s) on which you wish to perform a voluntary exit"
|
2020-07-23 03:10:23 +00:00
|
|
|
)
|
|
|
|
|
2021-01-11 20:03:28 +00:00
|
|
|
var au = aurora.NewAurora(true)
|
2020-07-29 04:55:26 +00:00
|
|
|
|
2020-09-17 01:34:42 +00:00
|
|
|
// InputDirectory from the cli.
|
|
|
|
func InputDirectory(cliCtx *cli.Context, promptText string, flag *cli.StringFlag) (string, error) {
|
2020-07-29 01:20:13 +00:00
|
|
|
directory := cliCtx.String(flag.Name)
|
2020-07-23 03:10:23 +00:00
|
|
|
if cliCtx.IsSet(flag.Name) {
|
2021-09-17 21:55:24 +00:00
|
|
|
return file.ExpandPath(directory)
|
2020-07-23 03:10:23 +00:00
|
|
|
}
|
|
|
|
// Append and log the appropriate directory name depending on the flag used.
|
|
|
|
if flag.Name == flags.WalletDirFlag.Name {
|
2021-09-17 21:55:24 +00:00
|
|
|
ok, err := file.HasDir(directory)
|
2020-07-23 03:10:23 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", errors.Wrapf(err, "could not check if wallet dir %s exists", directory)
|
|
|
|
}
|
|
|
|
if ok {
|
|
|
|
log.Infof("%s %s", au.BrightMagenta("(wallet path)"), directory)
|
|
|
|
return directory, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-17 21:55:24 +00:00
|
|
|
inputtedDir, err := prompt.DefaultPrompt(au.Bold(promptText).String(), directory)
|
2020-07-23 03:10:23 +00:00
|
|
|
if err != nil {
|
2020-07-29 04:55:26 +00:00
|
|
|
return "", err
|
2020-07-23 03:10:23 +00:00
|
|
|
}
|
2020-07-29 04:55:26 +00:00
|
|
|
if inputtedDir == directory {
|
2020-07-23 03:10:23 +00:00
|
|
|
return directory, nil
|
|
|
|
}
|
2021-09-17 21:55:24 +00:00
|
|
|
return file.ExpandPath(inputtedDir)
|
2020-07-23 03:10:23 +00:00
|
|
|
}
|
|
|
|
|
2020-09-17 01:34:42 +00:00
|
|
|
// InputRemoteKeymanagerConfig via the cli.
|
|
|
|
func InputRemoteKeymanagerConfig(cliCtx *cli.Context) (*remote.KeymanagerOpts, error) {
|
2020-07-23 03:10:23 +00:00
|
|
|
addr := cliCtx.String(flags.GrpcRemoteAddressFlag.Name)
|
2020-12-03 00:18:15 +00:00
|
|
|
requireTls := !cliCtx.Bool(flags.DisableRemoteSignerTlsFlag.Name)
|
2020-07-23 03:10:23 +00:00
|
|
|
crt := cliCtx.String(flags.RemoteSignerCertPathFlag.Name)
|
|
|
|
key := cliCtx.String(flags.RemoteSignerKeyPathFlag.Name)
|
|
|
|
ca := cliCtx.String(flags.RemoteSignerCACertPathFlag.Name)
|
2020-07-29 01:20:13 +00:00
|
|
|
log.Info("Input desired configuration")
|
|
|
|
var err error
|
|
|
|
if addr == "" {
|
2021-09-17 21:55:24 +00:00
|
|
|
addr, err = prompt.ValidatePrompt(
|
2020-08-20 17:53:09 +00:00
|
|
|
os.Stdin,
|
|
|
|
"Remote gRPC address (such as host.example.com:4000)",
|
2021-09-17 21:55:24 +00:00
|
|
|
prompt.NotEmpty)
|
2020-07-29 01:20:13 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-07-23 03:10:23 +00:00
|
|
|
}
|
2020-12-03 00:18:15 +00:00
|
|
|
if requireTls && crt == "" {
|
2021-09-17 21:55:24 +00:00
|
|
|
crt, err = prompt.ValidatePrompt(
|
2020-08-20 17:53:09 +00:00
|
|
|
os.Stdin,
|
|
|
|
"Path to TLS crt (such as /path/to/client.crt)",
|
|
|
|
validateCertPath)
|
2020-07-29 01:20:13 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-07-23 03:10:23 +00:00
|
|
|
}
|
2020-12-03 00:18:15 +00:00
|
|
|
if requireTls && key == "" {
|
2021-09-17 21:55:24 +00:00
|
|
|
key, err = prompt.ValidatePrompt(
|
2020-08-20 17:53:09 +00:00
|
|
|
os.Stdin,
|
|
|
|
"Path to TLS key (such as /path/to/client.key)",
|
|
|
|
validateCertPath)
|
2020-07-29 01:20:13 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-07-23 03:10:23 +00:00
|
|
|
}
|
2020-12-03 00:18:15 +00:00
|
|
|
if requireTls && ca == "" {
|
2021-09-17 21:55:24 +00:00
|
|
|
ca, err = prompt.ValidatePrompt(
|
2020-08-20 17:53:09 +00:00
|
|
|
os.Stdin,
|
|
|
|
"Path to certificate authority (CA) crt (such as /path/to/ca.crt)",
|
|
|
|
validateCertPath)
|
2020-07-29 01:20:13 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-07-23 03:10:23 +00:00
|
|
|
}
|
2020-12-03 00:18:15 +00:00
|
|
|
|
|
|
|
crtPath, keyPath, caPath := "", "", ""
|
|
|
|
if crt != "" {
|
2021-09-17 21:55:24 +00:00
|
|
|
crtPath, err = file.ExpandPath(strings.TrimRight(crt, "\r\n"))
|
2020-12-03 00:18:15 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt)
|
|
|
|
}
|
2020-07-29 08:33:28 +00:00
|
|
|
}
|
2020-12-03 00:18:15 +00:00
|
|
|
if key != "" {
|
2021-09-17 21:55:24 +00:00
|
|
|
keyPath, err = file.ExpandPath(strings.TrimRight(key, "\r\n"))
|
2020-12-03 00:18:15 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt)
|
|
|
|
}
|
2020-07-29 08:33:28 +00:00
|
|
|
}
|
2020-12-03 00:18:15 +00:00
|
|
|
if ca != "" {
|
2021-09-17 21:55:24 +00:00
|
|
|
caPath, err = file.ExpandPath(strings.TrimRight(ca, "\r\n"))
|
2020-12-03 00:18:15 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "could not determine absolute path for %s", crt)
|
|
|
|
}
|
2020-07-29 08:33:28 +00:00
|
|
|
}
|
2020-12-03 00:18:15 +00:00
|
|
|
|
2020-08-31 19:46:45 +00:00
|
|
|
newCfg := &remote.KeymanagerOpts{
|
2020-07-23 03:10:23 +00:00
|
|
|
RemoteCertificate: &remote.CertificateConfig{
|
2020-12-03 00:18:15 +00:00
|
|
|
RequireTls: requireTls,
|
2020-07-29 08:33:28 +00:00
|
|
|
ClientCertPath: crtPath,
|
|
|
|
ClientKeyPath: keyPath,
|
|
|
|
CACertPath: caPath,
|
2020-07-23 03:10:23 +00:00
|
|
|
},
|
2020-07-29 04:55:26 +00:00
|
|
|
RemoteAddr: addr,
|
2020-07-23 03:10:23 +00:00
|
|
|
}
|
|
|
|
fmt.Printf("%s\n", newCfg)
|
|
|
|
return newCfg, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func validateCertPath(input string) error {
|
|
|
|
if input == "" {
|
|
|
|
return errors.New("crt path cannot be empty")
|
|
|
|
}
|
2021-09-17 21:55:24 +00:00
|
|
|
if !prompt.IsValidUnicode(input) {
|
2020-07-24 00:43:01 +00:00
|
|
|
return errors.New("not valid unicode")
|
|
|
|
}
|
2021-09-17 21:55:24 +00:00
|
|
|
if !file.FileExists(input) {
|
2020-07-23 03:10:23 +00:00
|
|
|
return fmt.Errorf("no crt found at path: %s", input)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-09-17 01:34:42 +00:00
|
|
|
// FormatPromptError for the user.
|
|
|
|
func FormatPromptError(err error) error {
|
2020-07-23 03:10:23 +00:00
|
|
|
switch err {
|
|
|
|
case promptui.ErrAbort:
|
|
|
|
return errors.New("wallet creation aborted, closing")
|
|
|
|
case promptui.ErrInterrupt:
|
|
|
|
return errors.New("keyboard interrupt, closing")
|
|
|
|
case promptui.ErrEOF:
|
|
|
|
return errors.New("no input received, closing")
|
|
|
|
default:
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|