From b10503d166a034d562e05fea2346f3bea8101d16 Mon Sep 17 00:00:00 2001 From: dal Date: Thu, 10 Jul 2025 08:20:15 -0600 Subject: [PATCH 1/2] update rust types --- apps/api/libs/database/src/models.rs | 3 +++ apps/api/libs/database/src/schema.rs | 6 ++++++ .../handlers/src/organizations/post_organization_handler.rs | 3 +++ apps/api/server/src/routes/rest/routes/users/get_user.rs | 3 +++ apps/api/server/src/routes/ws/ws_utils.rs | 3 +++ 5 files changed, 18 insertions(+) diff --git a/apps/api/libs/database/src/models.rs b/apps/api/libs/database/src/models.rs index f1c6f784d..c19d1bb22 100644 --- a/apps/api/libs/database/src/models.rs +++ b/apps/api/libs/database/src/models.rs @@ -343,6 +343,9 @@ pub struct Organization { pub updated_at: DateTime, pub deleted_at: Option>, pub payment_required: bool, + pub domains: Option>, + pub restrict_new_user_invitations: bool, + pub default_role: UserOrganizationRole, } #[derive( diff --git a/apps/api/libs/database/src/schema.rs b/apps/api/libs/database/src/schema.rs index 34b30d295..af499ceca 100644 --- a/apps/api/libs/database/src/schema.rs +++ b/apps/api/libs/database/src/schema.rs @@ -438,6 +438,9 @@ diesel::table! { } diesel::table! { + use diesel::sql_types::*; + use super::sql_types::UserOrganizationRoleEnum; + organizations (id) { id -> Uuid, name -> Text, @@ -446,6 +449,9 @@ diesel::table! { updated_at -> Timestamptz, deleted_at -> Nullable, payment_required -> Bool, + domains -> Nullable>, + restrict_new_user_invitations -> Bool, + default_role -> UserOrganizationRoleEnum, } } diff --git a/apps/api/libs/handlers/src/organizations/post_organization_handler.rs b/apps/api/libs/handlers/src/organizations/post_organization_handler.rs index 6e86ffdd8..62dbd970d 100644 --- a/apps/api/libs/handlers/src/organizations/post_organization_handler.rs +++ b/apps/api/libs/handlers/src/organizations/post_organization_handler.rs @@ -34,6 +34,9 @@ pub async fn post_organization_handler(name: String, user: AuthenticatedUser) -> updated_at: now, deleted_at: None, payment_required: true, + domains: None, + restrict_new_user_invitations: false, + default_role: UserOrganizationRole::RestrictedQuerier, }; insert_into(organizations::table) diff --git a/apps/api/server/src/routes/rest/routes/users/get_user.rs b/apps/api/server/src/routes/rest/routes/users/get_user.rs index 961a51a0e..df8d4bf64 100644 --- a/apps/api/server/src/routes/rest/routes/users/get_user.rs +++ b/apps/api/server/src/routes/rest/routes/users/get_user.rs @@ -120,6 +120,9 @@ pub async fn get_user_information(user_id: &Uuid) -> Result { organizations::updated_at, organizations::deleted_at, organizations::payment_required, + organizations::domains, + organizations::restrict_new_user_invitations, + organizations::default_role, ) .nullable(), users_to_organizations::role.nullable(), diff --git a/apps/api/server/src/routes/ws/ws_utils.rs b/apps/api/server/src/routes/ws/ws_utils.rs index 54d146b44..8f2d54b27 100644 --- a/apps/api/server/src/routes/ws/ws_utils.rs +++ b/apps/api/server/src/routes/ws/ws_utils.rs @@ -410,6 +410,9 @@ pub async fn get_user_information(user_id: &Uuid) -> Result { organizations::updated_at, organizations::deleted_at, organizations::payment_required, + organizations::domains, + organizations::restrict_new_user_invitations, + organizations::default_role, ) .nullable(), users_to_organizations::role.nullable(), From caad613297474dc80ddc9aeca8958c8873edcbc1 Mon Sep 17 00:00:00 2001 From: dal Date: Thu, 10 Jul 2025 08:37:35 -0600 Subject: [PATCH 2/2] invite user check --- .../handlers/src/users/invite_user_handler.rs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/apps/api/libs/handlers/src/users/invite_user_handler.rs b/apps/api/libs/handlers/src/users/invite_user_handler.rs index 0c62e634f..c72160691 100644 --- a/apps/api/libs/handlers/src/users/invite_user_handler.rs +++ b/apps/api/libs/handlers/src/users/invite_user_handler.rs @@ -51,6 +51,35 @@ pub async fn invite_user_handler( .context("Failed to find organization")?; let organization_name = organization.name; + // Check if the organization has restricted new user invitations + if organization.restrict_new_user_invitations { + // Get the inviting user's role in the organization + let inviter_org_membership = inviting_user + .organizations + .iter() + .find(|org| org.id == organization_id) + .context("Inviting user is not a member of the organization")?; + + // Check if the user has admin permissions + match inviter_org_membership.role { + UserOrganizationRole::WorkspaceAdmin | UserOrganizationRole::DataAdmin => { + // User has permission to invite, continue + tracing::info!( + user_id = %inviting_user.id, + organization_id = %organization_id, + role = ?inviter_org_membership.role, + "Admin user bypassing invitation restriction" + ); + } + _ => { + // User does not have permission to invite + return Err(anyhow::anyhow!( + "New user invitations have been restricted by the organization administrators. Only workspace admins and data admins can send invites." + )); + } + } + } + let inviter_id = inviting_user.id; let now = Utc::now(); let mut successful_emails: Vec = Vec::new();