use crate::library::user::Session; use crate::library::user::User; use crate::route::to_api; use mongod::Model; use mongodb::bson::doc; use rocket::get; use rocket::http::Status; use rocket::outcome::Outcome; use rocket::post; use rocket::request::FromRequest; use rocket::serde::json::Json; use rocket::Request; use serde::Deserialize; use serde_json::json; use super::api_error; use super::FallibleApiResponse; macro_rules! check_admin { ($u:ident) => { if !$u.is_admin() { return Err(api_error("Forbidden")); } }; } #[rocket::async_trait] impl<'r> FromRequest<'r> for User { type Error = (); async fn from_request(request: &'r Request<'_>) -> rocket::request::Outcome { match request.headers().get_one("token") { Some(key) => { if let Some(session) = Session::find_one(doc! { "token": key}).await { let user = session.user.get().await; Outcome::Success(user) } else { Outcome::Error((Status::Unauthorized, ())) } } None => Outcome::Error((Status::Unauthorized, ())), } } } #[derive(Deserialize)] pub struct LoginData { pub username: String, pub password: String, } #[post("/login", data = "")] pub async fn login_route(login: Json) -> FallibleApiResponse { let (ses, role) = User::login(&login.username, &login.password) .await .ok_or_else(|| api_error("Login failed"))?; Ok(json!({ "token": ses.token, "role": role })) } #[derive(Deserialize)] pub struct PasswdData { pub old: String, pub new: String, } #[post("/passwd", data = "")] pub async fn passwd_route(passwd: Json, mut u: User) -> FallibleApiResponse { u.passwd(&passwd.old, &passwd.new) .await .map_err(|()| api_error("Password change failed"))?; Ok(json!({ "ok": 1 })) } #[get("/users")] pub async fn users_route(u: User) -> FallibleApiResponse { check_admin!(u); let users: Vec<_> = to_api(&User::find(doc! {}, None).await.unwrap()).await; Ok(json!({"users": users})) } #[post("/userCreate", data = "")] pub async fn user_create_route(user: Json, u: User) -> FallibleApiResponse { check_admin!(u); let new_user = User::create( &user.username, &user.password, crate::library::user::UserRole::Regular, ) .await .unwrap(); Ok(json!({"created": new_user._id})) }