hotfix
This commit is contained in:
1 parent
0cb8b068a8
commit
64b0c76120
11 files changed
+453
-5
No files matched your search
@@ -8,7 +8,7 @@ use crate::repositories::{AnyResult, RepositoryContext};
|
||||
use sea_orm::{
|
||||
ColumnTrait, EntityTrait, PaginatorTrait, QueryFilter, QuerySelect, Set, TransactionTrait,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::{Arc, OnceLock};
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -81,6 +81,39 @@ impl ComputedPermissionRepository {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Répare les membres sans aucune ligne de cache. Les membres déjà synchronisés ne sont pas recalculés.
|
||||
pub async fn repair_missing_members(&self) -> AnyResult<Vec<(Uuid, Uuid)>> {
|
||||
let members = server_user::Entity::find()
|
||||
.select_only()
|
||||
.column(server_user::Column::UserId)
|
||||
.column(server_user::Column::ServerId)
|
||||
.into_tuple::<(Uuid, Uuid)>()
|
||||
.all(&self.context.db)
|
||||
.await?;
|
||||
|
||||
let cached: HashSet<(Uuid, Uuid)> = computed_permission::Entity::find()
|
||||
.select_only()
|
||||
.column(computed_permission::Column::UserId)
|
||||
.column(computed_permission::Column::ServerId)
|
||||
.distinct()
|
||||
.into_tuple::<(Uuid, Uuid)>()
|
||||
.all(&self.context.db)
|
||||
.await?
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let mut repaired = Vec::new();
|
||||
for (user_id, server_id) in members {
|
||||
if cached.contains(&(user_id, server_id)) {
|
||||
continue;
|
||||
}
|
||||
self.full_sync_user(user_id, server_id).await?;
|
||||
repaired.push((user_id, server_id));
|
||||
}
|
||||
|
||||
Ok(repaired)
|
||||
}
|
||||
|
||||
/// Scope RÔLE : Recalcule le cache uniquement pour les membres d'un rôle spécifique.
|
||||
pub async fn sync_role_members(&self, role_id: Uuid, server_id: Uuid) -> AnyResult<()> {
|
||||
let user_ids = role_user::Entity::find()
|
||||
@@ -263,3 +296,46 @@ impl ComputedPermissionRepository {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::http::test_support::{state, user};
|
||||
use crate::models::computed_permission;
|
||||
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
||||
|
||||
#[tokio::test]
|
||||
async fn repair_missing_members_is_idempotent() {
|
||||
let state = state().await;
|
||||
let owner = user(&state, false).await;
|
||||
let server = state
|
||||
.services
|
||||
.server
|
||||
.create_server("repair".into(), None, false, owner.id)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
computed_permission::Entity::delete_many()
|
||||
.filter(computed_permission::Column::UserId.eq(owner.id))
|
||||
.filter(computed_permission::Column::ServerId.eq(server.id))
|
||||
.exec(&state.db)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let first = state
|
||||
.repositories
|
||||
.computed_permission
|
||||
.repair_missing_members()
|
||||
.await
|
||||
.unwrap();
|
||||
let second = state
|
||||
.repositories
|
||||
.computed_permission
|
||||
.repair_missing_members()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(first.contains(&(owner.id, server.id)));
|
||||
assert!(second.is_empty());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user