allow moving scheckbuch -> regular

This commit is contained in:
2025-05-03 12:27:02 +02:00
parent c47b1988b2
commit 9aab07422d
8 changed files with 228 additions and 127 deletions

View File

@ -1,15 +1,12 @@
use std::{
fmt::Display,
ops::{Deref, DerefMut},
};
use std::{fmt::Display, ops::DerefMut};
use argon2::{password_hash::SaltString, Argon2, PasswordHasher};
use chrono::{Datelike, Local, NaiveDate};
use log::info;
use rocket::async_trait;
use rocket::{
async_trait,
http::{Cookie, Status},
request::{self, FromRequest, Outcome},
request::{FromRequest, Outcome},
time::{Duration, OffsetDateTime},
tokio::io::AsyncReadExt,
Request,
@ -35,6 +32,7 @@ use scheckbuch::ScheckbuchUser;
mod basic;
mod fee;
pub(crate) mod member;
pub(crate) mod regular;
pub(crate) mod scheckbuch;
#[derive(FromRow, Serialize, Deserialize, Clone, Debug, Eq, Hash, PartialEq)]
@ -119,10 +117,7 @@ impl User {
));
};
if self.has_role(db, "Donau Linz").await {
self.send_welcome_mail_full_member(db, mail, smtp_pw)
.await?;
} else if self.has_role(db, "schnupperant").await {
if self.has_role(db, "schnupperant").await {
self.send_welcome_mail_schnupper(db, mail, smtp_pw).await?;
} else if let Some(scheckbuch) = ScheckbuchUser::new(db, self).await {
scheckbuch.notify(db, mail, smtp_pw).await?;
@ -182,57 +177,6 @@ ASKÖ Ruderverein Donau Linz", self.name),
Ok(())
}
async fn send_welcome_mail_full_member(
&self,
db: &SqlitePool,
mail: &str,
smtp_pw: &str,
) -> Result<(), String> {
// 2 things to do:
// 1. Send mail to user
Mail::send_single(
db,
mail,
"Willkommen im ASKÖ Ruderverein Donau Linz!",
format!(
"Hallo {0},
herzlich willkommen im ASKÖ Ruderverein Donau Linz! Wir freuen uns sehr, dich als neues Mitglied in unserem Verein begrüßen zu dürfen.
Um dir den Einstieg zu erleichtern, findest du in unserem Handbuch alle wichtigen Informationen über unseren Verein: https://rudernlinz.at/book. Bei weiteren Fragen stehen dir die Adressen info@rudernlinz.at (für allgemeine Fragen) und it@rudernlinz.at (bei technischen Fragen) jederzeit zur Verfügung.
Du kannst auch gerne unserer Signal-Gruppe beitreten, um auf dem Laufenden zu bleiben und dich mit anderen Mitgliedern auszutauschen: https://signal.group/#CjQKICFrq6zSsRHxrucS3jEcQn6lknEXacAykwwLV3vNLKxPEhA17jxz7cpjfu3JZokLq1TH
Für die Organisation unserer Ausfahrten nutzen wir app.rudernlinz.at. Logge dich einfach mit deinem Namen ('{0}' ohne Anführungszeichen) ein, beim ersten Mal kannst du das Passwortfeld leer lassen. Unter 'Geplante Ausfahrten' kannst du dich jederzeit zu den Ausfahrten anmelden.
Beim nächsten Treffen im Verein, erinnere jemand vom Vorstand (https://rudernlinz.at/unser-verein/vorstand/) bitte daran, deinen Fingerabdruck zu registrieren, damit du Zugang zum Bootshaus erhältst.
Damit du dich noch mehr verbunden fühlst (:-)), haben wir im Bootshaus ein WLAN für Vereinsmitglieder 'ASKÖ Ruderverein Donau Linz' eingerichtet. Das Passwort dafür lautet 'donau1921' (ohne Anführungszeichen). Bitte gib das Passwort an keine vereinsfremden Personen weiter.
Wir freuen uns darauf, dich bald am Wasser zu sehen und gemeinsam tolle Erfahrungen zu sammeln!
Riemen- & Dollenbruch
ASKÖ Ruderverein Donau Linz", self.name),
smtp_pw,
).await?;
// 2. Notify all coxes
Notification::create_for_steering_people(
db,
&format!(
"Liebe Steuerberechtigte, seit {} gibt es ein neues Mitglied: {}",
self.member_since_date.clone().unwrap(),
self.name
),
"Neues Vereinsmitglied",
None,
None,
)
.await;
Ok(())
}
pub async fn amount_boats(&self, db: &SqlitePool) -> i64 {
sqlx::query!(
"SELECT COUNT(*) as count FROM boat WHERE owner = ?",
@ -904,7 +848,7 @@ ASKÖ Ruderverein Donau Linz", self.name),
impl<'r> FromRequest<'r> for User {
type Error = LoginError;
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
async fn from_request(req: &'r Request<'_>) -> rocket::request::Outcome<Self, Self::Error> {
match req.cookies().get_private("loggedin_user") {
Some(user_id) => match user_id.value().parse::<i32>() {
Ok(user_id) => {
@ -939,7 +883,7 @@ macro_rules! special_user {
pub(crate) user: User,
}
impl Deref for $name {
impl std::ops::Deref for $name {
type Target = User;
fn deref(&self) -> &Self::Target {
&self.user
@ -953,20 +897,20 @@ macro_rules! special_user {
}
#[async_trait]
impl<'r> FromRequest<'r> for $name {
type Error = LoginError;
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
impl<'r> rocket::request::FromRequest<'r> for $name {
type Error = crate::model::user::LoginError;
async fn from_request(req: &'r rocket::request::Request<'_>) -> rocket::request::Outcome<Self, Self::Error> {
let db = req.rocket().state::<SqlitePool>().unwrap();
match User::from_request(req).await {
Outcome::Success(user) => {
rocket::request::Outcome::Success(user) => {
if special_user!(@check_roles user, db, $($role)*) {
Outcome::Success($name { user })
rocket::request::Outcome::Success($name { user })
} else {
Outcome::Forward(Status::Forbidden)
rocket::request::Outcome::Forward(rocket::http::Status::Forbidden)
}
}
Outcome::Error(f) => Outcome::Error(f),
Outcome::Forward(f) => Outcome::Forward(f),
rocket::request::Outcome::Error(f) => rocket::request::Outcome::Error(f),
rocket::request::Outcome::Forward(f) => rocket::request::Outcome::Forward(f),
}
}
}