From c4c7b753060fdabe6c83a4e5a062f7354d5dbc95 Mon Sep 17 00:00:00 2001 From: dal Date: Mon, 20 Jan 2025 15:12:32 -0700 Subject: [PATCH] feat: Update dataset group listing to include permissions - Enhanced the `list_dataset_groups` function to join with the `dataset_permissions` table, allowing retrieval of permission details for each dataset group. - Modified the `DatasetGroupInfo` struct to include `permission_id` and `assigned` fields, reflecting the new data structure. - Refactored the SQL query to group by necessary fields and ensure accurate permission data is returned, improving the functionality and security of dataset group listings. --- api/src/database/models.rs | 6 +++ .../users/assets/list_dataset_groups.rs | 45 +++++++++++++------ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/api/src/database/models.rs b/api/src/database/models.rs index 109e5b25f..d51b7a373 100644 --- a/api/src/database/models.rs +++ b/api/src/database/models.rs @@ -6,6 +6,12 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use uuid::Uuid; +allow_columns_to_appear_in_same_group_by_clause!( + dataset_groups::id, + dataset_groups::name, + dataset_permissions::id, +); + #[derive(Queryable, Insertable, Identifiable, Associations, Debug)] #[diesel(belongs_to(User, foreign_key = owner_id))] #[diesel(table_name = api_keys)] diff --git a/api/src/routes/rest/routes/users/assets/list_dataset_groups.rs b/api/src/routes/rest/routes/users/assets/list_dataset_groups.rs index 8df778f83..d4d84b9db 100644 --- a/api/src/routes/rest/routes/users/assets/list_dataset_groups.rs +++ b/api/src/routes/rest/routes/users/assets/list_dataset_groups.rs @@ -1,15 +1,14 @@ use anyhow::Result; use axum::http::StatusCode; use axum::Extension; -use chrono::{DateTime, Utc}; use diesel::prelude::*; use diesel_async::RunQueryDsl; use serde::Serialize; use uuid::Uuid; use crate::database::lib::get_pg_pool; -use crate::database::models::{DatasetGroup, User}; -use crate::database::schema::dataset_groups; +use crate::database::models::User; +use crate::database::schema::{dataset_groups, dataset_permissions}; use crate::routes::rest::ApiResponse; use crate::utils::user::user_info::get_user_organization_id; @@ -17,9 +16,8 @@ use crate::utils::user::user_info::get_user_organization_id; pub struct DatasetGroupInfo { pub id: Uuid, pub name: String, - pub organization_id: Uuid, - pub created_at: DateTime, - pub updated_at: DateTime, + pub permission_id: i32, + pub assigned: bool, } pub async fn list_dataset_groups( @@ -43,21 +41,40 @@ async fn list_dataset_groups_handler(user: User) -> Result let mut conn = get_pg_pool().get().await?; let organization_id = get_user_organization_id(&user.id).await?; - let groups: Vec = dataset_groups::table + let groups = dataset_groups::table + .left_join( + dataset_permissions::table.on(dataset_permissions::permission_id + .eq(dataset_groups::id) + .and(dataset_permissions::permission_type.eq("dataset_group")) + .and(dataset_permissions::deleted_at.is_null()) + .and(dataset_permissions::organization_id.eq(organization_id))), + ) + .select(( + dataset_groups::id, + dataset_groups::name, + diesel::dsl::sql::( + "COALESCE(count(dataset_permissions.id), 0)", + ), + diesel::dsl::sql::("dataset_permissions.id IS NOT NULL"), + )) + .group_by(( + dataset_groups::id, + dataset_groups::name, + dataset_permissions::id, + )) .filter(dataset_groups::organization_id.eq(organization_id)) .filter(dataset_groups::deleted_at.is_null()) .order_by(dataset_groups::created_at.desc()) - .load(&mut *conn) + .load::<(Uuid, String, i32, bool)>(&mut *conn) .await?; Ok(groups .into_iter() - .map(|group| DatasetGroupInfo { - id: group.id, - name: group.name, - organization_id: group.organization_id, - created_at: group.created_at, - updated_at: group.updated_at, + .map(|(id, name, permission_id, assigned)| DatasetGroupInfo { + id, + name, + permission_id, + assigned, }) .collect()) }