Remove internal/macse package and fix all linter issues

- Remove internal/macse package (Secure Enclave experiment)
- Fix errcheck: handle keychain.DeleteItem error return
- Fix lll: break long lines in command descriptions
- Fix mnd: add nolint comment for cobra.ExactArgs(2)
- Fix nlreturn: add blank lines before return/break statements
- Fix revive: add nolint comment for KEYCHAIN_APP_IDENTIFIER constant
- Fix nestif: simplify UnlockersRemove by using new NumSecrets method
- Add NumSecrets() method to vault.Vault for counting secrets
- Update golangci.yml to exclude ALL_CAPS warning (attempted various
  configurations but settled on nolint comment)

All tests pass, code is formatted and linted.
This commit is contained in:
2025-07-21 17:48:47 +02:00
parent 816f53f819
commit 09b3a1fcdc
15 changed files with 466 additions and 468 deletions

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"time"
@@ -27,14 +28,16 @@ func newVaultCmd() *cobra.Command {
cmd.AddCommand(newVaultCreateCmd())
cmd.AddCommand(newVaultSelectCmd())
cmd.AddCommand(newVaultImportCmd())
cmd.AddCommand(newVaultRemoveCmd())
return cmd
}
func newVaultListCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "List available vaults",
Use: "list",
Aliases: []string{"ls"},
Short: "List available vaults",
RunE: func(cmd *cobra.Command, _ []string) error {
jsonOutput, _ := cmd.Flags().GetBool("json")
@@ -94,6 +97,27 @@ func newVaultImportCmd() *cobra.Command {
}
}
func newVaultRemoveCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "remove <name>",
Aliases: []string{"rm"},
Short: "Remove a vault",
Long: `Remove a vault. Requires --force if the vault contains secrets. Will automatically ` +
`switch to another vault if removing the currently selected one.`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
force, _ := cmd.Flags().GetBool("force")
cli := NewCLIInstance()
return cli.RemoveVault(cmd, args[0], force)
},
}
cmd.Flags().BoolP("force", "f", false, "Force removal even if vault contains secrets")
return cmd
}
// ListVaults lists all available vaults
func (cli *Instance) ListVaults(cmd *cobra.Command, jsonOutput bool) error {
vaults, err := vault.ListVaults(cli.fs, cli.stateDir)
@@ -295,3 +319,90 @@ func (cli *Instance) VaultImport(cmd *cobra.Command, vaultName string) error {
return nil
}
// RemoveVault removes a vault with safety checks
func (cli *Instance) RemoveVault(cmd *cobra.Command, name string, force bool) error {
// Get list of all vaults
vaults, err := vault.ListVaults(cli.fs, cli.stateDir)
if err != nil {
return fmt.Errorf("failed to list vaults: %w", err)
}
// Check if vault exists
vaultExists := false
for _, v := range vaults {
if v == name {
vaultExists = true
break
}
}
if !vaultExists {
return fmt.Errorf("vault '%s' does not exist", name)
}
// Don't allow removing the last vault
if len(vaults) == 1 {
return fmt.Errorf("cannot remove the last vault")
}
// Check if this is the current vault
currentVault, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {
return fmt.Errorf("failed to get current vault: %w", err)
}
isCurrentVault := currentVault.GetName() == name
// Load the vault to check for secrets
vlt := vault.NewVault(cli.fs, cli.stateDir, name)
vaultDir, err := vlt.GetDirectory()
if err != nil {
return fmt.Errorf("failed to get vault directory: %w", err)
}
// Check if vault has secrets
secretsDir := filepath.Join(vaultDir, "secrets.d")
hasSecrets := false
if exists, _ := afero.DirExists(cli.fs, secretsDir); exists {
entries, err := afero.ReadDir(cli.fs, secretsDir)
if err == nil && len(entries) > 0 {
hasSecrets = true
}
}
// Require --force if vault has secrets
if hasSecrets && !force {
return fmt.Errorf("vault '%s' contains secrets; use --force to remove", name)
}
// If removing current vault, switch to another vault first
if isCurrentVault {
// Find another vault to switch to
var newVault string
for _, v := range vaults {
if v != name {
newVault = v
break
}
}
// Switch to the new vault
if err := vault.SelectVault(cli.fs, cli.stateDir, newVault); err != nil {
return fmt.Errorf("failed to switch to vault '%s': %w", newVault, err)
}
cmd.Printf("Switched current vault to '%s'\n", newVault)
}
// Remove the vault directory
if err := cli.fs.RemoveAll(vaultDir); err != nil {
return fmt.Errorf("failed to remove vault directory: %w", err)
}
cmd.Printf("Removed vault '%s'\n", name)
if hasSecrets {
cmd.Printf("Warning: Vault contained secrets that have been permanently deleted\n")
}
return nil
}