From b5d3d49ceaa2f89284ae5976afec0ff5663a24b0 Mon Sep 17 00:00:00 2001 From: Prasunna Soppa <70575890+prasunna09@users.noreply.github.com> Date: Fri, 6 Dec 2024 16:17:07 +0530 Subject: [PATCH] fix(router): validate each field for migration request body (#6525) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- .../router/src/core/payment_methods/cards.rs | 72 +++++++++++-------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 68b1790880dd..aaeb1aff16ac 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -28,7 +28,7 @@ use common_utils::{ consts, crypto::{self, Encryptable}, encryption::Encryption, - ext_traits::{AsyncExt, BytesExt, Encode, StringExt, ValueExt}, + ext_traits::{AsyncExt, BytesExt, ConfigExt, Encode, StringExt, ValueExt}, generate_id, id_type, request::Request, type_name, @@ -55,6 +55,7 @@ use hyperswitch_domain_models::customer::CustomerUpdate; use kgraph_utils::transformers::IntoDirValue; use masking::Secret; use router_env::{instrument, metrics::add_attributes, tracing}; +use serde_json::json; use strum::IntoEnumIterator; use super::{ @@ -381,7 +382,7 @@ pub async fn migrate_payment_method( key_store: &domain::MerchantKeyStore, ) -> errors::RouterResponse { let mut req = req; - let card_details = req.card.as_ref().get_required_value("card")?; + let card_details = &req.card.get_required_value("card")?; let card_number_validation_result = cards::CardNumber::from_str(card_details.card_number.peek()); @@ -780,17 +781,6 @@ pub async fn skip_locker_call_and_migrate_payment_method( let network_transaction_id = req.network_transaction_id.clone(); - migration_status.network_transaction_id_migrated(network_transaction_id.as_ref().map(|_| true)); - - migration_status.connector_mandate_details_migrated( - connector_mandate_details - .as_ref() - .map(|_| true) - .or_else(|| req.connector_mandate_details.as_ref().map(|_| false)), - ); - - migration_status.card_migrated(false); - let payment_method_id = generate_id(consts::ID_LENGTH, "pm"); let current_time = common_utils::date_time::now(); @@ -810,11 +800,11 @@ pub async fn skip_locker_call_and_migrate_payment_method( scheme: req.card_network.clone().or(card.scheme.clone()), metadata: payment_method_metadata.map(Secret::new), payment_method_data: payment_method_data_encrypted.map(Into::into), - connector_mandate_details, + connector_mandate_details: connector_mandate_details.clone(), customer_acceptance: None, client_secret: None, status: enums::PaymentMethodStatus::Active, - network_transaction_id, + network_transaction_id: network_transaction_id.clone(), payment_method_issuer_code: None, accepted_currency: None, token: None, @@ -843,6 +833,21 @@ pub async fn skip_locker_call_and_migrate_payment_method( logger::debug!("Payment method inserted in db"); + migration_status.network_transaction_id_migrated( + network_transaction_id.and_then(|val| (!val.is_empty_after_trim()).then_some(true)), + ); + + migration_status.connector_mandate_details_migrated( + connector_mandate_details + .clone() + .and_then(|val| if val == json!({}) { None } else { Some(true) }) + .or_else(|| { + req.connector_mandate_details + .clone() + .and_then(|val| (!val.0.is_empty()).then_some(false)) + }), + ); + if customer.default_payment_method_id.is_none() && req.payment_method.is_some() { let _ = set_default_payment_method( state, @@ -1166,10 +1171,14 @@ pub async fn get_client_secret_or_add_payment_method_for_migration( migration_status.connector_mandate_details_migrated( connector_mandate_details .clone() - .map(|_| true) - .or_else(|| req.connector_mandate_details.clone().map(|_| false)), + .and_then(|val| (val != json!({})).then_some(true)) + .or_else(|| { + req.connector_mandate_details + .clone() + .and_then(|val| (!val.0.is_empty()).then_some(false)) + }), ); - + //card is not migrated in this case migration_status.card_migrated(false); if res.status == enums::PaymentMethodStatus::AwaitingData { @@ -1722,15 +1731,6 @@ pub async fn save_migration_payment_method( let network_transaction_id = req.network_transaction_id.clone(); - migration_status.network_transaction_id_migrated(network_transaction_id.as_ref().map(|_| true)); - - migration_status.connector_mandate_details_migrated( - connector_mandate_details - .as_ref() - .map(|_| true) - .or_else(|| req.connector_mandate_details.as_ref().map(|_| false)), - ); - let response = match payment_method { #[cfg(feature = "payouts")] api_enums::PaymentMethod::BankTransfer => match req.bank_transfer.clone() { @@ -1940,8 +1940,8 @@ pub async fn save_migration_payment_method( pm_metadata.cloned(), None, locker_id, - connector_mandate_details, - network_transaction_id, + connector_mandate_details.clone(), + network_transaction_id.clone(), merchant_account.storage_scheme, payment_method_billing_address.map(Into::into), None, @@ -1954,6 +1954,20 @@ pub async fn save_migration_payment_method( } } + migration_status.card_migrated(true); + migration_status.network_transaction_id_migrated( + network_transaction_id.and_then(|val| (!val.is_empty_after_trim()).then_some(true)), + ); + + migration_status.connector_mandate_details_migrated( + connector_mandate_details + .and_then(|val| if val == json!({}) { None } else { Some(true) }) + .or_else(|| { + req.connector_mandate_details + .and_then(|val| (!val.0.is_empty()).then_some(false)) + }), + ); + Ok(services::ApplicationResponse::Json(resp)) }