From 4fe0b76e20200ef59e4f614c78efc3a07085b8f7 Mon Sep 17 00:00:00 2001 From: Itai Levi Date: Wed, 4 Oct 2023 12:02:49 -0400 Subject: [PATCH 1/5] feat(create_access_token): create access token service, request/response models --- src/apis/access_token_service_api.rs | 58 ++++++++++++++++++++++ src/apis/mod.rs | 1 + src/models/create_access_token_request.rs | 22 ++++++++ src/models/create_access_token_response.rs | 12 +++++ src/models/mod.rs | 4 ++ 5 files changed, 97 insertions(+) create mode 100644 src/apis/access_token_service_api.rs create mode 100644 src/models/create_access_token_request.rs create mode 100644 src/models/create_access_token_response.rs diff --git a/src/apis/access_token_service_api.rs b/src/apis/access_token_service_api.rs new file mode 100644 index 0000000..cc7107d --- /dev/null +++ b/src/apis/access_token_service_api.rs @@ -0,0 +1,58 @@ +use reqwest; + +use crate::apis::ResponseContent; +use super::{Error, configuration}; + +/// struct for passing parameters to the method [`create_access_token`] +#[derive(Clone, Debug, Default)] +pub struct CreateAccessTokenParams { + pub create_access_token_request: crate::models::CreateAccessTokenRequest +} + + + +/// struct for typed errors of method [`create_access_token`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum CreateAccessTokenError { + Status400(serde_json::Value), + Status401(serde_json::Value), + Status404(serde_json::Value), + UnknownValue(serde_json::Value), +} + + +pub async fn create_access_tokne(configuration: &configuration::Configuration, params: CreateAccessTokenParams) -> Result> { + let local_var_configuration = configuration; + + // unbox the parameters + let create_access_token_request = params.create_access_token_request; + + let local_var_client = &local_var_configuration.client; + + let local_var_uri_str = format!("{}/api/backend/v1/access_token", 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()); + } + 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.json(&create_access_token_request); + + let local_var_req = local_var_req_builder.build()?; + let local_var_resp = local_var_client.execute(local_var_req).await?; + + let local_var_status = local_var_resp.status(); + let local_var_content = local_var_resp.text().await?; + + if !local_var_status.is_client_error() && !local_var_status.is_server_error() { + serde_json::from_str(&local_var_content).map_err(Error::from) + } else { + let local_var_entity: Option = serde_json::from_str(&local_var_content).ok(); + let local_var_error: ResponseContent = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity }; + Err(Error::ResponseError(local_var_error)) + } +} + diff --git a/src/apis/mod.rs b/src/apis/mod.rs index a9392db..135cb65 100644 --- a/src/apis/mod.rs +++ b/src/apis/mod.rs @@ -65,6 +65,7 @@ pub fn urlencode>(s: T) -> String { } pub mod api_key_service_api; +pub mod access_token_service_api; pub mod auth_service_api; pub mod org_service_api; pub mod user_service_api; diff --git a/src/models/create_access_token_request.rs b/src/models/create_access_token_request.rs new file mode 100644 index 0000000..e2dc433 --- /dev/null +++ b/src/models/create_access_token_request.rs @@ -0,0 +1,22 @@ +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct CreateAccessTokenRequest { + #[serde(rename = "user_id")] + pub user_id: String, + #[serde(rename = "duration_in_minutes")] + pub duration_in_minutes: u64, + #[serde(rename = "active_org_id", skip_serializing_if = "Option::is_none")] + pub active_org_id: Option, + #[serde(rename = "with_active_org_support")] + pub with_active_org_support: bool, +} + +impl CreateAccessTokenRequest { + pub fn new(user_id: String, duration_in_minutes: u64, with_active_org_support: bool) -> CreateAccessTokenRequest { + CreateAccessTokenRequest { + user_id, + active_org_id: None, + duration_in_minutes, + with_active_org_support, + } + } +} diff --git a/src/models/create_access_token_response.rs b/src/models/create_access_token_response.rs new file mode 100644 index 0000000..fea22d7 --- /dev/null +++ b/src/models/create_access_token_response.rs @@ -0,0 +1,12 @@ +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct CreateAccessTokenResponse { + pub access_token: String, +} + +impl CreateAccessTokenResponse { + pub fn new(access_token: String) -> Self { + CreateAccessTokenResponse { + access_token, + } + } +} diff --git a/src/models/mod.rs b/src/models/mod.rs index c525cdd..7c34f8e 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -86,3 +86,7 @@ pub mod usernames_query; pub use self::usernames_query::UsernamesQuery; pub mod validate_api_key_response; pub use self::validate_api_key_response::ValidateApiKeyResponse; +pub mod create_access_token_response; +pub use self::create_access_token_response::CreateAccessTokenResponse; +pub mod create_access_token_request; +pub use self::create_access_token_request::CreateAccessTokenRequest; \ No newline at end of file From 330f22c9206c33e11c02adc1f7890f4a52cf22da Mon Sep 17 00:00:00 2001 From: Itai Levi Date: Wed, 4 Oct 2023 12:11:42 -0400 Subject: [PATCH 2/5] feat(create_access_token): add AccessTokenService, errors for errored response --- src/apis/access_token_service_api.rs | 4 +-- src/models/bad_create_access_token_error.rs | 17 +++++++++ src/models/mod.rs | 4 ++- src/propelauth/access_token.rs | 38 +++++++++++++++++++++ src/propelauth/errors.rs | 17 ++++++++- src/propelauth/mod.rs | 1 + 6 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 src/models/bad_create_access_token_error.rs create mode 100644 src/propelauth/access_token.rs diff --git a/src/apis/access_token_service_api.rs b/src/apis/access_token_service_api.rs index cc7107d..7a55c1c 100644 --- a/src/apis/access_token_service_api.rs +++ b/src/apis/access_token_service_api.rs @@ -15,14 +15,14 @@ pub struct CreateAccessTokenParams { #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] pub enum CreateAccessTokenError { - Status400(serde_json::Value), + Status400(crate::models::BadCreateAccessTokenError), Status401(serde_json::Value), Status404(serde_json::Value), UnknownValue(serde_json::Value), } -pub async fn create_access_tokne(configuration: &configuration::Configuration, params: CreateAccessTokenParams) -> Result> { +pub async fn create_access_token(configuration: &configuration::Configuration, params: CreateAccessTokenParams) -> Result> { let local_var_configuration = configuration; // unbox the parameters diff --git a/src/models/bad_create_access_token_error.rs b/src/models/bad_create_access_token_error.rs new file mode 100644 index 0000000..defaba3 --- /dev/null +++ b/src/models/bad_create_access_token_error.rs @@ -0,0 +1,17 @@ + +#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)] +pub struct BadCreateAccessTokenError { + #[serde(rename = "active_org_id", skip_serializing_if = "Option::is_none")] + pub active_org_id: Option>, + #[serde(rename = "user_id", skip_serializing_if = "Option::is_none")] + pub user_id: Option>, +} + +impl BadCreateAccessTokenError { + pub fn new() -> BadCreateAccessTokenError { + BadCreateAccessTokenError { + active_org_id: None, + user_id: None, + } + } +} diff --git a/src/models/mod.rs b/src/models/mod.rs index 7c34f8e..49d0e36 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -89,4 +89,6 @@ pub use self::validate_api_key_response::ValidateApiKeyResponse; pub mod create_access_token_response; pub use self::create_access_token_response::CreateAccessTokenResponse; pub mod create_access_token_request; -pub use self::create_access_token_request::CreateAccessTokenRequest; \ No newline at end of file +pub use self::create_access_token_request::CreateAccessTokenRequest; +pub mod bad_create_access_token_error; +pub use self::bad_create_access_token_error::BadCreateAccessTokenError; \ No newline at end of file diff --git a/src/propelauth/access_token.rs b/src/propelauth/access_token.rs new file mode 100644 index 0000000..30100eb --- /dev/null +++ b/src/propelauth/access_token.rs @@ -0,0 +1,38 @@ +use crate::apis::access_token_service_api::CreateAccessTokenParams; +use crate::apis::configuration::Configuration; + +use crate::models::CreateAccessTokenResponse; +use crate::propelauth::errors::CreateAccessTokenError; +use crate::propelauth::helpers::{is_valid_id, map_autogenerated_error}; + +pub struct AccessTokenService<'a> { + pub(crate) config: &'a Configuration, +} + +impl AccessTokenService<'_> { + pub async fn create_access_token(&self, params: CreateAccessTokenParams) -> Result { + if !is_valid_id(¶ms.create_access_token_request.user_id) { + return Err(CreateAccessTokenError::NotFound); + } + + crate::apis::access_token_service_api::create_access_token(&self.config, params) + .await + .map_err(|err| { + map_autogenerated_error( + err, + CreateAccessTokenError::UnexpectedException, + |status_code, err_entity| match (status_code.as_u16(), err_entity) { + ( + _, + Some(crate::apis::access_token_service_api::CreateAccessTokenError::Status400( + bad_request, + )), + ) => CreateAccessTokenError::BadRequest(bad_request), + (401, _) => CreateAccessTokenError::InvalidApiKey, + (404, _) => CreateAccessTokenError::NotFound, + _ => CreateAccessTokenError::UnexpectedException, + }, + ) + }) + } +} diff --git a/src/propelauth/errors.rs b/src/propelauth/errors.rs index 337392d..07bb5bc 100644 --- a/src/propelauth/errors.rs +++ b/src/propelauth/errors.rs @@ -1,7 +1,7 @@ use crate::models::{ BadCreateMagicLinkRequest, BadCreateOrgRequest, BadCreateUserRequest, BadFetchOrgQuery, BadFetchUsersByQuery, BadFetchUsersInOrgQuery, BadMigrateUserRequest, BadUpdateOrgRequest, - BadUpdatePasswordRequest, BadUpdateUserEmailRequest, BadUpdateUserMetadataRequest, + BadUpdatePasswordRequest, BadUpdateUserEmailRequest, BadUpdateUserMetadataRequest, BadCreateAccessTokenError, }; use thiserror::Error; @@ -203,6 +203,21 @@ pub enum FetchOrgsByQueryError { UnexpectedException, } +#[derive(Error, Debug, PartialEq, Clone)] +pub enum CreateAccessTokenError { + #[error("Invalid API Key")] + InvalidApiKey, + + #[error("Unexpected exception, please try again")] + UnexpectedException, + + #[error("Not found")] + NotFound, + + #[error("Bad request")] + BadRequest(BadCreateAccessTokenError), +} + #[derive(Error, Debug, Eq, PartialEq, Copy, Clone)] pub enum DetailedAuthError { #[error("Invalid public key for decoding the JWT - make sure it's formatted correctly")] diff --git a/src/propelauth/mod.rs b/src/propelauth/mod.rs index f88c81d..4da2b79 100644 --- a/src/propelauth/mod.rs +++ b/src/propelauth/mod.rs @@ -7,3 +7,4 @@ pub mod org; pub mod token; pub mod token_models; pub mod user; +pub mod access_token; From 86a4a2e2048e8aa467feab9dabfac98de100a61a Mon Sep 17 00:00:00 2001 From: Itai Levi Date: Wed, 4 Oct 2023 12:13:11 -0400 Subject: [PATCH 3/5] feat(auth): add access_token function to auth --- src/propelauth/auth.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/propelauth/auth.rs b/src/propelauth/auth.rs index 54d029c..6d1b9f4 100644 --- a/src/propelauth/auth.rs +++ b/src/propelauth/auth.rs @@ -10,6 +10,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::access_token::AccessTokenService; /// The main entrypoint of this library. /// All authentication, authorization and API requests starts from this struct @@ -96,6 +97,12 @@ impl PropelAuth { issuer: &self.issuer, } } + + pub fn access_token(&self) -> AccessTokenService { + AccessTokenService { + config: &self.config, + } + } } fn validate_auth_url(auth_url: &str) -> Result { From c09d46702b6cdd32f34282585fd572ce22cb0cf5 Mon Sep 17 00:00:00 2001 From: Itai Levi Date: Wed, 4 Oct 2023 12:13:36 -0400 Subject: [PATCH 4/5] chore: add comment for what the api is --- src/propelauth/auth.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/propelauth/auth.rs b/src/propelauth/auth.rs index 6d1b9f4..5621a2b 100644 --- a/src/propelauth/auth.rs +++ b/src/propelauth/auth.rs @@ -98,6 +98,7 @@ impl PropelAuth { } } + /// API requests related to access tokens. pub fn access_token(&self) -> AccessTokenService { AccessTokenService { config: &self.config, From ee7cb1713c2197ecf2154f96978607ad6712b0cc Mon Sep 17 00:00:00 2001 From: Itai Levi Date: Wed, 4 Oct 2023 12:18:27 -0400 Subject: [PATCH 5/5] docs(access_token): add docs for new access_token api, create_access_token --- docs/AccessTokenServiceApi.md | 32 ++++++++++++++++++++++++++++ docs/CreateAccessTokenRequest.md | 12 +++++++++++ docs/CreateAccessTokenResponse.md | 9 ++++++++ src/apis/access_token_service_api.rs | 2 +- 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 docs/AccessTokenServiceApi.md create mode 100644 docs/CreateAccessTokenRequest.md create mode 100644 docs/CreateAccessTokenResponse.md diff --git a/docs/AccessTokenServiceApi.md b/docs/AccessTokenServiceApi.md new file mode 100644 index 0000000..91aac61 --- /dev/null +++ b/docs/AccessTokenServiceApi.md @@ -0,0 +1,32 @@ +# \AccessTokenServiceApi + +All URIs are relative to _http://localhost_ + +| Method | HTTP request | Description | +| ----------------------------------------------------------------------- | ------------------------------------- | ----------- | +| [**create_access_Token**](AccessTokenServiceApi.md#create_access_token) | **POST** /api/backend/v1/access_token | + +## create_access_Token + +> crate::models::CreateAccessTokenResponse create_access_token(create_access_token_params) + +### Parameters + +| Name | Type | Description | Notes | +| -------------------------- | -------------------------------------------------------------------------- | ----------- | ----- | +| create_access_token_params | [**crate::models::CreateAccessTokenRequest**](CreateAccessTokenRequest.md) | | | + +### Return type + +[**crate::models::CreateAccessTokenResponse**](CreateAccessTokenResponse.md) + +### Authorization + +[BearerAuth](../README.md#BearerAuth) + +### HTTP request headers + +- **Content-Type**: Not defined +- **Accept**: application/json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) diff --git a/docs/CreateAccessTokenRequest.md b/docs/CreateAccessTokenRequest.md new file mode 100644 index 0000000..3c4fa93 --- /dev/null +++ b/docs/CreateAccessTokenRequest.md @@ -0,0 +1,12 @@ +# CreateAccessTokenRequest + +## Properties + +| Name | Type | Description | Notes | +| --------------------------- | -------------------- | ----------- | ----- | +| **user_id** | **String** | | +| **duration_in_minutes** | **u64** | | +| **active_org_id** | **Option\** | | +| **with_active_org_support** | **bool** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/CreateAccessTokenResponse.md b/docs/CreateAccessTokenResponse.md new file mode 100644 index 0000000..8cdbd82 --- /dev/null +++ b/docs/CreateAccessTokenResponse.md @@ -0,0 +1,9 @@ +# CreateAccessTokenResponse + +## Properties + +| Name | Type | Description | Notes | +| ---------------- | ---------- | ----------- | ----- | +| **access_token** | **String** | | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/src/apis/access_token_service_api.rs b/src/apis/access_token_service_api.rs index 7a55c1c..c377e17 100644 --- a/src/apis/access_token_service_api.rs +++ b/src/apis/access_token_service_api.rs @@ -31,7 +31,7 @@ pub async fn create_access_token(configuration: &configuration::Configuration, p let local_var_client = &local_var_configuration.client; let local_var_uri_str = format!("{}/api/backend/v1/access_token", 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 mut local_var_req_builder = local_var_client.request(reqwest::Method::POST, local_var_uri_str.as_str()); if let Some(ref local_var_user_agent) = local_var_configuration.user_agent { local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());