rename folder
@ -4,8 +4,9 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default = ["rowing-tera"]
|
||||
default = ["rowing-tera", "rest"]
|
||||
rowing-tera = ["rocket_dyn_templates", "tera"]
|
||||
rest = []
|
||||
|
||||
[dependencies]
|
||||
rocket = { version = "0.5.0-rc.3", features = ["secrets"]}
|
||||
|
@ -26,5 +26,8 @@ async fn rocket() -> _ {
|
||||
#[cfg(feature = "rowing-tera")]
|
||||
let rocket = tera::config(rocket);
|
||||
|
||||
#[cfg(feature = "rest")]
|
||||
let rocket = rest::config(rocket);
|
||||
|
||||
rocket
|
||||
}
|
||||
|
149
src/rest/mod.rs
Normal file
@ -0,0 +1,149 @@
|
||||
use rocket::{
|
||||
catch, catchers,
|
||||
fairing::AdHoc,
|
||||
fs::FileServer,
|
||||
get,
|
||||
request::FlashMessage,
|
||||
response::{Flash, Redirect},
|
||||
routes, Build, Rocket, State,
|
||||
};
|
||||
use rocket_dyn_templates::{tera::Context, Template};
|
||||
use serde::Deserialize;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
use crate::model::{
|
||||
log::Log,
|
||||
tripdetails::TripDetails,
|
||||
triptype::TripType,
|
||||
user::User,
|
||||
usertrip::{UserTrip, UserTripError},
|
||||
};
|
||||
|
||||
mod admin;
|
||||
mod auth;
|
||||
mod cox;
|
||||
mod misc;
|
||||
|
||||
#[get("/")]
|
||||
async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_>>) -> Template {
|
||||
let mut context = Context::new();
|
||||
|
||||
if user.is_cox || user.is_admin {
|
||||
let triptypes = TripType::all(db).await;
|
||||
context.insert("trip_types", &triptypes);
|
||||
}
|
||||
|
||||
let days = user.get_days(db).await;
|
||||
|
||||
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> {
|
||||
let Some(trip_details) = TripDetails::find_by_id(db, trip_details_id).await else { return Flash::error(Redirect::to("/"), "Trip_details do not exist.") };
|
||||
|
||||
match UserTrip::create(db, &user, &trip_details).await {
|
||||
Ok(_) => {
|
||||
Log::create(
|
||||
db,
|
||||
format!(
|
||||
"User {} registered for trip_details.id={}",
|
||||
user.name, trip_details_id
|
||||
),
|
||||
)
|
||||
.await;
|
||||
Flash::success(Redirect::to("/"), "Erfolgreich angemeldet!")
|
||||
}
|
||||
Err(UserTripError::EventAlreadyFull) => {
|
||||
Flash::error(Redirect::to("/"), "Event bereits ausgebucht!")
|
||||
}
|
||||
Err(UserTripError::AlreadyRegistered) => {
|
||||
Flash::error(Redirect::to("/"), "Du nimmst bereits teil!")
|
||||
}
|
||||
Err(UserTripError::AlreadyRegisteredAsCox) => {
|
||||
Flash::error(Redirect::to("/"), "Du hilfst bereits als Steuerperson aus!")
|
||||
}
|
||||
Err(UserTripError::CantRegisterAtOwnEvent) => Flash::error(
|
||||
Redirect::to("/"),
|
||||
"Du kannst bei einer selbst ausgeschriebenen Fahrt nicht mitrudern ;)",
|
||||
),
|
||||
Err(UserTripError::GuestNotAllowedForThisEvent) => Flash::error(
|
||||
Redirect::to("/"),
|
||||
"Bei dieser Ausfahrt können leider keine Gäste mitfahren.",
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/remove/<trip_details_id>")]
|
||||
async fn remove(db: &State<SqlitePool>, trip_details_id: i64, user: User) -> Flash<Redirect> {
|
||||
let Some(trip_details) = TripDetails::find_by_id(db, trip_details_id).await else {
|
||||
return Flash::error(Redirect::to("/"), "TripDetailsId does not exist");
|
||||
};
|
||||
|
||||
UserTrip::delete(db, &user, &trip_details).await;
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!(
|
||||
"User {} unregistered for trip_details.id={}",
|
||||
user.name, trip_details_id
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
||||
Flash::success(Redirect::to("/"), "Erfolgreich abgemeldet!")
|
||||
}
|
||||
|
||||
#[catch(401)] //unauthorized
|
||||
fn unauthorized_error() -> Redirect {
|
||||
Redirect::to("/auth")
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
pub struct Config {
|
||||
rss_key: String,
|
||||
}
|
||||
|
||||
pub fn config(rocket: Rocket<Build>) -> Rocket<Build> {
|
||||
rocket
|
||||
.mount("/", routes![index, join, remove])
|
||||
.mount("/auth", auth::routes())
|
||||
.mount("/cox", cox::routes())
|
||||
.mount("/admin", admin::routes())
|
||||
.mount("/", misc::routes())
|
||||
.mount("/public", FileServer::from("static/"))
|
||||
.register("/", catchers![unauthorized_error])
|
||||
.attach(Template::fairing())
|
||||
.attach(AdHoc::config::<Config>())
|
||||
}
|
||||
|
||||
//#[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");
|
||||
// }
|
||||
//}
|
0
rot_app/.gitignore → svelte/.gitignore
vendored
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 352 KiB After Width: | Height: | Size: 352 KiB |
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |