hacky-ruadat/src/rest/restreg.rs
2023-03-14 17:09:12 +01:00

136 lines
3.9 KiB
Rust

use rocket::{
form::Form,
response::{Flash, Redirect},
Route, State,
};
use sea_orm::{ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, Set};
use crate::models::{day, trip, user};
use super::NaiveDateForm;
#[derive(FromForm)]
struct RegisterForm {
day: NaiveDateForm,
#[field(validate = len(3..))]
name: String,
time: Option<String>,
cox_id: Option<i32>,
}
#[put("/", data = "<register>")]
async fn register(
db: &State<DatabaseConnection>,
register: Form<RegisterForm>,
user: user::Model,
) -> Flash<Redirect> {
let day = day::Entity::find_by_id(*register.day)
.one(db.inner())
.await
.unwrap()
.expect("There's no trip on this date (yet)");
if register.cox_id.is_none() && !day.open_registration {
log::error!("{} tried to register, even though the user it should not be possible to do so via UI -> manually crafted request?", user.name);
return Flash::error(
Redirect::to("/"),
"Don't (try to ;)) abuse this system! Incident has been reported...",
);
}
if let Some(cox_id) = register.cox_id {
let trip = trip::Entity::find_by_id(cox_id)
.one(db.inner())
.await
.unwrap()
.unwrap();
if trip.user_id == user.id {
log::warn!(
"{} tried to register for his own trip ({})",
user.name,
trip.id
);
return Flash::error(
Redirect::to("/"),
"Du kannst an deinen eigenen Ausfahrten nicht teilnehmen...",
);
}
}
let user = user::Model::find_or_create_user(&register.name, db.inner()).await;
let day = format!("{}", day.day.format("%Y-%m-%d"));
let trip = trip::ActiveModel {
day: Set(day.clone()),
user_id: Set(user.id),
begin: Set(register.time.clone()),
cox_id: Set(register.cox_id.clone()),
..Default::default()
};
match trip.insert(db.inner()).await {
Ok(_) => {
log::info!("{} registered for {:?}", user.name, day);
Flash::success(Redirect::to("/"), "Erfolgreich angemeldet!")
}
Err(_) => {
log::warn!(
"{} tried to register for {:?}, but is already registered",
user.name,
day
);
Flash::error(Redirect::to("/"), "Du bist bereits angemeldet")
}
}
}
#[derive(FromForm)]
struct DeleteForm {
id: i32,
}
#[delete("/", data = "<delete>")]
async fn delete(
db: &State<DatabaseConnection>,
delete: Form<DeleteForm>,
user: user::Model,
) -> Flash<Redirect> {
let trip = trip::Entity::find_by_id(delete.id)
.one(db.inner())
.await
.unwrap();
match trip {
None => {
log::error!("Tried to delete registration of non-existing trip (prob. hand crafted request (user.name = {})", user.name);
return Flash::error(Redirect::to("/"), "Du bist gar nicht angemeldet!");
}
Some(trip) => {
if trip.user_id != user.id {
log::error!(
"{} tried to delete a registration from user_id {} (probably hand-crafted request)",
user.name,
delete.id
);
return Flash::error(
Redirect::to("/"),
"Du kannst nur deine eigenen Anmeldungen löschen!",
);
}
log::info!("User {} deleted the registration for {:?}", user.name, trip);
trip::Entity::delete(trip::ActiveModel {
id: Set(trip.id),
..Default::default()
})
.exec(db.inner())
.await
.unwrap();
}
}
Flash::success(Redirect::to("/"), "Abmeldung erfolgreich")
}
pub fn routes() -> Vec<Route> {
routes![register, delete]
}