2023-04-04 15:16:21 +02:00
|
|
|
use chrono::{Duration, Local};
|
|
|
|
use rocket::{
|
|
|
|
catch, catchers, get,
|
|
|
|
request::FlashMessage,
|
|
|
|
response::{Flash, Redirect},
|
|
|
|
routes, Build, Rocket, State,
|
|
|
|
};
|
|
|
|
use rocket_dyn_templates::{context, tera::Context, Template};
|
2023-04-03 16:11:26 +02:00
|
|
|
use sqlx::SqlitePool;
|
|
|
|
|
2023-04-04 15:16:21 +02:00
|
|
|
use crate::model::{planned_event::PlannedEvent, user::User, usertrip::UserTrip, Day};
|
2023-04-03 22:03:45 +02:00
|
|
|
|
2023-04-04 10:44:14 +02:00
|
|
|
mod admin;
|
2023-04-03 16:11:26 +02:00
|
|
|
mod auth;
|
2023-04-04 15:16:21 +02:00
|
|
|
mod cox;
|
2023-03-26 14:40:56 +02:00
|
|
|
|
|
|
|
#[get("/")]
|
2023-04-04 15:16:21 +02:00
|
|
|
async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_>>) -> Template {
|
2023-04-04 12:19:56 +02:00
|
|
|
let mut days = Vec::new();
|
|
|
|
for i in 0..6 {
|
|
|
|
let date = (Local::now() + Duration::days(i)).date_naive();
|
|
|
|
days.push(Day::new(db, date).await);
|
|
|
|
}
|
2023-04-04 15:16:21 +02:00
|
|
|
|
|
|
|
let mut context = Context::new();
|
|
|
|
|
|
|
|
if let Some(msg) = flash {
|
|
|
|
context.insert("flash", &msg.into_inner());
|
|
|
|
}
|
|
|
|
context.insert("loggedin_user", &user);
|
|
|
|
context.insert("days", &days);
|
|
|
|
Template::render("index", context.into_json())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/join/<trip_details_id>")]
|
|
|
|
async fn join(db: &State<SqlitePool>, trip_details_id: i64, user: User) -> Flash<Redirect> {
|
|
|
|
if !PlannedEvent::rower_can_register(db, trip_details_id).await {
|
|
|
|
return Flash::error(Redirect::to("/"), "Bereits ausgebucht!");
|
|
|
|
}
|
|
|
|
|
|
|
|
if UserTrip::new(db, user.id, trip_details_id).await {
|
|
|
|
Flash::success(Redirect::to("/"), "Erfolgreich angemeldet!")
|
|
|
|
} else {
|
|
|
|
Flash::error(Redirect::to("/"), "Du nimmst bereits teil!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/remove/<trip_details_id>")]
|
|
|
|
async fn remove(db: &State<SqlitePool>, trip_details_id: i64, user: User) -> Flash<Redirect> {
|
|
|
|
//TODO: Check if > 2 hrs to event
|
|
|
|
|
|
|
|
UserTrip::delete(db, user.id, trip_details_id).await;
|
|
|
|
|
|
|
|
Flash::success(Redirect::to("/"), "Erfolgreich abgemeldet!")
|
2023-03-26 14:40:56 +02:00
|
|
|
}
|
|
|
|
|
2023-04-03 22:03:45 +02:00
|
|
|
#[catch(401)] //unauthorized
|
|
|
|
fn unauthorized_error() -> Redirect {
|
|
|
|
Redirect::to("/auth")
|
|
|
|
}
|
|
|
|
|
2023-04-03 16:11:26 +02:00
|
|
|
pub fn start(db: SqlitePool) -> Rocket<Build> {
|
2023-03-26 16:58:45 +02:00
|
|
|
rocket::build()
|
2023-04-03 16:11:26 +02:00
|
|
|
.manage(db)
|
2023-04-04 15:16:21 +02:00
|
|
|
.mount("/", routes![index, join, remove])
|
2023-04-03 16:11:26 +02:00
|
|
|
.mount("/auth", auth::routes())
|
2023-04-04 15:16:21 +02:00
|
|
|
.mount("/cox", cox::routes())
|
2023-04-04 10:44:14 +02:00
|
|
|
.mount("/admin", admin::routes())
|
2023-04-03 22:03:45 +02:00
|
|
|
.register("/", catchers![unauthorized_error])
|
2023-03-26 16:58:45 +02:00
|
|
|
.attach(Template::fairing())
|
2023-03-26 14:40:56 +02:00
|
|
|
}
|
|
|
|
|
2023-04-03 22:03:45 +02:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use crate::testdb;
|
|
|
|
|
|
|
|
use super::start;
|
|
|
|
use rocket::http::Status;
|
|
|
|
use rocket::local::asynchronous::Client;
|
|
|
|
use rocket::uri;
|
|
|
|
use sqlx::SqlitePool;
|
|
|
|
|
|
|
|
#[sqlx::test]
|
|
|
|
fn test_not_logged_in() {
|
|
|
|
let pool = testdb!();
|
|
|
|
|
|
|
|
let client = Client::tracked(start(pool))
|
|
|
|
.await
|
|
|
|
.expect("valid rocket instance");
|
|
|
|
let response = client.get(uri!(super::index)).dispatch().await;
|
|
|
|
|
|
|
|
assert_eq!(response.status(), Status::SeeOther);
|
|
|
|
let location = response.headers().get("Location").next().unwrap();
|
|
|
|
assert_eq!(location, "/auth");
|
|
|
|
}
|
|
|
|
}
|