1
use std::fs;
2
use std::path::Path;
3

            
4
use clap::Args;
5
use mk_lib::secrets::verify_vault;
6

            
7
use crate::secrets::context::Context;
8

            
9
#[derive(Debug, Args)]
10
pub struct PurgeSecret {
11
  #[arg(help = "The secret identifier")]
12
  path: String,
13

            
14
  #[arg(short, long, help = "The path to the secret vault")]
15
  vault_location: Option<String>,
16

            
17
  #[arg(short = 'y', long, help = "Confirm destructive secret deletion")]
18
  yes: bool,
19
}
20

            
21
impl PurgeSecret {
22
  pub fn execute(&self, context: &Context) -> anyhow::Result<()> {
23
    let path = self.path.as_str();
24
    let context_vault_location;
25
    let vault_location = match self.vault_location.as_deref() {
26
      Some(vault_location) => vault_location,
27
      None => {
28
        context_vault_location = context.vault_location();
29
        context_vault_location.as_str()
30
      },
31
    };
32

            
33
    assert!(!path.is_empty(), "Path or prefix must be provided");
34
    assert!(!vault_location.is_empty(), "Vault location must be provided");
35

            
36
    verify_vault(Path::new(vault_location))?;
37

            
38
    let path = Path::new(vault_location).join(path);
39
    let data_path = path.join("data.asc");
40
    if path.exists() && path.is_dir() && data_path.exists() && data_path.is_file() {
41
      if !self.yes {
42
        anyhow::bail!(
43
          "Refusing to delete secret '{}' without --yes. Re-run with --yes to confirm.",
44
          self.path
45
        );
46
      }
47
      fs::remove_dir_all(&path)?;
48
      println!("Secret '{}' removed from vault.", self.path);
49
    } else {
50
      println!(
51
        "Secret '{}' not found in vault. List available secrets with: mk secrets vault list",
52
        self.path
53
      );
54
    }
55
    Ok(())
56
  }
57
}