feat: Update dataset group listing to include dataset group permissions

- Modified the `list_dataset_groups` function to accept an additional `id` parameter for filtering dataset groups based on user permissions.
- Updated the SQL query to join with the `dataset_groups_permissions` table, allowing retrieval of permission counts for each dataset group.
- Refactored the `DatasetGroupInfo` struct to replace `permission_id` with `permission_count`, enhancing clarity and accuracy in the data representation.
- Ensured that the query groups by the new permission structure, improving the functionality and security of dataset group listings.
This commit is contained in:
dal 2025-01-20 15:40:50 -07:00
parent b9b5146299
commit df231a81d9
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
2 changed files with 20 additions and 10 deletions

View File

@ -10,6 +10,7 @@ allow_columns_to_appear_in_same_group_by_clause!(
dataset_groups::id,
dataset_groups::name,
dataset_permissions::id,
dataset_groups_permissions::id,
);
#[derive(Queryable, Insertable, Identifiable, Associations, Debug)]

View File

@ -1,4 +1,5 @@
use anyhow::Result;
use axum::extract::Path;
use axum::http::StatusCode;
use axum::Extension;
use diesel::prelude::*;
@ -8,7 +9,7 @@ use uuid::Uuid;
use crate::database::lib::get_pg_pool;
use crate::database::models::User;
use crate::database::schema::{dataset_groups, dataset_permissions};
use crate::database::schema::{dataset_groups, dataset_groups_permissions, dataset_permissions};
use crate::routes::rest::ApiResponse;
use crate::utils::user::user_info::get_user_organization_id;
@ -16,14 +17,15 @@ use crate::utils::user::user_info::get_user_organization_id;
pub struct DatasetGroupInfo {
pub id: Uuid,
pub name: String,
pub permission_id: i32,
pub permission_count: i64,
pub assigned: bool,
}
pub async fn list_dataset_groups(
Extension(user): Extension<User>,
Path(id): Path<Uuid>,
) -> Result<ApiResponse<Vec<DatasetGroupInfo>>, (StatusCode, &'static str)> {
let dataset_groups = match list_dataset_groups_handler(user).await {
let dataset_groups = match list_dataset_groups_handler(user, id).await {
Ok(groups) => groups,
Err(e) => {
tracing::error!("Error listing dataset groups: {:?}", e);
@ -37,11 +39,18 @@ pub async fn list_dataset_groups(
Ok(ApiResponse::JsonData(dataset_groups))
}
async fn list_dataset_groups_handler(user: User) -> Result<Vec<DatasetGroupInfo>> {
async fn list_dataset_groups_handler(user: User, id: Uuid) -> Result<Vec<DatasetGroupInfo>> {
let mut conn = get_pg_pool().get().await?;
let organization_id = get_user_organization_id(&user.id).await?;
let groups = dataset_groups::table
.left_join(
dataset_groups_permissions::table.on(dataset_groups_permissions::dataset_group_id
.eq(dataset_groups::id)
.and(dataset_groups_permissions::permission_type.eq("user"))
.and(dataset_groups_permissions::permission_id.eq(id))
.and(dataset_groups_permissions::deleted_at.is_null())),
)
.left_join(
dataset_permissions::table.on(dataset_permissions::permission_id
.eq(dataset_groups::id)
@ -52,28 +61,28 @@ async fn list_dataset_groups_handler(user: User) -> Result<Vec<DatasetGroupInfo>
.select((
dataset_groups::id,
dataset_groups::name,
diesel::dsl::sql::<diesel::sql_types::Integer>(
diesel::dsl::sql::<diesel::sql_types::BigInt>(
"COALESCE(count(dataset_permissions.id), 0)",
),
diesel::dsl::sql::<diesel::sql_types::Bool>("dataset_permissions.id IS NOT NULL"),
diesel::dsl::sql::<diesel::sql_types::Bool>("dataset_groups_permissions.id IS NOT NULL"),
))
.group_by((
dataset_groups::id,
dataset_groups::name,
dataset_permissions::id,
dataset_groups_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::<(Uuid, String, i32, bool)>(&mut *conn)
.load::<(Uuid, String, i64, bool)>(&mut *conn)
.await?;
Ok(groups
.into_iter()
.map(|(id, name, permission_id, assigned)| DatasetGroupInfo {
.map(|(id, name, permission_count, assigned)| DatasetGroupInfo {
id,
name,
permission_id,
permission_count,
assigned,
})
.collect())