Compare commits

..

No commits in common. "staging" and "language-improvement" have entirely different histories.

5 changed files with 49 additions and 45 deletions

View File

@ -367,6 +367,7 @@ ORDER BY departure DESC
min_distance: i32,
year: i32,
filter: Filter,
exclude_last_log: bool,
) -> Vec<LogbookWithBoatAndRowers> {
let logs: Vec<Logbook> = sqlx::query_as(
&format!("
@ -398,6 +399,9 @@ ORDER BY departure DESC
}
}
}
if exclude_last_log {
ret.pop();
}
ret
}

View File

@ -1,9 +1,9 @@
use std::{error::Error, fs};
use lettre::{
message::{header::ContentType, Attachment, MultiPart, SinglePart},
transport::smtp::authentication::Credentials,
Address, Message, SmtpTransport, Transport,
message::{Attachment, MultiPart, SinglePart, header::ContentType},
transport::smtp::authentication::Credentials,
};
use sqlx::{Sqlite, SqlitePool, Transaction};
@ -162,7 +162,7 @@ impl Mail {
}
}
if user.has_role(db, "schnupperant").await || user.has_role(db, "scheckbuch").await {
if user.has_role(db, "schnupperant").await {
continue;
}
@ -279,7 +279,7 @@ Der Vorstand");
}
}
if user.has_role(db, "schnupperant").await || user.has_role(db, "scheckbuch").await {
if user.has_role(db, "schnupperant").await {
continue;
}

View File

@ -2,7 +2,7 @@ use std::cmp;
use chrono::{Datelike, Local, NaiveDate};
use serde::Serialize;
use sqlx::{Acquire, Sqlite, SqlitePool, Transaction};
use sqlx::{Sqlite, SqlitePool, Transaction};
use crate::model::{
logbook::{Filter, Logbook, LogbookWithBoatAndRowers},
@ -141,7 +141,11 @@ impl Status {
}
}
pub(crate) async fn for_user_tx(db: &mut Transaction<'_, Sqlite>, user: &User) -> Option<Self> {
pub(crate) async fn for_user_tx(
db: &mut Transaction<'_, Sqlite>,
user: &User,
exclude_last_log: bool,
) -> Option<Self> {
let Ok(agebracket) = AgeBracket::try_from(user) else {
return None;
};
@ -160,6 +164,7 @@ impl Status {
agebracket.required_dist_single_day_in_km(),
year,
Filter::SingleDayOnly,
exclude_last_log,
)
.await;
let multi_day_trips_over_required_distance =
@ -169,6 +174,7 @@ impl Status {
agebracket.required_dist_multi_day_in_km(),
year,
Filter::MultiDayOnly,
exclude_last_log,
)
.await;
@ -189,7 +195,7 @@ impl Status {
pub(crate) async fn for_user(db: &SqlitePool, user: &User) -> Option<Self> {
let mut tx = db.begin().await.unwrap();
let ret = Self::for_user_tx(&mut tx, user).await;
let ret = Self::for_user_tx(&mut tx, user, false).await;
tx.commit().await.unwrap();
ret
}
@ -198,19 +204,11 @@ impl Status {
db: &mut Transaction<'_, Sqlite>,
user: &User,
) -> bool {
if let Some(status) = Self::for_user_tx(db, user).await {
if let Some(status) = Self::for_user_tx(db, user, false).await {
// if user has agebracket...
if status.achieved {
// ... and has achieved the 'Fahrtenabzeichen'
let mut without_last = db.begin().await.unwrap();
let last = Logbook::completed_with_user_tx(&mut without_last, user).await;
let last = last.last().unwrap();
sqlx::query!("DELETE FROM logbook WHERE id=?", last.logbook.id)
.execute(&mut *without_last)
.await
.unwrap(); //Okay, because we can only create a Logbook of a valid id
let without_last_entry = Self::for_user_tx(&mut without_last, user).await.unwrap();
let without_last_entry = Self::for_user_tx(db, user, true).await.unwrap();
if !without_last_entry.achieved {
// ... and this wasn't the case before the last logentry
return true;

View File

@ -1,8 +1,8 @@
use super::User;
use crate::{
model::family::Family, BOAT_STORAGE, DUAL_MEMBERSHIP, EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE,
FAMILY_TWO, FOERDERND, REGULAR, RENNRUDERBEITRAG, SCHECKBUCH, STUDENT_OR_PUPIL, TRIAL_ROWING,
TRIAL_ROWING_REDUCED, UNTERSTUETZEND,
BOAT_STORAGE, DUAL_MEMBERSHIP, EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE, FAMILY_TWO, FOERDERND,
REGULAR, RENNRUDERBEITRAG, STUDENT_OR_PUPIL, TRIAL_ROWING, TRIAL_ROWING_REDUCED,
UNTERSTUETZEND, model::family::Family,
};
use chrono::{Datelike, Local, NaiveDate};
use serde::Serialize;
@ -70,7 +70,6 @@ impl User {
&& !self.has_role(db, "Unterstützend").await
&& !self.has_role(db, "Förderndes Mitglied").await
&& !self.has_role(db, "schnupperant").await
&& !self.has_role(db, "scheckbuch").await
{
return None;
}
@ -111,7 +110,6 @@ impl User {
&& !self.has_role(db, "Unterstützend").await
&& !self.has_role(db, "Förderndes Mitglied").await
&& !self.has_role(db, "schnupperant").await
&& !self.has_role(db, "scheckbuch").await
{
return fee;
}
@ -164,8 +162,6 @@ impl User {
} else {
fee.add("Schnupperkurs".into(), TRIAL_ROWING);
}
} else if self.has_role(db, "scheckbuch").await {
fee.add("Scheckbuch".into(), SCHECKBUCH);
} else if self.has_role(db, "Unterstützend").await {
fee.add("Unterstützendes Mitglied".into(), UNTERSTUETZEND);
} else if self.has_role(db, "Förderndes Mitglied").await {

View File

@ -1,20 +1,21 @@
use std::{fmt::Display, ops::DerefMut};
use argon2::{password_hash::SaltString, Argon2, PasswordHasher};
use argon2::{Argon2, PasswordHasher, password_hash::SaltString};
use chrono::{Datelike, Local, NaiveDate};
use log::info;
use rocket::async_trait;
use rocket::{
Request,
http::{Cookie, Status},
request::{FromRequest, Outcome},
time::{Duration, OffsetDateTime},
Request,
};
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
use super::activity::{ActivityBuilder, ReasonAuth};
use super::{
Day,
log::Log,
logbook::Logbook,
mail::Mail,
@ -23,7 +24,6 @@ use super::{
role::Role,
stat::Stat,
tripdetails::TripDetails,
Day,
};
use crate::AMOUNT_DAYS_TO_SHOW_TRIPS_AHEAD;
use scheckbuch::ScheckbuchUser;
@ -487,7 +487,7 @@ ASKÖ Ruderverein Donau Linz", self.name),
.save(db)
.await;
return Err(LoginError::InvalidAuthenticationCombo); //User existed sometime ago; has
//been deleted
//been deleted
}
if let Some(user_pw) = user.pw.as_ref() {
@ -590,9 +590,9 @@ ASKÖ Ruderverein Donau Linz", self.name),
pub(crate) async fn amount_days_to_show(&self, db: &SqlitePool) -> i64 {
if self.allowed_to_steer(db).await {
let end_of_year = NaiveDate::from_ymd_opt(Local::now().year(), 12, 31).unwrap(); //Ok,
//december
//has 31
//days
//december
//has 31
//days
let days_left_in_year = end_of_year
.signed_duration_since(Local::now().date_naive())
.num_days()
@ -601,9 +601,9 @@ ASKÖ Ruderverein Donau Linz", self.name),
if days_left_in_year <= 31 {
let end_of_next_year =
NaiveDate::from_ymd_opt(Local::now().year() + 1, 12, 31).unwrap(); //Ok,
//december
//has 31
//days
//december
//has 31
//days
end_of_next_year
.signed_duration_since(Local::now().date_naive())
.num_days()
@ -835,8 +835,8 @@ special_user!(SteeringUser, +"cox", +"Bootsführer");
special_user!(AdminUser, +"admin");
special_user!(AllowedForPlannedTripsUser, +"Donau Linz", +"scheckbuch", +"Förderndes Mitglied");
special_user!(DonauLinzUser, +"Donau Linz", -"Unterstützend", -"Förderndes Mitglied"); // TODO:
// remove ->
// RegularUser
// remove ->
// RegularUser
special_user!(SchnupperBetreuerUser, +"schnupper-betreuer");
special_user!(VorstandUser, +"admin", +"Vorstand");
special_user!(EventUser, +"manage_events");
@ -950,17 +950,21 @@ mod test {
#[sqlx::test]
fn wrong_pw() {
let pool = testdb!();
assert!(User::login(&pool, "admin".into(), "admi".into())
.await
.is_err());
assert!(
User::login(&pool, "admin".into(), "admi".into())
.await
.is_err()
);
}
#[sqlx::test]
fn wrong_username() {
let pool = testdb!();
assert!(User::login(&pool, "admi".into(), "admin".into())
.await
.is_err());
assert!(
User::login(&pool, "admi".into(), "admin".into())
.await
.is_err()
);
}
#[sqlx::test]
@ -980,9 +984,11 @@ mod test {
let pool = testdb!();
let user = User::find_by_id(&pool, 1).await.unwrap();
assert!(User::login(&pool, "admin".into(), "abc".into())
.await
.is_err());
assert!(
User::login(&pool, "admin".into(), "abc".into())
.await
.is_err()
);
user.update_pw(&pool, "abc".into()).await;