From 0139fc69e46766d6cd491b42abc501abef720823 Mon Sep 17 00:00:00 2001 From: Mike Lloyd Date: Sat, 13 Jan 2024 22:49:50 -0800 Subject: [PATCH] Add command help --- Cargo.lock | 11 +++++++++ Cargo.toml | 2 +- README.md | 12 ++++++++++ src/command/cli.rs | 50 ++++++++++++++++++++++++++++++++++++++++- src/command/handlers.rs | 6 ++++- src/main.rs | 4 ++-- 6 files changed, 80 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f9c964..dec1d02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -320,6 +320,7 @@ dependencies = [ "anstyle", "clap_lex", "strsim", + "terminal_size", ] [[package]] @@ -1872,6 +1873,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "termtree" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index 6846b2f..740e4be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] anyhow = "1.0.75" -clap = { version = "4.4.11", features = ["derive"] } +clap = { version = "4.4.11", features = ["derive", "wrap_help"] } sqlx = { version = "0.7.3", features = [ "sqlite", "runtime-tokio", diff --git a/README.md b/README.md index 9f98af6..dba547b 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,18 @@ If the `RUDRIC_SESSION` token is set in the environment: - The expiration time and master key are decrypted from the session token using the session key - If the token is not expired, the master key will be used to interact with secrets in the vault. +# Configuration + +Rudric can be configured with a yaml file. By default, this file is stored in `XDG_CONFIG/rudric/config.yaml` (`$HOME/.config/rudric/config.yaml` on Linux and Mac). All config options are optional. An example config file might look like this: + +```yaml +# Options are: bash, zsh, fish, nu +default_shell: fish + +# Specify the default length of time that a session token is valid for +session_lifetime: 6h +``` + # Crates Encryption is all accomplished using the fantastic [Orion](https://github.com/orion-rs/orion) library. diff --git a/src/command/cli.rs b/src/command/cli.rs index 696f44a..62fc218 100644 --- a/src/command/cli.rs +++ b/src/command/cli.rs @@ -1,53 +1,99 @@ -// #![deny(missing_docs)] use clap::{Args, Parser, Subcommand}; use crate::types::shell_type::ShellType; +/// Store secrets in an encrypted state on disk #[derive(Parser)] #[command(author, version, about, long_about = None)] pub struct Cli { + /// Specify a subcommand #[command(subcommand)] pub command: Command, + + /// Specify an alternate config directory #[arg(short, long)] pub config_dir: Option, } +/// The subcommand to execute #[derive(Subcommand)] pub enum Command { + /// Set a master password and initialize the database Init, + + /// Create a new secret Create { + /// The name of the secret (must be unique) name: String, + /// Set the secret description #[arg(short = 'd', long)] description: Option, }, + + /// Fetch a secret value Get { + /// The name of the secret name: String, + /// Output the secret in json format #[arg(long)] json: bool, }, + + /// Edit an existing secret. Will open the secret value in $EDITOR or $VISUAL Edit { + /// The name of the secret name: String, + /// Edit the secret description #[arg(short = 'd', long)] description: bool, }, + + /// Delete a secret. Asks for confirmation Delete { + /// The name of the secret name: String, }, + + /// Rename a secret Rename { + /// The current name of the secret name: String, + + /// The new name of the secret. If blank, the user will be prompted for a new name new_name: Option, }, + + /// List all secrets List, + + /// Create a new session token. Setting this token as `RUDRIC_SESSION` in the environment will + /// prevent the user from being prompted for the password each time the program is invoked. Session(SessionArgs), + + /// Read from the .renv file (or an alternate file) and set the specified variables in the environment. + /// This command generates the shell code necessary to set the requested + /// environment variables. The output of this command must be sourced with something like + /// `rudric env | source` Env { + /// The shell format to use. Defaults to bash but a default can be specified in the config + /// file. shell: Option, + + /// Use an alternate environment file + #[arg(short, long)] + file: Option, }, + + /// Generate shell completions GenerateCompletions { + /// The shell to generate completions for shell: ShellType, }, + + /// Change the master password for the vault ChangePassword, } @@ -59,6 +105,8 @@ pub struct SessionArgs { #[derive(Subcommand)] pub enum SessionCmd { + /// Create a new session token New, + /// Invalidates the current session token End, } diff --git a/src/command/handlers.rs b/src/command/handlers.rs index 9360505..c146115 100644 --- a/src/command/handlers.rs +++ b/src/command/handlers.rs @@ -227,7 +227,11 @@ pub async fn handle_session(config_dir: &Path, session_cmd: SessionArgs) -> Resu Ok(()) } -pub async fn handle_env(config_dir: &Path, shell: Option) -> Result<()> { +pub async fn handle_env( + config_dir: &Path, + shell: Option, + file: Option, +) -> Result<()> { let app = App::new(config_dir, true).await?; let config = Config::load(config_dir)?; diff --git a/src/main.rs b/src/main.rs index e81d33c..c17cb3b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,8 +51,8 @@ async fn main() -> Result<()> { Command::Session(session_cmd) => { handle_session(&config_dir, session_cmd).await?; } - Command::Env { shell } => { - handle_env(&config_dir, shell).await?; + Command::Env { shell, file } => { + handle_env(&config_dir, shell, file).await?; } Command::ChangePassword => { handle_change_password(&config_dir).await?;