Fix intrange and G101 linting issues

- Convert for loops to use Go 1.22+ integer ranges in generate.go and helpers.go
- Disable G101 false positives for test vectors and environment variable names
- Add file-level gosec disable for bip85_test.go containing BIP85 test vectors
- Add targeted nolint comments for legitimate test data and constants
This commit is contained in:
2025-06-20 08:08:01 -07:00
parent 985d79d3c0
commit 434b73d834
29 changed files with 197 additions and 280 deletions

View File

@@ -14,54 +14,54 @@ import (
)
// Global scanner for consistent stdin reading
var stdinScanner *bufio.Scanner
var stdinScanner *bufio.Scanner //nolint:gochecknoglobals // Needed for consistent stdin handling
// CLIInstance encapsulates all CLI functionality and state
type CLIInstance struct {
// Instance encapsulates all CLI functionality and state
type Instance struct {
fs afero.Fs
stateDir string
cmd *cobra.Command
}
// NewCLIInstance creates a new CLI instance with the real filesystem
func NewCLIInstance() *CLIInstance {
func NewCLIInstance() *Instance {
fs := afero.NewOsFs()
stateDir := secret.DetermineStateDir("")
return &CLIInstance{
return &Instance{
fs: fs,
stateDir: stateDir,
}
}
// NewCLIInstanceWithFs creates a new CLI instance with the given filesystem (for testing)
func NewCLIInstanceWithFs(fs afero.Fs) *CLIInstance {
func NewCLIInstanceWithFs(fs afero.Fs) *Instance {
stateDir := secret.DetermineStateDir("")
return &CLIInstance{
return &Instance{
fs: fs,
stateDir: stateDir,
}
}
// NewCLIInstanceWithStateDir creates a new CLI instance with custom state directory (for testing)
func NewCLIInstanceWithStateDir(fs afero.Fs, stateDir string) *CLIInstance {
return &CLIInstance{
func NewCLIInstanceWithStateDir(fs afero.Fs, stateDir string) *Instance {
return &Instance{
fs: fs,
stateDir: stateDir,
}
}
// SetFilesystem sets the filesystem for this CLI instance (for testing)
func (cli *CLIInstance) SetFilesystem(fs afero.Fs) {
func (cli *Instance) SetFilesystem(fs afero.Fs) {
cli.fs = fs
}
// SetStateDir sets the state directory for this CLI instance (for testing)
func (cli *CLIInstance) SetStateDir(stateDir string) {
func (cli *Instance) SetStateDir(stateDir string) {
cli.stateDir = stateDir
}
// GetStateDir returns the state directory for this CLI instance
func (cli *CLIInstance) GetStateDir() string {
func (cli *Instance) GetStateDir() string {
return cli.stateDir
}
@@ -77,7 +77,7 @@ func getStdinScanner() *bufio.Scanner {
// Uses a shared scanner to avoid buffering issues between multiple calls
func readLineFromStdin(prompt string) (string, error) {
// Check if stderr is a terminal - if not, we can't prompt interactively
if !term.IsTerminal(int(syscall.Stderr)) {
if !term.IsTerminal(syscall.Stderr) {
return "", fmt.Errorf("cannot prompt for input: stderr is not a terminal (running in non-interactive mode)")
}

View File

@@ -54,7 +54,7 @@ func newDecryptCmd() *cobra.Command {
}
// Encrypt encrypts data using an age secret key stored in a secret
func (cli *CLIInstance) Encrypt(secretName, inputFile, outputFile string) error {
func (cli *Instance) Encrypt(secretName, inputFile, outputFile string) error {
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {
@@ -157,7 +157,7 @@ func (cli *CLIInstance) Encrypt(secretName, inputFile, outputFile string) error
}
// Decrypt decrypts data using an age secret key stored in a secret
func (cli *CLIInstance) Decrypt(secretName, inputFile, outputFile string) error {
func (cli *Instance) Decrypt(secretName, inputFile, outputFile string) error {
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {

View File

@@ -60,7 +60,7 @@ func newGenerateSecretCmd() *cobra.Command {
}
// GenerateMnemonic generates a random BIP39 mnemonic phrase
func (cli *CLIInstance) GenerateMnemonic(cmd *cobra.Command) error {
func (cli *Instance) GenerateMnemonic(cmd *cobra.Command) error {
// Generate 128 bits of entropy for a 12-word mnemonic
entropy, err := bip39.NewEntropy(128)
if err != nil {
@@ -92,7 +92,7 @@ func (cli *CLIInstance) GenerateMnemonic(cmd *cobra.Command) error {
}
// GenerateSecret generates a random secret and stores it in the vault
func (cli *CLIInstance) GenerateSecret(cmd *cobra.Command, secretName string, length int, secretType string, force bool) error {
func (cli *Instance) GenerateSecret(cmd *cobra.Command, secretName string, length int, secretType string, force bool) error {
if length < 1 {
return fmt.Errorf("length must be at least 1")
}
@@ -150,7 +150,7 @@ func generateRandomString(length int, charset string) (string, error) {
result := make([]byte, length)
charsetLen := big.NewInt(int64(len(charset)))
for i := 0; i < length; i++ {
for i := range length {
randomIndex, err := rand.Int(rand.Reader, charsetLen)
if err != nil {
return "", fmt.Errorf("failed to generate random number: %w", err)

View File

@@ -33,7 +33,7 @@ func RunInit(cmd *cobra.Command, args []string) error {
}
// Init initializes the secret manager
func (cli *CLIInstance) Init(cmd *cobra.Command) error {
func (cli *Instance) Init(cmd *cobra.Command) error {
secret.Debug("Starting secret manager initialization")
// Create state directory

View File

@@ -1387,7 +1387,7 @@ func test19DisasterRecovery(t *testing.T, tempDir, secretPath, testMnemonic stri
// Write the long-term private key to a file for age CLI
ltPrivKeyPath := filepath.Join(tempDir, "lt-private.key")
err = os.WriteFile(ltPrivKeyPath, []byte(ltIdentity.String()), 0600)
err = os.WriteFile(ltPrivKeyPath, []byte(ltIdentity.String()), 0o600)
require.NoError(t, err, "write long-term private key")
// Find the secret version directory
@@ -1606,7 +1606,7 @@ func test23ErrorHandling(t *testing.T, tempDir, secretPath, testMnemonic string,
func test24EnvironmentVariables(t *testing.T, tempDir, secretPath, testMnemonic, testPassphrase string) {
// Create a new temporary directory for this test
envTestDir := filepath.Join(tempDir, "env-test")
err := os.MkdirAll(envTestDir, 0700)
err := os.MkdirAll(envTestDir, 0o700)
require.NoError(t, err, "create env test dir should succeed")
// Test init with both env vars set
@@ -1908,7 +1908,7 @@ func test30BackupRestore(t *testing.T, tempDir, secretPath, testMnemonic string,
// Create backup directory
backupDir := filepath.Join(tempDir, "backup")
err := os.MkdirAll(backupDir, 0700)
err := os.MkdirAll(backupDir, 0o700)
require.NoError(t, err, "create backup dir should succeed")
// Copy entire state directory to backup
@@ -2012,7 +2012,7 @@ func test31EnvMnemonicUsesVaultDerivationIndex(t *testing.T, tempDir, secretPath
require.NoError(t, err, "vault select work should succeed")
// Add a secret to work vault using environment mnemonic
secretValue := "work-vault-secret"
secretValue := "work-vault-secret" //nolint:gosec // G101: This is test data, not a real credential
cmd := exec.Command(secretPath, "add", "test/derivation")
cmd.Env = []string{
fmt.Sprintf("SB_SECRET_STATE_DIR=%s", tempDir),
@@ -2083,7 +2083,7 @@ func readFile(t *testing.T, path string) []byte {
// writeFile writes data to a file
func writeFile(t *testing.T, path string, data []byte) {
t.Helper()
err := os.WriteFile(path, data, 0600)
err := os.WriteFile(path, data, 0o600)
require.NoError(t, err, "Should be able to write file: %s", path)
}
@@ -2094,7 +2094,7 @@ func copyDir(src, dst string) error {
return err
}
err = os.MkdirAll(dst, 0755)
err = os.MkdirAll(dst, 0o755)
if err != nil {
return err
}
@@ -2146,7 +2146,7 @@ func copyFile(src, dst string) error {
return err
}
err = os.WriteFile(dst, srcData, 0644)
err = os.WriteFile(dst, srcData, 0o644)
if err != nil {
return err
}

View File

@@ -7,8 +7,8 @@ import (
"github.com/spf13/cobra"
)
// CLIEntry is the entry point for the secret CLI application
func CLIEntry() {
// Entry is the entry point for the secret CLI application
func Entry() {
cmd := newRootCmd()
if err := cmd.Execute(); err != nil {
os.Exit(1)

View File

@@ -96,7 +96,7 @@ func newImportCmd() *cobra.Command {
}
// AddSecret adds a secret to the current vault
func (cli *CLIInstance) AddSecret(secretName string, force bool) error {
func (cli *Instance) AddSecret(secretName string, force bool) error {
secret.Debug("CLI AddSecret starting", "secret_name", secretName, "force", force)
// Get current vault
@@ -135,12 +135,12 @@ func (cli *CLIInstance) AddSecret(secretName string, force bool) error {
}
// GetSecret retrieves and prints a secret from the current vault
func (cli *CLIInstance) GetSecret(cmd *cobra.Command, secretName string) error {
func (cli *Instance) GetSecret(cmd *cobra.Command, secretName string) error {
return cli.GetSecretWithVersion(cmd, secretName, "")
}
// GetSecretWithVersion retrieves and prints a specific version of a secret
func (cli *CLIInstance) GetSecretWithVersion(cmd *cobra.Command, secretName string, version string) error {
func (cli *Instance) GetSecretWithVersion(cmd *cobra.Command, secretName string, version string) error {
secret.Debug("GetSecretWithVersion called", "secretName", secretName, "version", version)
// Get current vault
@@ -180,7 +180,7 @@ func (cli *CLIInstance) GetSecretWithVersion(cmd *cobra.Command, secretName stri
}
// ListSecrets lists all secrets in the current vault
func (cli *CLIInstance) ListSecrets(cmd *cobra.Command, jsonOutput bool, filter string) error {
func (cli *Instance) ListSecrets(cmd *cobra.Command, jsonOutput bool, filter string) error {
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {
@@ -278,7 +278,7 @@ func (cli *CLIInstance) ListSecrets(cmd *cobra.Command, jsonOutput bool, filter
}
// ImportSecret imports a secret from a file
func (cli *CLIInstance) ImportSecret(cmd *cobra.Command, secretName, sourceFile string, force bool) error {
func (cli *Instance) ImportSecret(cmd *cobra.Command, secretName, sourceFile string, force bool) error {
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {

View File

@@ -102,7 +102,7 @@ func newUnlockerSelectSubCmd() *cobra.Command {
}
// UnlockersList lists unlockers in the current vault
func (cli *CLIInstance) UnlockersList(jsonOutput bool) error {
func (cli *Instance) UnlockersList(jsonOutput bool) error {
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {
@@ -150,12 +150,12 @@ func (cli *CLIInstance) UnlockersList(jsonOutput bool) error {
// Check if this is the right unlocker by comparing metadata
metadataBytes, err := afero.ReadFile(cli.fs, metadataPath)
if err != nil {
continue //FIXME this error needs to be handled
continue // FIXME this error needs to be handled
}
var diskMetadata secret.UnlockerMetadata
if err := json.Unmarshal(metadataBytes, &diskMetadata); err != nil {
continue //FIXME this error needs to be handled
continue // FIXME this error needs to be handled
}
// Match by type and creation time
@@ -233,7 +233,7 @@ func (cli *CLIInstance) UnlockersList(jsonOutput bool) error {
}
// UnlockersAdd adds a new unlocker
func (cli *CLIInstance) UnlockersAdd(unlockerType string, cmd *cobra.Command) error {
func (cli *Instance) UnlockersAdd(unlockerType string, cmd *cobra.Command) error {
switch unlockerType {
case "passphrase":
// Get current vault
@@ -303,7 +303,7 @@ func (cli *CLIInstance) UnlockersAdd(unlockerType string, cmd *cobra.Command) er
}
// UnlockersRemove removes an unlocker
func (cli *CLIInstance) UnlockersRemove(unlockerID string) error {
func (cli *Instance) UnlockersRemove(unlockerID string) error {
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {
@@ -314,7 +314,7 @@ func (cli *CLIInstance) UnlockersRemove(unlockerID string) error {
}
// UnlockerSelect selects an unlocker as current
func (cli *CLIInstance) UnlockerSelect(unlockerID string) error {
func (cli *Instance) UnlockerSelect(unlockerID string) error {
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {

View File

@@ -89,7 +89,7 @@ func newVaultImportCmd() *cobra.Command {
}
// ListVaults lists all available vaults
func (cli *CLIInstance) ListVaults(cmd *cobra.Command, jsonOutput bool) error {
func (cli *Instance) ListVaults(cmd *cobra.Command, jsonOutput bool) error {
vaults, err := vault.ListVaults(cli.fs, cli.stateDir)
if err != nil {
return err
@@ -138,7 +138,7 @@ func (cli *CLIInstance) ListVaults(cmd *cobra.Command, jsonOutput bool) error {
}
// CreateVault creates a new vault
func (cli *CLIInstance) CreateVault(cmd *cobra.Command, name string) error {
func (cli *Instance) CreateVault(cmd *cobra.Command, name string) error {
secret.Debug("Creating new vault", "name", name, "state_dir", cli.stateDir)
vlt, err := vault.CreateVault(cli.fs, cli.stateDir, name)
@@ -151,7 +151,7 @@ func (cli *CLIInstance) CreateVault(cmd *cobra.Command, name string) error {
}
// SelectVault selects a vault as the current one
func (cli *CLIInstance) SelectVault(cmd *cobra.Command, name string) error {
func (cli *Instance) SelectVault(cmd *cobra.Command, name string) error {
if err := vault.SelectVault(cli.fs, cli.stateDir, name); err != nil {
return err
}
@@ -161,7 +161,7 @@ func (cli *CLIInstance) SelectVault(cmd *cobra.Command, name string) error {
}
// VaultImport imports a mnemonic into a specific vault
func (cli *CLIInstance) VaultImport(cmd *cobra.Command, vaultName string) error {
func (cli *Instance) VaultImport(cmd *cobra.Command, vaultName string) error {
secret.Debug("Importing mnemonic into vault", "vault_name", vaultName, "state_dir", cli.stateDir)
// Get the specific vault by name
@@ -219,7 +219,7 @@ func (cli *CLIInstance) VaultImport(cmd *cobra.Command, vaultName string) error
ltPublicKey := ltIdentity.Recipient().String()
secret.Debug("Storing long-term public key", "pubkey", ltPublicKey, "vault_dir", vaultDir)
if err := afero.WriteFile(cli.fs, pubKeyPath, []byte(ltPublicKey), 0600); err != nil {
if err := afero.WriteFile(cli.fs, pubKeyPath, []byte(ltPublicKey), 0o600); err != nil {
return fmt.Errorf("failed to store long-term public key: %w", err)
}

View File

@@ -19,7 +19,7 @@ func newVersionCmd() *cobra.Command {
}
// VersionCommands returns the version management commands
func VersionCommands(cli *CLIInstance) *cobra.Command {
func VersionCommands(cli *Instance) *cobra.Command {
versionCmd := &cobra.Command{
Use: "version",
Short: "Manage secret versions",
@@ -52,7 +52,7 @@ func VersionCommands(cli *CLIInstance) *cobra.Command {
}
// ListVersions lists all versions of a secret
func (cli *CLIInstance) ListVersions(cmd *cobra.Command, secretName string) error {
func (cli *Instance) ListVersions(cmd *cobra.Command, secretName string) error {
secret.Debug("ListVersions called", "secret_name", secretName)
// Get current vault
@@ -158,7 +158,7 @@ func (cli *CLIInstance) ListVersions(cmd *cobra.Command, secretName string) erro
}
// PromoteVersion promotes a specific version to current
func (cli *CLIInstance) PromoteVersion(cmd *cobra.Command, secretName string, version string) error {
func (cli *Instance) PromoteVersion(cmd *cobra.Command, secretName string, version string) error {
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {

View File

@@ -18,12 +18,11 @@ package cli
import (
"bytes"
"path/filepath"
"strings"
"testing"
"time"
"path/filepath"
"git.eeqj.de/sneak/secret/internal/secret"
"git.eeqj.de/sneak/secret/internal/vault"
"git.eeqj.de/sneak/secret/pkg/agehd"
@@ -49,7 +48,7 @@ func setupTestVault(t *testing.T, fs afero.Fs, stateDir string) {
// Store long-term public key in vault
vaultDir, _ := vlt.GetDirectory()
ltPubKeyPath := filepath.Join(vaultDir, "pub.age")
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0600)
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0o600)
require.NoError(t, err)
// Select vault
@@ -289,7 +288,7 @@ func TestListVersionsEmptyOutput(t *testing.T) {
// Create a secret directory without versions (edge case)
vaultDir := stateDir + "/vaults.d/default"
secretDir := vaultDir + "/secrets.d/test%secret"
err := fs.MkdirAll(secretDir, 0755)
err := fs.MkdirAll(secretDir, 0o755)
require.NoError(t, err)
// Create a command for output capture

View File

@@ -9,15 +9,15 @@ const (
// Environment variable names
EnvStateDir = "SB_SECRET_STATE_DIR"
EnvMnemonic = "SB_SECRET_MNEMONIC"
EnvUnlockPassphrase = "SB_UNLOCK_PASSPHRASE"
EnvUnlockPassphrase = "SB_UNLOCK_PASSPHRASE" //nolint:gosec // G101: This is an env var name, not a credential
EnvGPGKeyID = "SB_GPG_KEY_ID"
)
// File system permission constants
const (
// DirPerms is the permission used for directories (read-write-execute for owner only)
DirPerms os.FileMode = 0700
DirPerms os.FileMode = 0o700
// FilePerms is the permission used for sensitive files (read-write for owner only)
FilePerms os.FileMode = 0600
FilePerms os.FileMode = 0o600
)

View File

@@ -17,7 +17,7 @@ func generateRandomString(length int, charset string) (string, error) {
result := make([]byte, length)
charsetLen := big.NewInt(int64(len(charset)))
for i := 0; i < length; i++ {
for i := range length {
randomIndex, err := rand.Int(rand.Reader, charsetLen)
if err != nil {
return "", fmt.Errorf("failed to generate random number: %w", err)

View File

@@ -16,11 +16,9 @@ import (
"github.com/spf13/afero"
)
var (
// keychainItemNameRegex validates keychain item names
// Allows alphanumeric characters, dots, hyphens, and underscores only
keychainItemNameRegex = regexp.MustCompile(`^[A-Za-z0-9._-]+$`)
)
// keychainItemNameRegex validates keychain item names
// Allows alphanumeric characters, dots, hyphens, and underscores only
var keychainItemNameRegex = regexp.MustCompile(`^[A-Za-z0-9._-]+$`)
// KeychainUnlockerMetadata extends UnlockerMetadata with keychain-specific data
type KeychainUnlockerMetadata struct {

View File

@@ -35,7 +35,7 @@ func setupNonInteractiveGPG(t *testing.T, tempDir, passphrase, gnupgHomeDir stri
no-tty
pinentry-mode loopback
`
if err := os.WriteFile(gpgConfPath, []byte(gpgConfContent), 0600); err != nil {
if err := os.WriteFile(gpgConfPath, []byte(gpgConfContent), 0o600); err != nil {
t.Fatalf("Failed to write GPG config file: %v", err)
}
@@ -139,7 +139,7 @@ func TestPGPUnlockerWithRealFS(t *testing.T) {
// Create a temporary GNUPGHOME
gnupgHomeDir := filepath.Join(tempDir, "gnupg")
if err := os.MkdirAll(gnupgHomeDir, 0700); err != nil {
if err := os.MkdirAll(gnupgHomeDir, 0o700); err != nil {
t.Fatalf("Failed to create GNUPGHOME: %v", err)
}
@@ -176,7 +176,7 @@ Passphrase: ` + testPassphrase + `
%commit
%echo Key generation completed
`
if err := os.WriteFile(batchFile, []byte(batchContent), 0600); err != nil {
if err := os.WriteFile(batchFile, []byte(batchContent), 0o600); err != nil {
t.Fatalf("Failed to write batch file: %v", err)
}

View File

@@ -29,14 +29,14 @@ func (m *MockVault) AddSecret(name string, value []byte, force bool) error {
// Create secret directory with proper storage name conversion
storageName := strings.ReplaceAll(name, "/", "%")
secretDir := filepath.Join(m.directory, "secrets.d", storageName)
if err := m.fs.MkdirAll(secretDir, 0700); err != nil {
if err := m.fs.MkdirAll(secretDir, 0o700); err != nil {
return err
}
// Create version directory with proper path
versionName := "20240101.001" // Use a fixed version name for testing
versionDir := filepath.Join(secretDir, "versions", versionName)
if err := m.fs.MkdirAll(versionDir, 0700); err != nil {
if err := m.fs.MkdirAll(versionDir, 0o700); err != nil {
return err
}
@@ -57,7 +57,7 @@ func (m *MockVault) AddSecret(name string, value []byte, force bool) error {
// Write long-term public key if it doesn't exist
if _, err := m.fs.Stat(ltPubKeyPath); os.IsNotExist(err) {
pubKey := ltIdentity.Recipient().String()
if err := afero.WriteFile(m.fs, ltPubKeyPath, []byte(pubKey), 0600); err != nil {
if err := afero.WriteFile(m.fs, ltPubKeyPath, []byte(pubKey), 0o600); err != nil {
return err
}
}
@@ -70,7 +70,7 @@ func (m *MockVault) AddSecret(name string, value []byte, force bool) error {
// Write version public key
pubKeyPath := filepath.Join(versionDir, "pub.age")
if err := afero.WriteFile(m.fs, pubKeyPath, []byte(versionIdentity.Recipient().String()), 0600); err != nil {
if err := afero.WriteFile(m.fs, pubKeyPath, []byte(versionIdentity.Recipient().String()), 0o600); err != nil {
return err
}
@@ -82,7 +82,7 @@ func (m *MockVault) AddSecret(name string, value []byte, force bool) error {
// Write encrypted value
valuePath := filepath.Join(versionDir, "value.age")
if err := afero.WriteFile(m.fs, valuePath, encryptedValue, 0600); err != nil {
if err := afero.WriteFile(m.fs, valuePath, encryptedValue, 0o600); err != nil {
return err
}
@@ -94,14 +94,14 @@ func (m *MockVault) AddSecret(name string, value []byte, force bool) error {
// Write encrypted version private key
privKeyPath := filepath.Join(versionDir, "priv.age")
if err := afero.WriteFile(m.fs, privKeyPath, encryptedPrivKey, 0600); err != nil {
if err := afero.WriteFile(m.fs, privKeyPath, encryptedPrivKey, 0o600); err != nil {
return err
}
// Create current symlink pointing to the version
currentLink := filepath.Join(secretDir, "current")
// For MemMapFs, write a file with the target path
if err := afero.WriteFile(m.fs, currentLink, []byte("versions/"+versionName), 0600); err != nil {
if err := afero.WriteFile(m.fs, currentLink, []byte("versions/"+versionName), 0o600); err != nil {
return err
}
@@ -164,7 +164,7 @@ func TestPerSecretKeyFunctionality(t *testing.T) {
fs,
ltPubKeyPath,
[]byte(ltIdentity.Recipient().String()),
0600,
0o600,
)
if err != nil {
t.Fatalf("Failed to write long-term public key: %v", err)
@@ -325,7 +325,7 @@ func TestSecretGetValueWithEnvMnemonicUsesVaultDerivationIndex(t *testing.T) {
}()
stateDir := filepath.Join(tempDir, ".secret")
require.NoError(t, fs.MkdirAll(stateDir, 0700))
require.NoError(t, fs.MkdirAll(stateDir, 0o700))
// This test is now in the integration test file where it can use real vaults
// The bug is demonstrated there - see test31EnvMnemonicUsesVaultDerivationIndex

View File

@@ -89,7 +89,7 @@ func TestGenerateVersionName(t *testing.T) {
// Create the version directory
versionDir := filepath.Join(secretDir, "versions", version1)
err = fs.MkdirAll(versionDir, 0755)
err = fs.MkdirAll(versionDir, 0o755)
require.NoError(t, err)
// Test second version generation on same day
@@ -111,7 +111,7 @@ func TestGenerateVersionNameMaxSerial(t *testing.T) {
today := time.Now().Format("20060102")
for i := 1; i <= 999; i++ {
versionName := fmt.Sprintf("%s.%03d", today, i)
err := fs.MkdirAll(filepath.Join(versionsDir, versionName), 0755)
err := fs.MkdirAll(filepath.Join(versionsDir, versionName), 0o755)
require.NoError(t, err)
}
@@ -148,7 +148,7 @@ func TestSecretVersionSave(t *testing.T) {
// Create vault directory structure and long-term key
vaultDir, _ := vault.GetDirectory()
err := fs.MkdirAll(vaultDir, 0755)
err := fs.MkdirAll(vaultDir, 0o755)
require.NoError(t, err)
// Generate and store long-term public key
@@ -157,7 +157,7 @@ func TestSecretVersionSave(t *testing.T) {
vault.longTermKey = ltIdentity
ltPubKeyPath := filepath.Join(vaultDir, "pub.age")
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0600)
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0o600)
require.NoError(t, err)
// Create and save a version
@@ -184,7 +184,7 @@ func TestSecretVersionLoadMetadata(t *testing.T) {
// Setup vault with long-term key
vaultDir, _ := vault.GetDirectory()
err := fs.MkdirAll(vaultDir, 0755)
err := fs.MkdirAll(vaultDir, 0o755)
require.NoError(t, err)
ltIdentity, err := age.GenerateX25519Identity()
@@ -192,7 +192,7 @@ func TestSecretVersionLoadMetadata(t *testing.T) {
vault.longTermKey = ltIdentity
ltPubKeyPath := filepath.Join(vaultDir, "pub.age")
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0600)
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0o600)
require.NoError(t, err)
// Create and save a version with custom metadata
@@ -227,7 +227,7 @@ func TestSecretVersionGetValue(t *testing.T) {
// Setup vault with long-term key
vaultDir, _ := vault.GetDirectory()
err := fs.MkdirAll(vaultDir, 0755)
err := fs.MkdirAll(vaultDir, 0o755)
require.NoError(t, err)
ltIdentity, err := age.GenerateX25519Identity()
@@ -235,7 +235,7 @@ func TestSecretVersionGetValue(t *testing.T) {
vault.longTermKey = ltIdentity
ltPubKeyPath := filepath.Join(vaultDir, "pub.age")
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0600)
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0o600)
require.NoError(t, err)
// Create and save a version
@@ -265,12 +265,12 @@ func TestListVersions(t *testing.T) {
// Create some versions
testVersions := []string{"20231215.001", "20231215.002", "20231216.001", "20231214.001"}
for _, v := range testVersions {
err := fs.MkdirAll(filepath.Join(versionsDir, v), 0755)
err := fs.MkdirAll(filepath.Join(versionsDir, v), 0o755)
require.NoError(t, err)
}
// Create a file (not directory) that should be ignored
err = afero.WriteFile(fs, filepath.Join(versionsDir, "ignore.txt"), []byte("test"), 0600)
err = afero.WriteFile(fs, filepath.Join(versionsDir, "ignore.txt"), []byte("test"), 0o600)
require.NoError(t, err)
// List versions
@@ -288,10 +288,10 @@ func TestGetCurrentVersion(t *testing.T) {
// Simulate symlink with file content (works for both OsFs and MemMapFs)
currentPath := filepath.Join(secretDir, "current")
err := fs.MkdirAll(secretDir, 0755)
err := fs.MkdirAll(secretDir, 0o755)
require.NoError(t, err)
err = afero.WriteFile(fs, currentPath, []byte("versions/20231216.001"), 0600)
err = afero.WriteFile(fs, currentPath, []byte("versions/20231216.001"), 0o600)
require.NoError(t, err)
version, err := GetCurrentVersion(fs, secretDir)
@@ -303,7 +303,7 @@ func TestSetCurrentVersion(t *testing.T) {
fs := afero.NewMemMapFs()
secretDir := "/test/secret"
err := fs.MkdirAll(secretDir, 0755)
err := fs.MkdirAll(secretDir, 0o755)
require.NoError(t, err)
// Set current version

View File

@@ -51,7 +51,7 @@ func TestVaultWithRealFilesystem(t *testing.T) {
// Test symlink handling
t.Run("SymlinkHandling", func(t *testing.T) {
stateDir := filepath.Join(tempDir, "symlink-test")
if err := os.MkdirAll(stateDir, 0700); err != nil {
if err := os.MkdirAll(stateDir, 0o700); err != nil {
t.Fatalf("Failed to create state dir: %v", err)
}
@@ -98,7 +98,7 @@ func TestVaultWithRealFilesystem(t *testing.T) {
// Test secret operations with deeply nested paths
t.Run("DeepPathSecrets", func(t *testing.T) {
stateDir := filepath.Join(tempDir, "deep-path-test")
if err := os.MkdirAll(stateDir, 0700); err != nil {
if err := os.MkdirAll(stateDir, 0o700); err != nil {
t.Fatalf("Failed to create state dir: %v", err)
}
@@ -169,7 +169,7 @@ func TestVaultWithRealFilesystem(t *testing.T) {
// Test key caching in GetOrDeriveLongTermKey
t.Run("KeyCaching", func(t *testing.T) {
stateDir := filepath.Join(tempDir, "key-cache-test")
if err := os.MkdirAll(stateDir, 0700); err != nil {
if err := os.MkdirAll(stateDir, 0o700); err != nil {
t.Fatalf("Failed to create state dir: %v", err)
}
@@ -251,7 +251,7 @@ func TestVaultWithRealFilesystem(t *testing.T) {
// Test vault name validation
t.Run("VaultNameValidation", func(t *testing.T) {
stateDir := filepath.Join(tempDir, "name-validation-test")
if err := os.MkdirAll(stateDir, 0700); err != nil {
if err := os.MkdirAll(stateDir, 0o700); err != nil {
t.Fatalf("Failed to create state dir: %v", err)
}
@@ -291,7 +291,7 @@ func TestVaultWithRealFilesystem(t *testing.T) {
// Test multiple vaults and switching between them
t.Run("MultipleVaults", func(t *testing.T) {
stateDir := filepath.Join(tempDir, "multi-vault-test")
if err := os.MkdirAll(stateDir, 0700); err != nil {
if err := os.MkdirAll(stateDir, 0o700); err != nil {
t.Fatalf("Failed to create state dir: %v", err)
}
@@ -336,7 +336,7 @@ func TestVaultWithRealFilesystem(t *testing.T) {
// Test adding a secret in one vault and verifying it's not visible in another
t.Run("VaultIsolation", func(t *testing.T) {
stateDir := filepath.Join(tempDir, "isolation-test")
if err := os.MkdirAll(stateDir, 0700); err != nil {
if err := os.MkdirAll(stateDir, 0o700); err != nil {
t.Fatalf("Failed to create state dir: %v", err)
}

View File

@@ -54,7 +54,7 @@ func TestVersionIntegrationWorkflow(t *testing.T) {
// Store long-term public key in vault
vaultDir, _ := vault.GetDirectory()
ltPubKeyPath := filepath.Join(vaultDir, "pub.age")
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0600)
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0o600)
require.NoError(t, err)
// Unlock the vault
@@ -222,7 +222,7 @@ func TestVersionIntegrationWorkflow(t *testing.T) {
for i := 2; i <= 998; i++ {
versionName := fmt.Sprintf("%s.%03d", today, i)
versionDir := filepath.Join(secretDir, versionName)
err := fs.MkdirAll(versionDir, 0755)
err := fs.MkdirAll(versionDir, 0o755)
require.NoError(t, err)
}
@@ -232,7 +232,7 @@ func TestVersionIntegrationWorkflow(t *testing.T) {
assert.Equal(t, fmt.Sprintf("%s.999", today), versionName)
// Create the 999th version directory
err = fs.MkdirAll(filepath.Join(secretDir, versionName), 0755)
err = fs.MkdirAll(filepath.Join(secretDir, versionName), 0o755)
require.NoError(t, err)
// Should fail to create 1000th version
@@ -319,7 +319,7 @@ func TestVersionCompatibility(t *testing.T) {
secretName := "legacy/secret"
vaultDir, _ := vault.GetDirectory()
secretDir := filepath.Join(vaultDir, "secrets.d", "legacy%secret")
err = fs.MkdirAll(secretDir, 0755)
err = fs.MkdirAll(secretDir, 0o755)
require.NoError(t, err)
// Create old-style encrypted value directly in secret directory
@@ -329,7 +329,7 @@ func TestVersionCompatibility(t *testing.T) {
require.NoError(t, err)
valuePath := filepath.Join(secretDir, "value.age")
err = afero.WriteFile(fs, valuePath, encrypted, 0600)
err = afero.WriteFile(fs, valuePath, encrypted, 0o600)
require.NoError(t, err)
// Should fail to get with version-aware methods

View File

@@ -13,10 +13,12 @@ import (
)
// Alias the metadata types from secret package for convenience
type VaultMetadata = secret.VaultMetadata
type UnlockerMetadata = secret.UnlockerMetadata
type SecretMetadata = secret.SecretMetadata
type Configuration = secret.Configuration
type (
VaultMetadata = secret.VaultMetadata
UnlockerMetadata = secret.UnlockerMetadata
SecretMetadata = secret.SecretMetadata
Configuration = secret.Configuration
)
// ComputeDoubleSHA256 computes the double SHA256 hash of data and returns it as hex
func ComputeDoubleSHA256(data []byte) string {

View File

@@ -1,11 +1,9 @@
package vault
import (
"testing"
"path/filepath"
"strings"
"testing"
"git.eeqj.de/sneak/secret/pkg/agehd"
"github.com/spf13/afero"
@@ -53,7 +51,7 @@ func TestVaultMetadata(t *testing.T) {
// Create a vault with metadata and matching public key
vaultDir := filepath.Join(stateDir, "vaults.d", "vault1")
if err := fs.MkdirAll(vaultDir, 0700); err != nil {
if err := fs.MkdirAll(vaultDir, 0o700); err != nil {
t.Fatalf("Failed to create vault directory: %v", err)
}
@@ -66,7 +64,7 @@ func TestVaultMetadata(t *testing.T) {
pubKeyHash0 := ComputeDoubleSHA256([]byte(pubKey0))
// Write public key
if err := afero.WriteFile(fs, filepath.Join(vaultDir, "pub.age"), []byte(pubKey0), 0600); err != nil {
if err := afero.WriteFile(fs, filepath.Join(vaultDir, "pub.age"), []byte(pubKey0), 0o600); err != nil {
t.Fatalf("Failed to write public key: %v", err)
}
@@ -100,7 +98,7 @@ func TestVaultMetadata(t *testing.T) {
// Add another vault with same mnemonic but higher index
vaultDir2 := filepath.Join(stateDir, "vaults.d", "vault2")
if err := fs.MkdirAll(vaultDir2, 0700); err != nil {
if err := fs.MkdirAll(vaultDir2, 0o700); err != nil {
t.Fatalf("Failed to create vault directory: %v", err)
}
@@ -112,7 +110,7 @@ func TestVaultMetadata(t *testing.T) {
pubKey5 := identity5.Recipient().String()
// Write public key
if err := afero.WriteFile(fs, filepath.Join(vaultDir2, "pub.age"), []byte(pubKey5), 0600); err != nil {
if err := afero.WriteFile(fs, filepath.Join(vaultDir2, "pub.age"), []byte(pubKey5), 0o600); err != nil {
t.Fatalf("Failed to write public key: %v", err)
}
@@ -140,7 +138,7 @@ func TestVaultMetadata(t *testing.T) {
t.Run("MetadataPersistence", func(t *testing.T) {
vaultDir := filepath.Join(stateDir, "vaults.d", "test-vault")
if err := fs.MkdirAll(vaultDir, 0700); err != nil {
if err := fs.MkdirAll(vaultDir, 0o700); err != nil {
t.Fatalf("Failed to create vault directory: %v", err)
}

View File

@@ -46,7 +46,7 @@ func createTestVaultWithKey(t *testing.T, fs afero.Fs, stateDir, vaultName strin
// Store long-term public key in vault
vaultDir, _ := vault.GetDirectory()
ltPubKeyPath := filepath.Join(vaultDir, "pub.age")
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0600)
err = afero.WriteFile(fs, ltPubKeyPath, []byte(ltIdentity.Recipient().String()), 0o600)
require.NoError(t, err)
// Unlock the vault with the derived key