353 lines
11 KiB
Rust
353 lines
11 KiB
Rust
// TODO: put back in `src/model/user/mod.rs` once that is cleaned up
|
|
|
|
use super::{AllowedToEditPaymentStatusUser, ManageUserUser, User};
|
|
use crate::model::{family::Family, log::Log, mail::valid_mails, role::Role};
|
|
use chrono::NaiveDate;
|
|
use rocket::{fs::TempFile, tokio::io::AsyncReadExt};
|
|
use sqlx::SqlitePool;
|
|
|
|
impl User {
|
|
pub(crate) async fn update_mail(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_mail: &str,
|
|
) -> Result<(), String> {
|
|
let new_mail = new_mail.trim();
|
|
|
|
if !valid_mails(new_mail) {
|
|
return Err(format!(
|
|
"{new_mail} ist kein gültiges Format für eine Mailadresse"
|
|
));
|
|
}
|
|
|
|
sqlx::query!("UPDATE user SET mail = ? where id = ?", new_mail, self.id)
|
|
.execute(db)
|
|
.await
|
|
.unwrap(); //Okay, because we can only create a User of a valid id
|
|
|
|
let msg = match &self.mail {
|
|
Some(old_mail) => format!(
|
|
"{updated_by} has changed the mail address of {self} from {old_mail} to {new_mail}"
|
|
),
|
|
None => format!("{updated_by} has added a mail address for {self}: {new_mail}"),
|
|
};
|
|
Log::create(db, msg).await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn update_phone(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_phone: &str,
|
|
) {
|
|
let new_phone = new_phone.trim();
|
|
|
|
let query = if new_phone.is_empty() {
|
|
if self.phone.is_none() {
|
|
return; // nothing to do
|
|
}
|
|
sqlx::query!("UPDATE user SET phone = NULL where id = ?", self.id)
|
|
} else {
|
|
if let Some(old_phone) = &self.phone {
|
|
if old_phone == new_phone {
|
|
return; //nothing to do
|
|
}
|
|
}
|
|
sqlx::query!("UPDATE user SET phone = ? where id = ?", new_phone, self.id)
|
|
};
|
|
query.execute(db).await.unwrap(); //Okay, because we can only create a User of a valid id
|
|
|
|
let msg = match &self.phone {
|
|
Some(old_phone) if new_phone.is_empty() => format!("{updated_by} has removed the phone number of {self} (old number: {old_phone})"),
|
|
Some(old_phone) => format!("{updated_by} has changed the phone number of {self} from {old_phone} to {new_phone}"),
|
|
None => format!("{updated_by} has added a phone number for {self}: {new_phone}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
}
|
|
|
|
pub(crate) async fn update_address(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_address: &str,
|
|
) {
|
|
let new_address = new_address.trim();
|
|
|
|
let query = if new_address.is_empty() {
|
|
if !self.address.is_none() {
|
|
return; // nothing to do
|
|
}
|
|
sqlx::query!("UPDATE user SET address = NULL where id = ?", self.id)
|
|
} else {
|
|
if let Some(old_address) = &self.address {
|
|
if old_address == new_address {
|
|
return; //nothing to do
|
|
}
|
|
}
|
|
sqlx::query!(
|
|
"UPDATE user SET address = ? where id = ?",
|
|
new_address,
|
|
self.id
|
|
)
|
|
};
|
|
query.execute(db).await.unwrap(); //Okay, because we can only create a User of a valid id
|
|
|
|
let msg = match &self.address {
|
|
Some(old_address) if new_address.is_empty() => format!("{updated_by} has removed the address of {self} (old address: {old_address})"),
|
|
Some(old_address) => format!("{updated_by} has changed the address of {self} from {old_address} to {new_address}"),
|
|
None => format!("{updated_by} has added an address for {self}: {new_address}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
}
|
|
|
|
pub(crate) async fn update_nickname(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_nickname: &str,
|
|
) -> Result<(), String> {
|
|
let new_nickname = new_nickname.trim();
|
|
|
|
let query = if new_nickname.is_empty() {
|
|
sqlx::query!("UPDATE user SET nickname = NULL where id = ?", self.id)
|
|
} else {
|
|
sqlx::query!(
|
|
"UPDATE user SET nickname = ? where id = ?",
|
|
new_nickname,
|
|
self.id
|
|
)
|
|
};
|
|
query.execute(db).await.unwrap(); //Okay, because we can only create a User of a valid id
|
|
|
|
let msg = match &self.nickname {
|
|
Some(old_nickname) if new_nickname.is_empty() => format!("{updated_by} has removed the nickname of {self} (old nickname: {old_nickname})"),
|
|
Some(old_nickname) => format!("{updated_by} has changed the nickname of {self} from {old_nickname} to {new_nickname}"),
|
|
None => format!("{updated_by} has added a nickname for {self}: {new_nickname}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn update_member_since(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_member_since_date: &NaiveDate,
|
|
) {
|
|
sqlx::query!(
|
|
"UPDATE user SET member_since_date = ? where id = ?",
|
|
new_member_since_date,
|
|
self.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.unwrap(); //Okay, because we can only create a User of a valid id
|
|
|
|
let msg = match &self.member_since_date {
|
|
Some(old_member_since_date) => format!("{updated_by} has changed the member_since date of {self} from {old_member_since_date} to {new_member_since_date}"),
|
|
None => format!("{updated_by} has added a member_since_date for {self}: {new_member_since_date}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
}
|
|
|
|
pub(crate) async fn update_birthdate(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_birthdate: &NaiveDate,
|
|
) {
|
|
sqlx::query!(
|
|
"UPDATE user SET birthdate = ? where id = ?",
|
|
new_birthdate,
|
|
self.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.unwrap(); //Okay, because we can only create a User of a valid id
|
|
|
|
let msg = match &self.birthdate{
|
|
Some(old_birthdate) => format!("{updated_by} has changed the birthdate of {self} from {old_birthdate} to {new_birthdate}"),
|
|
None => format!("{updated_by} has added a birthdate for {self}: {new_birthdate}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
}
|
|
|
|
pub(crate) async fn update_family(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
family: Option<Family>,
|
|
) {
|
|
if let Some(family) = family {
|
|
let family_id = family.id;
|
|
sqlx::query!(
|
|
"UPDATE user SET family_id = ? where id = ?",
|
|
family_id,
|
|
self.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.unwrap();
|
|
} else {
|
|
sqlx::query!("UPDATE user SET family_id = NULL where id = ?", self.id)
|
|
.execute(db)
|
|
.await
|
|
.unwrap();
|
|
};
|
|
|
|
Family::clean_families_without_members(db).await;
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} hat die Familie von {self} aktualisiert."),
|
|
)
|
|
.await;
|
|
}
|
|
|
|
pub(crate) async fn remove_role(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
role: &Role,
|
|
) -> Result<(), String> {
|
|
if !self.has_role(db, &role.name).await {
|
|
return Err(format!("Kann Rolle {role} von User {self} nicht entfernen, da der User die Rolle gar nicht hat"));
|
|
}
|
|
|
|
sqlx::query!(
|
|
"DELETE FROM user_role WHERE user_id = ? and role_id = ?",
|
|
self.id,
|
|
role.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.unwrap();
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} has removed role {role} from user {self}"),
|
|
)
|
|
.await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn has_not_paid(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &AllowedToEditPaymentStatusUser,
|
|
) {
|
|
let paid = Role::find_by_name(db, "paid").await.unwrap();
|
|
|
|
sqlx::query!(
|
|
"DELETE FROM user_role WHERE user_id = ? and role_id = ?",
|
|
self.id,
|
|
paid.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.unwrap();
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} has set that user {self} has NOT paid the fee (yet)"),
|
|
)
|
|
.await;
|
|
}
|
|
pub(crate) async fn has_paid(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &AllowedToEditPaymentStatusUser,
|
|
) {
|
|
let paid = Role::find_by_name(db, "paid").await.unwrap();
|
|
|
|
sqlx::query!(
|
|
"INSERT INTO user_role(user_id, role_id) VALUES (?, ?)",
|
|
self.id,
|
|
paid.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.expect("paid role has no group");
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} has set that user {self} has paid the fee (yet)"),
|
|
)
|
|
.await;
|
|
}
|
|
|
|
pub(crate) async fn add_role(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
role: &Role,
|
|
) -> Result<(), String> {
|
|
if self.has_role(db, &role.name).await {
|
|
return Err(format!("Kann Rolle {role} von User {self} nicht hinzufügen, da der User die Rolle schon hat"));
|
|
}
|
|
|
|
sqlx::query!(
|
|
"INSERT INTO user_role(user_id, role_id) VALUES (?, ?)",
|
|
self.id,
|
|
role.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.map_err(|_| {
|
|
format!(
|
|
"User already has a role in the cluster '{}'",
|
|
role.cluster
|
|
.clone()
|
|
.expect("db trigger can't activate on empty string")
|
|
)
|
|
})?;
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} has added role {role} to user {self}"),
|
|
)
|
|
.await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn add_membership_pdf(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
membership_pdf: &TempFile<'_>,
|
|
) -> Result<(), String> {
|
|
if self.has_membership_pdf(db).await {
|
|
return Err(format!("User {self} hat bereits eine Beitrittserklärung."));
|
|
}
|
|
if membership_pdf.len() == 0 {
|
|
return Err(format!("Keine Beitrittserklärung mitgeschickt."));
|
|
}
|
|
|
|
let mut stream = membership_pdf.open().await.unwrap();
|
|
let mut buffer = Vec::new();
|
|
stream.read_to_end(&mut buffer).await.unwrap();
|
|
sqlx::query!(
|
|
"UPDATE user SET membership_pdf = ? where id = ?",
|
|
buffer,
|
|
self.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.unwrap(); //Okay, because we can only create a User of a valid id
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} has added the membership pdf for user {self}"),
|
|
)
|
|
.await;
|
|
|
|
Ok(())
|
|
}
|
|
}
|