Skip to content

Commit

Permalink
fix(connectors): Mask fields for webhook_resource_object (#4400)
Browse files Browse the repository at this point in the history
Co-authored-by: sai-harsha-vardhan <[email protected]>
  • Loading branch information
Sakilmostak and sai-harsha-vardhan authored Apr 19, 2024
1 parent 4330781 commit 110bf22
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 37 deletions.
36 changes: 12 additions & 24 deletions crates/router/src/connector/checkout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ pub mod transformers;

use std::fmt::Debug;

use common_utils::{
crypto,
ext_traits::{ByteSliceExt, Encode},
request::RequestContent,
};
use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent};
use diesel_models::enums;
use error_stack::ResultExt;
use masking::PeekInterface;
Expand Down Expand Up @@ -1295,27 +1291,19 @@ impl api::IncomingWebhook for Checkout {
let event_type_data: checkout::CheckoutWebhookEventTypeBody = request
.body
.parse_struct("CheckoutWebhookBody")
.change_context(errors::ConnectorError::WebhookEventTypeNotFound)?;
let resource_object = if checkout::is_chargeback_event(&event_type_data.transaction_type)
|| checkout::is_refund_event(&event_type_data.transaction_type)
{
// if other event, just return the json data.
let resource_object_data: checkout::CheckoutWebhookObjectResource = request
.change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;

if checkout::is_chargeback_event(&event_type_data.transaction_type) {
let dispute_webhook_body: checkout::CheckoutDisputeWebhookBody = request
.body
.parse_struct("CheckoutWebhookObjectResource")
.change_context(errors::ConnectorError::WebhookEventTypeNotFound)?;
resource_object_data.data
.parse_struct("CheckoutDisputeWebhookBody")
.change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;
Ok(Box::new(dispute_webhook_body.data))
} else if checkout::is_refund_event(&event_type_data.transaction_type) {
Ok(Box::new(checkout::RefundResponse::try_from(request)?))
} else {
// if payment_event, construct PaymentResponse and then serialize it to json and return.
let payment_response = checkout::PaymentsResponse::try_from(request)?;
payment_response
.encode_to_value()
.change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?
};
// Ideally this should be a strict type that has type information
// PII information is likely being logged here when this response will be logged.

Ok(Box::new(resource_object))
Ok(Box::new(checkout::PaymentsResponse::try_from(request)?))
}
}

fn get_dispute_details(
Expand Down
26 changes: 24 additions & 2 deletions crates/router/src/connector/checkout/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1237,7 +1237,7 @@ pub struct CheckoutWebhookBody {
pub links: Links,
}

#[derive(Debug, Deserialize)]
#[derive(Debug, Serialize, Deserialize)]
pub struct CheckoutDisputeWebhookData {
pub id: String,
pub payment_id: Option<String>,
Expand Down Expand Up @@ -1382,7 +1382,7 @@ impl TryFrom<&api::IncomingWebhookRequestDetails<'_>> for PaymentsResponse {
let details: CheckoutWebhookBody = request
.body
.parse_struct("CheckoutWebhookBody")
.change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?;
.change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;
let data = details.data;
let psync_struct = Self {
id: data.payment_id.unwrap_or(data.id),
Expand All @@ -1403,6 +1403,28 @@ impl TryFrom<&api::IncomingWebhookRequestDetails<'_>> for PaymentsResponse {
}
}

impl TryFrom<&api::IncomingWebhookRequestDetails<'_>> for RefundResponse {
type Error = error_stack::Report<errors::ConnectorError>;

fn try_from(request: &api::IncomingWebhookRequestDetails<'_>) -> Result<Self, Self::Error> {
let details: CheckoutWebhookBody = request
.body
.parse_struct("CheckoutWebhookBody")
.change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;
let data = details.data;
let refund_struct = Self {
action_id: data
.action_id
.ok_or(errors::ConnectorError::WebhookBodyDecodingFailed)?,
reference: data
.reference
.ok_or(errors::ConnectorError::WebhookBodyDecodingFailed)?,
};

Ok(refund_struct)
}
}

impl TryFrom<&types::SubmitEvidenceRouterData> for Evidence {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(item: &types::SubmitEvidenceRouterData) -> Result<Self, Self::Error> {
Expand Down
8 changes: 4 additions & 4 deletions crates/router/src/connector/stripe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2172,12 +2172,12 @@ impl api::IncomingWebhook for Stripe {
&self,
request: &api::IncomingWebhookRequestDetails<'_>,
) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> {
let details: stripe::WebhookEventObjectResource = request
let details: stripe::WebhookEvent = request
.body
.parse_struct("WebhookEventObjectResource")
.change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?;
.parse_struct("WebhookEvent")
.change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;

Ok(Box::new(details.data.object))
Ok(Box::new(details.event_data.event_object))
}
fn get_dispute_details(
&self,
Expand Down
7 changes: 4 additions & 3 deletions crates/router/src/connector/stripe/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3536,13 +3536,14 @@ pub struct WebhookPaymentMethodDetails {
pub payment_method: WebhookPaymentMethodType,
}

#[derive(Debug, Clone, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WebhookEventObjectData {
pub id: String,
pub object: WebhookEventObjectType,
pub amount: Option<i32>,
pub currency: String,
pub payment_intent: Option<String>,
pub client_secret: Option<Secret<String>>,
pub reason: Option<String>,
#[serde(with = "common_utils::custom_serde::timestamp")]
pub created: PrimitiveDateTime,
Expand All @@ -3551,7 +3552,7 @@ pub struct WebhookEventObjectData {
pub metadata: Option<StripeMetadata>,
}

#[derive(Debug, Clone, Deserialize, strum::Display)]
#[derive(Debug, Clone, Serialize, Deserialize, strum::Display)]
#[serde(rename_all = "snake_case")]
pub enum WebhookEventObjectType {
PaymentIntent,
Expand Down Expand Up @@ -3637,7 +3638,7 @@ pub enum WebhookEventStatus {
Unknown,
}

#[derive(Debug, Clone, Deserialize, PartialEq)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct EvidenceDetails {
#[serde(with = "common_utils::custom_serde::timestamp")]
pub due_by: PrimitiveDateTime,
Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/core/webhooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1449,6 +1449,8 @@ pub async fn webhooks_wrapper<W: types::OutgoingWebhookType, Ctx: PaymentMethodR
))
.await?;

logger::info!(incoming_webhook_payload = ?serialized_req);

let request_duration = Instant::now()
.saturating_duration_since(start_instant)
.as_millis();
Expand Down
6 changes: 3 additions & 3 deletions crates/router/src/routes/webhooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ pub async fn receive_incoming_webhook<W: types::OutgoingWebhookType>(
flow.clone(),
state,
&req,
WebhookBytes(body),
|state, auth, payload, req_state| {
(),
|state, auth, _, req_state| {
webhooks::webhooks_wrapper::<W, Oss>(
&flow,
state.to_owned(),
Expand All @@ -35,7 +35,7 @@ pub async fn receive_incoming_webhook<W: types::OutgoingWebhookType>(
auth.merchant_account,
auth.key_store,
&connector_id_or_name,
payload.0,
body.clone(),
)
},
&auth::MerchantIdAuth(merchant_id),
Expand Down
1 change: 0 additions & 1 deletion crates/router/src/services/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,6 @@ where
.await;
let external_latency = current_time.elapsed().as_millis();
logger::info!(raw_connector_request=?masked_request_body);
logger::info!(raw_connector_response=?response);
let status_code = response
.as_ref()
.map(|i| {
Expand Down

0 comments on commit 110bf22

Please sign in to comment.