Skip to main content

pebble_cms/cli/
user.rs

1use crate::{services::auth, Config, Database};
2use anyhow::Result;
3use std::path::Path;
4
5use super::UserCommand;
6
7pub async fn run(config_path: &Path, command: UserCommand) -> Result<()> {
8    let config = Config::load(config_path)?;
9    let db = Database::open(&config.database.path)?;
10
11    match command {
12        UserCommand::Add {
13            username,
14            email,
15            role,
16            password,
17        } => {
18            let password = match password {
19                Some(p) => p,
20                None => {
21                    let p = rpassword::prompt_password("Password: ")?;
22                    let p_confirm = rpassword::prompt_password("Confirm password: ")?;
23                    if p != p_confirm {
24                        anyhow::bail!("Passwords do not match");
25                    }
26                    p
27                }
28            };
29
30            let role = role.parse().map_err(|_| anyhow::anyhow!("Invalid role"))?;
31            auth::create_user(&db, &username, &email, &password, role)?;
32            tracing::info!("User '{}' created", username);
33        }
34        UserCommand::List => {
35            let conn = db.get()?;
36            let mut stmt = conn.prepare("SELECT username, email, role FROM users")?;
37            let users = stmt.query_map([], |row| {
38                Ok((
39                    row.get::<_, String>(0)?,
40                    row.get::<_, String>(1)?,
41                    row.get::<_, String>(2)?,
42                ))
43            })?;
44
45            println!("{:<20} {:<30} {:<10}", "USERNAME", "EMAIL", "ROLE");
46            println!("{}", "-".repeat(60));
47            for user in users {
48                let (username, email, role) = user?;
49                println!("{:<20} {:<30} {:<10}", username, email, role);
50            }
51        }
52        UserCommand::Remove { username } => {
53            let conn = db.get()?;
54            let affected = conn.execute("DELETE FROM users WHERE username = ?", [&username])?;
55            if affected > 0 {
56                tracing::info!("User '{}' removed", username);
57            } else {
58                tracing::warn!("User '{}' not found", username);
59            }
60        }
61        UserCommand::Passwd { username } => {
62            let password = rpassword::prompt_password("New password: ")?;
63            let password_confirm = rpassword::prompt_password("Confirm password: ")?;
64
65            if password != password_confirm {
66                anyhow::bail!("Passwords do not match");
67            }
68
69            auth::update_password(&db, &username, &password)?;
70            tracing::info!("Password updated for '{}'", username);
71        }
72    }
73
74    Ok(())
75}