user-role-cluster (#760)
All checks were successful
CI/CD Pipeline / test (push) Successful in 11m2s
CI/CD Pipeline / deploy-staging (push) Successful in 8m0s
CI/CD Pipeline / deploy-main (push) Has been skipped

Reviewed-on: #760
This commit is contained in:
2024-10-11 11:20:58 +02:00
parent aca4fc82e4
commit bdde326f03
10 changed files with 199 additions and 32 deletions

View File

@ -490,6 +490,17 @@ ASKÖ Ruderverein Donau Linz", self.name),
_ => true,
}
}
pub async fn has_membership_pdf_tx(&self, db: &mut Transaction<'_, Sqlite>) -> bool {
match sqlx::query_scalar!("SELECT membership_pdf FROM user WHERE id = ?", self.id)
.fetch_one(db.deref_mut())
.await
.unwrap()
{
Some(a) if a.is_empty() => false,
None => false,
_ => true,
}
}
pub async fn roles(&self, db: &SqlitePool) -> Vec<String> {
sqlx::query!(
@ -502,6 +513,21 @@ ASKÖ Ruderverein Donau Linz", self.name),
.into_iter().map(|r| r.name).collect()
}
pub async fn real_roles(&self, db: &SqlitePool) -> Vec<Role> {
sqlx::query_as!(
Role,
"SELECT r.id, r.name, r.cluster
FROM role r
JOIN user_role ur ON r.id = ur.role_id
JOIN user u ON u.id = ur.user_id
WHERE ur.user_id = ? AND u.deleted = 0;",
self.id
)
.fetch_all(db)
.await
.unwrap()
}
pub async fn has_role_tx(&self, db: &mut Transaction<'_, Sqlite>, role: &str) -> bool {
if sqlx::query!(
"SELECT * FROM user_role WHERE user_id=? AND role_id = (SELECT id FROM role WHERE name = ?)",
@ -697,14 +723,16 @@ ORDER BY last_access DESC
.is_ok()
}
pub async fn update(&self, db: &SqlitePool, data: UserEditForm<'_>) {
pub async fn update(&self, db: &SqlitePool, data: UserEditForm<'_>) -> Result<(), String> {
let mut db = db.begin().await.map_err(|e| e.to_string())?;
let mut family_id = data.family_id;
if family_id.is_some_and(|x| x == -1) {
family_id = Some(Family::insert(db).await)
family_id = Some(Family::insert_tx(&mut db).await)
}
if !self.has_membership_pdf(db).await {
if !self.has_membership_pdf_tx(&mut db).await {
if let Some(membership_pdf) = data.membership_pdf {
let mut stream = membership_pdf.open().await.unwrap();
let mut buffer = Vec::new();
@ -714,7 +742,7 @@ ORDER BY last_access DESC
buffer,
self.id
)
.execute(db)
.execute(db.deref_mut())
.await
.unwrap(); //Okay, because we can only create a User of a valid id
}
@ -735,28 +763,29 @@ ORDER BY last_access DESC
family_id,
self.id
)
.execute(db)
.execute(db.deref_mut())
.await
.unwrap(); //Okay, because we can only create a User of a valid id
// handle roles
sqlx::query!("DELETE FROM user_role WHERE user_id = ?", self.id)
.execute(db)
.execute(db.deref_mut())
.await
.unwrap();
for role_id in data.roles.into_keys() {
self.add_role(
db,
&Role::find_by_id(db, role_id.parse::<i32>().unwrap())
.await
.unwrap(),
)
.await;
let role = Role::find_by_id_tx(&mut db, role_id.parse::<i32>().unwrap())
.await
.unwrap();
self.add_role_tx(&mut db, &role).await?;
}
db.commit().await.map_err(|e| e.to_string())?;
Ok(())
}
pub async fn add_role(&self, db: &SqlitePool, role: &Role) {
pub async fn add_role(&self, db: &SqlitePool, role: &Role) -> Result<(), String> {
sqlx::query!(
"INSERT INTO user_role(user_id, role_id) VALUES (?, ?)",
self.id,
@ -764,7 +793,40 @@ ORDER BY last_access DESC
)
.execute(db)
.await
.unwrap();
.map_err(|_| {
format!(
"User already has a role in the cluster '{}'",
role.cluster
.clone()
.expect("db trigger can't activate on empty string")
)
})?;
Ok(())
}
pub async fn add_role_tx(
&self,
db: &mut Transaction<'_, Sqlite>,
role: &Role,
) -> Result<(), String> {
sqlx::query!(
"INSERT INTO user_role(user_id, role_id) VALUES (?, ?)",
self.id,
role.id
)
.execute(db.deref_mut())
.await
.map_err(|_| {
format!(
"User already has a role in the cluster '{}'",
role.cluster
.clone()
.expect("db trigger can't activate on empty string")
)
})?;
Ok(())
}
pub async fn remove_role(&self, db: &SqlitePool, role: &Role) {
@ -1234,7 +1296,8 @@ mod test {
membership_pdf: None,
},
)
.await;
.await
.unwrap();
let user = User::find_by_id(&pool, 1).await.unwrap();