Add an interactive "shell" mode of operation to avoid having to type in the password many times

master
Tom Alexander 5 years ago
parent b89b4ed329
commit 1cd0dd2ca7
No known key found for this signature in database
GPG Key ID: 76046DA92D2604F7

@ -1,7 +1,7 @@
use crypto::hmac::Hmac; use crypto::hmac::Hmac;
use crypto::mac::{Mac, MacResult}; use crypto::mac::{Mac, MacResult};
use crypto::sha2::Sha256; use crypto::sha2::Sha256;
use dialoguer::{theme::ColorfulTheme, Input, PasswordInput}; use dialoguer::{theme::ColorfulTheme, Input, PasswordInput, Select};
use docopt::Docopt; use docopt::Docopt;
use log::debug; use log::debug;
use rand::rngs::OsRng; use rand::rngs::OsRng;
@ -21,6 +21,7 @@ Usage:
foil set [--namespace=<ns>] [--db=<db>] foil set [--namespace=<ns>] [--db=<db>]
foil get [--namespace=<ns>] [--db=<db>] foil get [--namespace=<ns>] [--db=<db>]
foil list [--namespace=<ns>] [--db=<db>] foil list [--namespace=<ns>] [--db=<db>]
foil shell [--namespace=<ns>] [--db=<db>]
foil dump [--db=<db>] foil dump [--db=<db>]
foil generate <spec> foil generate <spec>
foil (-h | --help) foil (-h | --help)
@ -40,6 +41,7 @@ struct Args {
cmd_list: bool, cmd_list: bool,
cmd_generate: bool, cmd_generate: bool,
cmd_dump: bool, cmd_dump: bool,
cmd_shell: bool,
flag_db: Option<String>, flag_db: Option<String>,
flag_src: Option<String>, flag_src: Option<String>,
flag_namespace: String, flag_namespace: String,
@ -92,7 +94,7 @@ fn get_master_key(db_conn: &mut db::DbHandle) -> [u8; 32] {
master_key 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() { for note in db_conn.read_notes(master_key).unwrap() {
if note.namespace == namespace && note.category == "account" { if note.namespace == namespace && note.category == "account" {
println!("{}", note.title); 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"); println!("Reading a site from the database");
let host: String = Input::with_theme(&ColorfulTheme::default()) let host: String = Input::with_theme(&ColorfulTheme::default())
.with_prompt("hostname") .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"); println!("Adding a site to the database");
let host: String = Input::with_theme(&ColorfulTheme::default()) let host: String = Input::with_theme(&ColorfulTheme::default())
.with_prompt("hostname") .with_prompt("hostname")
@ -146,7 +148,7 @@ fn set(mut db_conn: db::DbHandle, master_key: [u8; 32], namespace: &str) {
println!("Successfully added password"); 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() { for note in db_conn.read_notes(master_key).unwrap() {
println!("===== note ====="); println!("===== note =====");
println!("namespace: {}", note.namespace); 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<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
pretty_env_logger::init(); pretty_env_logger::init();
let args: Args = Docopt::new(USAGE) let args: Args = Docopt::new(USAGE)
@ -173,13 +206,15 @@ fn main() -> Result<(), Box<dyn Error>> {
let master_key: [u8; 32] = get_master_key(&mut db_conn); let master_key: [u8; 32] = get_master_key(&mut db_conn);
if args.cmd_set { 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 { } 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 { } 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 { } 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(()) Ok(())

Loading…
Cancel
Save