1
use clap::{
2
  Args,
3
  Subcommand,
4
};
5

            
6
use super::context::Context;
7

            
8
pub use export_key::ExportKey;
9
pub use generate_key::GenerateKey;
10
pub use import_key::ImportKey;
11
pub use list_keys::ListKeys;
12
pub use purge_key::PurgeKey;
13

            
14
mod export_key;
15
mod generate_key;
16
mod import_key;
17
mod list_keys;
18
mod purge_key;
19

            
20
/// The help message for the key location
21
pub const KEY_LOCATION_HELP: &str = "The path to where the private keys are stored";
22

            
23
/// The struct that represents the key command
24
#[derive(Debug, Args)]
25
pub struct Key {
26
  /// The subcommand to run
27
  #[command(subcommand)]
28
  command: Option<KeyCommand>,
29

            
30
  /// The location to store the private key
31
  /// This is a global option that can be used with any subcommand
32
  /// If not provided, the default location will be used
33
  /// If the default location does not exist, it will be created
34
  /// If the default location is not provided, the key will not be created
35
  /// If the key already exists, it will not be created
36
  #[arg(short, long, help = KEY_LOCATION_HELP)]
37
  location: Option<String>,
38
}
39

            
40
/// The available subcommands for the key command
41
#[derive(Debug, Subcommand)]
42
enum KeyCommand {
43
  /// Generate a new private key
44
  #[command(visible_aliases = ["gen"], about = "Generate a new private key")]
45
  GenerateKey(GenerateKey),
46

            
47
  /// List all private keys
48
  #[command(visible_aliases = ["K", "ls"], about = "List all private keys")]
49
  ListKeys(ListKeys),
50

            
51
  /// Purge and remove a private key
52
  #[command(visible_aliases = ["rm"], about = "Purge and remove a private key")]
53
  PurgeKey(PurgeKey),
54

            
55
  /// Export a private key
56
  #[command(visible_aliases = ["export", "e"], about = "Export selected private key")]
57
  ExportKey(ExportKey),
58

            
59
  /// Import a GPG key from the local keyring (enables YubiKey and passphrase-protected key support)
60
  #[command(visible_aliases = ["import"], about = "Import a GPG key reference from the local keyring")]
61
  ImportKey(ImportKey),
62
}
63

            
64
impl Key {
65
  pub fn execute(&self, context: &mut Context) -> anyhow::Result<()> {
66
    if let Some(location) = &self.location {
67
      context.set_keys_location(location);
68
    }
69

            
70
    match &self.command {
71
      Some(command) => command.run(context),
72
      None => Err(anyhow::anyhow!(
73
        "No key subcommand given. Run 'mk secrets key --help' to see available subcommands."
74
      )),
75
    }
76
  }
77
}
78

            
79
impl KeyCommand {
80
  pub fn run(&self, context: &Context) -> anyhow::Result<()> {
81
    match self {
82
      KeyCommand::GenerateKey(args) => args.execute(context),
83
      KeyCommand::ListKeys(args) => args.execute(context),
84
      KeyCommand::PurgeKey(args) => args.execute(context),
85
      KeyCommand::ExportKey(args) => args.execute(context),
86
      KeyCommand::ImportKey(args) => args.execute(context),
87
    }
88
  }
89
}