|
|
@ -13,20 +13,16 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|
|
|
const CONFIG_PATH: &str = ".rustotpony/db.json";
|
|
|
|
const CONFIG_PATH: &str = ".rustotpony/db.json";
|
|
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
fn main() {
|
|
|
|
Cli::new().run();
|
|
|
|
Cli::run();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct Cli {
|
|
|
|
struct Cli {}
|
|
|
|
app: RusTOTPony<JsonDatabase>,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl Cli {
|
|
|
|
impl Cli {
|
|
|
|
fn new() -> Self {
|
|
|
|
fn app() -> RusTOTPony<JsonDatabase> {
|
|
|
|
let secret = Self::get_secret();
|
|
|
|
let secret = Self::get_secret();
|
|
|
|
let db = JsonDatabase::new(Self::get_database_path(), &secret);
|
|
|
|
let db = JsonDatabase::new(Self::get_database_path(), &secret);
|
|
|
|
Self {
|
|
|
|
RusTOTPony::new(db)
|
|
|
|
app: RusTOTPony::new(db),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn get_secret() -> String {
|
|
|
|
fn get_secret() -> String {
|
|
|
@ -35,35 +31,35 @@ impl Cli {
|
|
|
|
|
|
|
|
|
|
|
|
// fn get_secret_from_storage() -> String { }
|
|
|
|
// fn get_secret_from_storage() -> String { }
|
|
|
|
|
|
|
|
|
|
|
|
fn run(&mut self) {
|
|
|
|
fn run() {
|
|
|
|
match self.get_cli_api_matches().subcommand() {
|
|
|
|
match Self::get_cli_api_matches().subcommand() {
|
|
|
|
("dash", Some(_)) => {
|
|
|
|
("dash", Some(_)) => {
|
|
|
|
self.show_dashboard();
|
|
|
|
Self::show_dashboard();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
("list", Some(_)) => {
|
|
|
|
("list", Some(_)) => {
|
|
|
|
self.show_applications_list(false);
|
|
|
|
Self::show_applications_list(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// ("show-all", Some(_)) => {
|
|
|
|
// ("show-all", Some(_)) => {
|
|
|
|
// self.show_applications_list(true);
|
|
|
|
// Self::show_applications_list(true);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// ("show", Some(sub_app)) => {
|
|
|
|
// ("show", Some(sub_app)) => {
|
|
|
|
// let app_name: &str = sub_app
|
|
|
|
// let app_name: &str = sub_app
|
|
|
|
// .value_of("APPNAME")
|
|
|
|
// .value_of("APPNAME")
|
|
|
|
// .expect("Couldn't read APPNAME for 'show' command");
|
|
|
|
// .expect("Couldn't read APPNAME for 'show' command");
|
|
|
|
// self.show_application(app_name);
|
|
|
|
// Self::show_application(app_name);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
("add", Some(sub_app)) => {
|
|
|
|
("add", Some(sub_app)) => {
|
|
|
|
let app_name: &str = sub_app
|
|
|
|
let app_name: &str = sub_app
|
|
|
|
.value_of("APPNAME")
|
|
|
|
.value_of("APPNAME")
|
|
|
|
.expect("Couldn't read APPNAME for 'add' command");
|
|
|
|
.expect("Couldn't read APPNAME for 'add' command");
|
|
|
|
let key: &str = sub_app.value_of("USERNAME").unwrap_or("");
|
|
|
|
let key: &str = sub_app.value_of("USERNAME").unwrap_or("");
|
|
|
|
self.create_application(app_name, key);
|
|
|
|
Self::create_application(app_name, key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
("delete", Some(sub_app)) => {
|
|
|
|
("delete", Some(sub_app)) => {
|
|
|
|
let app_name: &str = sub_app
|
|
|
|
let app_name: &str = sub_app
|
|
|
|
.value_of("APPNAME")
|
|
|
|
.value_of("APPNAME")
|
|
|
|
.expect("Couldn't read APPNAME for 'delete' command");
|
|
|
|
.expect("Couldn't read APPNAME for 'delete' command");
|
|
|
|
self.delete_application(app_name);
|
|
|
|
Self::delete_application(app_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
("rename", Some(sub_app)) => {
|
|
|
|
("rename", Some(sub_app)) => {
|
|
|
|
let app_name: &str = sub_app
|
|
|
|
let app_name: &str = sub_app
|
|
|
@ -72,18 +68,18 @@ impl Cli {
|
|
|
|
let new_name: &str = sub_app
|
|
|
|
let new_name: &str = sub_app
|
|
|
|
.value_of("NEWNAME")
|
|
|
|
.value_of("NEWNAME")
|
|
|
|
.expect("Couldn't read NEWNAME for 'rename' command");
|
|
|
|
.expect("Couldn't read NEWNAME for 'rename' command");
|
|
|
|
self.rename_application(app_name, new_name);
|
|
|
|
Self::rename_application(app_name, new_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
("eradicate", Some(_)) => {
|
|
|
|
("eradicate", Some(_)) => {
|
|
|
|
self.eradicate_database();
|
|
|
|
Self::eradicate_database();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
_ => {
|
|
|
|
self.show_dashboard();
|
|
|
|
Self::show_dashboard();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn get_cli_api_matches(&self) -> clap::ArgMatches<'static> {
|
|
|
|
fn get_cli_api_matches() -> clap::ArgMatches<'static> {
|
|
|
|
App::new("🐴 RusTOTPony")
|
|
|
|
App::new("🐴 RusTOTPony")
|
|
|
|
.version(env!("CARGO_PKG_VERSION"))
|
|
|
|
.version(env!("CARGO_PKG_VERSION"))
|
|
|
|
.author("German Lashevich <german.lashevich@gmail.com>")
|
|
|
|
.author("German Lashevich <german.lashevich@gmail.com>")
|
|
|
@ -128,8 +124,8 @@ impl Cli {
|
|
|
|
home.join(Path::new(CONFIG_PATH))
|
|
|
|
home.join(Path::new(CONFIG_PATH))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn show_dashboard(&self) {
|
|
|
|
fn show_dashboard() {
|
|
|
|
match self.app.get_applications() {
|
|
|
|
match Self::app().get_applications() {
|
|
|
|
Ok(apps) => {
|
|
|
|
Ok(apps) => {
|
|
|
|
let mut is_first_iteration = true;
|
|
|
|
let mut is_first_iteration = true;
|
|
|
|
let lines_count = apps.len() + 1;
|
|
|
|
let lines_count = apps.len() + 1;
|
|
|
@ -167,11 +163,12 @@ impl Cli {
|
|
|
|
println!("[{:60}]", "=".repeat(idx as usize));
|
|
|
|
println!("[{:60}]", "=".repeat(idx as usize));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn show_applications_list(&self, _: bool) {
|
|
|
|
fn show_applications_list(_: bool) {
|
|
|
|
// TODO Create Table structure with HashMap as follows and metadata about columns - width, titles, names
|
|
|
|
// TODO Create Table structure with HashMap as follows and metadata about columns - width, titles, names
|
|
|
|
|
|
|
|
let app = Self::app();
|
|
|
|
let mut output_table: HashMap<&str, Vec<&str>> = HashMap::new();
|
|
|
|
let mut output_table: HashMap<&str, Vec<&str>> = HashMap::new();
|
|
|
|
let mut applications_count = 0;
|
|
|
|
let mut applications_count = 0;
|
|
|
|
let apps = match self.app.get_applications() {
|
|
|
|
let apps = match app.get_applications() {
|
|
|
|
Ok(v) => v,
|
|
|
|
Ok(v) => v,
|
|
|
|
Err(e) => {
|
|
|
|
Err(e) => {
|
|
|
|
println!("{}", e);
|
|
|
|
println!("{}", e);
|
|
|
@ -238,35 +235,35 @@ impl Cli {
|
|
|
|
println!("{}", header_row_delimiter);
|
|
|
|
println!("{}", header_row_delimiter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn show_application(&self, name: &str) {
|
|
|
|
fn show_application(name: &str) {
|
|
|
|
println!("{:?}", self.app.get_application(name));
|
|
|
|
println!("{:?}", Self::app().get_application(name));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn create_application(&mut self, name: &str, username: &str) {
|
|
|
|
fn create_application(name: &str, username: &str) {
|
|
|
|
let secret = rpassword::prompt_password_stdout("Enter your secret code: ").unwrap();
|
|
|
|
let secret = rpassword::prompt_password_stdout("Enter your secret code: ").unwrap();
|
|
|
|
match self.app.create_application(name, username, &secret) {
|
|
|
|
match Self::app().create_application(name, username, &secret) {
|
|
|
|
Ok(_) => {
|
|
|
|
Ok(_) => {
|
|
|
|
self.app.flush();
|
|
|
|
Self::app().flush();
|
|
|
|
println!("New application created: {}", name)
|
|
|
|
println!("New application created: {}", name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err) => println!("{} Aborting…", err),
|
|
|
|
Err(err) => println!("{} Aborting…", err),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn delete_application(&mut self, name: &str) {
|
|
|
|
fn delete_application(name: &str) {
|
|
|
|
match self.app.delete_application(name) {
|
|
|
|
match Self::app().delete_application(name) {
|
|
|
|
Ok(_) => {
|
|
|
|
Ok(_) => {
|
|
|
|
self.app.flush();
|
|
|
|
Self::app().flush();
|
|
|
|
println!("Application '{}' successfully deleted", name)
|
|
|
|
println!("Application '{}' successfully deleted", name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err) => println!("Couldn't delete application '{}': {}", name, err),
|
|
|
|
Err(err) => println!("Couldn't delete application '{}': {}", name, err),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn rename_application(&mut self, name: &str, newname: &str) {
|
|
|
|
fn rename_application(name: &str, newname: &str) {
|
|
|
|
match self.app.rename_application(name, newname) {
|
|
|
|
match Self::app().rename_application(name, newname) {
|
|
|
|
Ok(_) => {
|
|
|
|
Ok(_) => {
|
|
|
|
self.app.flush();
|
|
|
|
Self::app().flush();
|
|
|
|
println!(
|
|
|
|
println!(
|
|
|
|
"Application '{}' successfully renamed to '{}'",
|
|
|
|
"Application '{}' successfully renamed to '{}'",
|
|
|
|
name, newname
|
|
|
|
name, newname
|
|
|
@ -276,9 +273,9 @@ impl Cli {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn eradicate_database(&mut self) {
|
|
|
|
fn eradicate_database() {
|
|
|
|
self.app.delete_all_applications();
|
|
|
|
Self::app().delete_all_applications();
|
|
|
|
self.app.flush();
|
|
|
|
Self::app().flush();
|
|
|
|
println!("Done.");
|
|
|
|
println!("Done.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|