From 0ac2002cffa9f67acc91af1ff00a7386e6e09a5c Mon Sep 17 00:00:00 2001 From: Matthew Mauer Date: Tue, 11 Feb 2025 16:50:44 -0500 Subject: [PATCH 1/4] catch PropelAuthRateLimit error on all requests --- src/apis/api_key_service_api.rs | 1 + src/propelauth/access_token.rs | 2 + src/propelauth/api_key.rs | 70 +++++++++++++++++++++++++-------- src/propelauth/auth.rs | 3 +- src/propelauth/errors.rs | 54 +++++++++++++++++++++++++ src/propelauth/org.rs | 21 ++++++++++ src/propelauth/user.rs | 20 ++++++++++ 7 files changed, 153 insertions(+), 18 deletions(-) diff --git a/src/apis/api_key_service_api.rs b/src/apis/api_key_service_api.rs index 4a1a656..9799f90 100644 --- a/src/apis/api_key_service_api.rs +++ b/src/apis/api_key_service_api.rs @@ -56,6 +56,7 @@ pub enum ApiKeyError { wait_seconds: f64, user_facing_error: String, }, + PropelAuthRateLimit, InvalidPersonalAPIKey, InvalidOrgAPIKey, NotFound, diff --git a/src/propelauth/access_token.rs b/src/propelauth/access_token.rs index a54bc36..4389649 100644 --- a/src/propelauth/access_token.rs +++ b/src/propelauth/access_token.rs @@ -32,6 +32,7 @@ impl AccessTokenService<'_> { )), ) => CreateAccessTokenError::BadRequest(bad_request), (401, _) => CreateAccessTokenError::InvalidApiKey, + (429, _) => CreateAccessTokenError::PropelAuthRateLimit, (404, _) => CreateAccessTokenError::NotFound, _ => CreateAccessTokenError::UnexpectedException, }, @@ -61,6 +62,7 @@ impl AccessTokenService<'_> { )), ) => CreateAccessTokenError::BadRequest(bad_request), (401, _) => CreateAccessTokenError::InvalidApiKey, + (429, _) => CreateAccessTokenError::PropelAuthRateLimit, (404, _) => CreateAccessTokenError::NotFound, _ => CreateAccessTokenError::UnexpectedException, }, diff --git a/src/propelauth/api_key.rs b/src/propelauth/api_key.rs index d22b31a..244e8ff 100644 --- a/src/propelauth/api_key.rs +++ b/src/propelauth/api_key.rs @@ -1,7 +1,14 @@ -use crate::apis::api_key_service_api::{ApiKeyError, ApiKeyQueryParams, ApiKeyValidationErrorResponse, CreateApiKeyParams, UpdateApiKeyParams, ValidateApiKeyParams}; +use crate::apis::api_key_service_api::{ + ApiKeyError, ApiKeyQueryParams, ApiKeyValidationErrorResponse, CreateApiKeyParams, + UpdateApiKeyParams, ValidateApiKeyParams, +}; use crate::apis::configuration::Configuration; -use crate::models::{CreateApiKeyResponse, FetchApiKeyResponse, FetchApiKeysPagedResponse, ValidateApiKeyResponse}; -use crate::models::validate_api_key_response::{ValidateOrgApiKeyResponse, ValidatePersonalApiKeyResponse}; +use crate::models::validate_api_key_response::{ + ValidateOrgApiKeyResponse, ValidatePersonalApiKeyResponse, +}; +use crate::models::{ + CreateApiKeyResponse, FetchApiKeyResponse, FetchApiKeysPagedResponse, ValidateApiKeyResponse, +}; use crate::propelauth::helpers::map_autogenerated_error; pub struct ApiKeyService<'a> { @@ -9,7 +16,10 @@ pub struct ApiKeyService<'a> { } impl ApiKeyService<'_> { - pub async fn fetch_current_api_keys(&self, params: ApiKeyQueryParams) -> Result { + pub async fn fetch_current_api_keys( + &self, + params: ApiKeyQueryParams, + ) -> Result { crate::apis::api_key_service_api::fetch_current_api_keys(&self.config, params) .await .map_err(|err| { @@ -20,10 +30,11 @@ impl ApiKeyService<'_> { ( _, Some(crate::apis::api_key_service_api::ApiKeyError::BadRequest( - bad_request, - )), + bad_request, + )), ) => ApiKeyError::BadRequest(bad_request), (401, _) => ApiKeyError::InvalidIntegrationAPIKey, + (429, _) => ApiKeyError::PropelAuthRateLimit, (404, _) => ApiKeyError::NotFound, _ => ApiKeyError::UnexpectedExceptionWithSDK, }, @@ -31,7 +42,10 @@ impl ApiKeyService<'_> { }) } - pub async fn fetch_archived_api_keys(&self, params: ApiKeyQueryParams) -> Result { + pub async fn fetch_archived_api_keys( + &self, + params: ApiKeyQueryParams, + ) -> Result { crate::apis::api_key_service_api::fetch_archived_api_keys(&self.config, params) .await .map_err(|err| { @@ -42,10 +56,11 @@ impl ApiKeyService<'_> { ( _, Some(crate::apis::api_key_service_api::ApiKeyError::BadRequest( - bad_request, - )), + bad_request, + )), ) => ApiKeyError::BadRequest(bad_request), (401, _) => ApiKeyError::InvalidIntegrationAPIKey, + (429, _) => ApiKeyError::PropelAuthRateLimit, (404, _) => ApiKeyError::NotFound, _ => ApiKeyError::UnknownError, }, @@ -53,7 +68,10 @@ impl ApiKeyService<'_> { }) } - pub async fn fetch_api_key(&self, api_key_id: String) -> Result { + pub async fn fetch_api_key( + &self, + api_key_id: String, + ) -> Result { crate::apis::api_key_service_api::fetch_api_key(&self.config, api_key_id) .await .map_err(|err| { @@ -62,6 +80,7 @@ impl ApiKeyService<'_> { ApiKeyError::UnexpectedExceptionWithSDK, |status_code, _| match status_code.as_u16() { 401 => ApiKeyError::InvalidIntegrationAPIKey, + 429 => ApiKeyError::PropelAuthRateLimit, 404 => ApiKeyError::NotFound, _ => ApiKeyError::UnknownError, }, @@ -69,7 +88,10 @@ impl ApiKeyService<'_> { }) } - pub async fn create_api_key(&self, params: CreateApiKeyParams) -> Result { + pub async fn create_api_key( + &self, + params: CreateApiKeyParams, + ) -> Result { crate::apis::api_key_service_api::create_api_key(&self.config, params) .await .map_err(|err| { @@ -78,6 +100,7 @@ impl ApiKeyService<'_> { ApiKeyError::UnexpectedExceptionWithSDK, |status_code, _| match status_code.as_u16() { 401 => ApiKeyError::InvalidIntegrationAPIKey, + 429 => ApiKeyError::PropelAuthRateLimit, 404 => ApiKeyError::NotFound, _ => ApiKeyError::UnknownError, }, @@ -85,7 +108,11 @@ impl ApiKeyService<'_> { }) } - pub async fn update_api_key(&self, api_key_id: String, params: UpdateApiKeyParams) -> Result<(), ApiKeyError> { + pub async fn update_api_key( + &self, + api_key_id: String, + params: UpdateApiKeyParams, + ) -> Result<(), ApiKeyError> { crate::apis::api_key_service_api::update_api_key(&self.config, api_key_id, params) .await .map_err(|err| { @@ -94,6 +121,7 @@ impl ApiKeyService<'_> { ApiKeyError::UnexpectedExceptionWithSDK, |status_code, _| match status_code.as_u16() { 401 => ApiKeyError::InvalidIntegrationAPIKey, + 429 => ApiKeyError::PropelAuthRateLimit, 404 => ApiKeyError::NotFound, _ => ApiKeyError::UnknownError, }, @@ -112,6 +140,7 @@ impl ApiKeyService<'_> { ApiKeyError::UnexpectedExceptionWithSDK, |status_code, _| match status_code.as_u16() { 401 => ApiKeyError::InvalidIntegrationAPIKey, + 429 => ApiKeyError::PropelAuthRateLimit, 404 => ApiKeyError::NotFound, _ => ApiKeyError::UnknownError, }, @@ -127,10 +156,10 @@ impl ApiKeyService<'_> { ) -> Result { if hex::decode(¶ms.api_key_token).is_err() { return Err(ApiKeyError::InvalidAPIKey { - message: "Invalid API key format.".to_string() - }); + message: "Invalid API key format.".to_string(), + }); } - + crate::apis::api_key_service_api::validate_api_key(&self.config, params) .await .map_err(|err| { @@ -153,6 +182,7 @@ impl ApiKeyService<'_> { }, None => match status_code.as_u16() { 401 => ApiKeyError::InvalidIntegrationAPIKey, + 429 => ApiKeyError::PropelAuthRateLimit, 404 => ApiKeyError::NotFound, _ => ApiKeyError::UnknownError, }, @@ -161,7 +191,10 @@ impl ApiKeyService<'_> { }) } - pub async fn validate_personal_api_key(&self, params: ValidateApiKeyParams) -> Result { + pub async fn validate_personal_api_key( + &self, + params: ValidateApiKeyParams, + ) -> Result { let resp = self.validate_api_key(params).await?; if resp.user.is_none() || resp.org.is_some() { return Err(ApiKeyError::InvalidPersonalAPIKey); @@ -173,7 +206,10 @@ impl ApiKeyService<'_> { }) } - pub async fn validate_org_api_key(&self, params: ValidateApiKeyParams) -> Result { + pub async fn validate_org_api_key( + &self, + params: ValidateApiKeyParams, + ) -> Result { let resp = self.validate_api_key(params).await?; if resp.org.is_none() { return Err(ApiKeyError::InvalidOrgAPIKey); diff --git a/src/propelauth/auth.rs b/src/propelauth/auth.rs index 5621a2b..0f11800 100644 --- a/src/propelauth/auth.rs +++ b/src/propelauth/auth.rs @@ -3,6 +3,7 @@ use url::Url; use crate::apis::auth_service_api::token_verification_metadata; use crate::apis::configuration::Configuration; use crate::models::AuthTokenVerificationMetadata; +use crate::propelauth::access_token::AccessTokenService; use crate::propelauth::api_key::ApiKeyService; use crate::propelauth::errors::InitializationError; use crate::propelauth::helpers::map_autogenerated_error; @@ -10,7 +11,6 @@ use crate::propelauth::options::{AuthOptions, AuthOptionsWithTokenVerification}; use crate::propelauth::org::OrgService; use crate::propelauth::token::TokenService; use crate::propelauth::user::UserService; -use crate::propelauth::access_token::AccessTokenService; /// The main entrypoint of this library. /// All authentication, authorization and API requests starts from this struct @@ -57,6 +57,7 @@ impl PropelAuth { InitializationError::UnexpectedException, |status, _| match status.as_u16() { 401 => InitializationError::InvalidApiKey, + 429 => InitializationError::PropelAuthRateLimit, _ => InitializationError::UnexpectedException, }, ) diff --git a/src/propelauth/errors.rs b/src/propelauth/errors.rs index 02c4e6e..f5e8bad 100644 --- a/src/propelauth/errors.rs +++ b/src/propelauth/errors.rs @@ -14,6 +14,9 @@ pub enum InitializationError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Unexpected exception, please try again")] UnexpectedException, } @@ -23,6 +26,9 @@ pub enum ErrorsWithNotFound { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Not found")] NotFound, @@ -35,6 +41,9 @@ pub enum BatchFetchError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request: {0}")] BadRequest(String), @@ -47,6 +56,9 @@ pub enum FetchByQueryError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request")] BadRequest(BadFetchUsersByQuery), @@ -59,6 +71,9 @@ pub enum CreateUserError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request")] BadRequest(BadCreateUserRequest), @@ -71,6 +86,9 @@ pub enum UpdateUserMetadataError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request")] BadRequest(BadUpdateUserMetadataRequest), @@ -122,6 +140,9 @@ pub enum UpdatePasswordError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request")] BadRequest(BadUpdatePasswordRequest), @@ -137,6 +158,9 @@ pub enum ClearPasswordError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Not found")] NotFound, @@ -149,6 +173,9 @@ pub enum MigrateUserError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request")] BadRequest(BadMigrateUserRequest), @@ -161,6 +188,9 @@ pub enum CreateMagicLinkError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request")] BadRequest(BadCreateMagicLinkRequest), @@ -173,6 +203,9 @@ pub enum UpdateOrgError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Not found")] NotFound, @@ -188,6 +221,9 @@ pub enum SubscribeOrgToRoleMappingError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Not found")] NotFound, @@ -203,6 +239,9 @@ pub enum InviteUserToOrgError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Not found")] NotFound, @@ -218,6 +257,9 @@ pub enum CreateOrgError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request")] BadRequest(BadCreateOrgRequest), @@ -230,6 +272,9 @@ pub enum OrgMissingOrRoleError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Unknown role")] UnknownRoleError, @@ -245,6 +290,9 @@ pub enum FetchUsersInOrgError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request")] BadRequest(BadFetchUsersInOrgQuery), @@ -257,6 +305,9 @@ pub enum FetchOrgsByQueryError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Bad request")] BadRequest(BadFetchOrgQuery), @@ -269,6 +320,9 @@ pub enum CreateAccessTokenError { #[error("Invalid API Key")] InvalidApiKey, + #[error("Rate limited by PropelAuth")] + PropelAuthRateLimit, + #[error("Unexpected exception, please try again")] UnexpectedException, diff --git a/src/propelauth/org.rs b/src/propelauth/org.rs index e54041e..ed31535 100644 --- a/src/propelauth/org.rs +++ b/src/propelauth/org.rs @@ -41,6 +41,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -67,6 +68,7 @@ impl OrgService<'_> { )), ) => FetchOrgsByQueryError::BadRequest(bad_request), (401, _) => FetchOrgsByQueryError::InvalidApiKey, + (429, _) => FetchOrgsByQueryError::PropelAuthRateLimit, _ => FetchOrgsByQueryError::UnexpectedException, }, ) @@ -96,6 +98,7 @@ impl OrgService<'_> { )), ) => FetchUsersInOrgError::BadRequest(bad_request), (401, _) => FetchUsersInOrgError::InvalidApiKey, + (429, _) => FetchUsersInOrgError::PropelAuthRateLimit, _ => FetchUsersInOrgError::UnexpectedException, }, ) @@ -114,6 +117,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -133,6 +137,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -156,6 +161,7 @@ impl OrgService<'_> { |status_code, _| match status_code.as_u16() { 400 => OrgMissingOrRoleError::UnknownRoleError, 401 => OrgMissingOrRoleError::InvalidApiKey, + 429 => OrgMissingOrRoleError::PropelAuthRateLimit, 404 => OrgMissingOrRoleError::NotFound, _ => OrgMissingOrRoleError::UnexpectedException, }, @@ -180,6 +186,7 @@ impl OrgService<'_> { |status_code, _| match status_code.as_u16() { 400 => OrgMissingOrRoleError::UnknownRoleError, 401 => OrgMissingOrRoleError::InvalidApiKey, + 429 => OrgMissingOrRoleError::PropelAuthRateLimit, 404 => OrgMissingOrRoleError::NotFound, _ => OrgMissingOrRoleError::UnexpectedException, }, @@ -203,6 +210,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -230,6 +238,7 @@ impl OrgService<'_> { )), ) => CreateOrgError::BadRequest(bad_request), (401, _) => CreateOrgError::InvalidApiKey, + (429, _) => CreateOrgError::PropelAuthRateLimit, _ => CreateOrgError::UnexpectedException, }, ) @@ -264,6 +273,7 @@ impl OrgService<'_> { )), ) => UpdateOrgError::BadRequest(bad_request), (401, _) => UpdateOrgError::InvalidApiKey, + (429, _) => UpdateOrgError::PropelAuthRateLimit, (404, _) => UpdateOrgError::NotFound, _ => UpdateOrgError::UnexpectedException, }, @@ -301,6 +311,7 @@ impl OrgService<'_> { )), ) => SubscribeOrgToRoleMappingError::BadRequest(bad_request), (401, _) => SubscribeOrgToRoleMappingError::InvalidApiKey, + (429, _) => SubscribeOrgToRoleMappingError::PropelAuthRateLimit, (404, _) => SubscribeOrgToRoleMappingError::NotFound, _ => SubscribeOrgToRoleMappingError::UnexpectedException, }, @@ -325,6 +336,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -349,6 +361,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -373,6 +386,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -396,6 +410,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -419,6 +434,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -440,6 +456,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -461,6 +478,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -484,6 +502,7 @@ impl OrgService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -515,6 +534,7 @@ impl OrgService<'_> { )), ) => InviteUserToOrgError::BadRequest(bad_request), (401, _) => InviteUserToOrgError::InvalidApiKey, + (429, _) => InviteUserToOrgError::PropelAuthRateLimit, (404, _) => InviteUserToOrgError::NotFound, _ => InviteUserToOrgError::UnexpectedException, }, @@ -538,6 +558,7 @@ impl OrgService<'_> { 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 2338dce..577d77b 100644 --- a/src/propelauth/user.rs +++ b/src/propelauth/user.rs @@ -36,6 +36,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -59,6 +60,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -78,6 +80,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -107,6 +110,7 @@ impl UserService<'_> { } } (401, _) => BatchFetchError::InvalidApiKey, + (429, _) => BatchFetchError::PropelAuthRateLimit, _ => BatchFetchError::UnexpectedException, }, ) @@ -139,6 +143,7 @@ impl UserService<'_> { } } (401, _) => BatchFetchError::InvalidApiKey, + (429, _) => BatchFetchError::PropelAuthRateLimit, _ => BatchFetchError::UnexpectedException, }, ) @@ -171,6 +176,7 @@ impl UserService<'_> { } } (401, _) => BatchFetchError::InvalidApiKey, + (429, _) => BatchFetchError::PropelAuthRateLimit, _ => BatchFetchError::UnexpectedException, }, ) @@ -197,6 +203,7 @@ impl UserService<'_> { FetchByQueryError::BadRequest(bad_request) } (401, _) => FetchByQueryError::InvalidApiKey, + (429, _) => FetchByQueryError::PropelAuthRateLimit, _ => FetchByQueryError::UnexpectedException, }, ) @@ -224,6 +231,7 @@ impl UserService<'_> { )), ) => CreateUserError::BadRequest(bad_request), (401, _) => CreateUserError::InvalidApiKey, + (429, _) => CreateUserError::PropelAuthRateLimit, _ => CreateUserError::UnexpectedException, }, ) @@ -244,6 +252,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -266,6 +275,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -290,6 +300,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -312,6 +323,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -344,6 +356,7 @@ impl UserService<'_> { ), ) => UpdateUserMetadataError::BadRequest(bad_request), (401, _) => UpdateUserMetadataError::InvalidApiKey, + (429, _) => UpdateUserMetadataError::PropelAuthRateLimit, (404, _) => UpdateUserMetadataError::NotFound, _ => UpdateUserMetadataError::UnexpectedException, }, @@ -407,6 +420,7 @@ impl UserService<'_> { ), ) => UpdatePasswordError::BadRequest(bad_request), (401, _) => UpdatePasswordError::InvalidApiKey, + (429, _) => UpdatePasswordError::PropelAuthRateLimit, (404, _) => UpdatePasswordError::NotFound, _ => UpdatePasswordError::UnexpectedException, }, @@ -428,6 +442,7 @@ impl UserService<'_> { ClearPasswordError::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ClearPasswordError::InvalidApiKey, + 429 => ClearPasswordError::PropelAuthRateLimit, 404 => ClearPasswordError::NotFound, _ => ClearPasswordError::UnexpectedException, }, @@ -450,6 +465,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -520,6 +536,7 @@ impl UserService<'_> { )), ) => MigrateUserError::BadRequest(bad_request), (401, _) => MigrateUserError::InvalidApiKey, + (429, _) => MigrateUserError::PropelAuthRateLimit, _ => MigrateUserError::UnexpectedException, }, ) @@ -547,6 +564,7 @@ impl UserService<'_> { )), ) => CreateMagicLinkError::BadRequest(bad_request), (401, _) => CreateMagicLinkError::InvalidApiKey, + (429, _) => CreateMagicLinkError::PropelAuthRateLimit, _ => CreateMagicLinkError::UnexpectedException, }, ) @@ -569,6 +587,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, @@ -593,6 +612,7 @@ impl UserService<'_> { ErrorsWithNotFound::UnexpectedException, |status_code, _| match status_code.as_u16() { 401 => ErrorsWithNotFound::InvalidApiKey, + 429 => ErrorsWithNotFound::PropelAuthRateLimit, 404 => ErrorsWithNotFound::NotFound, _ => ErrorsWithNotFound::UnexpectedException, }, From 2d74ed6513f4b982a4ebe78585beb43223f52226 Mon Sep 17 00:00:00 2001 From: Matthew Mauer Date: Wed, 12 Feb 2025 12:24:58 -0500 Subject: [PATCH 2/4] bump minor version to 0.22.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d40cb96..8da8df3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "propelauth" -version = "0.21.0" +version = "0.22.0" authors = ["support@propelauth.com"] description = "A Rust crate for managing authentication and authorization with support for multi-tenant / B2B products, powered by PropelAuth" keywords = ["authentication", "auth", "authorization", "b2b", "tenant"] From c12bf8231ac231f75b647b0cdd0718dde0cb8d47 Mon Sep 17 00:00:00 2001 From: Matthew Mauer Date: Wed, 19 Feb 2025 13:33:28 -0500 Subject: [PATCH 3/4] move auth hostname into custom header --- src/apis/access_token_service_api.rs | 12 +++- src/apis/api_key_service_api.rs | 9 ++- src/apis/auth_service_api.rs | 39 ++++++---- src/apis/configuration.rs | 8 +-- src/apis/org_service_api.rs | 72 +++++++++++++++++++ src/apis/user_service_api.rs | 104 +++++++++++++++++++++++++++ src/propelauth/auth.rs | 49 +++++++------ 7 files changed, 251 insertions(+), 42 deletions(-) diff --git a/src/apis/access_token_service_api.rs b/src/apis/access_token_service_api.rs index 5becbc0..04e4e77 100644 --- a/src/apis/access_token_service_api.rs +++ b/src/apis/access_token_service_api.rs @@ -1,7 +1,7 @@ use reqwest; use super::{configuration, Error}; -use crate::apis::ResponseContent; +use crate::{apis::ResponseContent, propelauth::auth::AUTH_HOSTNAME_HEADER}; /// struct for passing parameters to the method [`create_access_token`] #[derive(Clone, Debug, Default)] @@ -49,6 +49,11 @@ pub async fn create_access_token( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&create_access_token_request); let local_var_req = local_var_req_builder.build()?; @@ -96,6 +101,11 @@ pub async fn create_access_token_v2( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&create_access_token_request); let local_var_req = local_var_req_builder.build()?; diff --git a/src/apis/api_key_service_api.rs b/src/apis/api_key_service_api.rs index 9799f90..7b76332 100644 --- a/src/apis/api_key_service_api.rs +++ b/src/apis/api_key_service_api.rs @@ -7,7 +7,7 @@ use hex; use reqwest; -use crate::apis::ResponseContent; +use crate::{apis::ResponseContent, propelauth::auth::AUTH_HOSTNAME_HEADER}; use super::{configuration, Error}; @@ -113,6 +113,7 @@ pub async fn fetch_current_api_keys( if let Some(ref bearer_token) = configuration.bearer_access_token { req_builder = req_builder.bearer_auth(bearer_token.to_owned()); } + req_builder = req_builder.header(AUTH_HOSTNAME_HEADER, configuration.auth_hostname.to_owned()); let req = req_builder.build()?; let resp = client.execute(req).await?; @@ -168,6 +169,7 @@ pub async fn fetch_archived_api_keys( if let Some(ref bearer_token) = configuration.bearer_access_token { req_builder = req_builder.bearer_auth(bearer_token.to_owned()); } + req_builder = req_builder.header(AUTH_HOSTNAME_HEADER, configuration.auth_hostname.to_owned()); let req = req_builder.build()?; let resp = client.execute(req).await?; @@ -210,6 +212,7 @@ pub async fn fetch_api_key( if let Some(ref bearer_token) = configuration.bearer_access_token { req_builder = req_builder.bearer_auth(bearer_token.to_owned()); } + req_builder = req_builder.header(AUTH_HOSTNAME_HEADER, configuration.auth_hostname.to_owned()); let req = req_builder.build()?; let resp = client.execute(req).await?; @@ -248,6 +251,7 @@ pub async fn create_api_key( if let Some(ref bearer_token) = configuration.bearer_access_token { req_builder = req_builder.bearer_auth(bearer_token.to_owned()); } + req_builder = req_builder.header(AUTH_HOSTNAME_HEADER, configuration.auth_hostname.to_owned()); req_builder = req_builder.json(¶ms); @@ -293,6 +297,7 @@ pub async fn update_api_key( if let Some(ref bearer_token) = configuration.bearer_access_token { req_builder = req_builder.bearer_auth(bearer_token.to_owned()); } + req_builder = req_builder.header(AUTH_HOSTNAME_HEADER, configuration.auth_hostname.to_owned()); req_builder = req_builder.json(¶ms); @@ -337,6 +342,7 @@ pub async fn delete_api_key( if let Some(ref bearer_token) = configuration.bearer_access_token { req_builder = req_builder.bearer_auth(bearer_token.to_owned()); } + req_builder = req_builder.header(AUTH_HOSTNAME_HEADER, configuration.auth_hostname.to_owned()); let req = req_builder.build()?; let resp = client.execute(req).await?; @@ -375,6 +381,7 @@ pub async fn validate_api_key( if let Some(ref bearer_token) = configuration.bearer_access_token { req_builder = req_builder.bearer_auth(bearer_token.to_owned()); } + req_builder = req_builder.header(AUTH_HOSTNAME_HEADER, configuration.auth_hostname.to_owned()); req_builder = req_builder.json(¶ms); diff --git a/src/apis/auth_service_api.rs b/src/apis/auth_service_api.rs index 33c4e64..61f9133 100644 --- a/src/apis/auth_service_api.rs +++ b/src/apis/auth_service_api.rs @@ -4,16 +4,14 @@ * 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 crate::apis::ResponseContent; -use super::{Error, configuration}; - +use super::{configuration, Error}; +use crate::{apis::ResponseContent, propelauth::auth::AUTH_HOSTNAME_HEADER}; /// struct for typed errors of method [`token_verification_metadata`] #[derive(Debug, Clone, Serialize, Deserialize)] @@ -23,24 +21,33 @@ pub enum TokenVerificationMetadataError { UnknownValue(serde_json::Value), } - -pub async fn token_verification_metadata(configuration: &configuration::Configuration) -> Result> { +pub async fn token_verification_metadata( + configuration: &configuration::Configuration, +) -> Result> { let local_var_configuration = configuration; // unbox the parameters - let local_var_client = &local_var_configuration.client; - let local_var_uri_str = format!("{}/api/backend/v1/token_verification_metadata", local_var_configuration.base_path); - let mut local_var_req_builder = local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str()); + let local_var_uri_str = format!( + "{}/api/backend/v1/token_verification_metadata", + local_var_configuration.base_path + ); + 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()); + 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?; @@ -51,9 +58,13 @@ pub async fn token_verification_metadata(configuration: &configuration::Configur 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 }; + 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)) } } - diff --git a/src/apis/configuration.rs b/src/apis/configuration.rs index 0ecd05e..37a79f9 100644 --- a/src/apis/configuration.rs +++ b/src/apis/configuration.rs @@ -4,17 +4,16 @@ * 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; - #[derive(Debug, Clone)] pub struct Configuration { pub base_path: String, + pub auth_hostname: String, pub user_agent: Option, pub client: reqwest::Client, pub basic_auth: Option, @@ -32,18 +31,17 @@ pub struct ApiKey { pub key: String, } - impl Default for Configuration { fn default() -> Self { Configuration { base_path: "http://localhost".to_owned(), + auth_hostname: "http://localhost".to_owned(), user_agent: Some("OpenAPI-Generator/0.1.0/rust".to_owned()), client: reqwest::Client::new(), basic_auth: None, oauth_access_token: None, bearer_access_token: None, api_key: None, - } } } diff --git a/src/apis/org_service_api.rs b/src/apis/org_service_api.rs index 7cd5669..a0fbe97 100644 --- a/src/apis/org_service_api.rs +++ b/src/apis/org_service_api.rs @@ -13,6 +13,7 @@ use reqwest; use super::{configuration, Error}; use crate::apis::ResponseContent; use crate::models::{FetchOrgOrderBy, SuccessfulResponse}; +use crate::propelauth::auth::AUTH_HOSTNAME_HEADER; /// struct for passing parameters to the method [`add_user_to_org`] #[derive(Clone, Debug, Default)] @@ -328,6 +329,11 @@ pub async fn add_user_to_org( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&add_user_to_org_request); let local_var_req = local_var_req_builder.build()?; @@ -376,6 +382,10 @@ pub async fn allow_org_to_enable_saml( 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?; @@ -422,6 +432,11 @@ pub async fn change_user_role_in_org( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&change_user_role_in_org_request); let local_var_req = local_var_req_builder.build()?; @@ -466,6 +481,11 @@ pub async fn create_org( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&create_org_request); let local_var_req = local_var_req_builder.build()?; @@ -514,6 +534,10 @@ pub async fn disallow_saml( 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?; @@ -562,6 +586,10 @@ pub async fn create_saml_connection_link( 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!({ "expires_in_seconds": expires_in_seconds, @@ -788,6 +816,10 @@ pub async fn fetch_org( 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?; @@ -829,6 +861,10 @@ pub async fn fetch_custom_role_mappings( 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?; @@ -892,6 +928,10 @@ pub async fn fetch_pending_invites( 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?; @@ -938,6 +978,11 @@ pub async fn revoke_pending_org_invite( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&revoke_pending_org_invite_request); let local_var_req = local_var_req_builder.build()?; @@ -1016,6 +1061,10 @@ pub async fn fetch_orgs_by_query( 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?; @@ -1085,6 +1134,10 @@ pub async fn fetch_users_in_org( 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?; @@ -1131,6 +1184,11 @@ pub async fn remove_user_from_org( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&remove_user_from_org_request); let local_var_req = local_var_req_builder.build()?; @@ -1180,6 +1238,11 @@ pub async fn update_org( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&update_org_request); let local_var_req = local_var_req_builder.build()?; @@ -1229,6 +1292,11 @@ pub async fn subscribe_org_to_role_mapping( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&update_org_request); let local_var_req = local_var_req_builder.build()?; @@ -1277,6 +1345,10 @@ pub async fn delete_org( 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?; diff --git a/src/apis/user_service_api.rs b/src/apis/user_service_api.rs index e02d8a5..303bbb2 100644 --- a/src/apis/user_service_api.rs +++ b/src/apis/user_service_api.rs @@ -12,6 +12,7 @@ use reqwest; use super::{configuration, Error, UserFacingError}; use crate::models::{FetchUsersOrderBy, ResendEmailConfirmationRequest}; +use crate::propelauth::auth::AUTH_HOSTNAME_HEADER; use crate::{apis::ResponseContent, models::InviteUserToOrgRequest}; /// struct for passing parameters to the method [`create_magic_link`] @@ -357,6 +358,11 @@ pub async fn create_magic_link( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&create_magic_link_request); let local_var_req = local_var_req_builder.build()?; @@ -401,6 +407,11 @@ pub async fn create_user( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&create_user_request); let local_var_req = local_var_req_builder.build()?; @@ -449,6 +460,10 @@ pub async fn delete_user( 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?; @@ -496,6 +511,10 @@ pub async fn disable_user( 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?; @@ -541,6 +560,11 @@ pub async fn resend_email_confirmation( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&request); let local_var_req = local_var_req_builder.build()?; @@ -586,6 +610,10 @@ pub async fn logout_all_user_sessions( 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?; @@ -633,6 +661,10 @@ pub async fn disable_user2fa( 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?; @@ -680,6 +712,10 @@ pub async fn enable_user( 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?; @@ -732,6 +768,10 @@ pub async fn fetch_user_by_email( 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?; @@ -784,6 +824,10 @@ pub async fn fetch_user_by_id( 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?; @@ -836,6 +880,10 @@ pub async fn fetch_user_by_username( 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?; @@ -887,6 +935,11 @@ pub async fn fetch_users_by_emails( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&emails_query); let local_var_req = local_var_req_builder.build()?; @@ -939,6 +992,11 @@ pub async fn fetch_users_by_ids( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&user_ids_query); let local_var_req = local_var_req_builder.build()?; @@ -1015,6 +1073,10 @@ pub async fn fetch_users_by_query( 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?; @@ -1066,6 +1128,11 @@ pub async fn fetch_users_by_usernames( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&usernames_query); let local_var_req = local_var_req_builder.build()?; @@ -1113,6 +1180,11 @@ pub async fn migrate_user( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&migrate_user_request); let local_var_req = local_var_req_builder.build()?; @@ -1162,6 +1234,11 @@ pub async fn update_user_email( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&update_email_request); let local_var_req = local_var_req_builder.build()?; @@ -1211,6 +1288,11 @@ pub async fn update_user_metadata( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&update_metadata_request); let local_var_req = local_var_req_builder.build()?; @@ -1260,6 +1342,11 @@ pub async fn update_user_password( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&update_password_request); let local_var_req = local_var_req_builder.build()?; @@ -1305,6 +1392,10 @@ pub async fn clear_user_password( 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?; @@ -1349,6 +1440,10 @@ pub async fn enable_user_can_create_orgs( 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?; @@ -1393,6 +1488,10 @@ pub async fn disable_user_can_create_orgs( 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?; @@ -1439,6 +1538,11 @@ pub async fn invite_user_to_org( 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(), + ); + local_var_req_builder = local_var_req_builder.json(&invite_user_to_org_request); let local_var_req = local_var_req_builder.build()?; diff --git a/src/propelauth/auth.rs b/src/propelauth/auth.rs index 0f11800..238eeb2 100644 --- a/src/propelauth/auth.rs +++ b/src/propelauth/auth.rs @@ -12,6 +12,9 @@ use crate::propelauth::org::OrgService; use crate::propelauth::token::TokenService; use crate::propelauth::user::UserService; +static BACKEND_API_BASE_URL: &str = "https://propelauth-api.com"; +pub(crate) static AUTH_HOSTNAME_HEADER: &str = "X-Propelauth-url"; + /// The main entrypoint of this library. /// All authentication, authorization and API requests starts from this struct #[derive(Debug, Clone)] @@ -25,9 +28,12 @@ impl PropelAuth { /// Initializes the PropelAuth library without making any external requests. This contrasts /// with `fetch_and_init` which will fetch the metadata needed to validate access tokens pub fn init(opts: AuthOptionsWithTokenVerification) -> Result { - let auth_url = validate_auth_url(&opts.auth_url)?; + let auth_hostname = validate_auth_url_extract_hostname(&opts.auth_url)?; + let issuer = "https://".to_string() + &auth_hostname; + let configuration = Configuration { - base_path: auth_url.clone(), + base_path: BACKEND_API_BASE_URL.to_string(), + auth_hostname, bearer_access_token: Some(opts.api_key), ..Default::default() }; @@ -35,16 +41,19 @@ impl PropelAuth { Ok(PropelAuth { config: configuration, token_verification_metadata: opts.manual_token_verification_metadata, - issuer: auth_url, + issuer, }) } /// Initializes the PropelAuth library by making a single external request. This contrasts /// with `init` where you manually specify the metadata needed to validate access tokens pub async fn fetch_and_init(opts: AuthOptions) -> Result { - let auth_url = validate_auth_url(&opts.auth_url)?; + let auth_hostname = validate_auth_url_extract_hostname(&opts.auth_url)?; + let issuer = "https://".to_string() + &auth_hostname; + let configuration = Configuration { - base_path: auth_url.clone(), + base_path: BACKEND_API_BASE_URL.to_string(), + auth_hostname, bearer_access_token: Some(opts.api_key), ..Default::default() }; @@ -66,7 +75,7 @@ impl PropelAuth { Ok(PropelAuth { config: configuration, token_verification_metadata, - issuer: auth_url, + issuer, }) } @@ -107,45 +116,43 @@ impl PropelAuth { } } -fn validate_auth_url(auth_url: &str) -> Result { +fn validate_auth_url_extract_hostname(auth_url: &str) -> Result { Ok(Url::parse(auth_url) .map_err(|_| InitializationError::InvalidAuthUrl)? - .origin() - .ascii_serialization()) + .host_str() + .ok_or(InitializationError::InvalidAuthUrl)? + .to_string()) } #[cfg(test)] mod tests { - use crate::propelauth::auth::validate_auth_url; + use crate::propelauth::auth::validate_auth_url_extract_hostname; use crate::propelauth::errors::InitializationError; #[test] fn bad_auth_url_is_rejected() { assert_eq!( Some(InitializationError::InvalidAuthUrl), - validate_auth_url("not.a.url").err() + validate_auth_url_extract_hostname("not.a.url").err() ); assert_eq!( Some(InitializationError::InvalidAuthUrl), - validate_auth_url("fake").err() + validate_auth_url_extract_hostname("fake").err() ); } #[test] - fn auth_urls_are_canonicalized() { + fn test_extract_hostname() { assert_eq!( - Some("https://blah.com".to_string()), - validate_auth_url("https://blah.com").ok() + Some("blah.com".to_string()), + validate_auth_url_extract_hostname("https://blah.com").ok() ); - assert_eq!( - Some("https://www.blah.com".to_string()), - validate_auth_url("https://www.blah.com/").ok() - ); + assert!(validate_auth_url_extract_hostname("blah").is_err()); assert_eq!( - Some("https://app.blah.co.uk".to_string()), - validate_auth_url("https://app.blah.co.uk/more").ok() + Some("app.blah.co.uk".to_string()), + validate_auth_url_extract_hostname("https://app.blah.co.uk/more").ok() ); } } From 250bc38339885271445d4d89b2640216a0edf8ae Mon Sep 17 00:00:00 2001 From: Matthew Mauer Date: Thu, 27 Feb 2025 16:07:37 -0500 Subject: [PATCH 4/4] bump patch version to 0.22.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8da8df3..ef23370 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "propelauth" -version = "0.22.0" +version = "0.22.1" authors = ["support@propelauth.com"] description = "A Rust crate for managing authentication and authorization with support for multi-tenant / B2B products, powered by PropelAuth" keywords = ["authentication", "auth", "authorization", "b2b", "tenant"]