mirror of https://github.com/buster-so/buster.git
178 lines
5.3 KiB
Rust
178 lines
5.3 KiB
Rust
use anyhow::{anyhow, Result};
|
|
use database::{
|
|
enums::{AssetPermissionRole, AssetType, IdentityType},
|
|
pool::get_pg_pool,
|
|
schema::chats,
|
|
};
|
|
use diesel::{ExpressionMethods, QueryDsl};
|
|
use diesel_async::RunQueryDsl;
|
|
use sharing::{
|
|
check_asset_permission::has_permission,
|
|
remove_asset_permissions::remove_share_by_email,
|
|
};
|
|
use tracing::{error, info};
|
|
use uuid::Uuid;
|
|
|
|
/// Handler for deleting sharing permissions for a specific chat
|
|
pub async fn delete_chat_sharing_handler(
|
|
chat_id: &Uuid,
|
|
user_id: &Uuid,
|
|
emails: Vec<String>,
|
|
) -> Result<()> {
|
|
info!(
|
|
chat_id = %chat_id,
|
|
user_id = %user_id,
|
|
email_count = emails.len(),
|
|
"Deleting chat sharing permissions"
|
|
);
|
|
|
|
// 1. Validate the chat exists
|
|
let mut conn = get_pg_pool().get().await.map_err(|e| {
|
|
error!("Database connection error: {}", e);
|
|
anyhow!("Failed to get database connection: {}", e)
|
|
})?;
|
|
|
|
let chat_exists = chats::table
|
|
.filter(chats::id.eq(chat_id))
|
|
.filter(chats::deleted_at.is_null())
|
|
.count()
|
|
.get_result::<i64>(&mut conn)
|
|
.await
|
|
.map_err(|e| {
|
|
error!("Error checking if chat exists: {}", e);
|
|
anyhow!("Database error: {}", e)
|
|
})?;
|
|
|
|
if chat_exists == 0 {
|
|
error!(chat_id = %chat_id, "Chat not found");
|
|
return Err(anyhow!("Chat not found"));
|
|
}
|
|
|
|
// 2. Check if user has permission to delete sharing (Owner or FullAccess)
|
|
let has_permission = has_permission(
|
|
*chat_id,
|
|
AssetType::Chat,
|
|
*user_id,
|
|
IdentityType::User,
|
|
AssetPermissionRole::FullAccess, // Owner role implicitly has FullAccess permissions
|
|
)
|
|
.await
|
|
.map_err(|e| {
|
|
error!(
|
|
chat_id = %chat_id,
|
|
user_id = %user_id,
|
|
"Error checking chat permissions: {}", e
|
|
);
|
|
anyhow!("Error checking chat permissions: {}", e)
|
|
})?;
|
|
|
|
if !has_permission {
|
|
error!(
|
|
chat_id = %chat_id,
|
|
user_id = %user_id,
|
|
"User does not have permission to delete sharing for this chat"
|
|
);
|
|
return Err(anyhow!("User does not have permission to delete sharing for this chat"));
|
|
}
|
|
|
|
// 3. Process each email and delete sharing permissions
|
|
for email in &emails {
|
|
// Validate email format
|
|
if !email.contains('@') {
|
|
error!(email = %email, "Invalid email format");
|
|
return Err(anyhow!("Invalid email format: {}", email));
|
|
}
|
|
|
|
match remove_share_by_email(
|
|
email,
|
|
*chat_id,
|
|
AssetType::Chat,
|
|
*user_id,
|
|
)
|
|
.await
|
|
{
|
|
Ok(_) => {
|
|
info!(
|
|
chat_id = %chat_id,
|
|
email = %email,
|
|
"Deleted sharing permission"
|
|
);
|
|
},
|
|
Err(e) => {
|
|
// If the error is because the permission doesn't exist, we can ignore it
|
|
if e.to_string().contains("No active permission found") {
|
|
info!(
|
|
chat_id = %chat_id,
|
|
email = %email,
|
|
"No active permission found to delete"
|
|
);
|
|
continue;
|
|
}
|
|
|
|
error!(
|
|
chat_id = %chat_id,
|
|
email = %email,
|
|
"Failed to delete sharing: {}", e
|
|
);
|
|
return Err(anyhow!("Failed to delete sharing for email {}: {}", email, e));
|
|
}
|
|
}
|
|
}
|
|
|
|
info!(
|
|
chat_id = %chat_id,
|
|
email_count = emails.len(),
|
|
"Successfully deleted chat sharing permissions"
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use database::enums::{AssetPermissionRole, AssetType, IdentityType};
|
|
use mockall::predicate::*;
|
|
use mockall::mock;
|
|
|
|
// Mock the has_permission function
|
|
mock! {
|
|
HasPermission {}
|
|
impl HasPermission {
|
|
pub async fn has_permission(
|
|
asset_id: Uuid,
|
|
asset_type: AssetType,
|
|
identity_id: Uuid,
|
|
identity_type: IdentityType,
|
|
required_role: AssetPermissionRole,
|
|
) -> Result<bool>;
|
|
}
|
|
}
|
|
|
|
// Mock the remove_share_by_email function
|
|
mock! {
|
|
RemoveShareByEmail {}
|
|
impl RemoveShareByEmail {
|
|
pub async fn remove_share_by_email(
|
|
email: &str,
|
|
asset_id: Uuid,
|
|
asset_type: AssetType,
|
|
updated_by: Uuid,
|
|
) -> Result<()>;
|
|
}
|
|
}
|
|
|
|
// Basic placeholder test
|
|
#[tokio::test]
|
|
async fn test_delete_chat_sharing_handler_invalid_email() {
|
|
// This is a simple placeholder test - would be replaced with actual mocked tests in real implementation
|
|
// Invalid email format test doesn't require mocking database or other functions
|
|
let chat_id = Uuid::new_v4();
|
|
let user_id = Uuid::new_v4();
|
|
let emails = vec!["invalid-email".to_string()];
|
|
|
|
let result = delete_chat_sharing_handler(&chat_id, &user_id, emails).await;
|
|
assert!(result.is_err());
|
|
assert!(result.unwrap_err().to_string().contains("Invalid email format"));
|
|
}
|
|
} |