forked from sneak/secret
Skip unlocker directories with missing metadata instead of failing
When an unlocker directory exists but is missing unlocker-metadata.json, log a debug warning and skip it instead of returning a hard error that crashes the entire 'unlocker ls' command. Closes #1
This commit is contained in:
parent
4f5d2126d6
commit
1a96360f6a
@ -213,7 +213,9 @@ func (v *Vault) ListUnlockers() ([]UnlockerMetadata, error) {
|
|||||||
return nil, fmt.Errorf("failed to check if metadata exists for unlocker %s: %w", file.Name(), err)
|
return nil, fmt.Errorf("failed to check if metadata exists for unlocker %s: %w", file.Name(), err)
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
return nil, fmt.Errorf("unlocker directory %s is missing metadata file", file.Name())
|
secret.Debug("Skipping unlocker directory with missing metadata file", "directory", file.Name())
|
||||||
|
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
metadataBytes, err := afero.ReadFile(v.fs, metadataPath)
|
metadataBytes, err := afero.ReadFile(v.fs, metadataPath)
|
||||||
|
|||||||
@ -243,3 +243,57 @@ func TestVaultOperations(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListUnlockers_SkipsMissingMetadata(t *testing.T) {
|
||||||
|
// Set test environment variables
|
||||||
|
testMnemonic := "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
||||||
|
t.Setenv(secret.EnvMnemonic, testMnemonic)
|
||||||
|
t.Setenv(secret.EnvUnlockPassphrase, "test-passphrase")
|
||||||
|
|
||||||
|
// Use in-memory filesystem
|
||||||
|
fs := afero.NewMemMapFs()
|
||||||
|
stateDir := "/test/state"
|
||||||
|
|
||||||
|
// Create vault
|
||||||
|
vlt, err := CreateVault(fs, stateDir, "test-vault")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create vault: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a passphrase unlocker so we have at least one valid unlocker
|
||||||
|
passphraseBuffer := memguard.NewBufferFromBytes([]byte("test-passphrase"))
|
||||||
|
defer passphraseBuffer.Destroy()
|
||||||
|
_, err = vlt.CreatePassphraseUnlocker(passphraseBuffer)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create passphrase unlocker: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a bogus unlocker directory with no metadata file
|
||||||
|
vaultDir, err := vlt.GetDirectory()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to get vault directory: %v", err)
|
||||||
|
}
|
||||||
|
bogusDir := filepath.Join(vaultDir, "unlockers.d", "bogus-no-metadata")
|
||||||
|
err = fs.MkdirAll(bogusDir, 0o700)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create bogus directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListUnlockers should succeed, skipping the bogus directory
|
||||||
|
unlockers, err := vlt.ListUnlockers()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ListUnlockers returned error when it should have skipped bad directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should still have the valid passphrase unlocker
|
||||||
|
if len(unlockers) == 0 {
|
||||||
|
t.Errorf("Expected at least one unlocker, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify we only got the valid unlocker(s), not the bogus one
|
||||||
|
for _, u := range unlockers {
|
||||||
|
if u.Type == "" {
|
||||||
|
t.Errorf("Got unlocker with empty type, likely from bogus directory")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user