extern crate docopt;
extern crate rpassword;
use docopt::Docopt;
use zeroize::Zeroize;
use rs_password_utils::{dice, pwned};
use std::str::FromStr;
const USAGE: &'static str = "
Password utilities, written in Rust.
Usage:
rs-password-utils pwned
rs-password-utils dice [(-w <count>)]
rs-password-utils [-h]
Options:
-w --words The amount of words that should comprise the passphrase
-h --help Show this screen.
";
#[tokio::main]
async fn main() -> Result<(), rs_password_utils::PasswordUtilsError> {
let args = Docopt::new(USAGE)
.and_then(|dopt| dopt.parse())
.unwrap_or_else(|e| e.exit());
if args.find("pwned").unwrap().as_bool() {
println!("Please type a password and press enter.");
let mut pass = rpassword::read_password()?;
pwned::check_pwned(&pass).await.map(|pwned_response| {
match pwned_response {
pwned::PwnedResponse::Ok => println!("The password is not found among leaked passwords."),
pwned::PwnedResponse::Pwned(times) => println!("The password is leaked!!! It was found in {} breaches. Stop using it and replace it with another one!", times)
}
})?;
pass.zeroize();
} else if args.find("dice").unwrap().as_bool() {
let arg_w = args.find("-w");
let arg_words = args.find("--words");
let usize_arg: usize = if (arg_w.is_some() && arg_w.unwrap().as_bool()) ||
(arg_words.is_some() && arg_words.unwrap().as_bool()) {
let arg = args.get_str("<count>");
FromStr::from_str(arg)?
} else {
6
};
let mut pass = dice::generate(usize_arg);
println!("{}", pass);
pass.zeroize();
}
Ok(())
}