diff --git a/api/libs/agents/src/tools/categories/file_tools/create_metrics.rs b/api/libs/agents/src/tools/categories/file_tools/create_metrics.rs index 88290541a..af18fdeb1 100644 --- a/api/libs/agents/src/tools/categories/file_tools/create_metrics.rs +++ b/api/libs/agents/src/tools/categories/file_tools/create_metrics.rs @@ -4,7 +4,12 @@ use anyhow::{anyhow, Result}; use async_trait::async_trait; use braintrust::{get_prompt_system_message, BraintrustClient}; use chrono::Utc; -use database::{pool::get_pg_pool, schema::metric_files}; +use database::{ + pool::get_pg_pool, + schema::{metric_files, asset_permissions}, + models::AssetPermission, + enums::{AssetType, IdentityType, AssetPermissionRole}, +}; use diesel::insert_into; use diesel_async::RunQueryDsl; use indexmap::IndexMap; @@ -120,6 +125,43 @@ impl ToolExecutor for CreateMetricFilesTool { .await { Ok(_) => { + // Get the user ID from the agent state + let user_id = self.agent.get_user_id(); + + // Create asset permissions for each metric file + let now = Utc::now(); + let asset_permissions: Vec = metric_records + .iter() + .map(|record| AssetPermission { + identity_id: user_id, + identity_type: IdentityType::User, + asset_id: record.id, + asset_type: AssetType::MetricFile, + role: AssetPermissionRole::Owner, + created_at: now, + updated_at: now, + deleted_at: None, + created_by: user_id, + updated_by: user_id, + }) + .collect(); + + // Insert asset permissions + match insert_into(asset_permissions::table) + .values(&asset_permissions) + .execute(&mut conn) + .await + { + Ok(_) => { + tracing::debug!("Successfully inserted asset permissions for {} metric files", asset_permissions.len()); + }, + Err(e) => { + tracing::error!("Error inserting asset permissions: {}", e); + // Continue with the process even if permissions failed + // We'll still return the created files + } + } + for (i, yml) in metric_ymls.into_iter().enumerate() { created_files.push(FileWithId { id: metric_records[i].id, diff --git a/api/src/routes/rest/routes/collections/sharing/list_sharing.rs b/api/src/routes/rest/routes/collections/sharing/list_sharing.rs new file mode 100644 index 000000000..58aae0275 --- /dev/null +++ b/api/src/routes/rest/routes/collections/sharing/list_sharing.rs @@ -0,0 +1,63 @@ +use axum::{ + extract::Path, + http::StatusCode, + Extension, +}; +use handlers::collections::sharing::list_collection_sharing_handler; +use middleware::AuthenticatedUser; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +use crate::routes::rest::ApiResponse; + +/// Response type for sharing permissions +#[derive(Debug, Serialize)] +pub struct SharingResponse { + pub permissions: Vec, +} + +/// Single sharing permission entry +#[derive(Debug, Serialize)] +pub struct SharingPermission { + pub user_id: Uuid, + pub email: String, + pub name: Option, + pub avatar_url: Option, + pub role: database::enums::AssetPermissionRole, +} + +/// REST handler for listing sharing permissions for a collection +pub async fn list_collection_sharing_rest_handler( + Extension(user): Extension, + Path(id): Path, +) -> Result, (StatusCode, String)> { + tracing::info!("Processing GET request for collection sharing with ID: {}, user_id: {}", id, user.id); + + match list_collection_sharing_handler(&id, &user.id).await { + Ok(permissions) => { + let response = SharingResponse { + permissions: permissions.into_iter().map(|p| SharingPermission { + user_id: p.user.as_ref().map(|u| u.id).unwrap_or_default(), + email: p.user.as_ref().map(|u| u.email.clone()).unwrap_or_default(), + name: p.user.as_ref().and_then(|u| u.name.clone()), + avatar_url: p.user.as_ref().and_then(|u| u.avatar_url.clone()), + role: p.permission.role, + }).collect(), + }; + Ok(ApiResponse::JsonData(response)) + }, + Err(e) => { + tracing::error!("Error listing sharing permissions: {}", e); + let error_message = e.to_string(); + + // Return appropriate status code based on error message + if error_message.contains("not found") { + return Err((StatusCode::NOT_FOUND, format!("Collection not found: {}", e))); + } else if error_message.contains("permission") { + return Err((StatusCode::FORBIDDEN, format!("Permission denied: {}", e))); + } else { + return Err((StatusCode::INTERNAL_SERVER_ERROR, format!("Failed to list sharing permissions: {}", e))); + } + } + } +} \ No newline at end of file