diff --git a/src/cli.rs b/src/cli.rs index f3b38bf..dba9afa 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -39,7 +39,7 @@ pub enum Subcommands { #[derive(Args)] pub struct UserCmd { #[command(subcommand)] - cmd: UserSubCmd, + pub cmd: UserSubCmd, } #[derive(Subcommand)] diff --git a/src/db/user.rs b/src/db/user.rs index 5b25f90..47ae42e 100644 --- a/src/db/user.rs +++ b/src/db/user.rs @@ -51,6 +51,22 @@ impl User { .verify_password(password.as_ref().as_bytes(), &password_hash) .is_ok() } + + pub fn all(pool: &DbPool) -> Result, DbError> { + let conn = pool.get()?; + + let mut stmt = conn.prepare("select * from users")?; + let users: Result, _> = stmt.query_map((), Self::from_row)?.collect(); + + Ok(users?) + } + + pub fn remove_by_username(pool: &DbPool, username: impl AsRef) -> Result { + let conn = pool.get()?; + let mut stmt = conn.prepare("delete from users where username = $1")?; + + Ok(stmt.execute((username.as_ref(),))? > 0) + } } fn hash_password(password: impl AsRef) -> String { diff --git a/src/main.rs b/src/main.rs index a989bb0..1ac2fb1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,36 @@ pub struct Context { } fn run_user_cli(data_dir: impl AsRef, cmd: UserCmd) -> Result<(), DbError> { + let manager = SqliteConnectionManager::file(data_dir.as_ref().join(DB_FILENAME)); + let pool = r2d2::Pool::new(manager)?; + + match cmd.cmd { + cli::UserSubCmd::List => { + let users = db::User::all(&pool)?; + + println!("id\tusername\tis admin"); + + for user in users { + println!("{}\t{}\t{}", user.id, user.username, user.admin); + } + } + cli::UserSubCmd::Add { + username, + password, + admin, + } => { + db::NewUser { + username, + password, + admin, + } + .insert(&pool)?; + } + cli::UserSubCmd::Remove { username } => { + db::User::remove_by_username(&pool, &username)?; + } + } + Ok(()) }