mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 05:17:02 +08:00
feat(router): mask keys in connector_account_details for merchant_connector_response in mca retrieve flow (#5848)
This commit is contained in:
committed by
GitHub
parent
ad40cedf5c
commit
71b52024c2
@ -7,7 +7,7 @@ use common_utils::{
|
|||||||
types::MinorUnit,
|
types::MinorUnit,
|
||||||
};
|
};
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
use masking::Secret;
|
use masking::{ExposeInterface, Secret};
|
||||||
|
|
||||||
use crate::{payment_address::PaymentAddress, payment_method_data};
|
use crate::{payment_address::PaymentAddress, payment_method_data};
|
||||||
|
|
||||||
@ -136,6 +136,74 @@ impl ConnectorAuthType {
|
|||||||
"ConnectorAuthType",
|
"ConnectorAuthType",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// show only first and last two digits of the key and mask others with *
|
||||||
|
// mask the entire key if it's length is less than or equal to 4
|
||||||
|
fn mask_key(&self, key: String) -> Secret<String> {
|
||||||
|
let key_len = key.len();
|
||||||
|
let masked_key = if key_len <= 4 {
|
||||||
|
"*".repeat(key_len)
|
||||||
|
} else {
|
||||||
|
// Show the first two and last two characters, mask the rest with '*'
|
||||||
|
let mut masked_key = String::new();
|
||||||
|
let key_len = key.len();
|
||||||
|
// Iterate through characters by their index
|
||||||
|
for (index, character) in key.chars().enumerate() {
|
||||||
|
if index < 2 || index >= key_len - 2 {
|
||||||
|
masked_key.push(character); // Keep the first two and last two characters
|
||||||
|
} else {
|
||||||
|
masked_key.push('*'); // Mask the middle characters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
masked_key
|
||||||
|
};
|
||||||
|
Secret::new(masked_key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask the keys in the auth_type
|
||||||
|
pub fn get_masked_keys(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
Self::TemporaryAuth => Self::TemporaryAuth,
|
||||||
|
Self::NoKey => Self::NoKey,
|
||||||
|
Self::HeaderKey { api_key } => Self::HeaderKey {
|
||||||
|
api_key: self.mask_key(api_key.clone().expose()),
|
||||||
|
},
|
||||||
|
Self::BodyKey { api_key, key1 } => Self::BodyKey {
|
||||||
|
api_key: self.mask_key(api_key.clone().expose()),
|
||||||
|
key1: self.mask_key(key1.clone().expose()),
|
||||||
|
},
|
||||||
|
Self::SignatureKey {
|
||||||
|
api_key,
|
||||||
|
key1,
|
||||||
|
api_secret,
|
||||||
|
} => Self::SignatureKey {
|
||||||
|
api_key: self.mask_key(api_key.clone().expose()),
|
||||||
|
key1: self.mask_key(key1.clone().expose()),
|
||||||
|
api_secret: self.mask_key(api_secret.clone().expose()),
|
||||||
|
},
|
||||||
|
Self::MultiAuthKey {
|
||||||
|
api_key,
|
||||||
|
key1,
|
||||||
|
api_secret,
|
||||||
|
key2,
|
||||||
|
} => Self::MultiAuthKey {
|
||||||
|
api_key: self.mask_key(api_key.clone().expose()),
|
||||||
|
key1: self.mask_key(key1.clone().expose()),
|
||||||
|
api_secret: self.mask_key(api_secret.clone().expose()),
|
||||||
|
key2: self.mask_key(key2.clone().expose()),
|
||||||
|
},
|
||||||
|
Self::CurrencyAuthKey { auth_key_map } => Self::CurrencyAuthKey {
|
||||||
|
auth_key_map: auth_key_map.clone(),
|
||||||
|
},
|
||||||
|
Self::CertificateAuth {
|
||||||
|
certificate,
|
||||||
|
private_key,
|
||||||
|
} => Self::CertificateAuth {
|
||||||
|
certificate: self.mask_key(certificate.clone().expose()),
|
||||||
|
private_key: self.mask_key(private_key.clone().expose()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
|
#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use api_models::{
|
|||||||
use common_utils::{
|
use common_utils::{
|
||||||
consts::X_HS_LATENCY,
|
consts::X_HS_LATENCY,
|
||||||
crypto::Encryptable,
|
crypto::Encryptable,
|
||||||
ext_traits::{StringExt, ValueExt},
|
ext_traits::{Encode, StringExt, ValueExt},
|
||||||
fp_utils::when,
|
fp_utils::when,
|
||||||
pii,
|
pii,
|
||||||
types::MinorUnit,
|
types::MinorUnit,
|
||||||
@ -15,7 +15,7 @@ use common_utils::{
|
|||||||
use diesel_models::enums as storage_enums;
|
use diesel_models::enums as storage_enums;
|
||||||
use error_stack::{report, ResultExt};
|
use error_stack::{report, ResultExt};
|
||||||
use hyperswitch_domain_models::payments::payment_intent::CustomerData;
|
use hyperswitch_domain_models::payments::payment_intent::CustomerData;
|
||||||
use masking::{ExposeInterface, PeekInterface};
|
use masking::{ExposeInterface, PeekInterface, Secret};
|
||||||
|
|
||||||
use super::domain;
|
use super::domain;
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -1103,13 +1103,29 @@ impl ForeignTryFrom<domain::MerchantConnectorAccount>
|
|||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
// parse the connector_account_details into ConnectorAuthType
|
||||||
|
let connector_account_details: hyperswitch_domain_models::router_data::ConnectorAuthType =
|
||||||
|
item.connector_account_details
|
||||||
|
.clone()
|
||||||
|
.into_inner()
|
||||||
|
.parse_value("ConnectorAuthType")
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("Failed while parsing value for ConnectorAuthType")?;
|
||||||
|
// get the masked keys from the ConnectorAuthType and encode it to secret value
|
||||||
|
let masked_connector_account_details = Secret::new(
|
||||||
|
connector_account_details
|
||||||
|
.get_masked_keys()
|
||||||
|
.encode_to_value()
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("Failed to encode ConnectorAuthType")?,
|
||||||
|
);
|
||||||
#[cfg(feature = "v2")]
|
#[cfg(feature = "v2")]
|
||||||
let response = Self {
|
let response = Self {
|
||||||
id: item.get_id(),
|
id: item.get_id(),
|
||||||
connector_type: item.connector_type,
|
connector_type: item.connector_type,
|
||||||
connector_name: item.connector_name,
|
connector_name: item.connector_name,
|
||||||
connector_label: item.connector_label,
|
connector_label: item.connector_label,
|
||||||
connector_account_details: item.connector_account_details.into_inner(),
|
connector_account_details: masked_connector_account_details,
|
||||||
disabled: item.disabled,
|
disabled: item.disabled,
|
||||||
payment_methods_enabled,
|
payment_methods_enabled,
|
||||||
metadata: item.metadata,
|
metadata: item.metadata,
|
||||||
@ -1149,7 +1165,7 @@ impl ForeignTryFrom<domain::MerchantConnectorAccount>
|
|||||||
connector_name: item.connector_name,
|
connector_name: item.connector_name,
|
||||||
connector_label: item.connector_label,
|
connector_label: item.connector_label,
|
||||||
merchant_connector_id: item.merchant_connector_id,
|
merchant_connector_id: item.merchant_connector_id,
|
||||||
connector_account_details: item.connector_account_details.into_inner(),
|
connector_account_details: masked_connector_account_details,
|
||||||
test_mode: item.test_mode,
|
test_mode: item.test_mode,
|
||||||
disabled: item.disabled,
|
disabled: item.disabled,
|
||||||
payment_methods_enabled,
|
payment_methods_enabled,
|
||||||
|
|||||||
Reference in New Issue
Block a user