mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 04:04:43 +08:00
feat: fetch merchant key store only once per session (#1400)
Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
@ -97,11 +97,9 @@ pub async fn get_address_for_payment_request(
|
||||
address_id: Option<&str>,
|
||||
merchant_id: &str,
|
||||
customer_id: Option<&String>,
|
||||
merchant_key_store: &domain::MerchantKeyStore,
|
||||
) -> CustomResult<Option<domain::Address>, errors::ApiErrorResponse> {
|
||||
let key = types::get_merchant_enc_key(db, merchant_id.to_string())
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while getting key for encryption")?;
|
||||
let key = merchant_key_store.key.get_inner().peek();
|
||||
|
||||
Ok(match req_address {
|
||||
Some(address) => {
|
||||
@ -118,49 +116,49 @@ pub async fn get_address_for_payment_request(
|
||||
.address
|
||||
.as_ref()
|
||||
.and_then(|value| value.line1.clone())
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
line2: address
|
||||
.address
|
||||
.as_ref()
|
||||
.and_then(|value| value.line2.clone())
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
line3: address
|
||||
.address
|
||||
.as_ref()
|
||||
.and_then(|value| value.line3.clone())
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
state: address
|
||||
.address
|
||||
.as_ref()
|
||||
.and_then(|value| value.state.clone())
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
zip: address
|
||||
.address
|
||||
.as_ref()
|
||||
.and_then(|value| value.zip.clone())
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
first_name: address
|
||||
.address
|
||||
.as_ref()
|
||||
.and_then(|value| value.first_name.clone())
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
last_name: address
|
||||
.address
|
||||
.as_ref()
|
||||
.and_then(|value| value.last_name.clone())
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
phone_number: address
|
||||
.phone
|
||||
.as_ref()
|
||||
.and_then(|value| value.number.clone())
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
country_code: address
|
||||
.phone
|
||||
@ -172,7 +170,7 @@ pub async fn get_address_for_payment_request(
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while encrypting address")?;
|
||||
Some(
|
||||
db.update_address(id.to_owned(), address_update)
|
||||
db.update_address(id.to_owned(), address_update, merchant_key_store)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::AddressNotFound)?,
|
||||
)
|
||||
@ -190,7 +188,7 @@ pub async fn get_address_for_payment_request(
|
||||
.phone
|
||||
.as_ref()
|
||||
.and_then(|a| a.number.clone())
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
country_code: address
|
||||
.phone
|
||||
@ -203,40 +201,41 @@ pub async fn get_address_for_payment_request(
|
||||
country: address_details.country,
|
||||
line1: address_details
|
||||
.line1
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
line2: address_details
|
||||
.line2
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
line3: address_details
|
||||
.line3
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
id: None,
|
||||
state: address_details
|
||||
.state
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
created_at: common_utils::date_time::now(),
|
||||
first_name: address_details
|
||||
.first_name
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
last_name: address_details
|
||||
.last_name
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
modified_at: common_utils::date_time::now(),
|
||||
zip: address_details
|
||||
.zip
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
})
|
||||
}
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while encrypting address while insert")?,
|
||||
merchant_key_store,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
@ -246,7 +245,7 @@ pub async fn get_address_for_payment_request(
|
||||
}
|
||||
}
|
||||
None => match address_id {
|
||||
Some(id) => Some(db.find_address(id).await)
|
||||
Some(id) => Some(db.find_address(id, merchant_key_store).await)
|
||||
.transpose()
|
||||
.to_not_found_response(errors::ApiErrorResponse::AddressNotFound)?,
|
||||
None => None,
|
||||
@ -257,10 +256,11 @@ pub async fn get_address_for_payment_request(
|
||||
pub async fn get_address_by_id(
|
||||
db: &dyn StorageInterface,
|
||||
address_id: Option<String>,
|
||||
merchant_key_store: &domain::MerchantKeyStore,
|
||||
) -> CustomResult<Option<domain::Address>, errors::ApiErrorResponse> {
|
||||
match address_id {
|
||||
None => Ok(None),
|
||||
Some(address_id) => Ok(db.find_address(&address_id).await.ok()),
|
||||
Some(address_id) => Ok(db.find_address(&address_id, merchant_key_store).await.ok()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,12 +870,17 @@ pub async fn get_customer_from_details<F: Clone>(
|
||||
customer_id: Option<String>,
|
||||
merchant_id: &str,
|
||||
payment_data: &mut PaymentData<F>,
|
||||
merchant_key_store: &domain::MerchantKeyStore,
|
||||
) -> CustomResult<Option<domain::Customer>, errors::StorageError> {
|
||||
match customer_id {
|
||||
None => Ok(None),
|
||||
Some(c_id) => {
|
||||
let customer = db
|
||||
.find_customer_optional_by_customer_id_merchant_id(&c_id, merchant_id)
|
||||
.find_customer_optional_by_customer_id_merchant_id(
|
||||
&c_id,
|
||||
merchant_id,
|
||||
merchant_key_store,
|
||||
)
|
||||
.await?;
|
||||
payment_data.email = payment_data.email.clone().or_else(|| {
|
||||
customer.as_ref().and_then(|inner| {
|
||||
@ -1010,6 +1015,7 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
|
||||
payment_data: &mut PaymentData<F>,
|
||||
req: Option<CustomerDetails>,
|
||||
merchant_id: &str,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
) -> CustomResult<(BoxedOperation<'a, F, R>, Option<domain::Customer>), errors::StorageError> {
|
||||
let request_customer_details = req
|
||||
.get_required_value("customer")
|
||||
@ -1022,7 +1028,11 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
|
||||
let optional_customer = match customer_id {
|
||||
Some(customer_id) => {
|
||||
let customer_data = db
|
||||
.find_customer_optional_by_customer_id_merchant_id(&customer_id, merchant_id)
|
||||
.find_customer_optional_by_customer_id_merchant_id(
|
||||
&customer_id,
|
||||
merchant_id,
|
||||
key_store,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Some(match customer_data {
|
||||
@ -1033,12 +1043,12 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
|
||||
| request_customer_details.phone.is_some()
|
||||
| request_customer_details.phone_country_code.is_some()
|
||||
{
|
||||
let key = types::get_merchant_enc_key(db, merchant_id.to_string()).await?;
|
||||
let key = key_store.key.get_inner().peek();
|
||||
let customer_update = async {
|
||||
Ok(Update {
|
||||
name: request_customer_details
|
||||
.name
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
email: request_customer_details
|
||||
.email
|
||||
@ -1046,14 +1056,14 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
|
||||
.async_lift(|inner| {
|
||||
types::encrypt_optional(
|
||||
inner.map(|inner| inner.expose()),
|
||||
&key,
|
||||
key,
|
||||
)
|
||||
})
|
||||
.await?,
|
||||
phone: request_customer_details
|
||||
.phone
|
||||
.clone()
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
phone_country_code: request_customer_details.phone_country_code,
|
||||
description: None,
|
||||
@ -1069,6 +1079,7 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
|
||||
customer_id,
|
||||
merchant_id.to_string(),
|
||||
customer_update,
|
||||
key_store,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
@ -1076,26 +1087,26 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let key = types::get_merchant_enc_key(db, merchant_id.to_string()).await?;
|
||||
let new_customer = async {
|
||||
let key = key_store.key.get_inner().peek();
|
||||
Ok(domain::Customer {
|
||||
customer_id: customer_id.to_string(),
|
||||
merchant_id: merchant_id.to_string(),
|
||||
name: request_customer_details
|
||||
.name
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
email: request_customer_details
|
||||
.email
|
||||
.clone()
|
||||
.async_lift(|inner| {
|
||||
types::encrypt_optional(inner.map(|inner| inner.expose()), &key)
|
||||
types::encrypt_optional(inner.map(|inner| inner.expose()), key)
|
||||
})
|
||||
.await?,
|
||||
phone: request_customer_details
|
||||
.phone
|
||||
.clone()
|
||||
.async_lift(|inner| types::encrypt_optional(inner, &key))
|
||||
.async_lift(|inner| types::encrypt_optional(inner, key))
|
||||
.await?,
|
||||
phone_country_code: request_customer_details.phone_country_code.clone(),
|
||||
description: None,
|
||||
@ -1110,15 +1121,19 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R>(
|
||||
.change_context(errors::StorageError::SerializationFailed)
|
||||
.attach_printable("Failed while encrypting Customer while insert")?;
|
||||
metrics::CUSTOMER_CREATED.add(&metrics::CONTEXT, 1, &[]);
|
||||
db.insert_customer(new_customer).await
|
||||
db.insert_customer(new_customer, key_store).await
|
||||
}
|
||||
})
|
||||
}
|
||||
None => match &payment_data.payment_intent.customer_id {
|
||||
None => None,
|
||||
Some(customer_id) => db
|
||||
.find_customer_optional_by_customer_id_merchant_id(customer_id, merchant_id)
|
||||
.await? // if customer_id is present in payment_intent but not found in customer table then shouldn't an error be thrown ?
|
||||
.find_customer_optional_by_customer_id_merchant_id(
|
||||
customer_id,
|
||||
merchant_id,
|
||||
key_store,
|
||||
)
|
||||
.await?
|
||||
.map(Ok),
|
||||
},
|
||||
};
|
||||
@ -2036,6 +2051,7 @@ pub async fn get_merchant_connector_account(
|
||||
merchant_id: &str,
|
||||
connector_label: &str,
|
||||
creds_identifier: Option<String>,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
) -> RouterResult<MerchantConnectorAccountType> {
|
||||
let db = &*state.store;
|
||||
match creds_identifier {
|
||||
@ -2075,6 +2091,7 @@ pub async fn get_merchant_connector_account(
|
||||
.find_merchant_connector_account_by_merchant_id_connector_label(
|
||||
merchant_id,
|
||||
connector_label,
|
||||
key_store,
|
||||
)
|
||||
.await
|
||||
.map(MerchantConnectorAccountType::DbVal)
|
||||
|
||||
Reference in New Issue
Block a user