diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 1082c85ad3..80958f641b 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -49,6 +49,7 @@ pub async fn payments_operation_core( operation: Op, req: Req, call_connector_action: CallConnectorAction, + auth_flow: services::AuthFlow, ) -> RouterResult<(PaymentData, Req, Option)> where F: Send + Clone + Sync, @@ -70,7 +71,6 @@ where let operation: BoxedOperation<'_, F, Req> = Box::new(operation); tracing::Span::current().record("merchant_id", merchant_account.merchant_id.as_str()); - let (operation, validate_result) = operation .to_validate_request()? .validate_request(&req, &merchant_account)?; @@ -85,6 +85,7 @@ where validate_result.mandate_type.to_owned(), &merchant_account, &key_store, + auth_flow, ) .await?; @@ -246,6 +247,7 @@ where operation.clone(), req, call_connector_action, + auth_flow, ) .await?; diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index ba3d0432b5..8fd6321049 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -2550,3 +2550,28 @@ pub async fn get_additional_payment_data( } } } + +pub fn validate_customer_access( + payment_intent: &storage::PaymentIntent, + auth_flow: services::AuthFlow, + request: &api::PaymentsRequest, +) -> Result<(), errors::ApiErrorResponse> { + if auth_flow == services::AuthFlow::Client && request.customer_id.is_some() { + let is_not_same_customer = request + .clone() + .customer_id + .and_then(|customer| { + payment_intent + .clone() + .customer_id + .map(|payment_customer| payment_customer != customer) + }) + .unwrap_or(false); + if is_not_same_customer { + Err(errors::ApiErrorResponse::GenericUnauthorized { + message: "Unauthorised access to update customer".to_string(), + })?; + } + } + Ok(()) +} diff --git a/crates/router/src/core/payments/operations.rs b/crates/router/src/core/payments/operations.rs index 21d4846a7c..bbbebfa8ef 100644 --- a/crates/router/src/core/payments/operations.rs +++ b/crates/router/src/core/payments/operations.rs @@ -26,6 +26,7 @@ use crate::{ core::errors::{self, CustomResult, RouterResult}, db::StorageInterface, routes::AppState, + services, types::{ self, api, domain, storage::{self, enums}, @@ -94,6 +95,7 @@ pub trait GetTracker: Send { mandate_type: Option, merchant_account: &domain::MerchantAccount, mechant_key_store: &domain::MerchantKeyStore, + auth_flow: services::AuthFlow, ) -> RouterResult<(BoxedOperation<'a, F, R>, D, Option)>; } diff --git a/crates/router/src/core/payments/operations/payment_cancel.rs b/crates/router/src/core/payments/operations/payment_cancel.rs index c21b545737..8256de6982 100644 --- a/crates/router/src/core/payments/operations/payment_cancel.rs +++ b/crates/router/src/core/payments/operations/payment_cancel.rs @@ -14,6 +14,7 @@ use crate::{ }, db::StorageInterface, routes::AppState, + services, types::{ api::{self, PaymentIdTypeExt}, domain, @@ -37,6 +38,7 @@ impl GetTracker, api::PaymentsCancelRequest> _mandate_type: Option, merchant_account: &domain::MerchantAccount, key_store: &domain::MerchantKeyStore, + _auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsCancelRequest>, PaymentData, diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs index 16002726ca..4984dbd0f0 100644 --- a/crates/router/src/core/payments/operations/payment_capture.rs +++ b/crates/router/src/core/payments/operations/payment_capture.rs @@ -13,6 +13,7 @@ use crate::{ }, db::StorageInterface, routes::AppState, + services, types::{ api::{self, PaymentIdTypeExt}, domain, @@ -38,6 +39,7 @@ impl GetTracker, api::PaymentsCaptu _mandate_type: Option, merchant_account: &domain::MerchantAccount, key_store: &domain::MerchantKeyStore, + _auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsCaptureRequest>, payments::PaymentData, diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs index 8c4c1688c0..6c16eb85de 100644 --- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs +++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs @@ -14,6 +14,7 @@ use crate::{ }, db::StorageInterface, routes::AppState, + services, types::{ self, api::{self, PaymentIdTypeExt}, @@ -39,6 +40,7 @@ impl GetTracker, api::PaymentsRequest> for Co mandate_type: Option, merchant_account: &domain::MerchantAccount, key_store: &domain::MerchantKeyStore, + _auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRequest>, PaymentData, diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 434b9444ac..301fd23006 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -15,6 +15,7 @@ use crate::{ }, db::StorageInterface, routes::AppState, + services, types::{ self, api::{self, PaymentIdTypeExt}, @@ -28,7 +29,6 @@ use crate::{ #[derive(Debug, Clone, Copy, PaymentOperation)] #[operation(ops = "all", flow = "authorize")] pub struct PaymentConfirm; - #[async_trait] impl GetTracker, api::PaymentsRequest> for PaymentConfirm { #[instrument(skip_all)] @@ -40,6 +40,7 @@ impl GetTracker, api::PaymentsRequest> for Pa mandate_type: Option, merchant_account: &domain::MerchantAccount, key_store: &domain::MerchantKeyStore, + auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRequest>, PaymentData, @@ -59,6 +60,8 @@ impl GetTracker, api::PaymentsRequest> for Pa .await .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + helpers::validate_customer_access(&payment_intent, auth_flow, request)?; + helpers::validate_payment_status_against_not_allowed_statuses( &payment_intent.status, &[ @@ -499,7 +502,6 @@ impl ValidateRequest for PaymentConfir operations::ValidateResult<'a>, )> { helpers::validate_customer_details_in_request(request)?; - let given_payment_id = match &request.payment_id { Some(id_type) => Some( id_type diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index f5fc016a1e..b621e59c9b 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -46,6 +46,7 @@ impl GetTracker, api::PaymentsRequest> for Pa mandate_type: Option, merchant_account: &domain::MerchantAccount, merchant_key_store: &domain::MerchantKeyStore, + _auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRequest>, PaymentData, diff --git a/crates/router/src/core/payments/operations/payment_method_validate.rs b/crates/router/src/core/payments/operations/payment_method_validate.rs index be6e5a1437..34f5b66c18 100644 --- a/crates/router/src/core/payments/operations/payment_method_validate.rs +++ b/crates/router/src/core/payments/operations/payment_method_validate.rs @@ -16,6 +16,7 @@ use crate::{ }, db::StorageInterface, routes::AppState, + services, types::{ self, api::{self, enums as api_enums, PaymentIdTypeExt}, @@ -71,6 +72,7 @@ impl GetTracker, api::VerifyRequest> for Paym _mandate_type: Option, merchant_account: &domain::MerchantAccount, _mechant_key_store: &domain::MerchantKeyStore, + _auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::VerifyRequest>, PaymentData, diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs index a2f014fac7..4aa523e0d2 100644 --- a/crates/router/src/core/payments/operations/payment_session.rs +++ b/crates/router/src/core/payments/operations/payment_session.rs @@ -15,6 +15,7 @@ use crate::{ }, db::StorageInterface, routes::AppState, + services, types::{ api::{self, PaymentIdTypeExt}, domain, @@ -40,6 +41,7 @@ impl GetTracker, api::PaymentsSessionRequest> _mandate_type: Option, merchant_account: &domain::MerchantAccount, key_store: &domain::MerchantKeyStore, + _auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsSessionRequest>, PaymentData, diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs index cb9cc845ed..282b89edc2 100644 --- a/crates/router/src/core/payments/operations/payment_start.rs +++ b/crates/router/src/core/payments/operations/payment_start.rs @@ -13,6 +13,7 @@ use crate::{ }, db::StorageInterface, routes::AppState, + services, types::{ api::{self, PaymentIdTypeExt}, domain, @@ -36,6 +37,7 @@ impl GetTracker, api::PaymentsStartRequest> f _mandate_type: Option, merchant_account: &domain::MerchantAccount, mechant_key_store: &domain::MerchantKeyStore, + _auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsStartRequest>, PaymentData, diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs index 4e8ae9d21b..bcb268eb4a 100644 --- a/crates/router/src/core/payments/operations/payment_status.rs +++ b/crates/router/src/core/payments/operations/payment_status.rs @@ -14,6 +14,7 @@ use crate::{ }, db::StorageInterface, routes::AppState, + services, types::{ api, domain, storage::{self, enums}, @@ -163,6 +164,7 @@ impl GetTracker, api::PaymentsRetrieveRequest _mandate_type: Option, merchant_account: &domain::MerchantAccount, key_store: &domain::MerchantKeyStore, + _auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRetrieveRequest>, PaymentData, diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 17171c8438..daeaeb32d7 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -15,6 +15,7 @@ use crate::{ }, db::StorageInterface, routes::AppState, + services, types::{ api::{self, PaymentIdTypeExt}, domain, @@ -39,6 +40,7 @@ impl GetTracker, api::PaymentsRequest> for Pa mandate_type: Option, merchant_account: &domain::MerchantAccount, key_store: &domain::MerchantKeyStore, + auth_flow: services::AuthFlow, ) -> RouterResult<( BoxedOperation<'a, F, api::PaymentsRequest>, PaymentData, @@ -63,6 +65,8 @@ impl GetTracker, api::PaymentsRequest> for Pa .setup_future_usage .or(payment_intent.setup_future_usage); + helpers::validate_customer_access(&payment_intent, auth_flow, request)?; + helpers::validate_card_data(request.payment_method_data.clone())?; helpers::validate_payment_status_against_not_allowed_statuses( @@ -548,7 +552,6 @@ impl ValidateRequest for PaymentUpdate operations::ValidateResult<'a>, )> { helpers::validate_customer_details_in_request(request)?; - let given_payment_id = match &request.payment_id { Some(id_type) => Some( id_type diff --git a/crates/router/src/scheduler/workflows/payment_sync.rs b/crates/router/src/scheduler/workflows/payment_sync.rs index b14cd8bc1b..805aeef316 100644 --- a/crates/router/src/scheduler/workflows/payment_sync.rs +++ b/crates/router/src/scheduler/workflows/payment_sync.rs @@ -7,6 +7,7 @@ use crate::{ errors, routes::AppState, scheduler::{consumer, process_data, utils}, + services, types::{ api, storage::{self, enums, ProcessTrackerExt}, @@ -54,6 +55,7 @@ impl ProcessTrackerWorkflow for PaymentsSyncWorkflow { operations::PaymentStatus, tracking_data.clone(), payment_flows::CallConnectorAction::Trigger, + services::AuthFlow::Client, ) .await?;