feat: Refactor dataset listing to include user-specific permissions

- Updated the `list_datasets` function to accept an additional `id` parameter for filtering datasets based on user permissions.
- Enhanced the SQL query to join with the `dataset_permissions` table, allowing retrieval of permission details for each dataset.
- Refactored the `DatasetInfo` struct to include an `assigned` field, improving clarity in the dataset representation.
- Improved error handling for dataset retrieval, ensuring robust logging and response management.
This commit is contained in:
dal 2025-01-20 15:47:01 -07:00
parent df231a81d9
commit 94be56e042
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
1 changed files with 30 additions and 25 deletions

View File

@ -1,15 +1,15 @@
use anyhow::Result;
use axum::extract::Path;
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::{Dataset, User};
use crate::database::schema::datasets;
use crate::database::models::User;
use crate::database::schema::{dataset_permissions, datasets};
use crate::routes::rest::ApiResponse;
use crate::utils::user::user_info::get_user_organization_id;
@ -17,18 +17,14 @@ use crate::utils::user::user_info::get_user_organization_id;
pub struct DatasetInfo {
pub id: Uuid,
pub name: String,
pub organization_id: Uuid,
pub data_source_id: Uuid,
pub enabled: bool,
pub imported: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub assigned: bool,
}
pub async fn list_datasets(
Extension(user): Extension<User>,
Path(id): Path<Uuid>,
) -> Result<ApiResponse<Vec<DatasetInfo>>, (StatusCode, &'static str)> {
let datasets = match list_datasets_handler(user).await {
let datasets = match list_datasets_handler(user, id).await {
Ok(datasets) => datasets,
Err(e) => {
tracing::error!("Error listing datasets: {:?}", e);
@ -39,28 +35,37 @@ pub async fn list_datasets(
Ok(ApiResponse::JsonData(datasets))
}
async fn list_datasets_handler(user: User) -> Result<Vec<DatasetInfo>> {
async fn list_datasets_handler(user: User, user_id: Uuid) -> Result<Vec<DatasetInfo>> {
let mut conn = get_pg_pool().get().await?;
let organization_id = get_user_organization_id(&user.id).await?;
let datasets: Vec<Dataset> = datasets::table
let datasets = match datasets::table
.left_join(
dataset_permissions::table.on(dataset_permissions::dataset_id
.eq(datasets::id)
.and(dataset_permissions::permission_type.eq("user"))
.and(dataset_permissions::permission_id.eq(user_id))
.and(dataset_permissions::deleted_at.is_null())),
)
.filter(datasets::organization_id.eq(organization_id))
.filter(datasets::deleted_at.is_null())
.order_by(datasets::created_at.desc())
.load(&mut *conn)
.await?;
.select((
datasets::id,
datasets::name,
diesel::dsl::sql::<diesel::sql_types::Bool>("dataset_permissions.id IS NOT NULL"),
))
.load::<(Uuid, String, bool)>(&mut *conn)
.await
{
Ok(datasets) => datasets,
Err(e) => {
tracing::error!("Error listing datasets: {:?}", e);
return Err(anyhow::anyhow!("Error listing datasets"));
}
};
Ok(datasets
.into_iter()
.map(|dataset| DatasetInfo {
id: dataset.id,
name: dataset.name,
organization_id: dataset.organization_id,
data_source_id: dataset.data_source_id,
enabled: dataset.enabled,
imported: dataset.imported,
created_at: dataset.created_at,
updated_at: dataset.updated_at,
})
.map(|(id, name, assigned)| DatasetInfo { id, name, assigned })
.collect())
}