From 33afab8729239e07d4baccb3271aa07998077569 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 9 Jul 2025 13:50:45 +0000 Subject: [PATCH] Add avatar_url to user-related responses across multiple endpoints Co-authored-by: dallin --- .../handlers/src/collections/list_collections_handler.rs | 6 ++++-- .../handlers/src/dashboards/list_dashboard_handler.rs | 6 ++++-- .../rest/routes/dataset_groups/assets/list_users.rs | 9 ++++++--- .../rest/routes/datasets/assets/get_dataset_overview.rs | 9 ++++++--- .../src/routes/rest/routes/datasets/list_datasets.rs | 6 +++++- .../server/src/routes/rest/routes/organizations/users.rs | 6 +++++- .../rest/routes/permission_groups/assets/list_users.rs | 9 ++++++--- 7 files changed, 36 insertions(+), 15 deletions(-) diff --git a/apps/api/libs/handlers/src/collections/list_collections_handler.rs b/apps/api/libs/handlers/src/collections/list_collections_handler.rs index c2aaab3e2..46927f435 100644 --- a/apps/api/libs/handlers/src/collections/list_collections_handler.rs +++ b/apps/api/libs/handlers/src/collections/list_collections_handler.rs @@ -82,6 +82,7 @@ async fn get_permissioned_collections( users::id, users::name.nullable(), users::email, + users::avatar_url.nullable(), collections::organization_id, )) .filter(collections::deleted_at.is_null()) @@ -124,6 +125,7 @@ async fn get_permissioned_collections( Uuid, Option, String, + Option, Uuid, )>(&mut conn) .await @@ -136,7 +138,7 @@ async fn get_permissioned_collections( // Filter collections based on user permissions // We'll include collections where the user has at least CanView permission - for (id, name, updated_at, created_at, role, creator_id, creator_name, email, org_id) in collection_results { + for (id, name, updated_at, created_at, role, creator_id, creator_name, email, creator_avatar_url, org_id) in collection_results { // Check if user has at least CanView permission let has_permission = check_permission_access( Some(role), @@ -157,7 +159,7 @@ async fn get_permissioned_collections( let owner = ListCollectionsUser { id: creator_id, name: creator_name.unwrap_or(email), - avatar_url: None, + avatar_url: creator_avatar_url, }; let collection = ListCollectionsCollection { diff --git a/apps/api/libs/handlers/src/dashboards/list_dashboard_handler.rs b/apps/api/libs/handlers/src/dashboards/list_dashboard_handler.rs index 7f5e3e5fe..d90bda80b 100644 --- a/apps/api/libs/handlers/src/dashboards/list_dashboard_handler.rs +++ b/apps/api/libs/handlers/src/dashboards/list_dashboard_handler.rs @@ -64,6 +64,7 @@ pub async fn list_dashboard_handler( dashboard_files::updated_at, asset_permissions::role, users::name.nullable(), + users::avatar_url.nullable(), dashboard_files::organization_id, )) .filter(dashboard_files::deleted_at.is_null()) @@ -106,6 +107,7 @@ pub async fn list_dashboard_handler( DateTime, AssetPermissionRole, Option, + Option, Uuid, )>(&mut conn) .await @@ -118,7 +120,7 @@ pub async fn list_dashboard_handler( // We'll include dashboards where the user has at least CanView permission let mut dashboards = Vec::new(); - for (id, name, created_by, created_at, updated_at, role, creator_name, org_id) in + for (id, name, created_by, created_at, updated_at, role, creator_name, creator_avatar_url, org_id) in dashboard_results { // Check if user has at least CanView permission @@ -141,7 +143,7 @@ pub async fn list_dashboard_handler( let owner = DashboardMember { id: created_by, name: creator_name.unwrap_or_else(|| "Unknown".to_string()), - avatar_url: None, + avatar_url: creator_avatar_url, }; let dashboard_item = BusterDashboardListItem { diff --git a/apps/api/server/src/routes/rest/routes/dataset_groups/assets/list_users.rs b/apps/api/server/src/routes/rest/routes/dataset_groups/assets/list_users.rs index 4c1c31fb7..8f8e422bc 100644 --- a/apps/api/server/src/routes/rest/routes/dataset_groups/assets/list_users.rs +++ b/apps/api/server/src/routes/rest/routes/dataset_groups/assets/list_users.rs @@ -20,6 +20,7 @@ pub struct UserInfo { pub id: Uuid, pub name: String, pub email: String, + pub avatar_url: Option, pub assigned: bool, } @@ -77,20 +78,22 @@ async fn list_users_handler(user: AuthenticatedUser, dataset_group_id: Uuid) -> users::id, users::name.nullable(), users::email, + users::avatar_url.nullable(), diesel::dsl::sql::( "dataset_groups_permissions.id IS NOT NULL", ), )) .order_by(users::created_at.desc()) - .load::<(Uuid, Option, String, bool)>(&mut *conn) + .load::<(Uuid, Option, String, Option, bool)>(&mut *conn) .await?; Ok(users .into_iter() - .map(|(id, name, email, assigned)| UserInfo { + .map(|(id, name, email, avatar_url, assigned)| UserInfo { id, - name: name.unwrap_or("".to_string()), + name: name.unwrap_or_else(|| email.clone()), email, + avatar_url, assigned, }) .collect()) diff --git a/apps/api/server/src/routes/rest/routes/datasets/assets/get_dataset_overview.rs b/apps/api/server/src/routes/rest/routes/datasets/assets/get_dataset_overview.rs index c4fed31d0..0697c4828 100644 --- a/apps/api/server/src/routes/rest/routes/datasets/assets/get_dataset_overview.rs +++ b/apps/api/server/src/routes/rest/routes/datasets/assets/get_dataset_overview.rs @@ -34,6 +34,7 @@ pub struct UserOverviewItem { pub id: Uuid, pub name: String, pub email: String, + pub avatar_url: Option, pub can_query: bool, pub lineage: Vec>, } @@ -86,15 +87,16 @@ pub async fn get_dataset_overview( users::email, users_to_organizations::role, users::name.nullable(), + users::avatar_url.nullable(), )) - .load::<(Uuid, String, UserOrganizationRole, Option)>(&mut conn) + .load::<(Uuid, String, UserOrganizationRole, Option, Option)>(&mut conn) .await .map_err(|e| { tracing::error!("Error getting users: {:?}", e); (StatusCode::INTERNAL_SERVER_ERROR, "Database error") })?; - let user_ids = users.iter().map(|(id, _, _, _)| *id).collect::>(); + let user_ids = users.iter().map(|(id, _, _, _, _)| *id).collect::>(); // Direct dataset access let datasets_query: Vec<(Uuid, String, Uuid)> = dataset_permissions::table @@ -207,7 +209,7 @@ pub async fn get_dataset_overview( let users = users .into_iter() - .map(|(id, email, role, name)| { + .map(|(id, email, role, name, avatar_url)| { let can_query = match role { UserOrganizationRole::WorkspaceAdmin | UserOrganizationRole::DataAdmin | UserOrganizationRole::Querier => true, UserOrganizationRole::RestrictedQuerier => { @@ -375,6 +377,7 @@ pub async fn get_dataset_overview( id, name: name.unwrap_or(email.clone()), email, + avatar_url, can_query, lineage, } diff --git a/apps/api/server/src/routes/rest/routes/datasets/list_datasets.rs b/apps/api/server/src/routes/rest/routes/datasets/list_datasets.rs index 3b6794e4d..46adb56f4 100644 --- a/apps/api/server/src/routes/rest/routes/datasets/list_datasets.rs +++ b/apps/api/server/src/routes/rest/routes/datasets/list_datasets.rs @@ -181,6 +181,7 @@ async fn get_org_datasets( users::id, users::name.nullable(), users::email, + users::avatar_url.nullable(), data_sources::id, data_sources::name, )) @@ -194,6 +195,7 @@ async fn get_org_datasets( users::id, users::name, users::email, + users::avatar_url, data_sources::id, data_sources::name, )) @@ -228,6 +230,7 @@ async fn get_org_datasets( Uuid, Option, String, + Option, Uuid, String, )>(&mut conn) @@ -250,6 +253,7 @@ async fn get_org_datasets( user_id, user_name, user_email, + user_avatar_url, data_source_id, data_source_name, )| { @@ -268,7 +272,7 @@ async fn get_org_datasets( owner: Some(ListDatasetOwner { id: user_id, name: user_name.unwrap_or(user_email), - avatar_url: None, + avatar_url: user_avatar_url, }), belongs_to: None, } diff --git a/apps/api/server/src/routes/rest/routes/organizations/users.rs b/apps/api/server/src/routes/rest/routes/organizations/users.rs index 16dcc299c..fe91bd3f3 100644 --- a/apps/api/server/src/routes/rest/routes/organizations/users.rs +++ b/apps/api/server/src/routes/rest/routes/organizations/users.rs @@ -19,6 +19,7 @@ pub struct UserResponse { pub id: Uuid, pub name: Option, pub email: String, + pub avatar_url: Option, pub role: UserOrganizationRole, pub status: UserOrganizationStatus, } @@ -50,6 +51,7 @@ async fn list_organization_users_handler(organization_id: Uuid) -> Result Result, + Option, UserOrganizationRole, UserOrganizationStatus, )>(&mut conn) @@ -66,10 +69,11 @@ async fn list_organization_users_handler(organization_id: Uuid) -> Result, pub assigned: bool, } @@ -76,20 +77,22 @@ async fn list_users_handler(user: AuthenticatedUser, permission_group_id: Uuid) users::id, users::name.nullable(), users::email, + users::avatar_url.nullable(), diesel::dsl::sql::( "permission_groups_to_identities.identity_id IS NOT NULL", ), )) .order_by(users::created_at.desc()) - .load::<(Uuid, Option, String, bool)>(&mut *conn) + .load::<(Uuid, Option, String, Option, bool)>(&mut *conn) .await?; Ok(users .into_iter() - .map(|(id, name, email, assigned)| UserInfo { + .map(|(id, name, email, avatar_url, assigned)| UserInfo { id, - name: name.unwrap_or("".to_string()), + name: name.unwrap_or_else(|| email.clone()), email, + avatar_url, assigned, }) .collect())