package cli_test import ( "testing" "git.eeqj.de/sneak/secret/internal/cli" "git.eeqj.de/sneak/secret/internal/secret" "git.eeqj.de/sneak/secret/internal/vault" "github.com/awnumar/memguard" "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/stretchr/testify/require" ) // TestCreateExistingVaultChangesNothing is a regression test for // https://git.eeqj.de/sneak/secret/issues/74, where running `secret init` // a second time, or `secret vault create` with the name of an existing // vault, replaced that vault's keys, so that none of its secrets could be // decrypted any more. Each must refuse, change nothing, and leave every // vault's secret readable through its passphrase unlocker. func TestCreateExistingVaultChangesNothing(t *testing.T) { t.Setenv(secret.EnvMnemonic, testMnemonic) t.Setenv(secret.EnvUnlockPassphrase, testPassphrase) // `secret init`, `secret vault create work`, `secret vault select // default`, and the secret "x" in each vault. "work" is then not the // current vault, which creating it again must not change. fs := afero.NewMemMapFs() c := cli.NewCLIInstanceWithStateDir(fs, testStateDir) cmd := &cobra.Command{} require.NoError(t, c.Init(cmd)) require.NoError(t, c.CreateVault(cmd, "work")) require.NoError(t, c.SelectVault(cmd, "default")) vaults, err := vault.ListVaults(fs, testStateDir) require.NoError(t, err) require.Len(t, vaults, 2) for _, name := range vaults { value := memguard.NewBufferFromBytes([]byte("value")) err := vault.NewVault(fs, testStateDir, name).AddSecret("x", value, false) require.NoError(t, err) } before := snapshotStateDir(t, fs) tests := []struct { command string want string run func(c *cli.Instance) error }{ { "init", "failed to create default vault: vault default already exists", func(c *cli.Instance) error { return c.Init(cmd) }, }, { "vault create default", "vault default already exists", func(c *cli.Instance) error { return c.CreateVault(cmd, "default") }, }, { "vault create work", "vault work already exists", func(c *cli.Instance) error { return c.CreateVault(cmd, "work") }, }, } for _, tt := range tests { t.Run(tt.command, func(t *testing.T) { fs := newFsFromSnapshot(t, before) err := tt.run(cli.NewCLIInstanceWithStateDir(fs, testStateDir)) require.EqualError(t, err, tt.want) require.Equal(t, before, snapshotStateDir(t, fs)) // Without the mnemonic, reading a secret goes through the // vault's passphrase unlocker. t.Setenv(secret.EnvMnemonic, "") for _, name := range vaults { value, err := vault.NewVault(fs, testStateDir, name).GetSecret("x") require.NoError(t, err) require.Equal(t, "value", string(value)) } }) } }