diff --git a/src/backend.rs b/src/backend.rs index 351718b..2b18e2f 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -82,7 +82,7 @@ impl Backend { ))?; statement.next()?; - let raw_hash = &statement.read::("password").unwrap(); + let raw_hash = &statement.read::("password")?; let hash = PasswordHash::new(raw_hash) .map_err(|_| anyhow::Error::msg("Failed to parse the password hash"))?; @@ -114,10 +114,23 @@ impl Backend { username ))?; - info!("Deleted `{}`)", username); + info!("Deleted `{}`", username); Ok(Response::Delete(ResponseDelete::Success)) } + pub fn list(&mut self) -> Result { + let mut list = Vec::new(); + for row in self.db.prepare(format!( + "SELECT username FROM Accounts;", + ))? + .iter() + .map(|row| row.unwrap()) { + list.push(row.read::<&str, _>("username").to_string()); + } + + Ok(Response::List(list)) + } + pub fn new(database: &std::path::Path) -> Result { let conn = sqlite::open(database)?; diff --git a/src/call.rs b/src/call.rs index cbe8f23..28139c0 100644 --- a/src/call.rs +++ b/src/call.rs @@ -9,6 +9,7 @@ pub enum Call { Register(String, String), Authenticate(String, String), Delete(String), + List, } #[derive(Debug)] @@ -38,6 +39,7 @@ pub enum Response { Register(ResponseRegister), Authenticate(ResponseAuthenticate), Delete(ResponseDelete), + List(Vec), } impl Call { @@ -46,6 +48,7 @@ impl Call { Self::Register(username, password) => backend.register(username, password), Self::Authenticate(username, password) => backend.authenticate(username, password), Self::Delete(username) => backend.delete(username), + Self::List => backend.list(), } } } diff --git a/src/main.rs b/src/main.rs index cd83a4f..90d4b00 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ mod backend; mod call; use anyhow::Result; -use call::Call; +use call::{Call, Response}; use clap::Parser; use log::info; use std::path::{Path, PathBuf}; @@ -20,6 +20,10 @@ struct Args { #[arg(short = 'D', long)] daemon: bool, + /// List all accounts + #[arg(short, long)] + list: bool, + /// Delete one or multiple account(s) #[arg(short, long, use_value_delimiter = true, value_delimiter = ',')] deletions: Option>, @@ -30,6 +34,12 @@ async fn main() -> Result<()> { env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init(); let args = Args::parse(); + if args.deletions == None && + !args.daemon && + !args.list { + return Err(anyhow::Error::msg("Nothing to do. run `baseauth --help` for a list of commands")); + } + if let Some(dir) = args.dir { std::env::set_current_dir(dir)?; } @@ -39,6 +49,22 @@ async fn main() -> Result<()> { let backend = backend::Backend::new(&Path::new("db.sqlite"))?; let tx = call::start_worker(backend).await?; + if args.list { + let (oneshot_tx, oneshot_rx) = oneshot::channel(); + tx.send((Call::List, oneshot_tx)).await?; + + if let Response::List(list) = oneshot_rx.await?? { + if list.len() > 0 { + println!("Registered accounts:"); + for user in list.iter() { + println!(" * {}", user); + } + } else { + println!("There are no accounts registered"); + } + }; + } + if let Some(d) = &args.deletions { for username in d.iter() { let (oneshot_tx, oneshot_rx) = oneshot::channel(); @@ -48,12 +74,10 @@ async fn main() -> Result<()> { let _ = oneshot_rx.await??; } } - + if args.daemon { api::start_worker(8080, tx).await?; loop {} - } else if args.deletions == None { - println!("Nothing to do. run `baseauth --help` for a list of commands"); } Ok(())