use quokka::{
helper::database::BaseRepository,
state::{CommandHandler, FromState},
};
use crate::{
entity::group::{GroupRepository, UserGroup, UserGroupRepository},
service::user_service::UserService,
};
#[derive(Clone, FromState)]
pub struct AdminCreateCommand {
user_service: UserService,
group_repository: GroupRepository,
user_group_repository: UserGroupRepository,
}
impl CommandHandler for AdminCreateCommand {
fn args() -> clap::Command
where
Self: Sized,
{
clap::Command::new("quokka-admin:user:admin:create")
.arg(clap::arg!(<username> "The name of the admin user"))
.arg(clap::arg!(<email> "The name of the admin user"))
.arg(clap::arg!(--password <password> "The password for the user"))
.arg(clap::arg!(--admin_group <group> "The admin group").default_value("admin"))
}
async fn call(self, args: clap::ArgMatches) -> quokka::Result<()> {
let username = args.get_one::<String>("username").cloned().unwrap();
let email = args.get_one::<String>("email").cloned().unwrap();
let password = args.get_one::<String>("password").cloned();
let admin_group = args.get_one::<String>("admin_group").unwrap();
let password = if let Some(password) = password {
password
} else {
println!("Enter a password for {username}");
let password1 = rpassword::read_password().map_err(quokka::Error::wrap_error(
"Error while reading password",
500,
))?;
println!("Confirm the password");
let password2 = rpassword::read_password().map_err(quokka::Error::wrap_error(
"Error while reading password",
500,
))?;
if password1 == password2 {
password2
} else {
return Err(quokka::Error::new("Passwords not matching"));
}
};
let user = self
.user_service
.register_user(crate::service::user_service::UserRegistration {
username,
password,
email,
})
.await?;
tracing::info!("User {} with id {} added", user.username, user.id);
if let Some(group) = self.group_repository.get_group_by_name(admin_group).await? {
self.user_group_repository
.create_entity(UserGroup {
user_id: user.id,
group_id: group.id,
created_at: time::OffsetDateTime::now_utc(),
updated_at: time::OffsetDateTime::now_utc(),
})
.await?;
tracing::info!("Adding user to group \"admin\"")
} else {
tracing::info!("Admin group missing. User will not be assigned to it.")
}
Ok(())
}
}