feat: add macro to generate ToEncryptable trait (#6313)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
Kartikeya Hegde
2024-11-04 11:24:13 +05:30
committed by GitHub
parent adc5262f13
commit 19cf0f7437
19 changed files with 949 additions and 738 deletions

View File

@ -1,8 +1,8 @@
use api_models::customers::CustomerRequestWithEncryption;
#[cfg(all(feature = "v2", feature = "customer_v2"))]
use common_enums::DeleteStatus;
use common_utils::{
crypto, date_time,
crypto::{self, Encryptable},
date_time,
encryption::Encryption,
errors::{CustomResult, ValidationError},
id_type, pii,
@ -13,19 +13,23 @@ use common_utils::{
};
use diesel_models::customers::CustomerUpdateInternal;
use error_stack::ResultExt;
use masking::{PeekInterface, Secret};
use masking::{PeekInterface, Secret, SwitchStrategy};
use rustc_hash::FxHashMap;
use time::PrimitiveDateTime;
use crate::type_encryption as types;
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
#[derive(Clone, Debug)]
#[derive(Clone, Debug, router_derive::ToEncryption)]
pub struct Customer {
pub customer_id: id_type::CustomerId,
pub merchant_id: id_type::MerchantId,
pub name: crypto::OptionalEncryptableName,
pub email: crypto::OptionalEncryptableEmail,
pub phone: crypto::OptionalEncryptablePhone,
#[encrypt]
pub name: Option<Encryptable<Secret<String>>>,
#[encrypt]
pub email: Option<Encryptable<Secret<String, pii::EmailStrategy>>>,
#[encrypt]
pub phone: Option<Encryptable<Secret<String>>>,
pub phone_country_code: Option<String>,
pub description: Option<Description>,
pub created_at: PrimitiveDateTime,
@ -39,12 +43,15 @@ pub struct Customer {
}
#[cfg(all(feature = "v2", feature = "customer_v2"))]
#[derive(Clone, Debug)]
#[derive(Clone, Debug, router_derive::ToEncryption)]
pub struct Customer {
pub merchant_id: id_type::MerchantId,
pub name: crypto::OptionalEncryptableName,
pub email: crypto::OptionalEncryptableEmail,
pub phone: crypto::OptionalEncryptablePhone,
#[encrypt]
pub name: Option<Encryptable<Secret<String>>>,
#[encrypt]
pub email: Option<Encryptable<Secret<String, pii::EmailStrategy>>>,
#[encrypt]
pub phone: Option<Encryptable<Secret<String>>>,
pub phone_country_code: Option<String>,
pub description: Option<Description>,
pub created_at: PrimitiveDateTime,
@ -98,8 +105,8 @@ impl super::behaviour::Conversion for Customer {
let decrypted = types::crypto_operation(
state,
common_utils::type_name!(Self::DstType),
types::CryptoOperation::BatchDecrypt(CustomerRequestWithEncryption::to_encryptable(
CustomerRequestWithEncryption {
types::CryptoOperation::BatchDecrypt(EncryptedCustomer::to_encryptable(
EncryptedCustomer {
name: item.name.clone(),
phone: item.phone.clone(),
email: item.email.clone(),
@ -113,16 +120,23 @@ impl super::behaviour::Conversion for Customer {
.change_context(ValidationError::InvalidValue {
message: "Failed while decrypting customer data".to_string(),
})?;
let encryptable_customer = CustomerRequestWithEncryption::from_encryptable(decrypted)
.change_context(ValidationError::InvalidValue {
let encryptable_customer = EncryptedCustomer::from_encryptable(decrypted).change_context(
ValidationError::InvalidValue {
message: "Failed while decrypting customer data".to_string(),
})?;
},
)?;
Ok(Self {
customer_id: item.customer_id,
merchant_id: item.merchant_id,
name: encryptable_customer.name,
email: encryptable_customer.email,
email: encryptable_customer.email.map(|email| {
let encryptable: Encryptable<Secret<String, pii::EmailStrategy>> = Encryptable::new(
email.clone().into_inner().switch_strategy(),
email.into_encrypted(),
);
encryptable
}),
phone: encryptable_customer.phone,
phone_country_code: item.phone_country_code,
description: item.description,
@ -198,8 +212,8 @@ impl super::behaviour::Conversion for Customer {
let decrypted = types::crypto_operation(
state,
common_utils::type_name!(Self::DstType),
types::CryptoOperation::BatchDecrypt(CustomerRequestWithEncryption::to_encryptable(
CustomerRequestWithEncryption {
types::CryptoOperation::BatchDecrypt(EncryptedCustomer::to_encryptable(
EncryptedCustomer {
name: item.name.clone(),
phone: item.phone.clone(),
email: item.email.clone(),
@ -213,17 +227,24 @@ impl super::behaviour::Conversion for Customer {
.change_context(ValidationError::InvalidValue {
message: "Failed while decrypting customer data".to_string(),
})?;
let encryptable_customer = CustomerRequestWithEncryption::from_encryptable(decrypted)
.change_context(ValidationError::InvalidValue {
let encryptable_customer = EncryptedCustomer::from_encryptable(decrypted).change_context(
ValidationError::InvalidValue {
message: "Failed while decrypting customer data".to_string(),
})?;
},
)?;
Ok(Self {
id: item.id,
merchant_reference_id: item.merchant_reference_id,
merchant_id: item.merchant_id,
name: encryptable_customer.name,
email: encryptable_customer.email,
email: encryptable_customer.email.map(|email| {
let encryptable: Encryptable<Secret<String, pii::EmailStrategy>> = Encryptable::new(
email.clone().into_inner().switch_strategy(),
email.into_encrypted(),
);
encryptable
}),
phone: encryptable_customer.phone,
phone_country_code: item.phone_country_code,
description: item.description,

View File

@ -10,16 +10,18 @@ use diesel_models::{enums, merchant_connector_account::MerchantConnectorAccountU
use error_stack::ResultExt;
use masking::{PeekInterface, Secret};
use rustc_hash::FxHashMap;
use serde_json::Value;
use super::behaviour;
use crate::type_encryption::{crypto_operation, CryptoOperation};
#[cfg(feature = "v1")]
#[derive(Clone, Debug)]
#[derive(Clone, Debug, router_derive::ToEncryption)]
pub struct MerchantConnectorAccount {
pub merchant_id: id_type::MerchantId,
pub connector_name: String,
pub connector_account_details: Encryptable<pii::SecretSerdeValue>,
#[encrypt]
pub connector_account_details: Encryptable<Secret<Value>>,
pub test_mode: Option<bool>,
pub disabled: Option<bool>,
pub merchant_connector_id: id_type::MerchantConnectorAccountId,
@ -38,8 +40,10 @@ pub struct MerchantConnectorAccount {
pub applepay_verified_domains: Option<Vec<String>>,
pub pm_auth_config: Option<pii::SecretSerdeValue>,
pub status: enums::ConnectorStatus,
pub connector_wallets_details: Option<Encryptable<pii::SecretSerdeValue>>,
pub additional_merchant_data: Option<Encryptable<pii::SecretSerdeValue>>,
#[encrypt]
pub connector_wallets_details: Option<Encryptable<Secret<Value>>>,
#[encrypt]
pub additional_merchant_data: Option<Encryptable<Secret<Value>>>,
pub version: common_enums::ApiVersion,
}
@ -51,12 +55,13 @@ impl MerchantConnectorAccount {
}
#[cfg(feature = "v2")]
#[derive(Clone, Debug)]
#[derive(Clone, Debug, router_derive::ToEncryption)]
pub struct MerchantConnectorAccount {
pub id: id_type::MerchantConnectorAccountId,
pub merchant_id: id_type::MerchantId,
pub connector_name: String,
pub connector_account_details: Encryptable<pii::SecretSerdeValue>,
#[encrypt]
pub connector_account_details: Encryptable<Secret<Value>>,
pub disabled: Option<bool>,
pub payment_methods_enabled: Option<Vec<pii::SecretSerdeValue>>,
pub connector_type: enums::ConnectorType,
@ -70,8 +75,10 @@ pub struct MerchantConnectorAccount {
pub applepay_verified_domains: Option<Vec<String>>,
pub pm_auth_config: Option<pii::SecretSerdeValue>,
pub status: enums::ConnectorStatus,
pub connector_wallets_details: Option<Encryptable<pii::SecretSerdeValue>>,
pub additional_merchant_data: Option<Encryptable<pii::SecretSerdeValue>>,
#[encrypt]
pub connector_wallets_details: Option<Encryptable<Secret<Value>>>,
#[encrypt]
pub additional_merchant_data: Option<Encryptable<Secret<Value>>>,
pub version: common_enums::ApiVersion,
}
@ -179,11 +186,13 @@ impl behaviour::Conversion for MerchantConnectorAccount {
let decrypted_data = crypto_operation(
state,
type_name!(Self::DstType),
CryptoOperation::BatchDecrypt(EncryptedMca::to_encryptable(EncryptedMca {
connector_account_details: other.connector_account_details,
additional_merchant_data: other.additional_merchant_data,
connector_wallets_details: other.connector_wallets_details,
})),
CryptoOperation::BatchDecrypt(EncryptedMerchantConnectorAccount::to_encryptable(
EncryptedMerchantConnectorAccount {
connector_account_details: other.connector_account_details,
additional_merchant_data: other.additional_merchant_data,
connector_wallets_details: other.connector_wallets_details,
},
)),
identifier.clone(),
key.peek(),
)
@ -193,11 +202,10 @@ impl behaviour::Conversion for MerchantConnectorAccount {
message: "Failed while decrypting connector account details".to_string(),
})?;
let decrypted_data = EncryptedMca::from_encryptable(decrypted_data).change_context(
ValidationError::InvalidValue {
let decrypted_data = EncryptedMerchantConnectorAccount::from_encryptable(decrypted_data)
.change_context(ValidationError::InvalidValue {
message: "Failed while decrypting connector account details".to_string(),
},
)?;
})?;
Ok(Self {
merchant_id: other.merchant_id,
@ -308,11 +316,13 @@ impl behaviour::Conversion for MerchantConnectorAccount {
let decrypted_data = crypto_operation(
state,
type_name!(Self::DstType),
CryptoOperation::BatchDecrypt(EncryptedMca::to_encryptable(EncryptedMca {
connector_account_details: other.connector_account_details,
additional_merchant_data: other.additional_merchant_data,
connector_wallets_details: other.connector_wallets_details,
})),
CryptoOperation::BatchDecrypt(EncryptedMerchantConnectorAccount::to_encryptable(
EncryptedMerchantConnectorAccount {
connector_account_details: other.connector_account_details,
additional_merchant_data: other.additional_merchant_data,
connector_wallets_details: other.connector_wallets_details,
},
)),
identifier.clone(),
key.peek(),
)
@ -322,11 +332,10 @@ impl behaviour::Conversion for MerchantConnectorAccount {
message: "Failed while decrypting connector account details".to_string(),
})?;
let decrypted_data = EncryptedMca::from_encryptable(decrypted_data).change_context(
ValidationError::InvalidValue {
let decrypted_data = EncryptedMerchantConnectorAccount::from_encryptable(decrypted_data)
.change_context(ValidationError::InvalidValue {
message: "Failed while decrypting connector account details".to_string(),
},
)?;
})?;
Ok(Self {
id: other.id,
@ -502,121 +511,3 @@ impl From<MerchantConnectorAccountUpdate> for MerchantConnectorAccountUpdateInte
}
}
}
pub struct McaFromRequestfromUpdate {
pub connector_account_details: Option<pii::SecretSerdeValue>,
pub connector_wallets_details: Option<pii::SecretSerdeValue>,
pub additional_merchant_data: Option<pii::SecretSerdeValue>,
}
pub struct McaFromRequest {
pub connector_account_details: pii::SecretSerdeValue,
pub connector_wallets_details: Option<pii::SecretSerdeValue>,
pub additional_merchant_data: Option<pii::SecretSerdeValue>,
}
pub struct DecryptedMca {
pub connector_account_details: Encryptable<pii::SecretSerdeValue>,
pub connector_wallets_details: Option<Encryptable<pii::SecretSerdeValue>>,
pub additional_merchant_data: Option<Encryptable<pii::SecretSerdeValue>>,
}
pub struct EncryptedMca {
pub connector_account_details: Encryption,
pub connector_wallets_details: Option<Encryption>,
pub additional_merchant_data: Option<Encryption>,
}
pub struct DecryptedUpdateMca {
pub connector_account_details: Option<Encryptable<pii::SecretSerdeValue>>,
pub connector_wallets_details: Option<Encryptable<pii::SecretSerdeValue>>,
pub additional_merchant_data: Option<Encryptable<pii::SecretSerdeValue>>,
}
impl ToEncryptable<DecryptedMca, Secret<serde_json::Value>, Encryption> for EncryptedMca {
fn from_encryptable(
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
) -> CustomResult<DecryptedMca, common_utils::errors::ParsingError> {
Ok(DecryptedMca {
connector_account_details: hashmap.remove("connector_account_details").ok_or(
error_stack::report!(common_utils::errors::ParsingError::EncodeError(
"Unable to convert from HashMap to DecryptedMca",
)),
)?,
connector_wallets_details: hashmap.remove("connector_wallets_details"),
additional_merchant_data: hashmap.remove("additional_merchant_data"),
})
}
fn to_encryptable(self) -> FxHashMap<String, Encryption> {
let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
map.insert(
"connector_account_details".to_string(),
self.connector_account_details,
);
self.connector_wallets_details
.map(|s| map.insert("connector_wallets_details".to_string(), s));
self.additional_merchant_data
.map(|s| map.insert("additional_merchant_data".to_string(), s));
map
}
}
impl ToEncryptable<DecryptedUpdateMca, Secret<serde_json::Value>, Secret<serde_json::Value>>
for McaFromRequestfromUpdate
{
fn from_encryptable(
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
) -> CustomResult<DecryptedUpdateMca, common_utils::errors::ParsingError> {
Ok(DecryptedUpdateMca {
connector_account_details: hashmap.remove("connector_account_details"),
connector_wallets_details: hashmap.remove("connector_wallets_details"),
additional_merchant_data: hashmap.remove("additional_merchant_data"),
})
}
fn to_encryptable(self) -> FxHashMap<String, Secret<serde_json::Value>> {
let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
self.connector_account_details
.map(|cad| map.insert("connector_account_details".to_string(), cad));
self.connector_wallets_details
.map(|s| map.insert("connector_wallets_details".to_string(), s));
self.additional_merchant_data
.map(|s| map.insert("additional_merchant_data".to_string(), s));
map
}
}
impl ToEncryptable<DecryptedMca, Secret<serde_json::Value>, Secret<serde_json::Value>>
for McaFromRequest
{
fn from_encryptable(
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
) -> CustomResult<DecryptedMca, common_utils::errors::ParsingError> {
Ok(DecryptedMca {
connector_account_details: hashmap.remove("connector_account_details").ok_or(
error_stack::report!(common_utils::errors::ParsingError::EncodeError(
"Unable to convert from HashMap to DecryptedMca",
)),
)?,
connector_wallets_details: hashmap.remove("connector_wallets_details"),
additional_merchant_data: hashmap.remove("additional_merchant_data"),
})
}
fn to_encryptable(self) -> FxHashMap<String, Secret<serde_json::Value>> {
let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
map.insert(
"connector_account_details".to_string(),
self.connector_account_details,
);
self.connector_wallets_details
.map(|s| map.insert("connector_wallets_details".to_string(), s));
self.additional_merchant_data
.map(|s| map.insert("additional_merchant_data".to_string(), s));
map
}
}

View File

@ -5,11 +5,21 @@ use std::marker::PhantomData;
use api_models::payments::Address;
#[cfg(feature = "v2")]
use api_models::payments::OrderDetailsWithAmount;
use common_utils::{self, crypto::Encryptable, id_type, pii, types::MinorUnit};
use common_utils::{
self,
crypto::Encryptable,
encryption::Encryption,
errors::CustomResult,
id_type, pii,
types::{keymanager::ToEncryptable, MinorUnit},
};
use diesel_models::payment_intent::TaxDetails;
#[cfg(feature = "v2")]
use error_stack::ResultExt;
use masking::Secret;
use router_derive::ToEncryption;
use rustc_hash::FxHashMap;
use serde_json::Value;
use time::PrimitiveDateTime;
pub mod payment_attempt;
@ -25,7 +35,7 @@ use crate::{business_profile, merchant_account};
use crate::{errors, payment_method_data, ApiModelToDieselModelConvertor};
#[cfg(feature = "v1")]
#[derive(Clone, Debug, PartialEq, serde::Serialize)]
#[derive(Clone, Debug, PartialEq, serde::Serialize, ToEncryption)]
pub struct PaymentIntent {
pub payment_id: id_type::PaymentId,
pub merchant_id: id_type::MerchantId,
@ -37,7 +47,7 @@ pub struct PaymentIntent {
pub customer_id: Option<id_type::CustomerId>,
pub description: Option<String>,
pub return_url: Option<String>,
pub metadata: Option<serde_json::Value>,
pub metadata: Option<Value>,
pub connector_id: Option<String>,
pub shipping_address_id: Option<String>,
pub billing_address_id: Option<String>,
@ -56,9 +66,9 @@ pub struct PaymentIntent {
pub business_country: Option<storage_enums::CountryAlpha2>,
pub business_label: Option<String>,
pub order_details: Option<Vec<pii::SecretSerdeValue>>,
pub allowed_payment_method_types: Option<serde_json::Value>,
pub connector_metadata: Option<serde_json::Value>,
pub feature_metadata: Option<serde_json::Value>,
pub allowed_payment_method_types: Option<Value>,
pub connector_metadata: Option<Value>,
pub feature_metadata: Option<Value>,
pub attempt_count: i16,
pub profile_id: Option<id_type::ProfileId>,
pub payment_link_id: Option<String>,
@ -78,10 +88,13 @@ pub struct PaymentIntent {
pub request_external_three_ds_authentication: Option<bool>,
pub charges: Option<pii::SecretSerdeValue>,
pub frm_metadata: Option<pii::SecretSerdeValue>,
pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
pub billing_details: Option<Encryptable<Secret<serde_json::Value>>>,
#[encrypt]
pub customer_details: Option<Encryptable<Secret<Value>>>,
#[encrypt]
pub billing_details: Option<Encryptable<Secret<Value>>>,
pub merchant_order_reference_id: Option<String>,
pub shipping_details: Option<Encryptable<Secret<serde_json::Value>>>,
#[encrypt]
pub shipping_details: Option<Encryptable<Secret<Value>>>,
pub is_payment_processor_token_flow: Option<bool>,
pub organization_id: id_type::OrganizationId,
pub tax_details: Option<TaxDetails>,
@ -225,7 +238,7 @@ impl AmountDetails {
}
#[cfg(feature = "v2")]
#[derive(Clone, Debug, PartialEq, serde::Serialize)]
#[derive(Clone, Debug, PartialEq, serde::Serialize, ToEncryption)]
pub struct PaymentIntent {
/// The global identifier for the payment intent. This is generated by the system.
/// The format of the global id is `{cell_id:5}_pay_{time_ordered_uuid:32}`.
@ -292,19 +305,22 @@ pub struct PaymentIntent {
/// Metadata related to fraud and risk management
pub frm_metadata: Option<pii::SecretSerdeValue>,
/// The details of the customer in a denormalized form. Only a subset of fields are stored.
pub customer_details: Option<Encryptable<Secret<serde_json::Value>>>,
#[encrypt]
pub customer_details: Option<Encryptable<Secret<Value>>>,
/// The reference id for the order in the merchant's system. This value can be passed by the merchant.
pub merchant_reference_id: Option<id_type::PaymentReferenceId>,
/// The billing address for the order in a denormalized form.
#[encrypt(ty = Value)]
pub billing_address: Option<Encryptable<Secret<Address>>>,
/// The shipping address for the order in a denormalized form.
#[encrypt(ty = Value)]
pub shipping_address: Option<Encryptable<Secret<Address>>>,
/// Capture method for the payment
pub capture_method: storage_enums::CaptureMethod,
/// Authentication type that is requested by the merchant for this payment.
pub authentication_type: common_enums::AuthenticationType,
/// This contains the pre routing results that are done when routing is done during listing the payment methods.
pub prerouting_algorithm: Option<serde_json::Value>,
pub prerouting_algorithm: Option<Value>,
/// The organization id for the payment. This is derived from the merchant account
pub organization_id: id_type::OrganizationId,
/// Denotes the request by the merchant whether to enable a payment link for this payment.
@ -323,7 +339,7 @@ pub struct PaymentIntent {
impl PaymentIntent {
fn get_request_incremental_authorization_value(
request: &api_models::payments::PaymentsCreateIntentRequest,
) -> common_utils::errors::CustomResult<
) -> CustomResult<
common_enums::RequestIncrementalAuthorization,
errors::api_error_response::ApiErrorResponse,
> {
@ -364,8 +380,7 @@ impl PaymentIntent {
request: api_models::payments::PaymentsCreateIntentRequest,
billing_address: Option<Encryptable<Secret<Address>>>,
shipping_address: Option<Encryptable<Secret<Address>>>,
) -> common_utils::errors::CustomResult<Self, errors::api_error_response::ApiErrorResponse>
{
) -> CustomResult<Self, errors::api_error_response::ApiErrorResponse> {
let allowed_payment_method_types = request
.get_allowed_payment_method_types_as_value()
.change_context(errors::api_error_response::ApiErrorResponse::InternalServerError)

View File

@ -3,7 +3,7 @@ use common_enums as storage_enums;
use common_utils::ext_traits::{Encode, ValueExt};
use common_utils::{
consts::{PAYMENTS_LIST_MAX_LIMIT_V1, PAYMENTS_LIST_MAX_LIMIT_V2},
crypto::{self, Encryptable},
crypto::Encryptable,
encryption::Encryption,
errors::{CustomResult, ValidationError},
id_type,
@ -21,7 +21,6 @@ use error_stack::ResultExt;
#[cfg(feature = "v2")]
use masking::ExposeInterface;
use masking::{Deserialize, PeekInterface, Secret};
use rustc_hash::FxHashMap;
use serde::Serialize;
use time::PrimitiveDateTime;
@ -1241,10 +1240,10 @@ impl behaviour::Conversion for PaymentIntent {
let decrypted_data = crypto_operation(
state,
type_name!(Self::DstType),
CryptoOperation::BatchDecrypt(EncryptedPaymentIntentAddress::to_encryptable(
EncryptedPaymentIntentAddress {
billing: storage_model.billing_address,
shipping: storage_model.shipping_address,
CryptoOperation::BatchDecrypt(super::EncryptedPaymentIntent::to_encryptable(
super::EncryptedPaymentIntent {
billing_address: storage_model.billing_address,
shipping_address: storage_model.shipping_address,
customer_details: storage_model.customer_details,
},
)),
@ -1254,7 +1253,7 @@ impl behaviour::Conversion for PaymentIntent {
.await
.and_then(|val| val.try_into_batchoperation())?;
let data = EncryptedPaymentIntentAddress::from_encryptable(decrypted_data)
let data = super::EncryptedPaymentIntent::from_encryptable(decrypted_data)
.change_context(common_utils::errors::CryptoError::DecodingFailed)
.attach_printable("Invalid batch operation data")?;
@ -1275,7 +1274,7 @@ impl behaviour::Conversion for PaymentIntent {
};
let billing_address = data
.billing
.billing_address
.map(|billing| {
billing.deserialize_inner_value(|value| value.parse_value("Address"))
})
@ -1284,7 +1283,7 @@ impl behaviour::Conversion for PaymentIntent {
.attach_printable("Error while deserializing Address")?;
let shipping_address = data
.shipping
.shipping_address
.map(|shipping| {
shipping.deserialize_inner_value(|value| value.parse_value("Address"))
})
@ -1513,10 +1512,10 @@ impl behaviour::Conversion for PaymentIntent {
let decrypted_data = crypto_operation(
state,
type_name!(Self::DstType),
CryptoOperation::BatchDecrypt(EncryptedPaymentIntentAddress::to_encryptable(
EncryptedPaymentIntentAddress {
billing: storage_model.billing_details,
shipping: storage_model.shipping_details,
CryptoOperation::BatchDecrypt(super::EncryptedPaymentIntent::to_encryptable(
super::EncryptedPaymentIntent {
billing_details: storage_model.billing_details,
shipping_details: storage_model.shipping_details,
customer_details: storage_model.customer_details,
},
)),
@ -1526,7 +1525,7 @@ impl behaviour::Conversion for PaymentIntent {
.await
.and_then(|val| val.try_into_batchoperation())?;
let data = EncryptedPaymentIntentAddress::from_encryptable(decrypted_data)
let data = super::EncryptedPaymentIntent::from_encryptable(decrypted_data)
.change_context(common_utils::errors::CryptoError::DecodingFailed)
.attach_printable("Invalid batch operation data")?;
@ -1578,9 +1577,9 @@ impl behaviour::Conversion for PaymentIntent {
shipping_cost: storage_model.shipping_cost,
tax_details: storage_model.tax_details,
customer_details: data.customer_details,
billing_details: data.billing,
billing_details: data.billing_details,
merchant_order_reference_id: storage_model.merchant_order_reference_id,
shipping_details: data.shipping,
shipping_details: data.shipping_details,
is_payment_processor_token_flow: storage_model.is_payment_processor_token_flow,
organization_id: storage_model.organization_id,
skip_external_tax_calculation: storage_model.skip_external_tax_calculation,
@ -1649,73 +1648,3 @@ impl behaviour::Conversion for PaymentIntent {
})
}
}
pub struct EncryptedPaymentIntentAddress {
pub shipping: Option<Encryption>,
pub billing: Option<Encryption>,
pub customer_details: Option<Encryption>,
}
pub struct PaymentAddressFromRequest {
pub shipping: Option<Secret<serde_json::Value>>,
pub billing: Option<Secret<serde_json::Value>>,
pub customer_details: Option<Secret<serde_json::Value>>,
}
pub struct DecryptedPaymentIntentAddress {
pub shipping: crypto::OptionalEncryptableValue,
pub billing: crypto::OptionalEncryptableValue,
pub customer_details: crypto::OptionalEncryptableValue,
}
impl ToEncryptable<DecryptedPaymentIntentAddress, Secret<serde_json::Value>, Encryption>
for EncryptedPaymentIntentAddress
{
fn from_encryptable(
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
) -> CustomResult<DecryptedPaymentIntentAddress, common_utils::errors::ParsingError> {
Ok(DecryptedPaymentIntentAddress {
shipping: hashmap.remove("shipping"),
billing: hashmap.remove("billing"),
customer_details: hashmap.remove("customer_details"),
})
}
fn to_encryptable(self) -> FxHashMap<String, Encryption> {
let mut map = FxHashMap::with_capacity_and_hasher(9, Default::default());
self.shipping.map(|s| map.insert("shipping".to_string(), s));
self.billing.map(|s| map.insert("billing".to_string(), s));
self.customer_details
.map(|s| map.insert("customer_details".to_string(), s));
map
}
}
impl
ToEncryptable<
DecryptedPaymentIntentAddress,
Secret<serde_json::Value>,
Secret<serde_json::Value>,
> for PaymentAddressFromRequest
{
fn from_encryptable(
mut hashmap: FxHashMap<String, Encryptable<Secret<serde_json::Value>>>,
) -> CustomResult<DecryptedPaymentIntentAddress, common_utils::errors::ParsingError> {
Ok(DecryptedPaymentIntentAddress {
shipping: hashmap.remove("shipping"),
billing: hashmap.remove("billing"),
customer_details: hashmap.remove("customer_details"),
})
}
fn to_encryptable(self) -> FxHashMap<String, Secret<serde_json::Value>> {
let mut map = FxHashMap::with_capacity_and_hasher(9, Default::default());
self.shipping.map(|s| map.insert("shipping".to_string(), s));
self.billing.map(|s| map.insert("billing".to_string(), s));
self.customer_details
.map(|s| map.insert("customer_details".to_string(), s));
map
}
}