1
0
forked from sneak/secret

fix: NumSecrets() now correctly counts secrets by checking for current file

NumSecrets() previously looked for non-directory, non-'current' files
directly under each secret directory, but the only children are
'current' (file, excluded) and 'versions' (directory, excluded),
so it always returned 0.

Now checks for the existence of the 'current' file, which is the
canonical indicator that a secret exists and has an active version.

This fixes the safety check in UnlockersRemove that was always
allowing removal of the last unlocker.
This commit is contained in:
clawbot 2026-02-08 12:04:15 -08:00
parent 128c53a11d
commit 341428d9ca
2 changed files with 24 additions and 10 deletions

View File

@ -227,27 +227,23 @@ func (v *Vault) NumSecrets() (int, error) {
return 0, fmt.Errorf("failed to read secrets directory: %w", err)
}
// Count only directories that contain at least one version file
// Count only directories that have a "current" version pointer file
count := 0
for _, entry := range entries {
if !entry.IsDir() {
continue
}
// Check if this secret directory contains any version files
// A valid secret has a "current" file pointing to the active version
secretDir := filepath.Join(secretsDir, entry.Name())
versionFiles, err := afero.ReadDir(v.fs, secretDir)
currentFile := filepath.Join(secretDir, "current")
exists, err := afero.Exists(v.fs, currentFile)
if err != nil {
continue // Skip directories we can't read
}
// Look for at least one version file (excluding "current" symlink)
for _, vFile := range versionFiles {
if !vFile.IsDir() && vFile.Name() != "current" {
count++
break // Found at least one version, count this secret
}
if exists {
count++
}
}

View File

@ -162,6 +162,24 @@ func TestVaultOperations(t *testing.T) {
}
})
// Test NumSecrets
t.Run("NumSecrets", func(t *testing.T) {
vlt, err := GetCurrentVault(fs, stateDir)
if err != nil {
t.Fatalf("Failed to get current vault: %v", err)
}
numSecrets, err := vlt.NumSecrets()
if err != nil {
t.Fatalf("Failed to count secrets: %v", err)
}
// We added one secret in SecretOperations
if numSecrets != 1 {
t.Errorf("Expected 1 secret, got %d", numSecrets)
}
})
// Test unlocker operations
t.Run("UnlockerOperations", func(t *testing.T) {
vlt, err := GetCurrentVault(fs, stateDir)