synthwave/src/route/user.rs
2024-08-12 18:48:33 +02:00

103 lines
2.5 KiB
Rust

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<Self, Self::Error> {
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 = "<login>")]
pub async fn login_route(login: Json<LoginData>) -> 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 = "<passwd>")]
pub async fn passwd_route(passwd: Json<PasswdData>, 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 = "<user>")]
pub async fn user_create_route(user: Json<LoginData>, 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}))
}