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 |