//nolint:testpackage // white-box test of unexported internals package cli import ( "path/filepath" "testing" "git.eeqj.de/sneak/secret/internal/secret" "git.eeqj.de/sneak/secret/internal/vault" "github.com/awnumar/memguard" "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // 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 the mnemonic unset, from the passphrase unlocker. It // then reads a secret with neither the mnemonic nor the passphrase set, so // through the new unlocker, which the add selects. func TestAddPGPUnlocker(t *testing.T) { newTestGPGKey(t) tests := []struct { name string // mnemonic is the mnemonic set while the unlocker is added. mnemonic string }{ {"long-term key from the mnemonic", testMnemonic}, {"long-term key from the current unlocker", ""}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { t.Setenv(secret.EnvMnemonic, testMnemonic) t.Setenv(secret.EnvUnlockPassphrase, testPassphrase) fs := afero.NewMemMapFs() vlt, err := vault.CreateVault(fs, listTestStateDir, listTestVaultName) 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) t.Setenv(secret.EnvMnemonic, test.mnemonic) instance, cmd := newTestInstance(fs) cmd.Flags().String("keyid", unreadableTestGPGUserID, "") require.NoError(t, instance.UnlockersAdd(unlockerTypePGP, cmd)) t.Setenv(secret.EnvMnemonic, "") t.Setenv(secret.EnvUnlockPassphrase, "") 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.ErrorContains(t, err, "failed to resolve GPG key fingerprint") assertDirEntries(t, base, filepath.Join(testVaultDir(listTestVaultName), listTestUnlockersDirName), listTestUnlockerDirOne) }