# API Chats Sharing - Delete Endpoint PRD ## Problem Statement ✅ Users need the ability to remove sharing permissions for chats through a REST API endpoint. ## Technical Design ### Endpoint Specification ✅ - **Method**: DELETE ✅ - **Path**: /chats/:id/sharing ✅ - **Description**: Removes sharing permissions for a chat ✅ - **Authentication**: Required ✅ - **Authorization**: User must have Owner or FullAccess permission for the chat ### Request Structure ✅ ```rust // Array of emails to remove sharing permissions for pub type DeleteShareRequest = Vec; ``` ### Response Structure ✅ ```rust // Success response is a simple message // Error responses include appropriate status codes and error messages ``` ### Implementation Details #### New Files ✅ 1. `/src/routes/rest/routes/chats/sharing/delete_sharing.rs` - REST handler for deleting sharing permissions ✅ 2. `/libs/handlers/src/chats/sharing/delete_sharing_handler.rs` - Business logic for deleting sharing permissions #### REST Handler Implementation ```rust // delete_sharing.rs pub async fn delete_chat_sharing_rest_handler( Extension(user): Extension, Path(id): Path, Json(emails): Json>, ) -> Result, (StatusCode, String)> { tracing::info!("Processing DELETE request for chat sharing with ID: {}, user_id: {}", id, user.id); match delete_chat_sharing_handler(&id, &user.id, emails).await { Ok(_) => Ok(ApiResponse::JsonData("Sharing permissions removed successfully".to_string())), Err(e) => { tracing::error!("Error removing sharing permissions: {}", e); // Map specific errors to appropriate status codes let error_message = e.to_string(); if error_message.contains("not found") { return Err((StatusCode::NOT_FOUND, format!("Chat not found: {}", e))); } else if error_message.contains("permission") { return Err((StatusCode::FORBIDDEN, format!("Insufficient permissions: {}", e))); } else if error_message.contains("Invalid email") { return Err((StatusCode::BAD_REQUEST, format!("Invalid email: {}", e))); } Err((StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to remove sharing permissions: {}", e))) } } } ``` #### Handler Implementation ```rust // delete_sharing_handler.rs pub async fn delete_chat_sharing_handler( chat_id: &Uuid, user_id: &Uuid, emails: Vec, ) -> Result<()> { // 1. Validate the chat exists let chat = match get_chat_by_id(chat_id).await { Ok(Some(chat)) => chat, Ok(None) => return Err(anyhow!("Chat not found")), Err(e) => return Err(anyhow!("Error fetching chat: {}", e)), }; // 2. Check if user has permission to delete sharing for the chat (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?; if !has_permission { return Err(anyhow!("User does not have permission to remove sharing for this chat")); } // 3. Process each email and remove sharing permissions for email in emails { match remove_share_by_email( &email, *chat_id, AssetType::Chat, ).await { Ok(_) => { tracing::info!("Removed sharing permission for email: {} on chat: {}", email, chat_id); }, Err(e) => { tracing::error!("Failed to remove sharing for email {}: {}", email, e); return Err(anyhow!("Failed to remove sharing for email {}: {}", email, e)); } } } Ok(()) } ``` ### Sharing Library Integration This endpoint leverages the following functions from the sharing library: 1. `has_permission` from `@[api/libs/sharing/src]/check_asset_permission.rs`: ```rust pub async fn has_permission( asset_id: Uuid, asset_type: AssetType, identity_id: Uuid, identity_type: IdentityType, required_role: AssetPermissionRole, ) -> Result ``` This function checks if a user has the required permission level for an asset. It's used to verify that the user has Owner or FullAccess permission to delete sharing for the chat. 2. `remove_share_by_email` from `@[api/libs/sharing/src]/remove_asset_permissions.rs`: ```rust pub async fn remove_share_by_email( email: &str, asset_id: Uuid, asset_type: AssetType, ) -> Result<()> ``` This function removes sharing permissions for a specific email on a specific asset. ### Error Handling The handler will return appropriate error responses: - 404 Not Found - If the chat doesn't exist - 403 Forbidden - If the user doesn't have permission to delete sharing for the chat - 400 Bad Request - For invalid email addresses - 500 Internal Server Error - For database errors or other unexpected issues ### Input Validation - Email addresses must be properly formatted (contains '@') - The chat ID must be a valid UUID ### Testing Strategy #### Unit Tests - Test permission validation logic - Test error handling for non-existent chats - Test error handling for unauthorized users - Test error handling for invalid emails - Test successful sharing deletions #### Integration Tests - Test DELETE /chats/:id/sharing with valid ID, authorized user, and valid emails - Test DELETE /chats/:id/sharing with valid ID, unauthorized user - Test DELETE /chats/:id/sharing with non-existent chat ID - Test DELETE /chats/:id/sharing with invalid email formats - Test DELETE /chats/:id/sharing with non-existent user emails #### Test Cases ✅ 1. Should remove sharing permissions for valid emails ✅ 2. Should return 403 when user doesn't have Owner or FullAccess permission ✅ 3. Should return 404 when chat doesn't exist ✅ 4. Should return 400 when email is invalid ✅ 5. Should handle gracefully when trying to remove sharing for a user that doesn't have access ### Performance Considerations - For bulk deletions with many emails, consider implementing a background job for processing - Monitor database performance for large batches of delete operations ### Security Considerations - Ensure that only users with Owner or FullAccess permission can delete sharing - Validate email addresses to prevent injection attacks - Implement rate limiting to prevent abuse - Consider implementing notifications for users whose permissions have been removed ### Monitoring - Log all requests with appropriate context - Track performance metrics for the endpoint - Monitor error rates and types - Track sharing deletion operations by user for audit purposes