diff --git a/src/apis/api_key_service_api.rs b/src/apis/api_key_service_api.rs index d14df3d..810a6ac 100644 --- a/src/apis/api_key_service_api.rs +++ b/src/apis/api_key_service_api.rs @@ -28,6 +28,7 @@ pub struct CreateApiKeyParams { pub metadata: Option, pub user_id: Option, pub org_id: Option, + pub display_name: Option, } /// struct for passing parameters to the method [`import_api_key`] @@ -38,6 +39,7 @@ pub struct ImportApiKeyParams { pub metadata: Option, pub user_id: Option, pub org_id: Option, + pub display_name: Option, } /// struct for passing parameters to the method [`update_api_key`] @@ -571,4 +573,4 @@ pub async fn validate_imported_api_key( }; Err(Error::ResponseError(error)) } -} \ No newline at end of file +} diff --git a/src/apis/mod.rs b/src/apis/mod.rs index f5efcb9..22a6c99 100644 --- a/src/apis/mod.rs +++ b/src/apis/mod.rs @@ -74,6 +74,7 @@ pub mod api_key_service_api; pub mod auth_service_api; pub mod employee_service_api; pub mod mfa_service_api; +pub mod scim_service_api; pub mod org_service_api; pub(crate) mod user_insights_service_api; pub mod user_service_api; diff --git a/src/apis/org_service_api.rs b/src/apis/org_service_api.rs index 1bfa5b1..ecaa4e4 100644 --- a/src/apis/org_service_api.rs +++ b/src/apis/org_service_api.rs @@ -304,6 +304,16 @@ pub enum DeleteOrgError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`set_oidc_idp_metadata`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum SetOidcIdpMetadataError { + 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, @@ -1335,6 +1345,54 @@ pub async fn subscribe_org_to_role_mapping( } } +pub async fn set_oidc_idp_metadata( + configuration: &configuration::Configuration, + set_idp_request: crate::models::SetOidcIdpMetadataRequest, +) -> Result> { + let local_var_configuration = configuration; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/api/backend/v1/oidc_idp_metadata", + 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); + } + 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); + }; + local_var_req_builder = local_var_req_builder.header( + AUTH_HOSTNAME_HEADER, + local_var_configuration.auth_hostname.to_owned(), + ); + local_var_req_builder = local_var_req_builder.json(&set_idp_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() { + Ok(SuccessfulResponse::new()) + } 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)) + } +} + pub async fn delete_org( configuration: &configuration::Configuration, params: DeleteOrgParams, diff --git a/src/apis/scim_service_api.rs b/src/apis/scim_service_api.rs new file mode 100644 index 0000000..41f0773 --- /dev/null +++ b/src/apis/scim_service_api.rs @@ -0,0 +1,155 @@ +/* + * propelauth + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.1.0 + * + * Generated by: https://openapi-generator.tech + */ + +use reqwest; + +use super::{configuration, Error}; +use crate::propelauth::auth::AUTH_HOSTNAME_HEADER; +use crate::apis::ResponseContent; +use crate::models::{ + FetchOrgScimGroupsError, FetchOrgScimGroupsRequest, + FetchScimGroupError, FetchScimGroupRequest, + ScimGroup, ScimGroupResultPage, +}; + + +pub async fn fetch_org_scim_groups( + configuration: &configuration::Configuration, + params: FetchOrgScimGroupsRequest, +) -> Result> { + let local_var_configuration = configuration; + + // unbox the parameters + let FetchOrgScimGroupsRequest { + org_id, + user_id, + page_size, + page_number, + } = params; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/api/backend/v1/scim/{org_id}/groups", + local_var_configuration.base_path, + org_id = crate::apis::urlencode(org_id) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); + + if let Some(ref local_var_str) = page_size { + local_var_req_builder = + local_var_req_builder.query(&[("page_size", &local_var_str.to_string())]); + } + if let Some(ref local_var_str) = page_number { + local_var_req_builder = + local_var_req_builder.query(&[("page_number", &local_var_str.to_string())]); + } + if let Some(ref local_var_str) = user_id { + local_var_req_builder = + local_var_req_builder.query(&[("user_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()); + } + 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 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: crate::apis::ResponseContent = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } +} + +pub async fn fetch_scim_group( + configuration: &configuration::Configuration, + params: FetchScimGroupRequest, +) -> Result> { + let local_var_configuration = configuration; + + // unbox the parameters + let FetchScimGroupRequest { + org_id, + group_id, + members_page_number, + members_page_size + } = params; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/api/backend/v1/scim/{org_id}/groups/{group_id}", + local_var_configuration.base_path, + org_id = crate::apis::urlencode(org_id), + group_id = crate::apis::urlencode(group_id) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); + + if let Some(ref local_var_str) = members_page_size { + local_var_req_builder = + local_var_req_builder.query(&[("members_page_size", &local_var_str.to_string())]); + } + if let Some(ref local_var_str) = members_page_number { + local_var_req_builder = + local_var_req_builder.query(&[("members_page_number", &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()); + } + 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 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: crate::apis::ResponseContent = ResponseContent { + status: local_var_status, + content: local_var_content, + entity: local_var_entity, + }; + Err(Error::ResponseError(local_var_error)) + } +} diff --git a/src/apis/user_service_api.rs b/src/apis/user_service_api.rs index 230d409..4ce26f7 100644 --- a/src/apis/user_service_api.rs +++ b/src/apis/user_service_api.rs @@ -79,6 +79,19 @@ pub struct FetchUserMfaMethodsParams { pub user_id: String, } +/// struct for passing parameters to the method [`fetch_user_oauth_tokens`] +#[derive(Clone, Debug, Default)] +pub struct FetchUserOAuthTokensParams { + pub user_id: String, +} + +/// struct for passing parameters to the method [`fetch_fresh_token_from_provider`] +#[derive(Clone, Debug)] +pub struct FetchFreshTokenFromProviderParams { + pub user_id: String, + pub provider: crate::models::SocialLoginTokenProvider, +} + /// struct for passing parameters to the method [`fetch_user_by_username`] #[derive(Clone, Debug, Default)] pub struct FetchUserByUsernameParams { @@ -247,6 +260,24 @@ pub enum FetchUserByIdError { UnknownValue(serde_json::Value), } +/// struct for typed errors of method [`fetch_user_oauth_tokens`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum FetchUserOAuthTokensError { + Status401(serde_json::Value), + Status404(serde_json::Value), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`fetch_fresh_token_from_provider`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum FetchFreshTokenFromProviderError { + Status401(serde_json::Value), + Status404(serde_json::Value), + UnknownValue(serde_json::Value), +} + /// struct for typed errors of method [`fetch_user_by_username`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -1744,4 +1775,106 @@ pub async fn fetch_user_mfa_methods( }; Err(Error::ResponseError(local_var_error)) } +} + +pub async fn fetch_user_oauth_tokens( + configuration: &configuration::Configuration, + params: FetchUserOAuthTokensParams, +) -> Result> { + let local_var_configuration = configuration; + + let user_id = params.user_id; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/api/backend/v1/user/{user_id}/oauth_token", + local_var_configuration.base_path, + user_id = crate::apis::urlencode(user_id) + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::GET, 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 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)) + } +} + +pub async fn fetch_fresh_token_from_provider( + configuration: &configuration::Configuration, + params: FetchFreshTokenFromProviderParams, +) -> Result> { + let local_var_configuration = configuration; + + let user_id = params.user_id; + let provider = params.provider; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!( + "{}/api/backend/v1/user/{user_id}/{provider}/fresh_token", + local_var_configuration.base_path, + user_id = crate::apis::urlencode(user_id), + provider = crate::apis::urlencode(provider.to_string()), + ); + let mut local_var_req_builder = + local_var_client.request(reqwest::Method::GET, 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 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/models/create_magic_link_request.rs b/src/models/create_magic_link_request.rs index 23d2ffd..38b89b1 100644 --- a/src/models/create_magic_link_request.rs +++ b/src/models/create_magic_link_request.rs @@ -7,7 +7,7 @@ * * Generated by: https://openapi-generator.tech */ - +use std::collections::HashMap; @@ -23,6 +23,10 @@ pub struct CreateMagicLinkRequest { pub create_new_user_if_one_doesnt_exist: Option, #[serde(rename = "expire_after_first_use", skip_serializing_if = "Option::is_none")] pub expire_after_first_use: Option, + #[serde(rename = "requires_interstitial", skip_serializing_if = "Option::is_none")] + pub requires_interstitial: Option, + #[serde(rename = "user_signup_query_parameters", skip_serializing_if = "Option::is_none")] + pub user_signup_query_parameters: Option>, } impl CreateMagicLinkRequest { @@ -33,8 +37,8 @@ impl CreateMagicLinkRequest { expires_in_hours: None, create_new_user_if_one_doesnt_exist: None, expire_after_first_use: None, + requires_interstitial: None, + user_signup_query_parameters: None } } } - - diff --git a/src/models/fetch_api_key_response.rs b/src/models/fetch_api_key_response.rs index 929b515..fba5c3f 100644 --- a/src/models/fetch_api_key_response.rs +++ b/src/models/fetch_api_key_response.rs @@ -6,10 +6,11 @@ pub struct FetchApiKeyResponse { pub metadata: Option, pub user_id: Option, pub org_id: Option, + pub display_name: Option, } impl FetchApiKeyResponse { - pub fn new(api_key_id: String, created_at: i32, expires_at_seconds: Option, metadata: Option, user_id: Option, org_id: Option) -> Self { - Self { api_key_id, created_at, expires_at_seconds, metadata, user_id, org_id } + pub fn new(api_key_id: String, created_at: i32, expires_at_seconds: Option, metadata: Option, user_id: Option, org_id: Option, display_name: Option) -> Self { + Self { api_key_id, created_at, expires_at_seconds, metadata, user_id, org_id, display_name } } } diff --git a/src/models/fetch_org_response.rs b/src/models/fetch_org_response.rs index 9958990..af3e33e 100644 --- a/src/models/fetch_org_response.rs +++ b/src/models/fetch_org_response.rs @@ -45,6 +45,9 @@ pub struct FetchOrgResponse { pub extra_domains: Vec, pub domain_autojoin: bool, pub domain_restrict: bool, + pub password_rotation_enabled: bool, + pub password_rotation_history_size: i32, + pub password_rotation_period: i32 } impl FetchOrgResponse { @@ -58,6 +61,9 @@ impl FetchOrgResponse { is_saml_in_test_mode: bool, domain_autojoin: bool, domain_restrict: bool, + password_rotation_enabled: bool, + password_rotation_history_size: i32, + password_rotation_period: i32, ) -> FetchOrgResponse { FetchOrgResponse { org_id, @@ -74,6 +80,9 @@ impl FetchOrgResponse { extra_domains: Vec::new(), domain_autojoin, domain_restrict, + password_rotation_enabled, + password_rotation_history_size, + password_rotation_period, } } } @@ -92,6 +101,7 @@ pub struct FetchOrgBasicResponse { pub custom_role_mapping_name: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub legacy_org_id: Option, + pub created_at: i64, } impl crate::models::FetchOrgBasicResponse { @@ -100,6 +110,7 @@ impl crate::models::FetchOrgBasicResponse { name: String, metadata: OrgMetadata, is_saml_configured: bool, + created_at: i64 ) -> crate::models::FetchOrgBasicResponse { crate::models::FetchOrgBasicResponse { org_id, @@ -109,6 +120,7 @@ impl crate::models::FetchOrgBasicResponse { max_users: None, custom_role_mapping_name: None, legacy_org_id: None, + created_at } } } diff --git a/src/models/mod.rs b/src/models/mod.rs index 14e46cb..3aaa6e5 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -118,6 +118,12 @@ pub mod fetch_saml_sp_metadata_response; pub use self::fetch_saml_sp_metadata_response::FetchSamlSpMetadataResponse; pub mod set_saml_idp_metadata_request; pub use self::set_saml_idp_metadata_request::SetSamlIdpMetadataRequest; +pub mod set_oidc_idp_metadata_request; +pub use self::set_oidc_idp_metadata_request::SetAzureOidcMetadataRequest; +pub use self::set_oidc_idp_metadata_request::SetGenericOidcMetadataRequest; +pub use self::set_oidc_idp_metadata_request::SetOidcIdpMetadataRequest; +pub use self::set_oidc_idp_metadata_request::SetOidcIdpMetadataRequestBase; +pub use self::set_oidc_idp_metadata_request::SetOktaOidcMetadataRequest; pub mod fetch_api_key_usage_response; pub use self::fetch_api_key_usage_response::FetchApiKeyUsageResponse; pub mod import_api_key_response; @@ -134,3 +140,18 @@ pub mod send_sms_mfa_code_response; pub use self::send_sms_mfa_code_response::SendSmsCodeResponse; pub mod verify_sms_challenge_response; pub use self::verify_sms_challenge_response::VerifySmsChallengeResponse; +pub mod social_login_token; +pub use self::social_login_token::SocialLoginToken; +pub use self::social_login_token::SocialLoginTokenProvider; +pub use self::social_login_token::SocialLoginTokensResponse; +pub mod scim_group; +pub use self::scim_group::ScimGroup; +pub use self::scim_group::ScimGroupMember; +pub use self::scim_group::ScimGroupResult; +pub use self::scim_group::ScimGroupResultPage; +pub mod scim_group_requests; +pub use self::scim_group_requests::FetchOrgScimGroupsRequest; +pub use self::scim_group_requests::FetchScimGroupRequest; +pub mod scim_group_errors; +pub use self::scim_group_errors::FetchOrgScimGroupsError; +pub use self::scim_group_errors::FetchScimGroupError; diff --git a/src/models/scim_group.rs b/src/models/scim_group.rs new file mode 100644 index 0000000..36c5f5e --- /dev/null +++ b/src/models/scim_group.rs @@ -0,0 +1,87 @@ +/* + * propelauth + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.1.0 + * + * Generated by: https://openapi-generator.tech + */ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct ScimGroupResult { + #[serde(rename = "group_id")] + pub group_id: String, + #[serde(rename = "display_name")] + pub display_name: String, + #[serde(rename = "external_id_from_idp")] + pub external_id_from_idp: Option, +} + +impl ScimGroupResult { + pub fn new(group_id: String, display_name: String) -> ScimGroupResult { + ScimGroupResult { + group_id, + display_name, + external_id_from_idp: None, + } + } +} + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct ScimGroupResultPage { + #[serde(rename = "groups")] + pub groups: Vec, + #[serde(rename = "total_groups")] + pub total_groups: i64, + #[serde(rename = "page_number")] + pub page_number: i64, + #[serde(rename = "page_size")] + pub page_size: i64, +} + +impl ScimGroupResultPage { + pub fn new(groups: Vec, total_groups: i64, page_number: i64, page_size: i64) -> ScimGroupResultPage { + ScimGroupResultPage { + groups, + total_groups, + page_number, + page_size, + } + } +} + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct ScimGroupMember { + #[serde(rename = "user_id")] + pub user_id: String, +} + +impl ScimGroupMember { + pub fn new(user_id: String) -> ScimGroupMember { + ScimGroupMember { user_id } + } +} + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct ScimGroup { + #[serde(rename = "group_id")] + pub group_id: String, + #[serde(rename = "display_name")] + pub display_name: String, + #[serde(rename = "external_id_from_idp")] + pub external_id_from_idp: Option, + #[serde(rename = "members")] + pub members: Vec, +} + +impl ScimGroup { + pub fn new(group_id: String, display_name: String, members: Vec) -> ScimGroup { + ScimGroup { + group_id, + display_name, + external_id_from_idp: None, + members, + } + } +} diff --git a/src/models/scim_group_errors.rs b/src/models/scim_group_errors.rs new file mode 100644 index 0000000..46d48b2 --- /dev/null +++ b/src/models/scim_group_errors.rs @@ -0,0 +1,27 @@ +/* + * propelauth + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.1.0 + * + * Generated by: https://openapi-generator.tech + */ + +/// struct for typed errors of method [`fetch_org_scim_groups`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum FetchOrgScimGroupsError { + Status401(serde_json::Value), + Status404(serde_json::Value), + UnknownValue(serde_json::Value), +} + +/// struct for typed errors of method [`fetch_scim_group`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum FetchScimGroupError { + Status401(serde_json::Value), + Status404(serde_json::Value), + UnknownValue(serde_json::Value), +} diff --git a/src/models/scim_group_requests.rs b/src/models/scim_group_requests.rs new file mode 100644 index 0000000..5274eb9 --- /dev/null +++ b/src/models/scim_group_requests.rs @@ -0,0 +1,27 @@ +/* + * propelauth + * + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 0.1.0 + * + * Generated by: https://openapi-generator.tech + */ + +/// struct for passing parameters to the method [`fetch_org_scim_groups`] +#[derive(Clone, Debug, Default)] +pub struct FetchOrgScimGroupsRequest { + pub org_id: String, + pub user_id: Option, + pub page_size: Option, + pub page_number: Option, +} + +/// struct for passing parameters to the method [`fetch_scim_group`] +#[derive(Clone, Debug, Default)] +pub struct FetchScimGroupRequest { + pub org_id: String, + pub group_id: String, + pub members_page_size: Option, + pub members_page_number: Option, +} diff --git a/src/models/set_oidc_idp_metadata_request.rs b/src/models/set_oidc_idp_metadata_request.rs new file mode 100644 index 0000000..a787910 --- /dev/null +++ b/src/models/set_oidc_idp_metadata_request.rs @@ -0,0 +1,47 @@ +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct SetOidcIdpMetadataRequestBase { + #[serde(rename = "org_id")] + pub org_id: String, + #[serde(rename = "client_id")] + pub client_id: String, + #[serde(rename = "client_secret")] + pub client_secret: String, + #[serde(rename = "uses_pkce")] + pub uses_pkce: bool, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct SetGenericOidcMetadataRequest { + #[serde(flatten)] + pub base: SetOidcIdpMetadataRequestBase, + #[serde(rename = "auth_url")] + pub auth_url: String, + #[serde(rename = "token_url")] + pub token_url: String, + #[serde(rename = "userinfo_url")] + pub userinfo_url: String, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct SetOktaOidcMetadataRequest { + #[serde(flatten)] + pub base: SetOidcIdpMetadataRequestBase, + #[serde(rename = "okta_sso_domain")] + pub okta_sso_domain: String, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct SetAzureOidcMetadataRequest { + #[serde(flatten)] + pub base: SetOidcIdpMetadataRequestBase, + #[serde(rename = "entra_tenant_id")] + pub entra_tenant_id: String, +} + +#[derive(Clone, Debug, PartialEq, Serialize)] +#[serde(tag = "idp_type")] +pub enum SetOidcIdpMetadataRequest { + Generic(SetGenericOidcMetadataRequest), + Okta(SetOktaOidcMetadataRequest), + Azure(SetAzureOidcMetadataRequest), +} diff --git a/src/models/social_login_token.rs b/src/models/social_login_token.rs new file mode 100644 index 0000000..bed2b65 --- /dev/null +++ b/src/models/social_login_token.rs @@ -0,0 +1,56 @@ +use std::collections::HashMap; + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum SocialLoginTokenProvider { + Apple, + Google, + Github, + Microsoft, + Slack, + Salesforce, + Linkedin, + Outreach, + Quickbooks, + Xero, + Salesloft, + Atlassian, + Gitlab, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct SocialLoginToken { + #[serde(rename = "access_token")] + pub access_token: String, + #[serde(rename = "refresh_token", skip_serializing_if = "Option::is_none")] + pub refresh_token: Option, + #[serde(rename = "token_provider")] + pub token_provider: SocialLoginTokenProvider, + #[serde(rename = "token_expiration", skip_serializing_if = "Option::is_none")] + pub token_expiration: Option, + #[serde(rename = "authorized_scopes", skip_serializing_if = "Option::is_none")] + pub authorized_scopes: Option>, +} + +pub type SocialLoginTokensResponse = HashMap; + +impl std::fmt::Display for SocialLoginTokenProvider { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match self { + SocialLoginTokenProvider::Apple => "apple", + SocialLoginTokenProvider::Google => "google", + SocialLoginTokenProvider::Github => "github", + SocialLoginTokenProvider::Microsoft => "microsoft", + SocialLoginTokenProvider::Slack => "slack", + SocialLoginTokenProvider::Salesforce => "salesforce", + SocialLoginTokenProvider::Linkedin => "linkedin", + SocialLoginTokenProvider::Outreach => "outreach", + SocialLoginTokenProvider::Quickbooks => "quickbooks", + SocialLoginTokenProvider::Xero => "xero", + SocialLoginTokenProvider::Salesloft => "salesloft", + SocialLoginTokenProvider::Atlassian => "atlassian", + SocialLoginTokenProvider::Gitlab => "gitlab", + }; + write!(f, "{}", s) + } +} diff --git a/src/models/update_org_request.rs b/src/models/update_org_request.rs index 5ca6a68..9266295 100644 --- a/src/models/update_org_request.rs +++ b/src/models/update_org_request.rs @@ -34,6 +34,12 @@ pub struct UpdateOrgRequest { pub require_2fa_by: Option, #[serde(rename = "extra_domains", skip_serializing_if = "Option::is_none")] pub extra_domains: Option>, + #[serde(rename = "password_rotation_enabled", skip_serializing_if = "Option::is_none")] + pub password_rotation_enabled: Option, + #[serde(rename = "password_rotation_history_size", skip_serializing_if = "Option::is_none")] + pub password_rotation_history_size: Option, + #[serde(rename = "password_rotation_period", skip_serializing_if = "Option::is_none")] + pub password_rotation_period: Option, } impl UpdateOrgRequest { @@ -49,6 +55,9 @@ impl UpdateOrgRequest { legacy_org_id: None, require_2fa_by: None, extra_domains: None, + password_rotation_enabled: None, + password_rotation_history_size: None, + password_rotation_period: None, } } } diff --git a/src/propelauth/auth.rs b/src/propelauth/auth.rs index 55f0ab4..38e4aec 100644 --- a/src/propelauth/auth.rs +++ b/src/propelauth/auth.rs @@ -13,6 +13,7 @@ use crate::propelauth::options::{AuthOptions, AuthOptionsWithTokenVerification}; use crate::propelauth::org::OrgService; use crate::propelauth::token::TokenService; use crate::propelauth::user::UserService; +use crate::propelauth::scim::ScimService; use crate::propelauth::user_insights::UserInsightsService; static BACKEND_API_BASE_URL: &str = "https://propelauth-api.com"; @@ -131,6 +132,13 @@ impl PropelAuth { config: &self.config, } } + + /// API requests related to scim. + pub fn scim(&self) -> ScimService { + ScimService { + config: &self.config, + } + } /// API requests related to user insights data. pub fn user_insights(&self) -> UserInsightsService { diff --git a/src/propelauth/mod.rs b/src/propelauth/mod.rs index 70459b1..1fd3455 100644 --- a/src/propelauth/mod.rs +++ b/src/propelauth/mod.rs @@ -11,3 +11,4 @@ pub mod token; pub mod token_models; pub mod user; pub mod user_insights; +pub mod scim; \ No newline at end of file diff --git a/src/propelauth/org.rs b/src/propelauth/org.rs index ed31535..5daeaad 100644 --- a/src/propelauth/org.rs +++ b/src/propelauth/org.rs @@ -10,8 +10,8 @@ use crate::models::{ AddUserToOrgRequest, ChangeUserRoleInOrgRequest, CreateOrgRequest, CreateOrgResponse, CreateSamlConnectionLinkResponse, FetchOrgResponse, FetchOrgsResponse, FetchSamlSpMetadataResponse, InviteUserToOrgRequest, RemoveUserFromOrgRequest, - RevokePendingOrgInviteRequest, SubscribeOrgToRoleMappingRequest, UpdateOrgRequest, - UserPagedResponse, + RevokePendingOrgInviteRequest, SetOidcIdpMetadataRequest, SubscribeOrgToRoleMappingRequest, + UpdateOrgRequest, UserPagedResponse, }; use crate::propelauth::errors::{ CreateOrgError, ErrorsWithNotFound, FetchOrgsByQueryError, FetchUsersInOrgError, @@ -443,6 +443,36 @@ impl OrgService<'_> { Ok(()) } + pub async fn set_oidc_idp_metadata( + &self, + request: SetOidcIdpMetadataRequest, + ) -> Result<(), ErrorsWithNotFound> { + let org_id = match &request { + SetOidcIdpMetadataRequest::Generic(r) => &r.base.org_id, + SetOidcIdpMetadataRequest::Okta(r) => &r.base.org_id, + SetOidcIdpMetadataRequest::Azure(r) => &r.base.org_id, + }; + if !is_valid_id(org_id) { + return Err(ErrorsWithNotFound::NotFound); + } + + crate::apis::org_service_api::set_oidc_idp_metadata(&self.config, request) + .await + .map_err(|err| { + map_autogenerated_error( + err, + ErrorsWithNotFound::UnexpectedException, + |status_code, _| match status_code.as_u16() { + 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, + 404 => ErrorsWithNotFound::NotFound, + _ => ErrorsWithNotFound::UnexpectedException, + }, + ) + })?; + Ok(()) + } + pub async fn saml_go_live(&self, org_id: String) -> Result<(), ErrorsWithNotFound> { if !is_valid_id(&org_id) { return Err(ErrorsWithNotFound::NotFound); diff --git a/src/propelauth/scim.rs b/src/propelauth/scim.rs new file mode 100644 index 0000000..91312ba --- /dev/null +++ b/src/propelauth/scim.rs @@ -0,0 +1,63 @@ +use crate::apis::configuration::Configuration; +use crate::models::{ + FetchOrgScimGroupsRequest, FetchScimGroupRequest, + ScimGroup, ScimGroupResultPage, +}; +use crate::propelauth::helpers::{is_valid_id, map_autogenerated_error}; +use crate::propelauth::errors::ErrorsWithNotFound; + +pub struct ScimService<'a> { + pub(crate) config: &'a Configuration, +} + +impl ScimService<'_> { + + pub async fn fetch_org_scim_groups( + &self, + params: FetchOrgScimGroupsRequest, + ) -> Result { + if !is_valid_id(¶ms.org_id) { + return Err(ErrorsWithNotFound::NotFound); + } + + crate::apis::scim_service_api::fetch_org_scim_groups(&self.config, params) + .await + .map_err(|err| { + map_autogenerated_error( + err, + ErrorsWithNotFound::UnexpectedException, + |status_code, _| match status_code.as_u16() { + 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, + 404 => ErrorsWithNotFound::NotFound, + _ => ErrorsWithNotFound::UnexpectedException, + }, + ) + }) + } + + pub async fn fetch_scim_group( + &self, + params: FetchScimGroupRequest, + ) -> Result { + if !is_valid_id(¶ms.org_id) { + return Err(ErrorsWithNotFound::NotFound); + } + + crate::apis::scim_service_api::fetch_scim_group(&self.config, params) + .await + .map_err(|err| { + map_autogenerated_error( + err, + ErrorsWithNotFound::UnexpectedException, + |status_code, _| match status_code.as_u16() { + 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, + 404 => ErrorsWithNotFound::NotFound, + _ => ErrorsWithNotFound::UnexpectedException, + }, + ) + }) + } + +} diff --git a/src/propelauth/user.rs b/src/propelauth/user.rs index 1e4e0f6..99ccc26 100644 --- a/src/propelauth/user.rs +++ b/src/propelauth/user.rs @@ -5,11 +5,13 @@ use crate::apis::user_service_api::{ FetchUserByUsernameParams, FetchUsersByEmailsError, FetchUsersByEmailsParams, FetchUsersByIdsError, FetchUsersByIdsParams, FetchUsersByQueryError, FetchUsersByQueryParams, FetchUsersByUsernamesError, FetchUsersByUsernamesParams, MigrateUserParams, MigrateUserPasswordParams, - UpdateUserEmailParams, UpdateUserMetadataParams, UpdateUserPasswordParams, FetchUserSignupQueryParamsParams, FetchUserMfaMethodsParams + UpdateUserEmailParams, UpdateUserMetadataParams, UpdateUserPasswordParams, FetchUserSignupQueryParamsParams, FetchUserMfaMethodsParams, + FetchUserOAuthTokensParams, FetchFreshTokenFromProviderParams, }; use crate::models::{ CreateMagicLinkRequest, CreateUserRequest, CreatedUserResponse, MagicLink, MigrateUserRequest, MigrateUserPasswordRequest, - UserMetadata, UserPagedResponse, FetchSignupQueryParamsResponse, FetchUserMfaMethodsResponse + UserMetadata, UserPagedResponse, FetchSignupQueryParamsResponse, FetchUserMfaMethodsResponse, + SocialLoginTokensResponse, SocialLoginToken, SocialLoginTokenProvider, }; use crate::propelauth::errors::{ BatchFetchError, ClearPasswordError, CreateMagicLinkError, CreateUserError, ErrorsWithNotFound, @@ -697,4 +699,57 @@ impl UserService<'_> { ) }) } + + pub async fn fetch_fresh_token_from_provider( + &self, + user_id: String, + provider: SocialLoginTokenProvider, + ) -> Result, ErrorsWithNotFound> { + if !is_valid_id(&user_id) { + return Ok(None); + } + + let params = FetchFreshTokenFromProviderParams { user_id, provider }; + crate::apis::user_service_api::fetch_fresh_token_from_provider(&self.config, params) + .await + .map(Some) + .map_err(|err| { + map_autogenerated_error( + err, + ErrorsWithNotFound::UnexpectedException, + |status_code, _| match status_code.as_u16() { + 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, + 404 => ErrorsWithNotFound::NotFound, + _ => ErrorsWithNotFound::UnexpectedException, + }, + ) + }) + } + + pub async fn fetch_user_oauth_tokens( + &self, + user_id: String, + ) -> Result, ErrorsWithNotFound> { + if !is_valid_id(&user_id) { + return Ok(None); + } + + let params = FetchUserOAuthTokensParams { user_id }; + crate::apis::user_service_api::fetch_user_oauth_tokens(&self.config, params) + .await + .map(Some) + .map_err(|err| { + map_autogenerated_error( + err, + ErrorsWithNotFound::UnexpectedException, + |status_code, _| match status_code.as_u16() { + 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, + 404 => ErrorsWithNotFound::NotFound, + _ => ErrorsWithNotFound::UnexpectedException, + }, + ) + }) + } }