check / check (push) Failing after 1s
init and vault create put the mnemonic into the process environment for vault.CreateVault to read back, so every program they ran, gpg included, inherited it, and SB_SECRET_MNEMONIC and SB_UNLOCK_PASSPHRASE were read at 13 places and never unset. Each command that may need them now reads both once, in its RunE, into locked buffers on the CLI Instance, and unsets them at once. The buffers are passed down: vault.CreateVault takes the mnemonic, a Vault carries Mnemonic and UnlockPassphrase, and the PGP, keychain and Secure Enclave unlocker constructors take both; CreatePGPUnlocker sets them on the vault it loads through SetMnemonic and SetUnlockPassphrase, new in VaultInterface. README warns against both variables. Model: opus-5-5
101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
//go:build !darwin
|
|
|
|
//nolint:testpackage // white-box test asserting unexported sentinel errors
|
|
package secret
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/spf13/afero"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestNewSecureEnclaveUnlocker(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
dir := "/tmp/test-se-unlocker"
|
|
metadata := UnlockerMetadata{
|
|
Type: seUnlockerType,
|
|
CreatedAt: time.Date(2026, 1, 15, 10, 30, 0, 0, time.UTC),
|
|
Flags: []string{seUnlockerType, "macos"},
|
|
}
|
|
|
|
unlocker := NewSecureEnclaveUnlocker(fs, dir, metadata)
|
|
require.NotNil(t, unlocker, "NewSecureEnclaveUnlocker should return a valid instance")
|
|
|
|
// Test GetType returns correct type
|
|
assert.Equal(t, seUnlockerType, unlocker.GetType())
|
|
|
|
// Test GetMetadata returns the metadata we passed in
|
|
assert.Equal(t, metadata, unlocker.GetMetadata())
|
|
|
|
// Test GetDirectory returns the directory we passed in
|
|
assert.Equal(t, dir, unlocker.GetDirectory())
|
|
|
|
// Test GetID returns a formatted string with the creation timestamp
|
|
expectedID := "2026-01-15.10.30-secure-enclave"
|
|
assert.Equal(t, expectedID, unlocker.GetID())
|
|
}
|
|
|
|
func TestSecureEnclaveUnlockerGetIdentityReturnsError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
metadata := UnlockerMetadata{
|
|
Type: seUnlockerType,
|
|
CreatedAt: time.Now().UTC(),
|
|
}
|
|
|
|
unlocker := NewSecureEnclaveUnlocker(fs, "/tmp/test", metadata)
|
|
|
|
identity, err := unlocker.GetIdentity()
|
|
assert.Nil(t, identity)
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, errSENotSupported)
|
|
}
|
|
|
|
func TestSecureEnclaveUnlockerRemoveReturnsError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
metadata := UnlockerMetadata{
|
|
Type: seUnlockerType,
|
|
CreatedAt: time.Now().UTC(),
|
|
}
|
|
|
|
unlocker := NewSecureEnclaveUnlocker(fs, "/tmp/test", metadata)
|
|
|
|
err := unlocker.Remove()
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, errSENotSupported)
|
|
}
|
|
|
|
func TestCreateSecureEnclaveUnlockerReturnsError(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
|
|
unlocker, err := CreateSecureEnclaveUnlocker(fs, "/tmp/test", nil, nil)
|
|
assert.Nil(t, unlocker)
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, errSENotSupported)
|
|
}
|
|
|
|
func TestSecureEnclaveUnlockerImplementsInterface(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
fs := afero.NewMemMapFs()
|
|
metadata := UnlockerMetadata{
|
|
Type: seUnlockerType,
|
|
CreatedAt: time.Now().UTC(),
|
|
}
|
|
|
|
unlocker := NewSecureEnclaveUnlocker(fs, "/tmp/test", metadata)
|
|
|
|
// Verify the stub implements the Unlocker interface
|
|
var _ Unlocker = unlocker
|
|
}
|