github.com/prysmaticlabs/prysm@v1.4.4/shared/cmd/helpers.go (about)

     1  package cmd
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/pkg/errors"
    10  	"github.com/prysmaticlabs/prysm/shared/fileutil"
    11  	"github.com/sirupsen/logrus"
    12  	"github.com/urfave/cli/v2"
    13  )
    14  
    15  var log = logrus.WithField("prefix", "node")
    16  
    17  // ConfirmAction uses the passed in actionText as the confirmation text displayed in the terminal.
    18  // The user must enter Y or N to indicate whether they confirm the action detailed in the warning text.
    19  // Returns a boolean representing the user's answer.
    20  func ConfirmAction(actionText, deniedText string) (bool, error) {
    21  	var confirmed bool
    22  	reader := bufio.NewReader(os.Stdin)
    23  	log.Warn(actionText)
    24  
    25  	for {
    26  		fmt.Print(">> ")
    27  
    28  		line, _, err := reader.ReadLine()
    29  		if err != nil {
    30  			return false, err
    31  		}
    32  		trimmedLine := strings.TrimSpace(string(line))
    33  		lineInput := strings.ToUpper(trimmedLine)
    34  		if lineInput != "Y" && lineInput != "N" {
    35  			log.Errorf("Invalid option of %s chosen, please only enter Y/N", line)
    36  			continue
    37  		}
    38  		if lineInput == "Y" {
    39  			confirmed = true
    40  			break
    41  		}
    42  		log.Warn(deniedText)
    43  		break
    44  	}
    45  
    46  	return confirmed, nil
    47  }
    48  
    49  // EnterPassword queries the user for their password through the terminal, in order to make sure it is
    50  // not passed in a visible way to the terminal.
    51  func EnterPassword(confirmPassword bool, pr PasswordReader) (string, error) {
    52  	var passphrase string
    53  	log.Info("Enter a password:")
    54  	bytePassword, err := pr.ReadPassword()
    55  	if err != nil {
    56  		return "", errors.Wrap(err, "could not read account password")
    57  	}
    58  	text := bytePassword
    59  	passphrase = strings.ReplaceAll(text, "\n", "")
    60  	if confirmPassword {
    61  		log.Info("Please re-enter your password:")
    62  		bytePassword, err := pr.ReadPassword()
    63  		if err != nil {
    64  			return "", errors.Wrap(err, "could not read account password")
    65  		}
    66  		text := bytePassword
    67  		confirmedPass := strings.ReplaceAll(text, "\n", "")
    68  		if passphrase != confirmedPass {
    69  			log.Info("Passwords did not match, please try again")
    70  			return EnterPassword(true, pr)
    71  		}
    72  	}
    73  	return passphrase, nil
    74  }
    75  
    76  // ExpandSingleEndpointIfFile expands the path for --http-web3provider if specified as a file.
    77  func ExpandSingleEndpointIfFile(ctx *cli.Context, flag *cli.StringFlag) error {
    78  	// Return early if no flag value is set.
    79  	if !ctx.IsSet(flag.Name) {
    80  		return nil
    81  	}
    82  	web3endpoint := ctx.String(flag.Name)
    83  	switch {
    84  	case strings.HasPrefix(web3endpoint, "http://"):
    85  	case strings.HasPrefix(web3endpoint, "https://"):
    86  	case strings.HasPrefix(web3endpoint, "ws://"):
    87  	case strings.HasPrefix(web3endpoint, "wss://"):
    88  	default:
    89  		web3endpoint, err := fileutil.ExpandPath(ctx.String(flag.Name))
    90  		if err != nil {
    91  			return errors.Wrapf(err, "could not expand path for %s", web3endpoint)
    92  		}
    93  		if err := ctx.Set(flag.Name, web3endpoint); err != nil {
    94  			return errors.Wrapf(err, "could not set %s to %s", flag.Name, web3endpoint)
    95  		}
    96  	}
    97  	return nil
    98  }
    99  
   100  // ExpandWeb3EndpointsIfFile expands the path for --fallback-web3provider if specified as a file.
   101  func ExpandWeb3EndpointsIfFile(ctx *cli.Context, flags *cli.StringSliceFlag) error {
   102  	// Return early if no flag value is set.
   103  	if !ctx.IsSet(flags.Name) {
   104  		return nil
   105  	}
   106  	rawFlags := ctx.StringSlice(flags.Name)
   107  	for i, rawValue := range rawFlags {
   108  		switch {
   109  		case strings.HasPrefix(rawValue, "http://"):
   110  		case strings.HasPrefix(rawValue, "https://"):
   111  		case strings.HasPrefix(rawValue, "ws://"):
   112  		case strings.HasPrefix(rawValue, "wss://"):
   113  		default:
   114  			web3endpoint, err := fileutil.ExpandPath(rawValue)
   115  			if err != nil {
   116  				return errors.Wrapf(err, "could not expand path for %s", rawValue)
   117  			}
   118  			// Given that rawFlags is a pointer this will replace the unexpanded path
   119  			// with the expanded one. Also there is no easy way to replace the string
   120  			// slice flag value compared to other flag types. This is why we resort to
   121  			// replacing it like this.
   122  			rawFlags[i] = web3endpoint
   123  		}
   124  	}
   125  	return nil
   126  }