fix: prevent deletion of roles that are currently in use #194

This commit is contained in:
rustmailer
2026-04-16 15:43:55 +08:00
parent 15dd26228c
commit 18a0d52c57
3 changed files with 35 additions and 4 deletions
+13 -2
View File
@@ -20,8 +20,8 @@ use crate::{
decrypt, encrypt, generate_token, id, decrypt, encrypt, generate_token, id,
modules::{ modules::{
database::{ database::{
async_find_impl, batch_delete_impl, delete_impl, list_all_impl, manager::DB_MANAGER, async_find_impl, async_secondary_find_impl, batch_delete_impl, delete_impl,
async_secondary_find_impl, update_impl, with_transaction, list_all_impl, manager::DB_MANAGER, update_impl, with_transaction,
}, },
error::{code::ErrorCode, BichonResult}, error::{code::ErrorCode, BichonResult},
token::{AccessTokenModel, AccessTokenModelKey, TokenType}, token::{AccessTokenModel, AccessTokenModelKey, TokenType},
@@ -132,6 +132,17 @@ pub struct BichonUserV2 {
} }
impl BichonUserV2 { impl BichonUserV2 {
pub fn is_using_role(&self, role_id: u64) -> bool {
if self.global_roles.contains(&role_id) {
return true;
}
if self.account_access_map.values().any(|&id| id == role_id) {
return true;
}
false
}
pub async fn list_all() -> BichonResult<Vec<UserModel>> { pub async fn list_all() -> BichonResult<Vec<UserModel>> {
Ok(list_all_impl::<UserModel>(DB_MANAGER.meta_db()).await?) Ok(list_all_impl::<UserModel>(DB_MANAGER.meta_db()).await?)
} }
+20
View File
@@ -37,6 +37,7 @@ use crate::{
users::{ users::{
payload::{RoleCreateRequest, RoleUpdateRequest}, payload::{RoleCreateRequest, RoleUpdateRequest},
permissions::*, permissions::*,
UserModel,
}, },
}, },
raise_error, utc_now, raise_error, utc_now,
@@ -344,6 +345,25 @@ impl UserRole {
ErrorCode::InvalidParameter ErrorCode::InvalidParameter
)); ));
} }
let all_users = UserModel::list_all().await?;
let active_users: Vec<String> = all_users
.iter()
.filter(|user| user.is_using_role(id))
.map(|user| user.username.clone())
.collect();
if !active_users.is_empty() {
let user_list = active_users.join(", ");
return Err(raise_error!(
format!(
"Cannot delete role (ID: {}): It is still assigned to the following users: {}",
id, user_list
),
ErrorCode::PermissionDenied
));
}
delete_impl(DB_MANAGER.meta_db(), move |rw| { delete_impl(DB_MANAGER.meta_db(), move |rw| {
rw.get() rw.get()
.primary::<UserRole>(id) .primary::<UserRole>(id)