mirror of https://github.com/buster-so/buster.git
fix the user org id
This commit is contained in:
parent
b2bc117694
commit
28d3e3ee14
|
@ -12,7 +12,7 @@ use uuid::Uuid;
|
|||
|
||||
use crate::metrics::Version;
|
||||
use super::{BusterDashboard, BusterDashboardResponse, DashboardConfig};
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use database::enums::{AssetPermissionRole, AssetType, IdentityType, Verification};
|
||||
use database::schema::asset_permissions;
|
||||
use std::collections::HashMap;
|
||||
|
@ -37,7 +37,10 @@ pub async fn create_dashboard_handler(user: &AuthenticatedUser) -> Result<Buster
|
|||
let dashboard_id = Uuid::new_v4();
|
||||
|
||||
// Get user's organization ID
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
// Current timestamp
|
||||
let now = Utc::now();
|
||||
|
|
|
@ -5,16 +5,16 @@ use chrono::Utc;
|
|||
use diesel::insert_into;
|
||||
use diesel_async::RunQueryDsl;
|
||||
use jsonwebtoken::{encode, EncodingKey, Header};
|
||||
use middleware::AuthenticatedUser;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::env;
|
||||
use uuid::Uuid;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
use database::pool::get_pg_pool;
|
||||
use database::models::ApiKey;
|
||||
use database::schema::api_keys;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::models::ApiKey;
|
||||
use database::organization::get_user_organization_id;
|
||||
use database::pool::get_pg_pool;
|
||||
use database::schema::api_keys;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct PostApiKeyResponse {
|
||||
|
@ -70,7 +70,10 @@ async fn post_api_key_handler(user: AuthenticatedUser) -> Result<String> {
|
|||
};
|
||||
|
||||
let organization_id = match get_user_organization_id(&user.id).await {
|
||||
Ok(organization_id) => organization_id,
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting organization ID: {:?}", e);
|
||||
return Err(anyhow::anyhow!("Error getting organization ID"));
|
||||
|
|
|
@ -12,7 +12,7 @@ use axum::http::StatusCode;
|
|||
use middleware::AuthenticatedUser;
|
||||
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use database::enums::{AssetPermissionRole, AssetType, UserOrganizationRole};
|
||||
use database::pool::{get_pg_pool, PgPool};
|
||||
use database::schema::{
|
||||
|
@ -370,7 +370,10 @@ async fn is_organization_admin_or_owner(
|
|||
user_id: Arc<Uuid>,
|
||||
) -> anyhow::Result<bool> {
|
||||
let user_organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(organization_id) => organization_id,
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {}", e);
|
||||
return Ok(false);
|
||||
|
|
|
@ -11,7 +11,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{datasets, datasets_to_dataset_groups};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
/// Represents dataset information with its assignment status to a dataset group
|
||||
|
@ -44,7 +44,10 @@ pub async fn list_datasets(
|
|||
|
||||
async fn list_datasets_handler(user: AuthenticatedUser, dataset_group_id: Uuid) -> Result<Vec<DatasetInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -14,7 +14,7 @@ use database::schema::{
|
|||
};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
/// Represents permission group information with its assignment status to a dataset group
|
||||
|
@ -52,7 +52,10 @@ async fn list_permission_groups_handler(
|
|||
dataset_group_id: Uuid,
|
||||
) -> Result<Vec<PermissionGroupInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -11,7 +11,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{dataset_groups_permissions, users, users_to_organizations};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
/// Represents user information with their assignment status to a dataset group
|
||||
|
@ -45,7 +45,10 @@ pub async fn list_users(
|
|||
|
||||
async fn list_users_handler(user: AuthenticatedUser, dataset_group_id: Uuid) -> Result<Vec<UserInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -13,7 +13,7 @@ use database::models::DatasetToDatasetGroup;
|
|||
use database::schema::datasets_to_dataset_groups;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -46,7 +46,10 @@ async fn put_datasets_handler(
|
|||
dataset_group_id: Uuid,
|
||||
assignments: Vec<DatasetAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -13,7 +13,7 @@ use database::models::DatasetGroupPermission;
|
|||
use database::schema::dataset_groups_permissions;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -46,7 +46,10 @@ async fn put_permission_groups_handler(
|
|||
dataset_group_id: Uuid,
|
||||
assignments: Vec<PermissionGroupAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -13,7 +13,7 @@ use database::models::DatasetGroupPermission;
|
|||
use database::schema::dataset_groups_permissions;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -46,7 +46,10 @@ async fn put_users_handler(
|
|||
dataset_group_id: Uuid,
|
||||
assignments: Vec<UserAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -9,7 +9,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::dataset_groups;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
pub async fn delete_dataset_group(
|
||||
|
@ -17,10 +17,14 @@ pub async fn delete_dataset_group(
|
|||
Path(dataset_group_id): Path<Uuid>,
|
||||
) -> Result<ApiResponse<()>, (StatusCode, &'static str)> {
|
||||
// Check if user is workspace admin or data admin
|
||||
let organization_id = get_user_organization_id(&user.id).await.map_err(|e| {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id")
|
||||
})?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => return Err((StatusCode::FORBIDDEN, "User does not belong to any organization")),
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
match is_user_workspace_admin_or_data_admin(&user, &organization_id).await {
|
||||
Ok(true) => (),
|
||||
|
|
|
@ -11,7 +11,7 @@ use database::pool::get_pg_pool;
|
|||
use database::models::DatasetGroup;
|
||||
use database::schema::dataset_groups;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -41,7 +41,10 @@ pub async fn list_dataset_groups(
|
|||
|
||||
async fn list_dataset_groups_handler(user: AuthenticatedUser) -> Result<Vec<DatasetGroupInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
let dataset_groups = dataset_groups::table
|
||||
.filter(dataset_groups::deleted_at.is_null())
|
||||
|
|
|
@ -12,7 +12,7 @@ use database::models::DatasetGroup;
|
|||
use database::schema::dataset_groups;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -33,10 +33,14 @@ pub async fn post_dataset_group(
|
|||
Json(request): Json<PostDatasetGroupRequest>,
|
||||
) -> Result<ApiResponse<PostDatasetGroupResponse>, (StatusCode, &'static str)> {
|
||||
// Check if user is workspace admin or data admin
|
||||
let organization_id = get_user_organization_id(&user.id).await.map_err(|e| {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id")
|
||||
})?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => return Err((StatusCode::FORBIDDEN, "User does not belong to any organization")),
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
match is_user_workspace_admin_or_data_admin(&user, &organization_id).await {
|
||||
Ok(true) => (),
|
||||
|
@ -75,7 +79,10 @@ async fn post_dataset_group_handler(
|
|||
) -> Result<DatasetGroup> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
let dataset_group = DatasetGroup {
|
||||
id: Uuid::new_v4(),
|
||||
|
|
|
@ -10,7 +10,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::dataset_groups;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
|
@ -24,10 +24,14 @@ pub async fn put_dataset_group(
|
|||
Json(request): Json<Vec<DatasetGroupUpdate>>,
|
||||
) -> Result<ApiResponse<()>, (StatusCode, &'static str)> {
|
||||
// Check if user is workspace admin or data admin
|
||||
let organization_id = get_user_organization_id(&user.id).await.map_err(|e| {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id")
|
||||
})?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => return Err((StatusCode::FORBIDDEN, "User does not belong to any organization")),
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
match is_user_workspace_admin_or_data_admin(&user, &organization_id).await {
|
||||
Ok(true) => (),
|
||||
|
|
|
@ -19,7 +19,7 @@ use database::{
|
|||
};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct UserPermissionLineage {
|
||||
|
@ -49,10 +49,14 @@ pub async fn get_dataset_overview(
|
|||
Path(dataset_id): Path<Uuid>,
|
||||
) -> Result<ApiResponse<DatasetOverview>, (StatusCode, &'static str)> {
|
||||
// Check if user is workspace admin or data admin
|
||||
let organization_id = get_user_organization_id(&user.id).await.map_err(|e| {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id")
|
||||
})?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => return Err((StatusCode::FORBIDDEN, "User does not belong to any organization")),
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
match is_user_workspace_admin_or_data_admin(&user, &organization_id).await {
|
||||
Ok(true) => (),
|
||||
|
|
|
@ -15,7 +15,7 @@ use database::{
|
|||
};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct AssetWithAssignment {
|
||||
|
@ -35,10 +35,14 @@ pub async fn list_assets(
|
|||
Path((dataset_id, permission_type)): Path<(Uuid, String)>,
|
||||
) -> Result<ApiResponse<Vec<AssetWithAssignment>>, (StatusCode, &'static str)> {
|
||||
// Check if user is workspace admin or data admin
|
||||
let organization_id = get_user_organization_id(&user.id).await.map_err(|e| {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id")
|
||||
})?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => return Err((StatusCode::FORBIDDEN, "User does not belong to any organization")),
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
match is_user_workspace_admin_or_data_admin(&user, &organization_id).await {
|
||||
Ok(true) => (),
|
||||
|
|
|
@ -16,7 +16,7 @@ use database::{
|
|||
};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct AssetAssignment {
|
||||
|
@ -45,7 +45,10 @@ pub async fn put_permissions_handler(
|
|||
(dataset_id, permission_type): (Uuid, String),
|
||||
assignments: Vec<AssetAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
match is_user_workspace_admin_or_data_admin(&user, &organization_id).await {
|
||||
Ok(true) => (),
|
||||
|
|
|
@ -2,25 +2,24 @@ use anyhow::{anyhow, Result};
|
|||
use axum::{extract::Json, Extension};
|
||||
use diesel::{ExpressionMethods, QueryDsl};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use middleware::AuthenticatedUser;
|
||||
use reqwest::StatusCode;
|
||||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
use crate::{
|
||||
database::{
|
||||
enums::DatasetType,
|
||||
pool::get_pg_pool,
|
||||
models::{DataSource, Dataset},
|
||||
pool::get_pg_pool,
|
||||
schema::{data_sources, datasets},
|
||||
},
|
||||
routes::rest::ApiResponse,
|
||||
utils::{
|
||||
security::checks::is_user_workspace_admin_or_data_admin,
|
||||
user::user_info::get_user_organization_id,
|
||||
},
|
||||
utils::security::checks::is_user_workspace_admin_or_data_admin,
|
||||
};
|
||||
|
||||
use database::organization::get_user_organization_id;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct PostDatasetReq {
|
||||
pub name: String,
|
||||
|
@ -33,12 +32,18 @@ pub async fn post_dataset(
|
|||
) -> Result<ApiResponse<Dataset>, (axum::http::StatusCode, String)> {
|
||||
// Check if user is workspace admin or data admin
|
||||
let organization_id = match get_user_organization_id(&user.id).await {
|
||||
Ok(id) => id,
|
||||
Ok(Some(id)) => id,
|
||||
Ok(None) => {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"User does not belong to any organization",
|
||||
));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Error getting user organization id".to_string(),
|
||||
"Error getting user organization id",
|
||||
));
|
||||
}
|
||||
};
|
||||
|
@ -48,14 +53,14 @@ pub async fn post_dataset(
|
|||
Ok(false) => {
|
||||
return Err((
|
||||
StatusCode::FORBIDDEN,
|
||||
"Insufficient permissions".to_string(),
|
||||
"Insufficient permissions",
|
||||
))
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error checking user permissions: {:?}", e);
|
||||
return Err((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Error checking user permissions".to_string(),
|
||||
"Error checking user permissions",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +78,7 @@ pub async fn post_dataset(
|
|||
tracing::error!("Error creating dataset: {:?}", e);
|
||||
return Err((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Error creating dataset".to_string(),
|
||||
"Error creating dataset",
|
||||
));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{dataset_groups, dataset_groups_permissions};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
/// Represents dataset group information with its assignment status to a permission group
|
||||
|
@ -47,7 +47,10 @@ async fn list_dataset_groups_handler(
|
|||
permission_group_id: Uuid,
|
||||
) -> Result<Vec<DatasetGroupInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -11,7 +11,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{dataset_permissions, datasets};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
/// Represents dataset information with its assignment status to a permission group
|
||||
|
@ -44,7 +44,10 @@ pub async fn list_datasets(
|
|||
|
||||
async fn list_datasets_handler(user: AuthenticatedUser, permission_group_id: Uuid) -> Result<Vec<DatasetInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -12,7 +12,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{permission_groups_to_identities, users, users_to_organizations};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
/// Represents user information with their assignment status to a permission group
|
||||
|
@ -46,7 +46,10 @@ pub async fn list_users(
|
|||
|
||||
async fn list_users_handler(user: AuthenticatedUser, permission_group_id: Uuid) -> Result<Vec<UserInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -13,7 +13,7 @@ use database::models::DatasetGroupPermission;
|
|||
use database::schema::dataset_groups_permissions;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -46,7 +46,10 @@ async fn put_dataset_groups_handler(
|
|||
permission_group_id: Uuid,
|
||||
assignments: Vec<DatasetGroupAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -13,7 +13,7 @@ use database::models::DatasetPermission;
|
|||
use database::schema::dataset_permissions;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -46,7 +46,10 @@ async fn put_datasets_handler(
|
|||
permission_group_id: Uuid,
|
||||
assignments: Vec<DatasetAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -14,7 +14,7 @@ use database::models::PermissionGroupToIdentity;
|
|||
use database::schema::permission_groups_to_identities;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -47,7 +47,10 @@ async fn put_users_handler(
|
|||
permission_group_id: Uuid,
|
||||
assignments: Vec<UserAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -9,7 +9,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::permission_groups;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
pub async fn delete_permission_group(
|
||||
|
@ -17,10 +17,14 @@ pub async fn delete_permission_group(
|
|||
Path(permission_group_id): Path<Uuid>,
|
||||
) -> Result<ApiResponse<()>, (StatusCode, &'static str)> {
|
||||
// Check if user is workspace admin or data admin
|
||||
let organization_id = get_user_organization_id(&user.id).await.map_err(|e| {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id")
|
||||
})?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => return Err((StatusCode::FORBIDDEN, "User does not belong to any organization")),
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
match is_user_workspace_admin_or_data_admin(&user, &organization_id).await {
|
||||
Ok(true) => (),
|
||||
|
@ -48,7 +52,10 @@ pub async fn delete_permission_group(
|
|||
|
||||
async fn delete_permission_group_handler(user: AuthenticatedUser, permission_group_id: Uuid) -> Result<()> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
let rows_affected = diesel::update(
|
||||
permission_groups::table
|
||||
|
|
|
@ -10,7 +10,7 @@ use database::pool::get_pg_pool;
|
|||
use database::models::PermissionGroup;
|
||||
use database::schema::permission_groups;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -47,7 +47,10 @@ async fn get_permission_group_handler(
|
|||
permission_group_id: Uuid,
|
||||
) -> Result<PermissionGroupInfo> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
let permission_group = permission_groups::table
|
||||
.filter(permission_groups::id.eq(permission_group_id))
|
||||
|
|
|
@ -11,7 +11,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{permission_groups, permission_groups_to_identities, dataset_permissions, dataset_groups_permissions};
|
||||
use database::enums::IdentityType;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -47,7 +47,10 @@ pub async fn list_permission_groups(
|
|||
|
||||
async fn list_permission_groups_handler(user: AuthenticatedUser) -> Result<Vec<PermissionGroupInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
let permission_groups = permission_groups::table
|
||||
.left_join(
|
||||
|
|
|
@ -12,7 +12,7 @@ use database::models::PermissionGroup;
|
|||
use database::schema::permission_groups;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -36,10 +36,14 @@ pub async fn post_permission_group(
|
|||
Json(request): Json<PostPermissionGroupRequest>,
|
||||
) -> Result<ApiResponse<PostPermissionGroupResponse>, (StatusCode, &'static str)> {
|
||||
// Check if user is workspace admin or data admin
|
||||
let organization_id = get_user_organization_id(&user.id).await.map_err(|e| {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id")
|
||||
})?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => return Err((StatusCode::FORBIDDEN, "User does not belong to any organization")),
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err((StatusCode::INTERNAL_SERVER_ERROR, "Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
match is_user_workspace_admin_or_data_admin(&user, &organization_id).await {
|
||||
Ok(true) => (),
|
||||
|
@ -80,7 +84,10 @@ async fn post_permission_group_handler(
|
|||
request: PostPermissionGroupRequest,
|
||||
) -> Result<PermissionGroup> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
let permission_group = PermissionGroup {
|
||||
id: Uuid::new_v4(),
|
||||
|
|
|
@ -10,7 +10,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::permission_groups;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
|
@ -39,7 +39,10 @@ async fn put_permission_group_handler(
|
|||
user: AuthenticatedUser,
|
||||
request: Vec<PermissionGroupUpdate>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
let now = Utc::now();
|
||||
|
||||
// Check if user is workspace admin or data admin
|
||||
|
|
|
@ -12,7 +12,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{users, users_to_organizations};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -43,7 +43,16 @@ pub async fn list_attributes(
|
|||
async fn list_attributes_handler(user: AuthenticatedUser, user_id: Uuid) -> Result<Vec<AttributeInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
|
||||
let organization_id = get_user_organization_id(&user_id).await?;
|
||||
let organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err(anyhow::anyhow!("Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -11,7 +11,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{dataset_groups, dataset_groups_permissions, dataset_permissions};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -42,7 +42,16 @@ pub async fn list_dataset_groups(
|
|||
|
||||
async fn list_dataset_groups_handler(user: AuthenticatedUser, 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 organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err(anyhow::anyhow!("Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!("User is not authorized to list dataset groups"));
|
||||
|
|
|
@ -11,7 +11,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{dataset_permissions, datasets};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -38,7 +38,16 @@ pub async fn list_datasets(
|
|||
|
||||
async fn list_datasets_handler(user: AuthenticatedUser, 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 organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err(anyhow::anyhow!("Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!("User is not authorized to list datasets"));
|
||||
|
|
|
@ -14,7 +14,7 @@ use database::schema::{
|
|||
};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -45,7 +45,10 @@ pub async fn list_permission_groups(
|
|||
|
||||
async fn list_permission_groups_handler(user: AuthenticatedUser, user_id: Uuid) -> Result<Vec<PermissionGroupInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user.id).await?;
|
||||
let organization_id = match get_user_organization_id(&user.id).await? {
|
||||
Some(organization_id) => organization_id,
|
||||
None => return Err(anyhow::anyhow!("User does not belong to any organization")),
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -11,7 +11,7 @@ use database::pool::get_pg_pool;
|
|||
use database::schema::{teams, teams_to_users};
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -47,7 +47,16 @@ pub async fn list_teams(
|
|||
|
||||
async fn list_teams_handler(user: AuthenticatedUser, user_id: Uuid) -> Result<Vec<TeamInfo>> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
let organization_id = get_user_organization_id(&user_id).await?;
|
||||
let organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err(anyhow::anyhow!("Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!("User is not authorized to list teams"));
|
||||
|
|
|
@ -13,7 +13,7 @@ use database::models::DatasetGroupPermission;
|
|||
use database::schema::dataset_groups_permissions;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -44,7 +44,16 @@ async fn put_dataset_groups_handler(
|
|||
user_id: Uuid,
|
||||
assignments: Vec<DatasetGroupAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user_id).await?;
|
||||
let organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err(anyhow::anyhow!("Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -13,7 +13,7 @@ use database::models::DatasetPermission;
|
|||
use database::schema::dataset_permissions;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -44,7 +44,16 @@ async fn put_datasets_handler(
|
|||
user_id: Uuid,
|
||||
assignments: Vec<DatasetAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user_id).await?;
|
||||
let organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err(anyhow::anyhow!("Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!("User is not authorized to assign datasets"));
|
||||
|
|
|
@ -14,7 +14,7 @@ use database::models::PermissionGroupToIdentity;
|
|||
use database::schema::permission_groups_to_identities;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -45,7 +45,16 @@ async fn put_permission_groups_handler(
|
|||
user_id: Uuid,
|
||||
assignments: Vec<PermissionGroupAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user_id).await?;
|
||||
let organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err(anyhow::anyhow!("Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
|
|
@ -15,7 +15,7 @@ use database::models::TeamToUser;
|
|||
use database::schema::teams_to_users;
|
||||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use middleware::AuthenticatedUser;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
|
@ -51,7 +51,16 @@ async fn put_teams_handler(
|
|||
user_id: Uuid,
|
||||
assignments: Vec<TeamAssignment>,
|
||||
) -> Result<()> {
|
||||
let organization_id = get_user_organization_id(&user_id).await?;
|
||||
let organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(Some(organization_id)) => organization_id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error getting user organization id: {:?}", e);
|
||||
return Err(anyhow::anyhow!("Error getting user organization id"));
|
||||
}
|
||||
};
|
||||
|
||||
if !is_user_workspace_admin_or_data_admin(&user, &organization_id).await? {
|
||||
return Err(anyhow::anyhow!("User is not authorized to list teams"));
|
||||
|
|
|
@ -8,7 +8,7 @@ use database::{enums::UserOrganizationRole, pool::get_pg_pool};
|
|||
use crate::routes::rest::ApiResponse;
|
||||
use crate::utils::clients::sentry_utils::send_sentry_error;
|
||||
use crate::utils::security::checks::is_user_workspace_admin_or_data_admin;
|
||||
use crate::utils::user::user_info::get_user_organization_id;
|
||||
use database::organization::get_user_organization_id;
|
||||
use axum::http::StatusCode;
|
||||
use diesel::{update, ExpressionMethods};
|
||||
use diesel_async::RunQueryDsl;
|
||||
|
@ -64,7 +64,10 @@ pub async fn update_user_handler(
|
|||
};
|
||||
|
||||
let user_organization_id = match get_user_organization_id(&user_id).await {
|
||||
Ok(id) => id,
|
||||
Ok(Some(id)) => id,
|
||||
Ok(None) => {
|
||||
return Err(anyhow::anyhow!("User does not belong to any organization"));
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Error getting user organization id: {:?}",
|
||||
|
|
|
@ -2,13 +2,10 @@ pub mod charting;
|
|||
pub mod clients;
|
||||
pub mod security;
|
||||
pub mod serde_helpers;
|
||||
pub mod sharing;
|
||||
pub mod stored_values;
|
||||
pub mod user;
|
||||
pub mod validation;
|
||||
|
||||
pub use agents::*;
|
||||
pub use security::*;
|
||||
pub use stored_values::*;
|
||||
pub use user::*;
|
||||
pub use validation::*;
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
pub mod search_engine;
|
|
@ -1,291 +0,0 @@
|
|||
use sqlx::Row;
|
||||
use tokio_stream::StreamExt;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::Serialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
use database::pool::get_sqlx_pool;
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct MessageSearchResult {
|
||||
pub id: Uuid,
|
||||
#[serde(rename = "name")]
|
||||
pub title: String,
|
||||
pub summary_question: String,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub highlights: Vec<String>,
|
||||
pub score: f64,
|
||||
#[serde(rename = "type")]
|
||||
pub type_: SearchObjectType,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct GenericSearchResult {
|
||||
pub id: Uuid,
|
||||
pub name: String,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub highlights: Vec<String>,
|
||||
pub score: f64,
|
||||
#[serde(rename = "type")]
|
||||
pub type_: SearchObjectType,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
#[serde(untagged)]
|
||||
pub enum SearchObject {
|
||||
Message(MessageSearchResult),
|
||||
Collection(GenericSearchResult),
|
||||
Dashboard(GenericSearchResult),
|
||||
DataSource(GenericSearchResult),
|
||||
Dataset(GenericSearchResult),
|
||||
PermissionGroup(GenericSearchResult),
|
||||
Team(GenericSearchResult),
|
||||
Term(GenericSearchResult),
|
||||
}
|
||||
|
||||
impl SearchObject {
|
||||
pub fn updated_at(&self) -> DateTime<Utc> {
|
||||
match self {
|
||||
SearchObject::Message(m) => m.updated_at,
|
||||
SearchObject::Collection(c) => c.updated_at,
|
||||
SearchObject::Dashboard(d) => d.updated_at,
|
||||
SearchObject::DataSource(ds) => ds.updated_at,
|
||||
SearchObject::Dataset(d) => d.updated_at,
|
||||
SearchObject::PermissionGroup(pg) => pg.updated_at,
|
||||
SearchObject::Team(t) => t.updated_at,
|
||||
SearchObject::Term(t) => t.updated_at,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn score(&self) -> f64 {
|
||||
match self {
|
||||
SearchObject::Message(m) => m.score,
|
||||
SearchObject::Collection(c) => c.score,
|
||||
SearchObject::Dashboard(d) => d.score,
|
||||
SearchObject::DataSource(ds) => ds.score,
|
||||
SearchObject::Dataset(d) => d.score,
|
||||
SearchObject::PermissionGroup(pg) => pg.score,
|
||||
SearchObject::Team(t) => t.score,
|
||||
SearchObject::Term(t) => t.score,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SearchObjectType {
|
||||
Thread,
|
||||
Collection,
|
||||
Dashboard,
|
||||
DataSource,
|
||||
Dataset,
|
||||
PermissionGroup,
|
||||
Team,
|
||||
Term,
|
||||
}
|
||||
|
||||
impl ToString for SearchObjectType {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
SearchObjectType::Thread => "thread".to_string(),
|
||||
SearchObjectType::Collection => "collection".to_string(),
|
||||
SearchObjectType::Dashboard => "dashboard".to_string(),
|
||||
SearchObjectType::DataSource => "data_source".to_string(),
|
||||
SearchObjectType::Dataset => "dataset".to_string(),
|
||||
SearchObjectType::PermissionGroup => "permission_group".to_string(),
|
||||
SearchObjectType::Team => "team".to_string(),
|
||||
SearchObjectType::Term => "term".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SearchOptions {
|
||||
pub num_results: i64,
|
||||
pub asset_types: Vec<SearchObjectType>,
|
||||
}
|
||||
|
||||
impl Default for SearchOptions {
|
||||
fn default() -> Self {
|
||||
SearchOptions {
|
||||
num_results: 10,
|
||||
asset_types: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SearchOptions {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn with_custom_options(num_results: i64, asset_types: Vec<SearchObjectType>) -> Self {
|
||||
SearchOptions {
|
||||
num_results,
|
||||
asset_types,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn asset_types_to_string(&self) -> String {
|
||||
self.asset_types
|
||||
.iter()
|
||||
.map(|t| format!("'{}'", t.to_string()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Will need to implement search for shared assets via team. Likely will just fetch user teams or get them from a cache.
|
||||
pub async fn search_engine(
|
||||
user_id: Uuid,
|
||||
organization_id: Uuid,
|
||||
query_text: String,
|
||||
options: SearchOptions,
|
||||
) -> Result<Vec<SearchObject>> {
|
||||
let mut conn = get_sqlx_pool().acquire().await?;
|
||||
|
||||
let search_terms: Vec<String> = query_text
|
||||
.split_whitespace()
|
||||
.map(|term| sanitize_search_term(term.to_lowercase()))
|
||||
.collect();
|
||||
|
||||
let query = format!(
|
||||
r#"
|
||||
SELECT DISTINCT ON (asset_search.content, asset_search.asset_type)
|
||||
asset_search.asset_id,
|
||||
asset_search.content,
|
||||
asset_search.updated_at,
|
||||
asset_search.asset_type,
|
||||
pgroonga_score(asset_search.tableoid, asset_search.ctid) AS rank
|
||||
FROM
|
||||
asset_search
|
||||
INNER JOIN
|
||||
asset_permissions
|
||||
ON
|
||||
asset_search.asset_id = asset_permissions.asset_id
|
||||
WHERE
|
||||
asset_search.asset_type IN ({})
|
||||
AND asset_search.content &@~ '{}'
|
||||
AND (asset_permissions.identity_id = '{}' OR asset_permissions.identity_id = '{}')
|
||||
AND asset_permissions.deleted_at IS NULL
|
||||
AND asset_search.deleted_at IS NULL
|
||||
ORDER BY asset_search.content, asset_search.asset_type, rank DESC
|
||||
LIMIT {};
|
||||
"#,
|
||||
options.asset_types_to_string(),
|
||||
search_terms
|
||||
.iter()
|
||||
.map(|term| term.replace('\'', "''"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" OR "),
|
||||
user_id,
|
||||
organization_id,
|
||||
options.num_results
|
||||
);
|
||||
|
||||
let mut results = sqlx::raw_sql(&query).fetch(&mut *conn);
|
||||
let mut results_vec = Vec::new();
|
||||
while let Some(row) = results.try_next().await? {
|
||||
let content: String = match row.try_get("content") {
|
||||
Ok(content) => content,
|
||||
Err(e) => return Err(anyhow!("Error getting content: {:?}", e)),
|
||||
};
|
||||
|
||||
// Skip empty content
|
||||
if content.trim().is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let id: Uuid = match row.try_get("asset_id") {
|
||||
Ok(id) => id,
|
||||
Err(e) => return Err(anyhow!("Error getting asset_id: {:?}", e)),
|
||||
};
|
||||
let updated_at: DateTime<Utc> = match row.try_get("updated_at") {
|
||||
Ok(updated_at) => updated_at,
|
||||
Err(e) => return Err(anyhow!("Error getting updated_at: {:?}", e)),
|
||||
};
|
||||
let score: f64 = match row.try_get("rank") {
|
||||
Ok(score) => score,
|
||||
Err(e) => return Err(anyhow!("Error getting rank: {:?}", e)),
|
||||
};
|
||||
|
||||
let asset_type: SearchObjectType = match row.try_get("asset_type") {
|
||||
Ok(asset_type) => match asset_type {
|
||||
"thread" => SearchObjectType::Thread,
|
||||
"collection" => SearchObjectType::Collection,
|
||||
"dashboard" => SearchObjectType::Dashboard,
|
||||
"data_source" => SearchObjectType::DataSource,
|
||||
"dataset" => SearchObjectType::Dataset,
|
||||
"permission_group" => SearchObjectType::PermissionGroup,
|
||||
"team" => SearchObjectType::Team,
|
||||
"term" => SearchObjectType::Term,
|
||||
_ => return Err(anyhow!("Invalid asset type: {:?}", asset_type)),
|
||||
},
|
||||
Err(e) => return Err(anyhow!("Error getting asset_type: {:?}", e)),
|
||||
};
|
||||
|
||||
let highlights = find_highlights(&content, &search_terms);
|
||||
|
||||
results_vec.push(SearchObject::Message(MessageSearchResult {
|
||||
id,
|
||||
title: content.clone(),
|
||||
updated_at,
|
||||
summary_question: content,
|
||||
highlights,
|
||||
score,
|
||||
type_: asset_type,
|
||||
}));
|
||||
}
|
||||
let results = results_vec;
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
fn find_highlights(content: &str, search_terms: &[String]) -> Vec<String> {
|
||||
let content_lower = content.to_lowercase();
|
||||
let mut highlights = Vec::new();
|
||||
|
||||
for term in search_terms {
|
||||
if let Some(pos) = content_lower.find(term) {
|
||||
// Just grab the exact matching portion from the original content
|
||||
highlights.push(content[pos..pos + term.len()].to_string());
|
||||
}
|
||||
}
|
||||
|
||||
highlights
|
||||
}
|
||||
|
||||
fn sanitize_search_term(term: String) -> String {
|
||||
// First pass: only allow alphanumeric, spaces, and basic punctuation
|
||||
let filtered = term
|
||||
.chars()
|
||||
.filter(|c| {
|
||||
c.is_alphanumeric()
|
||||
|| c.is_whitespace()
|
||||
|| matches!(c, '-' | '_' | '.' | ',' | '@' | '#')
|
||||
})
|
||||
.collect::<String>();
|
||||
|
||||
// Second pass: escape special PostgreSQL operators and wildcards
|
||||
let escaped = filtered
|
||||
.replace('\\', "\\\\") // Escape backslashes first
|
||||
.replace('%', "\\%") // Escape LIKE wildcards
|
||||
.replace('_', "\\_")
|
||||
.replace('*', "\\*") // Escape full-text search wildcards
|
||||
.replace(':', "\\:")
|
||||
.replace('&', "\\&")
|
||||
.replace('|', "\\|")
|
||||
.replace('!', "\\!")
|
||||
.replace('(', "\\(") // Escape parentheses
|
||||
.replace(')', "\\)");
|
||||
|
||||
// Third pass: prevent SQL comments
|
||||
let no_comments = escaped
|
||||
.replace("--", "")
|
||||
.replace("/*", "")
|
||||
.replace("*/", "");
|
||||
|
||||
// Fourth pass: limit length to prevent buffer overflow attacks
|
||||
no_comments.chars().take(100).collect()
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1 +0,0 @@
|
|||
pub mod asset_sharing;
|
|
@ -1 +0,0 @@
|
|||
pub mod user_info;
|
|
@ -1,55 +0,0 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use diesel::{BoolExpressionMethods, ExpressionMethods, JoinOnDsl, QueryDsl};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use uuid::Uuid;
|
||||
|
||||
use database::{
|
||||
pool::get_pg_pool,
|
||||
models::Organization,
|
||||
schema::{organizations, users_to_organizations},
|
||||
};
|
||||
|
||||
pub async fn get_user_organization_id(user_id: &Uuid) -> Result<Uuid> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
|
||||
let organization_id = match users_to_organizations::table
|
||||
.select(users_to_organizations::organization_id)
|
||||
.filter(users_to_organizations::user_id.eq(user_id))
|
||||
.filter(users_to_organizations::deleted_at.is_null())
|
||||
.first::<Uuid>(&mut conn)
|
||||
.await
|
||||
{
|
||||
Ok(organization_id) => organization_id,
|
||||
Err(diesel::NotFound) => return Err(anyhow!("User not found")),
|
||||
Err(e) => return Err(anyhow!("Error getting user organization id: {}", e)),
|
||||
};
|
||||
|
||||
Ok(organization_id)
|
||||
}
|
||||
|
||||
pub async fn get_user_organization(user_id: &Uuid) -> Result<Organization> {
|
||||
let mut conn = get_pg_pool().get().await?;
|
||||
|
||||
let organization = match organizations::table
|
||||
.inner_join(
|
||||
users_to_organizations::table.on(users_to_organizations::organization_id
|
||||
.eq(organizations::id)
|
||||
.and(
|
||||
users_to_organizations::user_id
|
||||
.eq(user_id)
|
||||
.and(users_to_organizations::deleted_at.is_null()),
|
||||
)),
|
||||
)
|
||||
.select(organizations::all_columns)
|
||||
.filter(users_to_organizations::user_id.eq(user_id))
|
||||
.filter(users_to_organizations::deleted_at.is_null())
|
||||
.first::<Organization>(&mut conn)
|
||||
.await
|
||||
{
|
||||
Ok(organization) => organization,
|
||||
Err(diesel::NotFound) => return Err(anyhow!("Organization not found.")),
|
||||
Err(e) => return Err(anyhow!("Error getting user organization id: {}", e)),
|
||||
};
|
||||
|
||||
Ok(organization)
|
||||
}
|
Loading…
Reference in New Issue