diff --git a/api/src/routes/rest/routes/datasets/assets/get_dataset_overview.rs b/api/src/routes/rest/routes/datasets/assets/get_dataset_overview.rs index 97559fdad..6041a4f57 100644 --- a/api/src/routes/rest/routes/datasets/assets/get_dataset_overview.rs +++ b/api/src/routes/rest/routes/datasets/assets/get_dataset_overview.rs @@ -1,6 +1,6 @@ use anyhow::Result; use axum::http::StatusCode; -use axum::{extract::Path, Extension, Json}; +use axum::{extract::Path, Extension}; use diesel::prelude::*; use diesel_async::RunQueryDsl; use serde::Serialize; @@ -9,7 +9,7 @@ use uuid::Uuid; use crate::database::{ enums::{UserOrganizationRole, UserOrganizationStatus}, lib::get_pg_pool, - models::{User, UserToOrganization}, + models::User, schema::{ dataset_permissions, datasets_to_permission_groups, permission_groups_to_users, users, users_to_organizations, @@ -20,22 +20,24 @@ use crate::utils::security::checks::is_user_workspace_admin_or_data_admin; #[derive(Debug, Serialize)] pub struct UserPermissionLineage { - pub user_id: Uuid, - pub email: String, + pub id: Option, + #[serde(rename = "type")] + pub type_: String, + pub name: Option, +} + +#[derive(Debug, Serialize)] +pub struct UserOverviewItem { + pub id: Uuid, + pub name: String, pub can_query: bool, - pub organization_role_access: bool, - pub permission_group_access: bool, - pub dataset_group_access: bool, - pub direct_access: bool, + pub lineage: Vec>, } #[derive(Debug, Serialize)] pub struct DatasetOverview { pub dataset_id: Uuid, - pub total_permission_groups: i64, - pub total_dataset_groups: i64, - pub total_users: i64, - pub user_permission_lineages: Vec, + pub users: Vec, } pub async fn get_dataset_overview( @@ -61,7 +63,7 @@ pub async fn get_dataset_overview( })?; // Get all active users in the organization - let all_users = users_to_organizations::table + let users = users_to_organizations::table .inner_join(users::table.on(users_to_organizations::user_id.eq(users::id))) .filter(users_to_organizations::status.eq(UserOrganizationStatus::Active)) .filter(users_to_organizations::deleted_at.is_null()) @@ -73,143 +75,74 @@ pub async fn get_dataset_overview( (StatusCode::INTERNAL_SERVER_ERROR, "Database error") })?; - // Get permission group access for all users - let permission_group_access = permission_groups_to_users::table - .inner_join( - datasets_to_permission_groups::table - .on(datasets_to_permission_groups::permission_group_id - .eq(permission_groups_to_users::permission_group_id)), - ) - .filter(datasets_to_permission_groups::dataset_id.eq(dataset_id)) - .filter(datasets_to_permission_groups::deleted_at.is_null()) - .select(permission_groups_to_users::user_id) - .load::(&mut conn) - .await - .map_err(|e| { - tracing::error!("Error checking permission group access: {:?}", e); - (StatusCode::INTERNAL_SERVER_ERROR, "Database error") - })?; - - // Get dataset group access - let dataset_group_access = dataset_permissions::table - .filter( - dataset_permissions::dataset_id - .eq(dataset_id) - .and(dataset_permissions::permission_type.eq("dataset_group")) - .and(dataset_permissions::deleted_at.is_null()), - ) - .select(dataset_permissions::permission_id) - .load::(&mut conn) - .await - .map_err(|e| { - tracing::error!("Error checking dataset group access: {:?}", e); - (StatusCode::INTERNAL_SERVER_ERROR, "Database error") - })?; - - // Get direct access users - let direct_access = dataset_permissions::table - .filter( - dataset_permissions::dataset_id - .eq(dataset_id) - .and(dataset_permissions::permission_type.eq("user")) - .and(dataset_permissions::deleted_at.is_null()), - ) - .select(dataset_permissions::permission_id) - .load::(&mut conn) - .await - .map_err(|e| { - tracing::error!("Error checking direct access: {:?}", e); - (StatusCode::INTERNAL_SERVER_ERROR, "Database error") - })?; - - // Build user lineages - let user_permission_lineages = all_users + let users = users .into_iter() - .map(|(user_id, email, role)| { - let organization_role_access = matches!( - role, - UserOrganizationRole::WorkspaceAdmin - | UserOrganizationRole::DataAdmin - | UserOrganizationRole::Querier - ); - - let permission_group_access = permission_group_access.contains(&user_id); - let dataset_group_access = dataset_group_access.contains(&user_id); - let direct_access = direct_access.contains(&user_id); - - let can_query = if role == UserOrganizationRole::Viewer { - false - } else { - organization_role_access - || (role == UserOrganizationRole::RestrictedQuerier - && (permission_group_access || dataset_group_access || direct_access)) + .map(|(id, email, role)| { + let can_query = match role { + UserOrganizationRole::WorkspaceAdmin => true, + UserOrganizationRole::DataAdmin => true, + UserOrganizationRole::Querier => true, + _ => false, }; - UserPermissionLineage { - user_id, - email, - can_query, - organization_role_access, - permission_group_access, - dataset_group_access, - direct_access, + let mut lineage = vec![]; + let mut org_lineage = vec![UserPermissionLineage { + id: Some(id), + type_: String::from("user"), + name: Some(String::from("Default Access")), + }]; + + match role { + UserOrganizationRole::WorkspaceAdmin => { + org_lineage.push(UserPermissionLineage { + id: Some(id), + type_: String::from("user"), + name: Some(String::from("Workspace Admin")), + }); + } + UserOrganizationRole::DataAdmin => { + org_lineage.push(UserPermissionLineage { + id: Some(id), + type_: String::from("user"), + name: Some(String::from("Data Admin")), + }); + } + UserOrganizationRole::Querier => { + org_lineage.push(UserPermissionLineage { + id: Some(id), + type_: String::from("user"), + name: Some(String::from("Querier")), + }); + } + UserOrganizationRole::RestrictedQuerier => { + org_lineage.push(UserPermissionLineage { + id: Some(id), + type_: String::from("user"), + name: Some(String::from("Restricted Querier")), + }); + } + UserOrganizationRole::Viewer => { + org_lineage.push(UserPermissionLineage { + id: Some(id), + type_: String::from("user"), + name: Some(String::from("Viewer")), + }); + } + _ => (), } + + lineage.push(org_lineage); + + return UserOverviewItem { + id, + name: email, + can_query, + lineage, + }; }) .collect(); - // Count active permissions for each type - let permission_groups_count = dataset_permissions::table - .filter( - dataset_permissions::dataset_id - .eq(dataset_id) - .and(dataset_permissions::permission_type.eq("permission_group")) - .and(dataset_permissions::deleted_at.is_null()), - ) - .count() - .get_result::(&mut conn) - .await - .map_err(|e| { - tracing::error!("Error counting permission groups: {:?}", e); - (StatusCode::INTERNAL_SERVER_ERROR, "Database error") - })?; - - let dataset_groups_count = dataset_permissions::table - .filter( - dataset_permissions::dataset_id - .eq(dataset_id) - .and(dataset_permissions::permission_type.eq("dataset_group")) - .and(dataset_permissions::deleted_at.is_null()), - ) - .count() - .get_result::(&mut conn) - .await - .map_err(|e| { - tracing::error!("Error counting dataset groups: {:?}", e); - (StatusCode::INTERNAL_SERVER_ERROR, "Database error") - })?; - - let users_count = dataset_permissions::table - .filter( - dataset_permissions::dataset_id - .eq(dataset_id) - .and(dataset_permissions::permission_type.eq("user")) - .and(dataset_permissions::deleted_at.is_null()), - ) - .count() - .get_result::(&mut conn) - .await - .map_err(|e| { - tracing::error!("Error counting users: {:?}", e); - (StatusCode::INTERNAL_SERVER_ERROR, "Database error") - })?; - - let overview = DatasetOverview { - dataset_id, - total_permission_groups: permission_groups_count, - total_dataset_groups: dataset_groups_count, - total_users: users_count, - user_permission_lineages, - }; + let overview = DatasetOverview { dataset_id, users }; Ok(ApiResponse::JsonData(overview)) }