forked from TrueCloudLab/restic
Add integration test for key handling
This commit is contained in:
parent
a99a460b32
commit
cfaf8ab8a6
4 changed files with 90 additions and 91 deletions
|
@ -3,14 +3,14 @@ package main
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/restic/restic/backend"
|
"github.com/restic/restic/backend"
|
||||||
"github.com/restic/restic/repository"
|
"github.com/restic/restic/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CmdKey struct {
|
type CmdKey struct {
|
||||||
global *GlobalOptions
|
global *GlobalOptions
|
||||||
|
newPassword string
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -56,25 +56,18 @@ func (cmd CmdKey) listKeys(s *repository.Repository) error {
|
||||||
return tab.Write(cmd.global.stdout)
|
return tab.Write(cmd.global.stdout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd CmdKey) getNewPassword() (string, error) {
|
func (cmd CmdKey) getNewPassword() string {
|
||||||
newPassword := os.Getenv("RESTIC_NEWPASSWORD")
|
if cmd.newPassword != "" {
|
||||||
|
return cmd.newPassword
|
||||||
if newPassword == "" {
|
|
||||||
newPassword = cmd.global.ReadPasswordTwice(
|
|
||||||
"enter password for new key: ",
|
|
||||||
"enter password again: ")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return newPassword, nil
|
return cmd.global.ReadPasswordTwice(
|
||||||
|
"enter password for new key: ",
|
||||||
|
"enter password again: ")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd CmdKey) addKey(repo *repository.Repository) error {
|
func (cmd CmdKey) addKey(repo *repository.Repository) error {
|
||||||
newPassword, err := cmd.getNewPassword()
|
id, err := repository.AddKey(repo, cmd.getNewPassword(), repo.Key())
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id, err := repository.AddKey(repo, newPassword, repo.Key())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("creating new key failed: %v\n", err)
|
return fmt.Errorf("creating new key failed: %v\n", err)
|
||||||
}
|
}
|
||||||
|
@ -99,12 +92,7 @@ func (cmd CmdKey) deleteKey(repo *repository.Repository, name string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd CmdKey) changePassword(repo *repository.Repository) error {
|
func (cmd CmdKey) changePassword(repo *repository.Repository) error {
|
||||||
newPassword, err := cmd.getNewPassword()
|
id, err := repository.AddKey(repo, cmd.getNewPassword(), repo.Key())
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id, err := repository.AddKey(repo, newPassword, repo.Key())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("creating new key failed: %v\n", err)
|
return fmt.Errorf("creating new key failed: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,10 @@ func (o GlobalOptions) ReadPassword(prompt string) string {
|
||||||
}
|
}
|
||||||
fmt.Fprintln(os.Stderr)
|
fmt.Fprintln(os.Stderr)
|
||||||
|
|
||||||
|
if len(pw) == 0 {
|
||||||
|
o.Exitf(1, "an empty password is not a password")
|
||||||
|
}
|
||||||
|
|
||||||
return string(pw)
|
return string(pw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,14 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/restic/restic/backend"
|
"github.com/restic/restic/backend"
|
||||||
|
@ -62,16 +64,12 @@ func cmdBackup(t testing.TB, global GlobalOptions, target []string, parentID bac
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdList(t testing.TB, global GlobalOptions, tpe string) []backend.ID {
|
func cmdList(t testing.TB, global GlobalOptions, tpe string) []backend.ID {
|
||||||
rd, wr := io.Pipe()
|
var buf bytes.Buffer
|
||||||
global.stdout = wr
|
global.stdout = &buf
|
||||||
cmd := &CmdList{global: &global}
|
cmd := &CmdList{global: &global}
|
||||||
|
|
||||||
go func() {
|
OK(t, cmd.Execute([]string{tpe}))
|
||||||
OK(t, cmd.Execute([]string{tpe}))
|
IDs := parseIDsFromReader(t, &buf)
|
||||||
OK(t, wr.Close())
|
|
||||||
}()
|
|
||||||
|
|
||||||
IDs := parseIDsFromReader(t, rd)
|
|
||||||
|
|
||||||
return IDs
|
return IDs
|
||||||
}
|
}
|
||||||
|
@ -86,11 +84,6 @@ func cmdFsck(t testing.TB, global GlobalOptions) {
|
||||||
OK(t, cmd.Execute(nil))
|
OK(t, cmd.Execute(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmdKey(t testing.TB, global GlobalOptions, args ...string) {
|
|
||||||
cmd := &CmdKey{global: &global}
|
|
||||||
OK(t, cmd.Execute(args))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBackup(t *testing.T) {
|
func TestBackup(t *testing.T) {
|
||||||
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
|
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
|
||||||
datafile := filepath.Join("testdata", "backup-data.tar.gz")
|
datafile := filepath.Join("testdata", "backup-data.tar.gz")
|
||||||
|
@ -181,10 +174,6 @@ func appendRandomData(filename string, bytes uint) error {
|
||||||
return f.Close()
|
return f.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInit(t *testing.T) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIncrementalBackup(t *testing.T) {
|
func TestIncrementalBackup(t *testing.T) {
|
||||||
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
|
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
|
||||||
datafile := filepath.Join("testdata", "backup-data.tar.gz")
|
datafile := filepath.Join("testdata", "backup-data.tar.gz")
|
||||||
|
@ -229,18 +218,78 @@ func TestIncrementalBackup(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyAddRemove(t *testing.T) {
|
func cmdKey(t testing.TB, global GlobalOptions, args ...string) string {
|
||||||
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
|
var buf bytes.Buffer
|
||||||
datafile := filepath.Join("testdata", "backup-data.tar.gz")
|
|
||||||
fd, err := os.Open(datafile)
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
t.Skipf("unable to find data file %q, skipping", datafile)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
OK(t, err)
|
|
||||||
OK(t, fd.Close())
|
|
||||||
|
|
||||||
|
global.stdout = &buf
|
||||||
|
cmd := &CmdKey{global: &global}
|
||||||
|
OK(t, cmd.Execute(args))
|
||||||
|
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdKeyListOtherIDs(t testing.TB, global GlobalOptions) []string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
global.stdout = &buf
|
||||||
|
cmd := &CmdKey{global: &global}
|
||||||
|
OK(t, cmd.Execute([]string{"list"}))
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(&buf)
|
||||||
|
exp := regexp.MustCompile(`^ ([a-f0-9]+) `)
|
||||||
|
|
||||||
|
IDs := []string{}
|
||||||
|
for scanner.Scan() {
|
||||||
|
if id := exp.FindStringSubmatch(scanner.Text()); id != nil {
|
||||||
|
IDs = append(IDs, id[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return IDs
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdKeyAddNewKey(t testing.TB, global GlobalOptions, newPassword string) {
|
||||||
|
cmd := &CmdKey{global: &global, newPassword: newPassword}
|
||||||
|
OK(t, cmd.Execute([]string{"add"}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdKeyPasswd(t testing.TB, global GlobalOptions, newPassword string) {
|
||||||
|
cmd := &CmdKey{global: &global, newPassword: newPassword}
|
||||||
|
OK(t, cmd.Execute([]string{"passwd"}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdKeyRemove(t testing.TB, global GlobalOptions, IDs []string) {
|
||||||
|
cmd := &CmdKey{global: &global}
|
||||||
|
t.Logf("remove %d keys: %q\n", len(IDs), IDs)
|
||||||
|
for _, id := range IDs {
|
||||||
|
OK(t, cmd.Execute([]string{"rm", id}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKeyAddRemove(t *testing.T) {
|
||||||
|
passwordList := []string{
|
||||||
|
"OnnyiasyatvodsEvVodyawit",
|
||||||
|
"raicneirvOjEfEigonOmLasOd",
|
||||||
|
}
|
||||||
|
|
||||||
|
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
|
||||||
cmdInit(t, global)
|
cmdInit(t, global)
|
||||||
|
|
||||||
|
cmdKeyPasswd(t, global, "geheim2")
|
||||||
|
global.password = "geheim2"
|
||||||
|
t.Logf("changed password to %q", global.password)
|
||||||
|
|
||||||
|
for _, newPassword := range passwordList {
|
||||||
|
cmdKeyAddNewKey(t, global, newPassword)
|
||||||
|
t.Logf("added new password %q", newPassword)
|
||||||
|
global.password = newPassword
|
||||||
|
cmdKeyRemove(t, global, cmdKeyListOtherIDs(t, global))
|
||||||
|
}
|
||||||
|
|
||||||
|
global.password = passwordList[len(passwordList)-1]
|
||||||
|
t.Logf("testing access with last password %q\n", global.password)
|
||||||
cmdKey(t, global, "list")
|
cmdKey(t, global, "list")
|
||||||
|
|
||||||
|
cmdFsck(t, global)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
set -e
|
|
||||||
|
|
||||||
dump_repo() {
|
|
||||||
if [ "$FAILED" == "1" ]; then
|
|
||||||
tar cvz "$RESTIC_REPOSITORY" | base64 >&2
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
FAILED=1
|
|
||||||
|
|
||||||
trap dump_repo 0
|
|
||||||
|
|
||||||
prepare
|
|
||||||
unset RESTIC_PASSWORD
|
|
||||||
RESTIC_PASSWORD=foo run restic init
|
|
||||||
RESTIC_PASSWORD=foo run restic key list
|
|
||||||
|
|
||||||
RESTIC_PASSWORD=foo RESTIC_NEWPASSWORD=foobar run restic key passwd
|
|
||||||
RESTIC_PASSWORD=foobar run restic key list
|
|
||||||
RESTIC_PASSWORD=foobar RESTIC_NEWPASSWORD=foo run restic key passwd
|
|
||||||
|
|
||||||
OLD_PWD=foo
|
|
||||||
for i in {1..3}; do
|
|
||||||
NEW_PWD=bar$i
|
|
||||||
RESTIC_PASSWORD=$OLD_PWD RESTIC_NEWPASSWORD=$NEW_PWD run restic key add
|
|
||||||
RESTIC_PASSWORD=$OLD_PWD run restic key list
|
|
||||||
RESTIC_PASSWORD=$NEW_PWD run restic key list
|
|
||||||
|
|
||||||
export RESTIC_PASSWORD=$OLD_PWD
|
|
||||||
ID=$(restic key list | grep '^\*'|cut -d ' ' -f 1| sed 's/^.//')
|
|
||||||
unset RESTIC_PASSWORD
|
|
||||||
RESTIC_PASSWORD=$NEW_PWD run restic key rm $ID
|
|
||||||
RESTIC_PASSWORD=$NEW_PWD run restic key list
|
|
||||||
|
|
||||||
OLD_PWD=bar$i
|
|
||||||
done
|
|
||||||
|
|
||||||
RESTIC_PASSWORD=$OLD_PWD run restic fsck -o --check-data
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
|
|
||||||
FAILED=0
|
|
Loading…
Reference in a new issue