use std::str::FromStr; use actix::Addr; use actix_http::error::ResponseError; use actix_identity::Identity; use actix_web::{http::header, web, HttpResponse}; use askama::Template; use serde::Deserialize; use crate::error::ServiceError; use crate::model::{DbExecutor, NewUser}; use crate::util::UserRequest; use crate::Secret; pub mod user_creation; use user_creation::{PassHashExecutor, PassHashRequest, SaveUserRequest}; #[derive(Template)] #[template(path = "admin.htm")] struct AdminTemplate; pub async fn index(ident: Identity, db: web::Data>) -> HttpResponse { if let Some(name) = ident.identity() { ident.remember(name.clone()); let user = match db.send(UserRequest(name.clone())).await.unwrap() { Ok(v) => v, Err(_) => { ident.forget(); return HttpResponse::Found() .header(header::LOCATION, "/login") .finish(); } }; if user.power_level != 9001 { return ServiceError::Unauthorized.error_response(); } let page = AdminTemplate.render().unwrap(); HttpResponse::Ok().content_type("text/html").body(page) } else { HttpResponse::Found() .header(header::LOCATION, "/user/login") .finish() } } #[derive(Deserialize, Debug)] #[serde(rename_all = "kebab-case")] pub struct UserData { pub user: String, pub balance: String, pub password: String, } pub async fn create_user( ident: Identity, params: web::Form, db: web::Data>, hasher: web::Data>, sec: web::Data, ) -> HttpResponse { if let Some(name) = ident.identity() { ident.remember(name.clone()); let user = match db.send(UserRequest(name.clone())).await.unwrap() { Ok(v) => v, Err(_) => { ident.forget(); return HttpResponse::Found() .header(header::LOCATION, "/login") .finish(); } }; if user.power_level != 9001 { return ServiceError::Unauthorized.error_response(); } let new_login = params.into_inner(); let balance = match u64::from_str(&new_login.balance) { Ok(v) => v, Err(e) => { return HttpResponse::Ok() .content_type("text/html") .body(e.to_string()) } }; let hash = hasher .send(PassHashRequest::new(new_login.password, sec.0.clone())) .await .unwrap() .unwrap(); let new_user = NewUser { name: new_login.user, // TODO Let the admin pick power_level: 0, balance: balance, }; db.send(SaveUserRequest::new(new_user, hash)) .await .unwrap() .unwrap(); HttpResponse::Found() .header(header::LOCATION, "/admin") .finish() } else { HttpResponse::Found() .header(header::LOCATION, "/login") .finish() } }