From d182159e24c3bab54188eb5c98a3ffd411e8eb74 Mon Sep 17 00:00:00 2001 From: pfvatterott Date: Fri, 12 Dec 2025 10:46:44 -0700 Subject: [PATCH 1/2] isolated org apis --- src/apis/org_service_api.rs | 72 +++++++++++++++++++++++++++++++ src/apis/user_service_api.rs | 18 ++++++++ src/models/fetch_org_response.rs | 3 ++ src/models/fetch_orgs_response.rs | 5 ++- src/models/update_org_request.rs | 3 ++ src/propelauth/errors.rs | 19 ++++++++ src/propelauth/org.rs | 35 ++++++++++++--- 7 files changed, 147 insertions(+), 8 deletions(-) diff --git a/src/apis/org_service_api.rs b/src/apis/org_service_api.rs index 1bfa5b1..d87b5da 100644 --- a/src/apis/org_service_api.rs +++ b/src/apis/org_service_api.rs @@ -120,6 +120,12 @@ pub struct RevokePendingOrgInviteParams { pub revoke_pending_org_invite_request: crate::models::RevokePendingOrgInviteRequest, } +/// struct for passing parameters to the method [`migrate_org_to_isolated`] +#[derive(Clone, Debug, Default)] +pub struct MigrateOrgToIsolatedParams { + pub org_id: String, +} + /// struct for typed errors of method [`add_user_to_org`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -304,6 +310,16 @@ pub enum DeleteOrgError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`migrate_org_to_isolated`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum MigrateOrgToIsolatedError { + Status400(serde_json::Value), + Status401(serde_json::Value), + Status404(serde_json::Value), + UnknownValue(serde_json::Value), +} + pub async fn add_user_to_org( configuration: &configuration::Configuration, params: AddUserToOrgParams, @@ -1385,3 +1401,59 @@ pub async fn delete_org( Err(Error::ResponseError(local_var_error)) } } + +pub async fn migrate_org_to_isolated( + configuration: &configuration::Configuration, + params: MigrateOrgToIsolatedParams, +) -> Result> { + let local_var_configuration = configuration; + + // unbox the parameters + let org_id = params.org_id; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/api/backend/v1/isolate_org", + local_var_configuration.base_path + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); + + if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { + local_var_req_builder = + local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); + } + if let Some(ref local_var_token) = local_var_configuration.bearer_access_token { + local_var_req_builder = local_var_req_builder.bearer_auth(local_var_token.to_owned()); + }; + local_var_req_builder = local_var_req_builder.header( + AUTH_HOSTNAME_HEADER, + local_var_configuration.auth_hostname.to_owned(), + ); + + let request = serde_json::json!({ + "org_id": org_id, + }); + + local_var_req_builder = local_var_req_builder.json(&request); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + serde_json::from_str(&local_var_content).map_err(Error::from) + } else { + let local_var_entity: Option = + serde_json::from_str(&local_var_content).ok(); + let local_var_error = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } +} \ No newline at end of file diff --git a/src/apis/user_service_api.rs b/src/apis/user_service_api.rs index 230d409..ade1c70 100644 --- a/src/apis/user_service_api.rs +++ b/src/apis/user_service_api.rs @@ -57,6 +57,7 @@ pub struct FetchUserByEmailParams { pub email: String, /// Defaults to false pub include_orgs: Option, + pub isolated_org_id: Option } /// struct for passing parameters to the method [`fetch_user_by_id`] @@ -85,6 +86,7 @@ pub struct FetchUserByUsernameParams { pub username: String, /// Defaults to false pub include_orgs: Option, + pub isolated_org_id: Option } /// struct for passing parameters to the method [`fetch_users_by_emails`] @@ -112,6 +114,7 @@ pub struct FetchUsersByQueryParams { pub email_or_username: Option, pub include_orgs: Option, pub legacy_user_id: Option, + pub isolated_org_id: Option } /// struct for passing parameters to the method [`fetch_users_by_usernames`] @@ -773,6 +776,7 @@ pub async fn fetch_user_by_email( // unbox the parameters let email = params.email; let include_orgs = params.include_orgs; + let isolated_org_id = params.isolated_org_id; let local_var_client = &local_var_configuration.client; @@ -788,6 +792,10 @@ pub async fn fetch_user_by_email( local_var_req_builder = local_var_req_builder.query(&[("include_orgs", &local_var_str.to_string())]); } + if let Some(ref local_var_str) = isolated_org_id { + local_var_req_builder = + local_var_req_builder.query(&[("isolated_org_id", &local_var_str.to_string())]); + } if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); @@ -885,6 +893,7 @@ pub async fn fetch_user_by_username( // unbox the parameters let username = params.username; let include_orgs = params.include_orgs; + let isolated_org_id = params.isolated_org_id; let local_var_client = &local_var_configuration.client; @@ -899,6 +908,10 @@ pub async fn fetch_user_by_username( local_var_req_builder = local_var_req_builder.query(&[("include_orgs", &local_var_str.to_string())]); } + if let Some(ref local_var_str) = isolated_org_id { + local_var_req_builder = + local_var_req_builder.query(&[("isolated_org_id", &local_var_str.to_string())]); + } local_var_req_builder = local_var_req_builder.query(&[("username", &username.to_string())]); if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { local_var_req_builder = @@ -1059,6 +1072,7 @@ pub async fn fetch_users_by_query( let email_or_username = params.email_or_username; let include_orgs = params.include_orgs; let legacy_user_id = params.legacy_user_id; + let isolated_org_id = params.isolated_org_id; let local_var_client = &local_var_configuration.client; @@ -1093,6 +1107,10 @@ pub async fn fetch_users_by_query( local_var_req_builder = local_var_req_builder.query(&[("legacy_user_id", &local_var_str.to_string())]); } + if let Some(ref local_var_str) = isolated_org_id { + local_var_req_builder = + local_var_req_builder.query(&[("isolated_org_id", &local_var_str.to_string())]); + } if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone()); diff --git a/src/models/fetch_org_response.rs b/src/models/fetch_org_response.rs index 9958990..51812ce 100644 --- a/src/models/fetch_org_response.rs +++ b/src/models/fetch_org_response.rs @@ -45,6 +45,7 @@ pub struct FetchOrgResponse { pub extra_domains: Vec, pub domain_autojoin: bool, pub domain_restrict: bool, + pub isolated: bool } impl FetchOrgResponse { @@ -58,6 +59,7 @@ impl FetchOrgResponse { is_saml_in_test_mode: bool, domain_autojoin: bool, domain_restrict: bool, + isolated: bool, ) -> FetchOrgResponse { FetchOrgResponse { org_id, @@ -74,6 +76,7 @@ impl FetchOrgResponse { extra_domains: Vec::new(), domain_autojoin, domain_restrict, + isolated } } } diff --git a/src/models/fetch_orgs_response.rs b/src/models/fetch_orgs_response.rs index 7e9a1f8..bea3177 100644 --- a/src/models/fetch_orgs_response.rs +++ b/src/models/fetch_orgs_response.rs @@ -23,16 +23,19 @@ pub struct FetchOrgsResponse { pub page_size: i64, #[serde(rename = "has_more_results")] pub has_more_results: bool, + #[serde(rename = "isolated")] + pub isolated: bool, } impl FetchOrgsResponse { - pub fn new(orgs: Vec, total_orgs: i64, current_page: i64, page_size: i64, has_more_results: bool) -> FetchOrgsResponse { + pub fn new(orgs: Vec, total_orgs: i64, current_page: i64, page_size: i64, has_more_results: bool, isolated: bool) -> FetchOrgsResponse { FetchOrgsResponse { orgs, total_orgs, current_page, page_size, has_more_results, + isolated } } } diff --git a/src/models/update_org_request.rs b/src/models/update_org_request.rs index 5ca6a68..438a0a1 100644 --- a/src/models/update_org_request.rs +++ b/src/models/update_org_request.rs @@ -34,6 +34,8 @@ pub struct UpdateOrgRequest { pub require_2fa_by: Option, #[serde(rename = "extra_domains", skip_serializing_if = "Option::is_none")] pub extra_domains: Option>, + #[serde(rename = "sso_trust_level", skip_serializing_if = "Option::is_none")] + pub sso_trust_level: Option, } impl UpdateOrgRequest { @@ -49,6 +51,7 @@ impl UpdateOrgRequest { legacy_org_id: None, require_2fa_by: None, extra_domains: None, + sso_trust_level: None } } } diff --git a/src/propelauth/errors.rs b/src/propelauth/errors.rs index 7f79515..91144ce 100644 --- a/src/propelauth/errors.rs +++ b/src/propelauth/errors.rs @@ -300,6 +300,25 @@ pub enum OrgMissingOrRoleError { UnexpectedException, } + +#[derive(Error, Debug, Eq, PartialEq, Copy, Clone)] +pub enum OrgMissingOrMigrateError { + #[error("Invalid API Key")] + InvalidApiKey, + + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + + #[error("Migrate Org Exception")] + MigrateOrgToIsolatedException, + + #[error("Not found")] + NotFound, + + #[error("Unexpected exception, please try again")] + UnexpectedException, +} + #[derive(Error, Debug, PartialEq, Clone)] pub enum FetchUsersInOrgError { #[error("Invalid API Key")] diff --git a/src/propelauth/org.rs b/src/propelauth/org.rs index ed31535..605d9d2 100644 --- a/src/propelauth/org.rs +++ b/src/propelauth/org.rs @@ -1,10 +1,6 @@ use crate::apis::configuration::Configuration; use crate::apis::org_service_api::{ - AddUserToOrgParams, AllowOrgToEnableSamlParams, ChangeUserRoleInOrgParams, CreateOrgParams, - CreateSamlConnectionLinkParams, DeleteOrgParams, DisallowSamlParams, FetchOrgParams, - FetchOrgsByQueryParams, FetchPendingInvitesParams, FetchUsersInOrgParams, - RemoveUserFromOrgParams, RevokePendingOrgInviteParams, SubscribeOrgToRoleMappingParams, - UpdateOrgParams, + AddUserToOrgParams, AllowOrgToEnableSamlParams, ChangeUserRoleInOrgParams, CreateOrgParams, CreateSamlConnectionLinkParams, DeleteOrgParams, DisallowSamlParams, FetchOrgParams, FetchOrgsByQueryParams, FetchPendingInvitesParams, FetchUsersInOrgParams, MigrateOrgToIsolatedParams, RemoveUserFromOrgParams, RevokePendingOrgInviteParams, SubscribeOrgToRoleMappingParams, UpdateOrgParams }; use crate::models::{ AddUserToOrgRequest, ChangeUserRoleInOrgRequest, CreateOrgRequest, CreateOrgResponse, @@ -14,8 +10,7 @@ use crate::models::{ UserPagedResponse, }; use crate::propelauth::errors::{ - CreateOrgError, ErrorsWithNotFound, FetchOrgsByQueryError, FetchUsersInOrgError, - OrgMissingOrRoleError, UpdateOrgError, + CreateOrgError, ErrorsWithNotFound, FetchOrgsByQueryError, FetchUsersInOrgError, OrgMissingOrMigrateError, OrgMissingOrRoleError, UpdateOrgError }; use crate::propelauth::helpers::{is_valid_id, map_autogenerated_error}; @@ -566,4 +561,30 @@ impl OrgService<'_> { })?; Ok(()) } + + pub async fn migrate_org_to_isolated( + &self, + params: MigrateOrgToIsolatedParams, + ) -> Result<(), OrgMissingOrMigrateError> { + if !is_valid_id(¶ms.org_id) { + return Err(OrgMissingOrMigrateError::NotFound); + } + + crate::apis::org_service_api::migrate_org_to_isolated(&self.config, params) + .await + .map_err(|err| { + map_autogenerated_error( + err, + OrgMissingOrMigrateError::UnexpectedException, + |status_code, _| match status_code.as_u16() { + 400 => OrgMissingOrMigrateError::MigrateOrgToIsolatedException, + 401 => OrgMissingOrMigrateError::InvalidApiKey, + 429 => OrgMissingOrMigrateError::PropelAuthRateLimit, + 404 => OrgMissingOrMigrateError::NotFound, + _ => OrgMissingOrMigrateError::UnexpectedException, + }, + ) + })?; + Ok(()) + } } From 6a621d8c6f441b9a69ba3b949bbca90600cd3a23 Mon Sep 17 00:00:00 2001 From: pfvatterott Date: Tue, 6 Jan 2026 10:27:13 -0700 Subject: [PATCH 2/2] Include isolated_org_id in fetch users response --- src/models/user_metadata.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/models/user_metadata.rs b/src/models/user_metadata.rs index b8eda28..3156383 100644 --- a/src/models/user_metadata.rs +++ b/src/models/user_metadata.rs @@ -48,6 +48,8 @@ pub struct UserMetadata { pub metadata: Option>, #[serde(rename = "properties", skip_serializing_if = "Option::is_none")] pub properties: Option>, + #[serde(rename = "isolated_org_id", skip_serializing_if = "Option::is_none")] + pub isolated_org_id: Option, /// `role_in_org` is only returned when using `fetch_users_in_org` /// and is their role for the org specified in the query. #[serde(rename = "role_in_org", default)] @@ -88,6 +90,7 @@ impl UserMetadata { legacy_user_id: None, metadata: None, properties: None, + isolated_org_id: None, role_in_org: None, additional_roles_in_org: None, }