From 1cd0dd2ca7767669f8ae8a549d9e45debf1be59b Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Thu, 25 Jul 2019 17:12:31 -0400 Subject: [PATCH] Add an interactive "shell" mode of operation to avoid having to type in the password many times --- src/main.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 72fa2fe..1e2be17 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use crypto::hmac::Hmac; use crypto::mac::{Mac, MacResult}; use crypto::sha2::Sha256; -use dialoguer::{theme::ColorfulTheme, Input, PasswordInput}; +use dialoguer::{theme::ColorfulTheme, Input, PasswordInput, Select}; use docopt::Docopt; use log::debug; use rand::rngs::OsRng; @@ -21,6 +21,7 @@ Usage: foil set [--namespace=] [--db=] foil get [--namespace=] [--db=] foil list [--namespace=] [--db=] + foil shell [--namespace=] [--db=] foil dump [--db=] foil generate foil (-h | --help) @@ -40,6 +41,7 @@ struct Args { cmd_list: bool, cmd_generate: bool, cmd_dump: bool, + cmd_shell: bool, flag_db: Option, flag_src: Option, flag_namespace: String, @@ -92,7 +94,7 @@ fn get_master_key(db_conn: &mut db::DbHandle) -> [u8; 32] { master_key } -fn list(mut db_conn: db::DbHandle, master_key: [u8; 32], namespace: &str) { +fn list(db_conn: &mut db::DbHandle, master_key: [u8; 32], namespace: &str) { for note in db_conn.read_notes(master_key).unwrap() { if note.namespace == namespace && note.category == "account" { println!("{}", note.title); @@ -100,7 +102,7 @@ fn list(mut db_conn: db::DbHandle, master_key: [u8; 32], namespace: &str) { } } -fn get(mut db_conn: db::DbHandle, master_key: [u8; 32], namespace: &str) { +fn get(db_conn: &mut db::DbHandle, master_key: [u8; 32], namespace: &str) { println!("Reading a site from the database"); let host: String = Input::with_theme(&ColorfulTheme::default()) .with_prompt("hostname") @@ -118,7 +120,7 @@ fn get(mut db_conn: db::DbHandle, master_key: [u8; 32], namespace: &str) { } } -fn set(mut db_conn: db::DbHandle, master_key: [u8; 32], namespace: &str) { +fn set(db_conn: &mut db::DbHandle, master_key: [u8; 32], namespace: &str) { println!("Adding a site to the database"); let host: String = Input::with_theme(&ColorfulTheme::default()) .with_prompt("hostname") @@ -146,7 +148,7 @@ fn set(mut db_conn: db::DbHandle, master_key: [u8; 32], namespace: &str) { println!("Successfully added password"); } -fn dump(mut db_conn: db::DbHandle, master_key: [u8; 32]) { +fn dump(db_conn: &mut db::DbHandle, master_key: [u8; 32]) { for note in db_conn.read_notes(master_key).unwrap() { println!("===== note ====="); println!("namespace: {}", note.namespace); @@ -156,6 +158,37 @@ fn dump(mut db_conn: db::DbHandle, master_key: [u8; 32]) { } } +fn shell_generate() { + let spec: String = Input::with_theme(&ColorfulTheme::default()) + .with_prompt("Password Spec") + .default("30,AAAa111..".to_owned()) + .interact() + .unwrap(); + + generate::generate(&spec); +} + +fn shell(db_conn: &mut db::DbHandle, master_key: [u8; 32], namespace: &str) { + loop { + let selections = &["get", "list", "set", "generate", "exit"]; + + let selection = Select::with_theme(&ColorfulTheme::default()) + .with_prompt("Main Menu") + .default(0) + .items(&selections[..]) + .interact() + .unwrap(); + match selections[selection] { + "get" => get(db_conn, master_key, namespace), + "list" => list(db_conn, master_key, namespace), + "set" => set(db_conn, master_key, namespace), + "generate" => shell_generate(), + "exit" => break, + _ => panic!("Unrecognized command"), + }; + } +} + fn main() -> Result<(), Box> { pretty_env_logger::init(); let args: Args = Docopt::new(USAGE) @@ -173,13 +206,15 @@ fn main() -> Result<(), Box> { let master_key: [u8; 32] = get_master_key(&mut db_conn); if args.cmd_set { - set(db_conn, master_key, &args.flag_namespace); + set(&mut db_conn, master_key, &args.flag_namespace); } else if args.cmd_get { - get(db_conn, master_key, &args.flag_namespace); + get(&mut db_conn, master_key, &args.flag_namespace); } else if args.cmd_list { - list(db_conn, master_key, &args.flag_namespace); + list(&mut db_conn, master_key, &args.flag_namespace); } else if args.cmd_dump { - dump(db_conn, master_key); + dump(&mut db_conn, master_key); + } else if args.cmd_shell { + shell(&mut db_conn, master_key, &args.flag_namespace); } Ok(())