Files
secret/internal/cli/unlockers_add_test.go
T
clawbot af9ac6d979
check / check (push) Failing after 2s
Rename the Go module to sneak.berlin/go/secret (closes #43)
REPO_POLICIES.md requires the module root sneak.berlin/go/<name>.
go.mod, every import (rewritten with gofmt -r), the -X flags in
script/build and the examples in the pkg READMEs now use the new path.
go mod tidy lists go-humanize and fatih/color as direct requirements,
since internal/cli imports them.

This breaks anyone who fetched or imported git.eeqj.de/sneak/secret:
they must switch to sneak.berlin/go/secret, which resolves to this
repository.

Model: opus-5-5
2026-10-05 02:45:37 +02:00

107 lines
3.4 KiB
Go

//nolint:testpackage // white-box test of unexported internals
package cli
import (
"path/filepath"
"testing"
"github.com/awnumar/memguard"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sneak.berlin/go/secret/internal/secret"
"sneak.berlin/go/secret/internal/vault"
)
// unknownTestGPGUserID is a GPG user ID that no key in the test keyring has.
const unknownTestGPGUserID = "not-in-keyring@example.com"
// The secret TestAddPGPUnlocker stores, then reads through the new unlocker.
const (
addTestSecretName = "api-key"
addTestSecretValue = "value"
)
// TestAddPGPUnlocker adds a PGP unlocker for a throwaway GPG key to a vault
// with a passphrase unlocker, getting the vault's long-term key from the
// mnemonic or, with no mnemonic given, from the passphrase unlocker. It
// then reads a secret with neither the mnemonic nor the passphrase given, so
// through the new unlocker, which the add selects.
//
//nolint:paralleltest // t.Setenv (GNUPGHOME) forbids parallel tests
func TestAddPGPUnlocker(t *testing.T) {
newTestGPGKey(t)
passphrase := memguard.NewBufferFromBytes([]byte(testPassphrase))
t.Cleanup(passphrase.Destroy)
tests := []struct {
name string
// mnemonic is the mnemonic given while the unlocker is added, or nil.
mnemonic *memguard.LockedBuffer
}{
{"long-term key from the mnemonic", testMnemonicBuffer(t)},
{"long-term key from the current unlocker", nil},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fs := afero.NewMemMapFs()
vlt, err := vault.CreateVault(fs, listTestStateDir, listTestVaultName,
testMnemonicBuffer(t), nil)
require.NoError(t, err)
err = vlt.AddSecret(addTestSecretName,
memguard.NewBufferFromBytes([]byte(addTestSecretValue)), false)
require.NoError(t, err)
_, err = vlt.CreatePassphraseUnlocker(
memguard.NewBufferFromBytes([]byte(testPassphrase)))
require.NoError(t, err)
instance, cmd := newTestInstance(fs)
instance.Mnemonic = test.mnemonic
instance.UnlockPassphrase = passphrase
cmd.Flags().String("keyid", unreadableTestGPGUserID, "")
require.NoError(t, instance.UnlockersAdd(unlockerTypePGP, cmd))
reopened := vault.NewVault(fs, listTestStateDir, listTestVaultName)
current, err := reopened.GetCurrentUnlocker()
require.NoError(t, err)
assert.Equal(t, unlockerTypePGP, current.GetType())
value, err := reopened.GetSecret(addTestSecretName)
require.NoError(t, err)
defer value.Destroy()
assert.Equal(t, addTestSecretValue, value.String())
})
}
}
// TestAddPGPUnlockerUnknownKey asserts that adding a PGP unlocker for a key
// the keyring does not hold fails at looking up the key's fingerprint and
// leaves no new unlocker directory. The error must come from the lookup: a
// lookup moved after anything is written would also come after getting the
// vault's long-term key, which fails first here: this vault's unlockers hold
// no keys.
//
//nolint:paralleltest // t.Setenv (GNUPGHOME) forbids parallel tests
func TestAddPGPUnlockerUnknownKey(t *testing.T) {
newTestGPGKey(t)
base := newListTestVault(t, 1)
instance, cmd := newTestInstance(base)
cmd.Flags().String("keyid", unknownTestGPGUserID, "")
err := instance.addPGPUnlocker(cmd)
require.ErrorIs(t, err, secret.ErrGPGKeyNotFound)
assertDirEntries(t, base,
filepath.Join(testVaultDir(listTestVaultName), listTestUnlockersDirName),
listTestUnlockerDirOne)
}