Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(connector): mask pii information in connector request and response for stripe, aci, adyen, airwallex and authorizedotnet #3678

Merged
merged 55 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
2101406
feat(events): pass connector event ref to handle_response
lsampras Feb 1, 2024
6d487e5
pass connector event ref to handle_response v2
AkshayaFoiger Feb 2, 2024
d060eb5
feat(router): add serde::serialize to res obj
AkshayaFoiger Feb 2, 2024
c86d710
refactor(connector): make event logging optional for connector response
lsampras Feb 3, 2024
f9a0b34
fix(connector): fix serialization errors for connector
lsampras Feb 5, 2024
e1e7929
fix(connector): fix nmi handle response
lsampras Feb 5, 2024
1579fe4
fix(connector): add stripe connector serializing
lsampras Feb 6, 2024
fe2f2ff
fix(connector): fix event_builder not used warning
AkshayaFoiger Feb 6, 2024
20890fa
fix(connector): fix clippy error
AkshayaFoiger Feb 6, 2024
f3ec39a
feat(events): update connector events to use masked response
lsampras Feb 6, 2024
cbed0f9
fix(connector): fix DDL commands
AkshayaFoiger Feb 6, 2024
58d3981
Merge branch 'main' into 3517-featevent_viewer-add-masking-for-connec…
AkshayaFoiger Feb 6, 2024
60588b6
Merge branch 'main' into 3517-featevent_viewer-add-masking-for-connec…
AkshayaFoiger Feb 6, 2024
76e0965
fix(connector): fix clippy error
AkshayaFoiger Feb 6, 2024
45c2624
fix(connector): fix clippy error
AkshayaFoiger Feb 7, 2024
790d97a
Merge branch 'main' into 3517-featevent_viewer-add-masking-for-connec…
AkshayaFoiger Feb 7, 2024
4db99c2
fix(connector): fix clippy error
AkshayaFoiger Feb 7, 2024
a47f878
chore: run formatter
hyperswitch-bot[bot] Feb 7, 2024
e6ec9a0
fix(connector): log nmi refundsync response
AkshayaFoiger Feb 7, 2024
9f682bc
chore: run formatter
hyperswitch-bot[bot] Feb 7, 2024
9dc398e
chore(lints): disable clippy lint
lsampras Feb 8, 2024
14ca64c
fix(connector): remove comment
AkshayaFoiger Feb 9, 2024
9793b82
fix(connectors): update set_response_body
AkshayaFoiger Feb 9, 2024
9ff88bf
fix(connector): mask error response
AkshayaFoiger Feb 12, 2024
c53dc38
fix(connector): fix clippy error
AkshayaFoiger Feb 13, 2024
3b75184
refactor(events): set_error_response_body()
AkshayaFoiger Feb 13, 2024
c13f826
Merge branch 'main' into 3517-featevent_viewer-add-masking-for-connec…
AkshayaFoiger Feb 13, 2024
ea53568
chore: run formatter
hyperswitch-bot[bot] Feb 13, 2024
dd23059
fix(connector): fix clippy error
AkshayaFoiger Feb 13, 2024
5577ac6
fix(connectors): add set_response_body to template
AkshayaFoiger Feb 13, 2024
529c490
refactor(connector): log deserialization error
AkshayaFoiger Feb 13, 2024
59b2142
Merge branch 'main' into connector-response-masking
AkshayaFoiger Feb 14, 2024
ef2a68e
Merge branch 'main' into connector-response-masking
AkshayaFoiger Feb 14, 2024
11ff99a
refactor(connectors): [Stripe] add data masking
AkshayaFoiger Feb 15, 2024
7c4f724
refactor(connectors): [ACI] data masking
AkshayaFoiger Feb 15, 2024
af8431d
refactor(connectors): [Adyen] PII data masking
AkshayaFoiger Feb 16, 2024
b871bb5
refactor(connectors): [Airwallex] PII data masking
AkshayaFoiger Feb 16, 2024
b5a4959
refactor(connectors): [authorizedotnet] data mask
AkshayaFoiger Feb 16, 2024
3682cf5
refactor(connector): remove masking for qr code
AkshayaFoiger Feb 16, 2024
81c970e
chore: run formatter
hyperswitch-bot[bot] Feb 16, 2024
d0a8019
Update crates/router/src/connector/aci/transformers.rs
AkshayaFoiger Feb 16, 2024
e785a71
Update crates/router/src/connector/aci/transformers.rs
AkshayaFoiger Feb 16, 2024
3d2a6e9
fix(connector): resolve comments
AkshayaFoiger Feb 16, 2024
c1c097a
refactor(connectors): account holder type
AkshayaFoiger Feb 18, 2024
af5de90
refactor(connector): revert changes to bankdebit()
AkshayaFoiger Feb 18, 2024
89ad1ab
Merge branch 'main' into connector-response-masking
AkshayaFoiger Feb 19, 2024
83287c0
Merge branch 'main' into connector-response-masking
AkshayaFoiger Feb 19, 2024
fd91434
refactor(connectors): mask payment token in stripe
AkshayaFoiger Feb 20, 2024
4670f63
refactor(connectors): update adyen
AkshayaFoiger Feb 20, 2024
066af85
refcator(connectors): update aci
AkshayaFoiger Feb 21, 2024
d1f337a
chore: run formatter
hyperswitch-bot[bot] Feb 21, 2024
e21f645
refactor(connectors): update authorize.net and aci
AkshayaFoiger Feb 21, 2024
efecce0
refactor(connectors): update aci and stripe
AkshayaFoiger Feb 21, 2024
6cfd207
refactor(connectors): mask payment_method
AkshayaFoiger Feb 22, 2024
acd5141
refactor(coonectors): resolve comments
AkshayaFoiger Feb 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions crates/router/src/connector/aci/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::str::FromStr;
use api_models::enums::BankNames;
use common_utils::pii::Email;
use error_stack::report;
use masking::Secret;
use masking::{ExposeInterface, Secret};
use reqwest::Url;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -382,7 +382,7 @@ pub struct Instruction {
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
pub struct BankDetails {
#[serde(rename = "bankAccount.holder")]
pub account_holder: String,
pub account_holder: Secret<String>,
}

#[allow(dead_code)]
Expand Down Expand Up @@ -657,10 +657,11 @@ impl FromStr for AciPaymentStatus {
#[serde(rename_all = "camelCase")]
pub struct AciPaymentsResponse {
id: String,
registration_id: Option<String>,
registration_id: Option<Secret<String>>,
// ndc is an internal unique identifier for the request.
ndc: String,
timestamp: String,
// Number useful for support purposes.
build_number: String,
pub(super) result: ResultCode,
pub(super) redirect: Option<AciRedirectionData>,
Expand Down Expand Up @@ -734,7 +735,7 @@ impl<F, T>
.response
.registration_id
.map(|id| types::MandateReference {
connector_mandate_id: Some(id),
connector_mandate_id: Some(id.expose()),
payment_method_id: None,
});

Expand Down
7 changes: 6 additions & 1 deletion crates/router/src/connector/adyen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use base64::Engine;
use common_utils::request::RequestContent;
use diesel_models::{enums as storage_enums, enums};
use error_stack::{IntoReport, ResultExt};
use masking::ExposeInterface;
use ring::hmac;
use router_env::{instrument, tracing};

Expand Down Expand Up @@ -467,8 +468,10 @@ impl
.response
.parse_struct("AdyenCaptureResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

types::RouterData::try_from(types::ResponseRouterData {
response,
data: data.clone(),
Expand Down Expand Up @@ -610,8 +613,10 @@ impl
.response
.parse_struct("AdyenPaymentResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

let is_multiple_capture_sync = match data.request.sync_type {
types::SyncRequestType::MultipleCaptureSync(_) => true,
types::SyncRequestType::SinglePaymentSync => false,
Expand Down Expand Up @@ -1513,7 +1518,7 @@ impl api::IncomingWebhook for Adyen {
let notif_item = get_webhook_object_from_body(request.body)
.change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?;

let base64_signature = notif_item.additional_data.hmac_signature;
let base64_signature = notif_item.additional_data.hmac_signature.expose();
Ok(base64_signature.as_bytes().to_vec())
}

Expand Down
52 changes: 24 additions & 28 deletions crates/router/src/connector/adyen/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use api_models::{enums, payments, webhooks};
use cards::CardNumber;
use common_utils::ext_traits::Encode;
use error_stack::ResultExt;
use masking::PeekInterface;
use masking::{ExposeInterface, PeekInterface};
use reqwest::Url;
use serde::{Deserialize, Serialize};
use time::{Duration, OffsetDateTime, PrimitiveDateTime};
Expand Down Expand Up @@ -95,10 +95,10 @@ pub struct AdditionalData {
pub recurring_processing_model: Option<AdyenRecurringModel>,
/// Enable recurring details in dashboard to receive this ID, https://docs.adyen.com/online-payments/tokenization/create-and-use-tokens#test-and-go-live
#[serde(rename = "recurring.recurringDetailReference")]
recurring_detail_reference: Option<String>,
recurring_detail_reference: Option<Secret<String>>,
#[serde(rename = "recurring.shopperReference")]
recurring_shopper_reference: Option<String>,
network_tx_reference: Option<String>,
network_tx_reference: Option<Secret<String>>,
#[cfg(feature = "payouts")]
payout_eligible: Option<PayoutEligibility>,
funds_availability: Option<String>,
Expand Down Expand Up @@ -553,7 +553,7 @@ pub struct JCSVoucherData {
first_name: Secret<String>,
last_name: Option<Secret<String>>,
shopper_email: Email,
telephone_number: String,
telephone_number: Secret<String>,
}

#[derive(Debug, Clone, Serialize)]
Expand Down Expand Up @@ -604,14 +604,6 @@ pub struct BacsDirectDebitData {
holder_name: Secret<String>,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MandateData {
#[serde(rename = "type")]
payment_type: PaymentType,
stored_payment_method_id: String,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BancontactCardData {
Expand Down Expand Up @@ -674,7 +666,7 @@ impl TryFrom<&Box<payments::JCSVoucherData>> for JCSVoucherData {
first_name: jcs_data.first_name.clone(),
last_name: jcs_data.last_name.clone(),
shopper_email: jcs_data.email.clone(),
telephone_number: jcs_data.phone_number.clone(),
telephone_number: Secret::new(jcs_data.phone_number.clone()),
})
}
}
Expand Down Expand Up @@ -1031,7 +1023,7 @@ impl TryFrom<&api_enums::BankNames> for OpenBankingUKIssuer {
pub struct BlikRedirectionData {
#[serde(rename = "type")]
payment_type: PaymentType,
blik_code: String,
blik_code: Secret<String>,
}

#[derive(Debug, Clone, Serialize)]
Expand All @@ -1047,7 +1039,7 @@ pub struct BankRedirectionWithIssuer<'a> {
pub struct AdyenMandate {
#[serde(rename = "type")]
payment_type: PaymentType,
stored_payment_method_id: String,
stored_payment_method_id: Secret<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -1060,7 +1052,7 @@ pub struct AdyenCard {
expiry_year: Secret<String>,
cvc: Option<Secret<String>>,
brand: Option<CardBrand>, //Mandatory for mandate using network_txns_id
network_payment_reference: Option<String>,
network_payment_reference: Option<Secret<String>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -1143,7 +1135,7 @@ pub struct AdyenRefundRequest {
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AdyenRefundResponse {
merchant_account: String,
merchant_account: Secret<String>,
psp_reference: String,
payment_psp_reference: String,
reference: String,
Expand Down Expand Up @@ -2131,11 +2123,11 @@ impl<'a> TryFrom<&api_models::payments::BankRedirectData> for AdyenPaymentMethod
api_models::payments::BankRedirectData::Blik { blik_code } => {
Ok(AdyenPaymentMethod::Blik(Box::new(BlikRedirectionData {
payment_type: PaymentType::Blik,
blik_code: blik_code.clone().ok_or(
blik_code: Secret::new(blik_code.clone().ok_or(
errors::ConnectorError::MissingRequiredField {
field_name: "blik_code",
},
)?,
)?),
})))
}
api_models::payments::BankRedirectData::Eps { bank_name, .. } => Ok(
Expand Down Expand Up @@ -2357,7 +2349,9 @@ impl<'a>
payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids) => {
let adyen_mandate = AdyenMandate {
payment_type: PaymentType::try_from(payment_method_type)?,
stored_payment_method_id: connector_mandate_ids.get_connector_mandate_id()?,
stored_payment_method_id: Secret::new(
connector_mandate_ids.get_connector_mandate_id()?,
),
};
Ok::<AdyenPaymentMethod<'_>, Self::Error>(AdyenPaymentMethod::Mandate(Box::new(
adyen_mandate,
Expand All @@ -2375,7 +2369,7 @@ impl<'a>
expiry_year: card.card_exp_year.clone(),
cvc: None,
brand: Some(brand),
network_payment_reference: Some(network_mandate_id),
network_payment_reference: Some(Secret::new(network_mandate_id)),
};
Ok(AdyenPaymentMethod::AdyenCard(Box::new(adyen_card)))
}
Expand Down Expand Up @@ -3047,12 +3041,14 @@ pub fn get_adyen_response(
.as_ref()
.and_then(|data| data.recurring_detail_reference.to_owned())
.map(|mandate_id| types::MandateReference {
connector_mandate_id: Some(mandate_id),
connector_mandate_id: Some(mandate_id.expose()),
payment_method_id: None,
});
let network_txn_id = response
.additional_data
.and_then(|additional_data| additional_data.network_tx_reference);
let network_txn_id = response.additional_data.and_then(|additional_data| {
additional_data
.network_tx_reference
.map(|network_tx_id| network_tx_id.expose())
});

let payments_response_data = types::PaymentsResponseData::TransactionResponse {
resource_id: types::ResponseId::ConnectorTransactionId(response.psp_reference),
Expand Down Expand Up @@ -3314,7 +3310,7 @@ pub fn get_redirection_error_response(
pub fn get_qr_metadata(
response: &QrCodeResponseResponse,
) -> errors::CustomResult<Option<serde_json::Value>, errors::ConnectorError> {
let image_data = crate_utils::QrImage::new_from_data(response.action.qr_code_data.to_owned())
let image_data = crate_utils::QrImage::new_from_data(response.action.qr_code_data.clone())
.change_context(errors::ConnectorError::ResponseHandlingFailed)?;

let image_data_url = Url::parse(image_data.data.clone().as_str()).ok();
Expand Down Expand Up @@ -3636,7 +3632,7 @@ impl TryFrom<&AdyenRouterData<&types::PaymentsCaptureRouterData>> for AdyenCaptu
#[derive(Default, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AdyenCaptureResponse {
merchant_account: String,
merchant_account: Secret<String>,
payment_psp_reference: String,
psp_reference: String,
reference: String,
Expand Down Expand Up @@ -3789,7 +3785,7 @@ pub enum DisputeStatus {
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AdyenAdditionalDataWH {
pub hmac_signature: String,
pub hmac_signature: Secret<String>,
pub dispute_status: Option<DisputeStatus>,
pub chargeback_reason_code: Option<String>,
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/connector/airwallex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,10 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
.response
.parse_struct("airwallex AirwallexPaymentsSyncResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

types::PaymentsSyncRouterData::try_from(types::ResponseRouterData {
response,
data: data.clone(),
Expand Down
25 changes: 17 additions & 8 deletions crates/router/src/connector/airwallex/transformers.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use error_stack::{IntoReport, ResultExt};
use masking::PeekInterface;
use masking::{ExposeInterface, PeekInterface};
use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime;
use url::Url;
Expand Down Expand Up @@ -416,10 +416,10 @@ pub enum AirwallexNextActionStage {
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
pub struct AirwallexRedirectFormData {
#[serde(rename = "JWT")]
jwt: Option<String>,
jwt: Option<Secret<String>>,
#[serde(rename = "threeDSMethodData")]
three_ds_method_data: Option<String>,
token: Option<String>,
three_ds_method_data: Option<Secret<String>>,
token: Option<Secret<String>>,
provider: Option<String>,
version: Option<String>,
}
Expand All @@ -439,7 +439,7 @@ pub struct AirwallexPaymentsResponse {
id: String,
amount: Option<f32>,
//ID of the PaymentConsent related to this PaymentIntent
payment_consent_id: Option<String>,
payment_consent_id: Option<Secret<String>>,
next_action: Option<AirwallexPaymentsNextAction>,
}

Expand All @@ -450,7 +450,7 @@ pub struct AirwallexPaymentsSyncResponse {
id: String,
amount: Option<f32>,
//ID of the PaymentConsent related to this PaymentIntent
payment_consent_id: Option<String>,
payment_consent_id: Option<Secret<String>>,
next_action: Option<AirwallexPaymentsNextAction>,
}

Expand All @@ -464,18 +464,27 @@ fn get_redirection_form(
//Some form fields might be empty based on the authentication type by the connector
(
"JWT".to_string(),
response_url_data.data.jwt.unwrap_or_default(),
response_url_data
.data
.jwt
.map(|jwt| jwt.expose())
.unwrap_or_default(),
),
(
"threeDSMethodData".to_string(),
response_url_data
.data
.three_ds_method_data
.map(|three_ds_method_data| three_ds_method_data.expose())
.unwrap_or_default(),
),
(
"token".to_string(),
response_url_data.data.token.unwrap_or_default(),
response_url_data
.data
.token
.map(|token: Secret<String>| token.expose())
.unwrap_or_default(),
),
(
"provider".to_string(),
Expand Down
5 changes: 4 additions & 1 deletion crates/router/src/connector/authorizedotnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,10 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
let response: authorizedotnet::AuthorizedotnetPaymentsResponse = intermediate_response
.parse_struct("AuthorizedotnetPaymentsResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

types::RouterData::try_from(types::ResponseRouterData {
response,
data: data.clone(),
Expand Down Expand Up @@ -353,7 +355,6 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
))?;
let connector_req =
authorizedotnet::CreateTransactionRequest::try_from(&connector_router_data)?;

Ok(RequestContent::Json(Box::new(connector_req)))
}

Expand Down Expand Up @@ -400,8 +401,10 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
let response: authorizedotnet::AuthorizedotnetPaymentsResponse = intermediate_response
.parse_struct("AuthorizedotnetPaymentsResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

types::RouterData::try_from(types::ResponseRouterData {
response,
data: data.clone(),
Expand Down
Loading
Loading