From 8ffcda0204bd1b6ff4d36e5cf5c6a3bf557b57cf Mon Sep 17 00:00:00 2001 From: Mani Chandra Dulam Date: Mon, 13 Nov 2023 12:36:18 +0530 Subject: [PATCH 1/7] feat: Add new auth type and status for mca --- crates/api_models/src/admin.rs | 6 ++ crates/common_enums/src/enums.rs | 22 ++++++ crates/diesel_models/src/enums.rs | 7 +- .../src/merchant_connector_account.rs | 4 ++ crates/diesel_models/src/schema.rs | 1 + crates/kgraph_utils/benches/evaluation.rs | 1 + crates/kgraph_utils/src/mca.rs | 1 + .../src/connector/square/transformers.rs | 1 + crates/router/src/core/admin.rs | 68 ++++++++++++++++++- .../src/db/merchant_connector_account.rs | 2 + crates/router/src/types.rs | 1 + .../domain/merchant_connector_account.rs | 7 ++ crates/router/src/types/transformers.rs | 1 + .../down.sql | 3 + .../up.sql | 5 ++ 15 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 migrations/2023-11-12-131143_connector-status-column/down.sql create mode 100644 migrations/2023-11-12-131143_connector-status-column/up.sql diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 979214a071a9..08cf3473b881 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -604,6 +604,8 @@ pub struct MerchantConnectorCreate { pub profile_id: Option, pub pm_auth_config: Option, + + pub status: Option, } #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] @@ -709,6 +711,8 @@ pub struct MerchantConnectorResponse { pub applepay_verified_domains: Option>, pub pm_auth_config: Option, + + pub status: Option } /// Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc." @@ -783,6 +787,8 @@ pub struct MerchantConnectorUpdate { pub connector_webhook_details: Option, pub pm_auth_config: Option, + + pub status: Option, } ///Details of FrmConfigs are mentioned here... it should be passed in payment connector create api call, and stored in merchant_connector_table diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index f0386fc2f42e..87b06a70c97f 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -1853,3 +1853,25 @@ pub enum ApplePayFlow { Simplified, Manual, } + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + PartialEq, + serde::Serialize, + serde::Deserialize, + strum::Display, + strum::EnumString, + utoipa::ToSchema, +)] +#[router_derive::diesel_enum(storage_type = "pg_enum")] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum ConnectorStatus { + #[default] + Inactive, + Active, +} diff --git a/crates/diesel_models/src/enums.rs b/crates/diesel_models/src/enums.rs index ec021f0f51a5..817fee633190 100644 --- a/crates/diesel_models/src/enums.rs +++ b/crates/diesel_models/src/enums.rs @@ -3,9 +3,10 @@ pub mod diesel_exports { pub use super::{ DbAttemptStatus as AttemptStatus, DbAuthenticationType as AuthenticationType, DbCaptureMethod as CaptureMethod, DbCaptureStatus as CaptureStatus, - DbConnectorType as ConnectorType, DbCountryAlpha2 as CountryAlpha2, DbCurrency as Currency, - DbDisputeStage as DisputeStage, DbDisputeStatus as DisputeStatus, - DbEventClass as EventClass, DbEventObjectType as EventObjectType, DbEventType as EventType, + DbConnectorStatus as ConnectorStatus, DbConnectorType as ConnectorType, + DbCountryAlpha2 as CountryAlpha2, DbCurrency as Currency, DbDisputeStage as DisputeStage, + DbDisputeStatus as DisputeStatus, DbEventClass as EventClass, + DbEventObjectType as EventObjectType, DbEventType as EventType, DbFraudCheckStatus as FraudCheckStatus, DbFraudCheckType as FraudCheckType, DbFutureUsage as FutureUsage, DbIntentStatus as IntentStatus, DbMandateStatus as MandateStatus, DbMandateType as MandateType, diff --git a/crates/diesel_models/src/merchant_connector_account.rs b/crates/diesel_models/src/merchant_connector_account.rs index a4faa45ce4bc..ffb805d37bed 100644 --- a/crates/diesel_models/src/merchant_connector_account.rs +++ b/crates/diesel_models/src/merchant_connector_account.rs @@ -42,6 +42,7 @@ pub struct MerchantConnectorAccount { #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, pub pm_auth_config: Option, + pub status: Option, } #[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)] @@ -70,6 +71,7 @@ pub struct MerchantConnectorAccountNew { #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, pub pm_auth_config: Option, + pub status: Option, } #[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)] @@ -93,6 +95,7 @@ pub struct MerchantConnectorAccountUpdateInternal { #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, pub pm_auth_config: Option, + pub status: Option, } impl MerchantConnectorAccountUpdateInternal { @@ -115,6 +118,7 @@ impl MerchantConnectorAccountUpdateInternal { frm_config: self.frm_config, modified_at: self.modified_at.unwrap_or(source.modified_at), pm_auth_config: self.pm_auth_config, + status: self.status.or(source.status), ..source } diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs index 72d5217038c1..d39b8561799e 100644 --- a/crates/diesel_models/src/schema.rs +++ b/crates/diesel_models/src/schema.rs @@ -492,6 +492,7 @@ diesel::table! { profile_id -> Nullable, applepay_verified_domains -> Nullable>>, pm_auth_config -> Nullable, + status -> Nullable, } } diff --git a/crates/kgraph_utils/benches/evaluation.rs b/crates/kgraph_utils/benches/evaluation.rs index ecea12203f8a..6fe029f6001c 100644 --- a/crates/kgraph_utils/benches/evaluation.rs +++ b/crates/kgraph_utils/benches/evaluation.rs @@ -65,6 +65,7 @@ fn build_test_data<'a>(total_enabled: usize, total_pm_types: usize) -> graph::Kn profile_id: None, applepay_verified_domains: None, pm_auth_config: None, + status: None, }; kgraph_utils::mca::make_mca_graph(vec![stripe_account]).expect("Failed graph construction") diff --git a/crates/kgraph_utils/src/mca.rs b/crates/kgraph_utils/src/mca.rs index 34babd7a02bd..96d87a6ffb86 100644 --- a/crates/kgraph_utils/src/mca.rs +++ b/crates/kgraph_utils/src/mca.rs @@ -410,6 +410,7 @@ mod tests { profile_id: None, applepay_verified_domains: None, pm_auth_config: None, + status: None, }; make_mca_graph(vec![stripe_account]).expect("Failed graph construction") diff --git a/crates/router/src/connector/square/transformers.rs b/crates/router/src/connector/square/transformers.rs index 54a7c461dbfc..dfb49e8e6775 100644 --- a/crates/router/src/connector/square/transformers.rs +++ b/crates/router/src/connector/square/transformers.rs @@ -334,6 +334,7 @@ impl TryFrom<&types::ConnectorAuthType> for SquareAuthType { | types::ConnectorAuthType::SignatureKey { .. } | types::ConnectorAuthType::MultiAuthKey { .. } | types::ConnectorAuthType::CurrencyAuthKey { .. } + | types::ConnectorAuthType::TemporaryAuth { .. } | types::ConnectorAuthType::NoKey { .. } => { Err(errors::ConnectorError::FailedToObtainAuthType.into()) } diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index e1e5ea744e2f..8e6f15d0c488 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -861,6 +861,31 @@ pub async fn create_payment_connector( payment_link_config: None, }; + let connector_status = match (req.status, auth) { + (Some(common_enums::ConnectorStatus::Active), types::ConnectorAuthType::TemporaryAuth) => { + return Err(errors::ApiErrorResponse::InvalidRequestData { + message: "Connector status cannot be active when using TemporaryAuth".to_string(), + } + .into()); + } + (Some(status), _) => status, + (None, types::ConnectorAuthType::TemporaryAuth) => common_enums::ConnectorStatus::Inactive, + (None, _) => common_enums::ConnectorStatus::Active, + }; + + let disabled = match (req.disabled, connector_status) { + (Some(true), common_enums::ConnectorStatus::Inactive) => { + return Err(errors::ApiErrorResponse::InvalidRequestData { + message: "Connector cannot be enabled when connector_status is inactive or when using TemporaryAuth" + .to_string(), + } + .into()); + } + (Some(disabled), _) => Some(disabled), + (None, common_enums::ConnectorStatus::Inactive) => Some(true), + (None, _) => None, + }; + state .store .update_specific_fields_in_merchant(merchant_id, merchant_account_update, &key_store) @@ -886,7 +911,7 @@ pub async fn create_payment_connector( .attach_printable("Unable to encrypt connector account details")?, payment_methods_enabled, test_mode: req.test_mode, - disabled: req.disabled, + disabled, metadata: req.metadata, frm_configs, connector_label: Some(connector_label), @@ -911,6 +936,7 @@ pub async fn create_payment_connector( profile_id: Some(profile_id.clone()), applepay_verified_domains: None, pm_auth_config: req.pm_auth_config.clone(), + status: Some(connector_status), }; let mut default_routing_config = @@ -1071,6 +1097,43 @@ pub async fn update_payment_connector( let frm_configs = get_frm_config_as_secret(req.frm_configs); + let auth: types::ConnectorAuthType = req + .connector_account_details + .clone() + .unwrap_or(mca.connector_account_details.clone().into_inner()) + .parse_value("ConnectorAuthType") + .change_context(errors::ApiErrorResponse::InvalidDataFormat { + field_name: "connector_account_details".to_string(), + expected_format: "auth_type and api_key".to_string(), + })?; + + let connector_status = match (req.status, auth) { + (Some(common_enums::ConnectorStatus::Active), types::ConnectorAuthType::TemporaryAuth) => { + return Err(errors::ApiErrorResponse::InvalidRequestData { + message: "Connector status cannot be active when using TemporaryAuth".to_string(), + } + .into()); + } + (Some(status), _) => Some(status), + (None, types::ConnectorAuthType::TemporaryAuth) => { + Some(common_enums::ConnectorStatus::Inactive) + } + (None, _) => None, + }; + + let disabled = match (req.disabled, connector_status.or(mca.status)) { + (Some(true), Some(common_enums::ConnectorStatus::Inactive)) => { + return Err(errors::ApiErrorResponse::InvalidRequestData { + message: "Connector cannot be enabled when connector_status is inactive or when using TemporaryAuth" + .to_string(), + } + .into()); + } + (Some(disabled), _) => Some(disabled), + (None, Some(common_enums::ConnectorStatus::Inactive)) => Some(true), + (None, _) => None, + }; + let payment_connector = storage::MerchantConnectorAccountUpdate::Update { merchant_id: None, connector_type: Some(req.connector_type), @@ -1086,7 +1149,7 @@ pub async fn update_payment_connector( .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed while encrypting data")?, test_mode: req.test_mode, - disabled: req.disabled, + disabled, payment_methods_enabled, metadata: req.metadata, frm_configs, @@ -1103,6 +1166,7 @@ pub async fn update_payment_connector( }, applepay_verified_domains: None, pm_auth_config: req.pm_auth_config, + status: connector_status, }; let updated_mca = db diff --git a/crates/router/src/db/merchant_connector_account.rs b/crates/router/src/db/merchant_connector_account.rs index ecf52531f28a..39fb306a00e4 100644 --- a/crates/router/src/db/merchant_connector_account.rs +++ b/crates/router/src/db/merchant_connector_account.rs @@ -643,6 +643,7 @@ impl MerchantConnectorAccountInterface for MockDb { profile_id: t.profile_id, applepay_verified_domains: t.applepay_verified_domains, pm_auth_config: t.pm_auth_config, + status: t.status, }; accounts.push(account.clone()); account @@ -839,6 +840,7 @@ mod merchant_connector_account_cache_tests { profile_id: Some(profile_id.to_string()), applepay_verified_domains: None, pm_auth_config: None, + status: None, }; db.insert_merchant_connector_account(mca.clone(), &merchant_key) diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index f2e86a4bf335..4dccb73f5e85 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -880,6 +880,7 @@ pub struct ResponseRouterData { #[derive(Default, Debug, Clone, serde::Deserialize)] #[serde(tag = "auth_type")] pub enum ConnectorAuthType { + TemporaryAuth, HeaderKey { api_key: Secret, }, diff --git a/crates/router/src/types/domain/merchant_connector_account.rs b/crates/router/src/types/domain/merchant_connector_account.rs index 58c2e018316c..04f843e931b5 100644 --- a/crates/router/src/types/domain/merchant_connector_account.rs +++ b/crates/router/src/types/domain/merchant_connector_account.rs @@ -35,6 +35,7 @@ pub struct MerchantConnectorAccount { pub profile_id: Option, pub applepay_verified_domains: Option>, pub pm_auth_config: Option, + pub status: Option, } #[derive(Debug)] @@ -54,6 +55,7 @@ pub enum MerchantConnectorAccountUpdate { applepay_verified_domains: Option>, pm_auth_config: Option, connector_label: Option, + status: Option, }, } @@ -89,6 +91,7 @@ impl behaviour::Conversion for MerchantConnectorAccount { profile_id: self.profile_id, applepay_verified_domains: self.applepay_verified_domains, pm_auth_config: self.pm_auth_config, + status: self.status, }, ) } @@ -128,6 +131,7 @@ impl behaviour::Conversion for MerchantConnectorAccount { profile_id: other.profile_id, applepay_verified_domains: other.applepay_verified_domains, pm_auth_config: other.pm_auth_config, + status: other.status, }) } @@ -155,6 +159,7 @@ impl behaviour::Conversion for MerchantConnectorAccount { profile_id: self.profile_id, applepay_verified_domains: self.applepay_verified_domains, pm_auth_config: self.pm_auth_config, + status: self.status, }) } } @@ -177,6 +182,7 @@ impl From for MerchantConnectorAccountUpdateInte applepay_verified_domains, pm_auth_config, connector_label, + status, } => Self { merchant_id, connector_type, @@ -194,6 +200,7 @@ impl From for MerchantConnectorAccountUpdateInte applepay_verified_domains, pm_auth_config, connector_label, + status, }, } } diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 1cd016de18e6..31652ccbd913 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -842,6 +842,7 @@ impl TryFrom for api_models::admin::MerchantCo profile_id: item.profile_id, applepay_verified_domains: item.applepay_verified_domains, pm_auth_config: item.pm_auth_config, + status: item.status, }) } } diff --git a/migrations/2023-11-12-131143_connector-status-column/down.sql b/migrations/2023-11-12-131143_connector-status-column/down.sql new file mode 100644 index 000000000000..9463f4d77135 --- /dev/null +++ b/migrations/2023-11-12-131143_connector-status-column/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE merchant_connector_account DROP COLUMN IF EXISTS status; +DROP TYPE IF EXISTS "ConnectorStatus"; diff --git a/migrations/2023-11-12-131143_connector-status-column/up.sql b/migrations/2023-11-12-131143_connector-status-column/up.sql new file mode 100644 index 000000000000..7c74d9caebed --- /dev/null +++ b/migrations/2023-11-12-131143_connector-status-column/up.sql @@ -0,0 +1,5 @@ +-- Your SQL goes here +CREATE TYPE "ConnectorStatus" AS ENUM ('active', 'inactive'); + +ALTER TABLE merchant_connector_account +ADD COLUMN status "ConnectorStatus"; From 0070ac5ee71c2e05ec333ae021e2671e1fc90b85 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 06:19:23 +0000 Subject: [PATCH 2/7] chore: run formatter --- crates/api_models/src/admin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 08cf3473b881..3716d134c5c6 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -712,7 +712,7 @@ pub struct MerchantConnectorResponse { pub pm_auth_config: Option, - pub status: Option + pub status: Option, } /// Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc." From cc40e66aca9181c3312856e498ffb4a4636f793d Mon Sep 17 00:00:00 2001 From: Mani Chandra Dulam Date: Thu, 16 Nov 2023 15:30:55 +0530 Subject: [PATCH 3/7] fix: clippy and open_api_spec --- crates/router/src/core/verification/utils.rs | 1 + openapi/openapi_spec.json | 24 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/crates/router/src/core/verification/utils.rs b/crates/router/src/core/verification/utils.rs index 433430507fb1..56960d3cb480 100644 --- a/crates/router/src/core/verification/utils.rs +++ b/crates/router/src/core/verification/utils.rs @@ -60,6 +60,7 @@ pub async fn check_existence_and_add_domain_to_db( applepay_verified_domains: Some(already_verified_domains.clone()), pm_auth_config: None, connector_label: None, + status: None, }; state .store diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index 23f8f1b3628b..1fa24e05eb19 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -6605,6 +6605,14 @@ }, "pm_auth_config": { "nullable": true + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/common_enums.ConnectorStatus" + } + ], + "nullable": true } } }, @@ -6833,6 +6841,14 @@ }, "pm_auth_config": { "nullable": true + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/common_enums.ConnectorStatus" + } + ], + "nullable": true } } }, @@ -6938,6 +6954,14 @@ }, "pm_auth_config": { "nullable": true + }, + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/common_enums.ConnectorStatus" + } + ], + "nullable": true } } }, From e768486449ac59cfc43654014e325df6c84a8e45 Mon Sep 17 00:00:00 2001 From: Mani Chandra Dulam Date: Thu, 16 Nov 2023 17:30:51 +0530 Subject: [PATCH 4/7] refactor: make status non nullable --- crates/api_models/src/admin.rs | 2 +- crates/diesel_models/src/merchant_connector_account.rs | 6 +++--- crates/diesel_models/src/schema.rs | 2 +- crates/kgraph_utils/benches/evaluation.rs | 2 +- crates/kgraph_utils/src/mca.rs | 2 +- crates/router/src/core/admin.rs | 8 ++++---- crates/router/src/db/merchant_connector_account.rs | 2 +- .../src/types/domain/merchant_connector_account.rs | 2 +- .../2023-11-12-131143_connector-status-column/up.sql | 6 ++++++ openapi/openapi_spec.json | 10 +++------- 10 files changed, 22 insertions(+), 20 deletions(-) diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 3716d134c5c6..16a70ff55383 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -712,7 +712,7 @@ pub struct MerchantConnectorResponse { pub pm_auth_config: Option, - pub status: Option, + pub status: api_enums::ConnectorStatus, } /// Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc." diff --git a/crates/diesel_models/src/merchant_connector_account.rs b/crates/diesel_models/src/merchant_connector_account.rs index ffb805d37bed..e45ef0026261 100644 --- a/crates/diesel_models/src/merchant_connector_account.rs +++ b/crates/diesel_models/src/merchant_connector_account.rs @@ -42,7 +42,7 @@ pub struct MerchantConnectorAccount { #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, pub pm_auth_config: Option, - pub status: Option, + pub status: storage_enums::ConnectorStatus, } #[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)] @@ -71,7 +71,7 @@ pub struct MerchantConnectorAccountNew { #[diesel(deserialize_as = super::OptionalDieselArray)] pub applepay_verified_domains: Option>, pub pm_auth_config: Option, - pub status: Option, + pub status: storage_enums::ConnectorStatus, } #[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)] @@ -118,7 +118,7 @@ impl MerchantConnectorAccountUpdateInternal { frm_config: self.frm_config, modified_at: self.modified_at.unwrap_or(source.modified_at), pm_auth_config: self.pm_auth_config, - status: self.status.or(source.status), + status: self.status.unwrap_or(source.status), ..source } diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs index d39b8561799e..dd7eabb50b9d 100644 --- a/crates/diesel_models/src/schema.rs +++ b/crates/diesel_models/src/schema.rs @@ -492,7 +492,7 @@ diesel::table! { profile_id -> Nullable, applepay_verified_domains -> Nullable>>, pm_auth_config -> Nullable, - status -> Nullable, + status -> ConnectorStatus, } } diff --git a/crates/kgraph_utils/benches/evaluation.rs b/crates/kgraph_utils/benches/evaluation.rs index 6fe029f6001c..6105dc85d7e6 100644 --- a/crates/kgraph_utils/benches/evaluation.rs +++ b/crates/kgraph_utils/benches/evaluation.rs @@ -65,7 +65,7 @@ fn build_test_data<'a>(total_enabled: usize, total_pm_types: usize) -> graph::Kn profile_id: None, applepay_verified_domains: None, pm_auth_config: None, - status: None, + status: api_enums::ConnectorStatus::Inactive, }; kgraph_utils::mca::make_mca_graph(vec![stripe_account]).expect("Failed graph construction") diff --git a/crates/kgraph_utils/src/mca.rs b/crates/kgraph_utils/src/mca.rs index 96d87a6ffb86..deea51bd8808 100644 --- a/crates/kgraph_utils/src/mca.rs +++ b/crates/kgraph_utils/src/mca.rs @@ -410,7 +410,7 @@ mod tests { profile_id: None, applepay_verified_domains: None, pm_auth_config: None, - status: None, + status: api_enums::ConnectorStatus::Inactive, }; make_mca_graph(vec![stripe_account]).expect("Failed graph construction") diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index df4b5d3db918..e0abe8f9f282 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -936,7 +936,7 @@ pub async fn create_payment_connector( profile_id: Some(profile_id.clone()), applepay_verified_domains: None, pm_auth_config: req.pm_auth_config.clone(), - status: Some(connector_status), + status: connector_status, }; let mut default_routing_config = @@ -1133,8 +1133,8 @@ pub async fn update_payment_connector( (None, _) => None, }; - let disabled = match (req.disabled, connector_status.or(mca.status)) { - (Some(true), Some(common_enums::ConnectorStatus::Inactive)) => { + let disabled = match (req.disabled, connector_status.unwrap_or(mca.status)) { + (Some(true), common_enums::ConnectorStatus::Inactive) => { return Err(errors::ApiErrorResponse::InvalidRequestData { message: "Connector cannot be enabled when connector_status is inactive or when using TemporaryAuth" .to_string(), @@ -1142,7 +1142,7 @@ pub async fn update_payment_connector( .into()); } (Some(disabled), _) => Some(disabled), - (None, Some(common_enums::ConnectorStatus::Inactive)) => Some(true), + (None, common_enums::ConnectorStatus::Inactive) => Some(true), (None, _) => None, }; diff --git a/crates/router/src/db/merchant_connector_account.rs b/crates/router/src/db/merchant_connector_account.rs index 39fb306a00e4..4fbb8f19ccff 100644 --- a/crates/router/src/db/merchant_connector_account.rs +++ b/crates/router/src/db/merchant_connector_account.rs @@ -840,7 +840,7 @@ mod merchant_connector_account_cache_tests { profile_id: Some(profile_id.to_string()), applepay_verified_domains: None, pm_auth_config: None, - status: None, + status: common_enums::ConnectorStatus::Inactive, }; db.insert_merchant_connector_account(mca.clone(), &merchant_key) diff --git a/crates/router/src/types/domain/merchant_connector_account.rs b/crates/router/src/types/domain/merchant_connector_account.rs index 04f843e931b5..c84abbefc381 100644 --- a/crates/router/src/types/domain/merchant_connector_account.rs +++ b/crates/router/src/types/domain/merchant_connector_account.rs @@ -35,7 +35,7 @@ pub struct MerchantConnectorAccount { pub profile_id: Option, pub applepay_verified_domains: Option>, pub pm_auth_config: Option, - pub status: Option, + pub status: enums::ConnectorStatus, } #[derive(Debug)] diff --git a/migrations/2023-11-12-131143_connector-status-column/up.sql b/migrations/2023-11-12-131143_connector-status-column/up.sql index 7c74d9caebed..7a992d142d6f 100644 --- a/migrations/2023-11-12-131143_connector-status-column/up.sql +++ b/migrations/2023-11-12-131143_connector-status-column/up.sql @@ -3,3 +3,9 @@ CREATE TYPE "ConnectorStatus" AS ENUM ('active', 'inactive'); ALTER TABLE merchant_connector_account ADD COLUMN status "ConnectorStatus"; + +UPDATE merchant_connector_account SET status='active'; + +ALTER TABLE merchant_connector_account +ALTER COLUMN status SET NOT NULL, +ALTER COLUMN status SET DEFAULT 'inactive'; diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index 1fa24e05eb19..592b10e08fcf 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -6698,7 +6698,8 @@ "required": [ "connector_type", "connector_name", - "merchant_connector_id" + "merchant_connector_id", + "status" ], "properties": { "connector_type": { @@ -6843,12 +6844,7 @@ "nullable": true }, "status": { - "allOf": [ - { - "$ref": "#/components/schemas/common_enums.ConnectorStatus" - } - ], - "nullable": true + "$ref": "#/components/schemas/common_enums.ConnectorStatus" } } }, From 02ad25d84344bc649157475b58b0cdaae532fc6b Mon Sep 17 00:00:00 2001 From: Mani Chandra Dulam Date: Thu, 16 Nov 2023 17:39:52 +0530 Subject: [PATCH 5/7] fix: open_api_spec --- openapi/openapi_spec.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index 592b10e08fcf..aeb08d22990c 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -6844,7 +6844,7 @@ "nullable": true }, "status": { - "$ref": "#/components/schemas/common_enums.ConnectorStatus" + "$ref": "#/components/schemas/api_enums.ConnectorStatus" } } }, From f4f7c361aa9276a5042b3cb93c290853d7b0f04e Mon Sep 17 00:00:00 2001 From: Mani Chandra Dulam Date: Thu, 16 Nov 2023 19:14:05 +0530 Subject: [PATCH 6/7] fix: open_api_spec --- crates/api_models/src/admin.rs | 7 +++++-- crates/common_enums/src/enums.rs | 10 +++++----- crates/router/src/openapi.rs | 1 + openapi/openapi_spec.json | 29 ++++++++++++++--------------- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 16a70ff55383..78e1b9362635 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -605,7 +605,8 @@ pub struct MerchantConnectorCreate { pub pm_auth_config: Option, - pub status: Option, + #[schema(value_type = ConnectorStatus, example = "inactive")] + pub status: Option, } #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] @@ -712,6 +713,7 @@ pub struct MerchantConnectorResponse { pub pm_auth_config: Option, + #[schema(value_type = ConnectorStatus, example = "inactive")] pub status: api_enums::ConnectorStatus, } @@ -788,7 +790,8 @@ pub struct MerchantConnectorUpdate { pub pm_auth_config: Option, - pub status: Option, + #[schema(value_type = ConnectorStatus, example = "inactive")] + pub status: Option, } ///Details of FrmConfigs are mentioned here... it should be passed in payment connector create api call, and stored in merchant_connector_table diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 87b06a70c97f..ac791f667bb5 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -1858,18 +1858,18 @@ pub enum ApplePayFlow { Clone, Copy, Debug, - Default, Eq, PartialEq, - serde::Serialize, - serde::Deserialize, strum::Display, strum::EnumString, - utoipa::ToSchema, + serde::Deserialize, + serde::Serialize, + ToSchema, + Default, )] #[router_derive::diesel_enum(storage_type = "pg_enum")] -#[serde(rename_all = "snake_case")] #[strum(serialize_all = "snake_case")] +#[serde(rename_all = "snake_case")] pub enum ConnectorStatus { #[default] Inactive, diff --git a/crates/router/src/openapi.rs b/crates/router/src/openapi.rs index dbcd8cbe4ce2..5b0714823767 100644 --- a/crates/router/src/openapi.rs +++ b/crates/router/src/openapi.rs @@ -170,6 +170,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::enums::AttemptStatus, api_models::enums::CaptureStatus, api_models::enums::ReconStatus, + api_models::enums::ConnectorStatus, api_models::admin::MerchantConnectorCreate, api_models::admin::MerchantConnectorUpdate, api_models::admin::PrimaryBusinessDetails, diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index aeb08d22990c..5ed9d6c605a2 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -3973,6 +3973,13 @@ } } }, + "ConnectorStatus": { + "type": "string", + "enum": [ + "inactive", + "active" + ] + }, "ConnectorType": { "type": "string", "enum": [ @@ -6474,7 +6481,8 @@ "description": "Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc.\"", "required": [ "connector_type", - "connector_name" + "connector_name", + "status" ], "properties": { "connector_type": { @@ -6607,12 +6615,7 @@ "nullable": true }, "status": { - "allOf": [ - { - "$ref": "#/components/schemas/common_enums.ConnectorStatus" - } - ], - "nullable": true + "$ref": "#/components/schemas/ConnectorStatus" } } }, @@ -6844,7 +6847,7 @@ "nullable": true }, "status": { - "$ref": "#/components/schemas/api_enums.ConnectorStatus" + "$ref": "#/components/schemas/ConnectorStatus" } } }, @@ -6852,7 +6855,8 @@ "type": "object", "description": "Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc.\"", "required": [ - "connector_type" + "connector_type", + "status" ], "properties": { "connector_type": { @@ -6952,12 +6956,7 @@ "nullable": true }, "status": { - "allOf": [ - { - "$ref": "#/components/schemas/common_enums.ConnectorStatus" - } - ], - "nullable": true + "$ref": "#/components/schemas/ConnectorStatus" } } }, From 11b03fe307436d3ffa66550d462f7cf0c16a2569 Mon Sep 17 00:00:00 2001 From: Mani Chandra Dulam Date: Fri, 17 Nov 2023 13:08:59 +0530 Subject: [PATCH 7/7] refactor: move validation to a function --- crates/router/src/core/admin.rs | 98 ++++++++++++++++----------------- 1 file changed, 46 insertions(+), 52 deletions(-) diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 77571ac24a84..c921a9164cb0 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -861,31 +861,6 @@ pub async fn create_payment_connector( payment_link_config: None, }; - let connector_status = match (req.status, auth) { - (Some(common_enums::ConnectorStatus::Active), types::ConnectorAuthType::TemporaryAuth) => { - return Err(errors::ApiErrorResponse::InvalidRequestData { - message: "Connector status cannot be active when using TemporaryAuth".to_string(), - } - .into()); - } - (Some(status), _) => status, - (None, types::ConnectorAuthType::TemporaryAuth) => common_enums::ConnectorStatus::Inactive, - (None, _) => common_enums::ConnectorStatus::Active, - }; - - let disabled = match (req.disabled, connector_status) { - (Some(true), common_enums::ConnectorStatus::Inactive) => { - return Err(errors::ApiErrorResponse::InvalidRequestData { - message: "Connector cannot be enabled when connector_status is inactive or when using TemporaryAuth" - .to_string(), - } - .into()); - } - (Some(disabled), _) => Some(disabled), - (None, common_enums::ConnectorStatus::Inactive) => Some(true), - (None, _) => None, - }; - state .store .update_specific_fields_in_merchant(merchant_id, merchant_account_update, &key_store) @@ -893,6 +868,15 @@ pub async fn create_payment_connector( .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("error updating the merchant account when creating payment connector")?; + let (connector_status, disabled) = validate_status_and_disabled( + req.status, + req.disabled, + auth, + // The validate_status_and_disabled function will use this value only + // when the status can be active. So we are passing this as fallback. + api_enums::ConnectorStatus::Active, + )?; + let merchant_connector_account = domain::MerchantConnectorAccount { merchant_id: merchant_id.to_string(), connector_type: req.connector_type, @@ -1119,32 +1103,8 @@ pub async fn update_payment_connector( expected_format: "auth_type and api_key".to_string(), })?; - let connector_status = match (req.status, auth) { - (Some(common_enums::ConnectorStatus::Active), types::ConnectorAuthType::TemporaryAuth) => { - return Err(errors::ApiErrorResponse::InvalidRequestData { - message: "Connector status cannot be active when using TemporaryAuth".to_string(), - } - .into()); - } - (Some(status), _) => Some(status), - (None, types::ConnectorAuthType::TemporaryAuth) => { - Some(common_enums::ConnectorStatus::Inactive) - } - (None, _) => None, - }; - - let disabled = match (req.disabled, connector_status.unwrap_or(mca.status)) { - (Some(true), common_enums::ConnectorStatus::Inactive) => { - return Err(errors::ApiErrorResponse::InvalidRequestData { - message: "Connector cannot be enabled when connector_status is inactive or when using TemporaryAuth" - .to_string(), - } - .into()); - } - (Some(disabled), _) => Some(disabled), - (None, common_enums::ConnectorStatus::Inactive) => Some(true), - (None, _) => None, - }; + let (connector_status, disabled) = + validate_status_and_disabled(req.status, req.disabled, auth, mca.status)?; let payment_connector = storage::MerchantConnectorAccountUpdate::Update { merchant_id: None, @@ -1178,7 +1138,7 @@ pub async fn update_payment_connector( }, applepay_verified_domains: None, pm_auth_config: req.pm_auth_config, - status: connector_status, + status: Some(connector_status), }; let updated_mca = db @@ -1786,3 +1746,37 @@ pub async fn validate_dummy_connector_enabled( Ok(()) } } + +pub fn validate_status_and_disabled( + status: Option, + disabled: Option, + auth: types::ConnectorAuthType, + current_status: api_enums::ConnectorStatus, +) -> RouterResult<(api_enums::ConnectorStatus, Option)> { + let connector_status = match (status, auth) { + (Some(common_enums::ConnectorStatus::Active), types::ConnectorAuthType::TemporaryAuth) => { + return Err(errors::ApiErrorResponse::InvalidRequestData { + message: "Connector status cannot be active when using TemporaryAuth".to_string(), + } + .into()); + } + (Some(status), _) => status, + (None, types::ConnectorAuthType::TemporaryAuth) => common_enums::ConnectorStatus::Inactive, + (None, _) => current_status, + }; + + let disabled = match (disabled, connector_status) { + (Some(true), common_enums::ConnectorStatus::Inactive) => { + return Err(errors::ApiErrorResponse::InvalidRequestData { + message: "Connector cannot be enabled when connector_status is inactive or when using TemporaryAuth" + .to_string(), + } + .into()); + } + (Some(disabled), _) => Some(disabled), + (None, common_enums::ConnectorStatus::Inactive) => Some(true), + (None, _) => None, + }; + + Ok((connector_status, disabled)) +}