diff --git a/src/model/user.rs b/src/model/user.rs index 5a8c3d8..d2b0cde 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -842,6 +842,43 @@ impl<'r> FromRequest<'r> for DonauLinzUser { } } +#[derive(Debug, Serialize, Deserialize)] +pub struct SchnupperBetreuerUser(pub(crate) User); + +impl From for User { + fn from(val: SchnupperBetreuerUser) -> Self { + val.0 + } +} + +impl Deref for SchnupperBetreuerUser { + type Target = User; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[async_trait] +impl<'r> FromRequest<'r> for SchnupperBetreuerUser { + type Error = LoginError; + + async fn from_request(req: &'r Request<'_>) -> request::Outcome { + let db = req.rocket().state::().unwrap(); + match User::from_request(req).await { + Outcome::Success(user) => { + if user.has_role(db, "schnupper-betreuer").await { + Outcome::Success(SchnupperBetreuerUser(user)) + } else { + Outcome::Forward(Status::Forbidden) + } + } + Outcome::Error(f) => Outcome::Error(f), + Outcome::Forward(f) => Outcome::Forward(f), + } + } +} + #[derive(Debug, Serialize, Deserialize)] pub struct VorstandUser(pub(crate) User); diff --git a/src/tera/admin/mod.rs b/src/tera/admin/mod.rs index 04b23cd..7f3dae4 100644 --- a/src/tera/admin/mod.rs +++ b/src/tera/admin/mod.rs @@ -11,6 +11,7 @@ use crate::{ pub mod boat; pub mod mail; pub mod planned_event; +pub mod schnupper; pub mod user; #[get("/rss?")] @@ -74,6 +75,7 @@ async fn list(db: &State, _admin: AdminUser, list_form: Form Vec { let mut ret = Vec::new(); ret.append(&mut user::routes()); + ret.append(&mut schnupper::routes()); ret.append(&mut boat::routes()); ret.append(&mut mail::routes()); ret.append(&mut planned_event::routes()); diff --git a/src/tera/admin/schnupper.rs b/src/tera/admin/schnupper.rs new file mode 100644 index 0000000..41d536d --- /dev/null +++ b/src/tera/admin/schnupper.rs @@ -0,0 +1,60 @@ +use crate::model::{ + role::Role, + user::{SchnupperBetreuerUser, User, UserWithRoles}, +}; +use futures::future::join_all; +use rocket::{ + get, + http::Status, + request::{FlashMessage, FromRequest, Outcome}, + routes, Request, Route, State, +}; +use rocket_dyn_templates::{tera::Context, Template}; +use sqlx::SqlitePool; + +// Custom request guard to extract the Referer header +struct Referer(String); + +#[rocket::async_trait] +impl<'r> FromRequest<'r> for Referer { + type Error = (); + + async fn from_request(request: &'r Request<'_>) -> Outcome { + match request.headers().get_one("Referer") { + Some(referer) => Outcome::Success(Referer(referer.to_string())), + None => Outcome::Error((Status::BadRequest, ())), + } + } +} + +#[get("/schnupper")] +async fn index( + db: &State, + user: SchnupperBetreuerUser, + flash: Option>, +) -> Template { + let schnupperant = Role::find_by_name(db, "schnupperant").await.unwrap(); + + let user_futures: Vec<_> = User::all_with_role(db, &schnupperant) + .await + .into_iter() + .map(|u| async move { UserWithRoles::from_user(u, db).await }) + .collect(); + let users: Vec = join_all(user_futures).await; + + let mut context = Context::new(); + if let Some(msg) = flash { + context.insert("flash", &msg.into_inner()); + } + context.insert("schnupperanten", &users); + context.insert( + "loggedin_user", + &UserWithRoles::from_user(user.into(), db).await, + ); + + Template::render("admin/schnupper/index", context.into_json()) +} + +pub fn routes() -> Vec { + routes![index] +} diff --git a/templates/admin/schnupper/index.html.tera b/templates/admin/schnupper/index.html.tera new file mode 100644 index 0000000..a3e9d5a --- /dev/null +++ b/templates/admin/schnupper/index.html.tera @@ -0,0 +1,19 @@ +{% import "includes/macros" as macros %} +{% extends "base" %} +{% block content %} +
+ {% if flash %}{{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }}{% endif %} +

Schnupper Verwaltung

+
+ +
+
+{% endblock content %} diff --git a/templates/index.html.tera b/templates/index.html.tera index dec52f8..06c03e7 100644 --- a/templates/index.html.tera +++ b/templates/index.html.tera @@ -79,6 +79,21 @@ {% endif %} + {% if "schnupper-betreuer" in loggedin_user.roles %} +
+ +
+ {% endif %} {% if "Vorstand" in loggedin_user.roles %}