From d5615a67c8854510d6781db316e30177ab43b522 Mon Sep 17 00:00:00 2001 From: Pauline Middelink Date: Mon, 24 Jul 2017 23:01:16 +0200 Subject: [PATCH] Refactor password resolving. Instead of determining the password lazily during ReadPassword(), do so now in cobra.PersistentPreRunE() so we can store the result in the globalOptions and reuse/override when applicable without having to worry about the environment or flag options interfering. --- cmd/restic/cmd_key.go | 9 ++------- cmd/restic/global.go | 28 ++++++++++++++++------------ cmd/restic/main.go | 7 +++++++ 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/cmd/restic/cmd_key.go b/cmd/restic/cmd_key.go index 101346426..5e7ccf35c 100644 --- a/cmd/restic/cmd_key.go +++ b/cmd/restic/cmd_key.go @@ -3,7 +3,6 @@ package main import ( "context" "fmt" - "os" "github.com/restic/restic/internal/errors" "github.com/restic/restic/internal/repository" @@ -60,14 +59,10 @@ func getNewPassword(gopts GlobalOptions) (string, error) { return testKeyNewPassword, nil } - // Since we already have an open repository, temporary remove the overrides - // to prompt the user for their passwd - oldPasswd := os.Getenv("RESTIC_PASSWORD") - defer func() { os.Setenv("RESTIC_PASSWORD", oldPasswd) }() - os.Unsetenv("RESTIC_PASSWORD") + // Since we already have an open repository, temporary remove the password + // to prompt the user for the passwd. newopts := gopts newopts.password = "" - newopts.PasswordFile = "" return ReadPasswordTwice(newopts, "enter password for new key: ", diff --git a/cmd/restic/global.go b/cmd/restic/global.go index 3eabefa29..a29840a09 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -53,11 +53,6 @@ var globalOptions = GlobalOptions{ } func init() { - pw := os.Getenv("RESTIC_PASSWORD") - if pw != "" { - globalOptions.password = pw - } - var cancel context.CancelFunc globalOptions.ctx, cancel = context.WithCancel(context.Background()) AddCleanupHandler(func() error { @@ -207,6 +202,20 @@ func Exitf(exitcode int, format string, args ...interface{}) { Exit(exitcode) } +// resolvePassword determines the password to be used for opening the repository. +func resolvePassword(opts GlobalOptions, env string) (string, error) { + if opts.PasswordFile != "" { + s, err := ioutil.ReadFile(opts.PasswordFile) + return strings.TrimSpace(string(s)), errors.Wrap(err, "Readfile") + } + + if pwd := os.Getenv(env); pwd != "" { + return pwd, nil + } + + return "", nil +} + // readPassword reads the password from the given reader directly. func readPassword(in io.Reader) (password string, err error) { buf := make([]byte, 1000) @@ -238,13 +247,8 @@ func readPasswordTerminal(in *os.File, out io.Writer, prompt string) (password s // ReadPassword reads the password from a password file, the environment // variable RESTIC_PASSWORD or prompts the user. func ReadPassword(opts GlobalOptions, prompt string) (string, error) { - if opts.PasswordFile != "" { - s, err := ioutil.ReadFile(opts.PasswordFile) - return strings.TrimSpace(string(s)), errors.Wrap(err, "Readfile") - } - - if pwd := os.Getenv("RESTIC_PASSWORD"); pwd != "" { - return pwd, nil + if opts.password != "" { + return opts.password, nil } var ( diff --git a/cmd/restic/main.go b/cmd/restic/main.go index b53fc986c..195f9e2cc 100644 --- a/cmd/restic/main.go +++ b/cmd/restic/main.go @@ -36,6 +36,13 @@ directories in an encrypted repository stored on different backends. } globalOptions.extended = opts + pwd, err := resolvePassword(globalOptions, "RESTIC_PASSWORD") + if err != nil { + fmt.Fprintf(os.Stderr, "Resolving password failed: %v\n", err) + Exit(1) + } + globalOptions.password = pwd + // run the debug functions for all subcommands (if build tag "debug" is // enabled) if err := runDebug(); err != nil {