mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 13:30:39 +08:00
feat: encrypt PII fields before saving it in the database (#1043)
Co-authored-by: Nishant Joshi <nishant.joshi@juspay.in>
This commit is contained in:
@ -1,91 +1,66 @@
|
||||
use common_utils::{consts, custom_serde, date_time, generate_id};
|
||||
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
|
||||
use masking::Secret;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::{OffsetDateTime, PrimitiveDateTime};
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
use crate::{enums, schema::address};
|
||||
use crate::{encryption::Encryption, enums, schema::address};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Insertable, router_derive::DebugAsDisplay)]
|
||||
#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
|
||||
#[diesel(table_name = address)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct AddressNew {
|
||||
pub address_id: String,
|
||||
pub city: Option<String>,
|
||||
pub country: Option<enums::CountryAlpha2>,
|
||||
pub line1: Option<Secret<String>>,
|
||||
pub line2: Option<Secret<String>>,
|
||||
pub line3: Option<Secret<String>>,
|
||||
pub state: Option<Secret<String>>,
|
||||
pub zip: Option<Secret<String>>,
|
||||
pub first_name: Option<Secret<String>>,
|
||||
pub last_name: Option<Secret<String>>,
|
||||
pub phone_number: Option<Secret<String>>,
|
||||
pub line1: Option<Encryption>,
|
||||
pub line2: Option<Encryption>,
|
||||
pub line3: Option<Encryption>,
|
||||
pub state: Option<Encryption>,
|
||||
pub zip: Option<Encryption>,
|
||||
pub first_name: Option<Encryption>,
|
||||
pub last_name: Option<Encryption>,
|
||||
pub phone_number: Option<Encryption>,
|
||||
pub country_code: Option<String>,
|
||||
pub customer_id: String,
|
||||
pub merchant_id: String,
|
||||
pub created_at: PrimitiveDateTime,
|
||||
pub modified_at: PrimitiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable, frunk::LabelledGeneric)]
|
||||
#[derive(Clone, Debug, Identifiable, Queryable, frunk::LabelledGeneric)]
|
||||
#[diesel(table_name = address)]
|
||||
pub struct Address {
|
||||
#[serde(skip_serializing)]
|
||||
pub id: i32,
|
||||
#[serde(skip_serializing)]
|
||||
pub address_id: String,
|
||||
pub city: Option<String>,
|
||||
pub country: Option<enums::CountryAlpha2>,
|
||||
pub line1: Option<Secret<String>>,
|
||||
pub line2: Option<Secret<String>>,
|
||||
pub line3: Option<Secret<String>>,
|
||||
pub state: Option<Secret<String>>,
|
||||
pub zip: Option<Secret<String>>,
|
||||
pub first_name: Option<Secret<String>>,
|
||||
pub last_name: Option<Secret<String>>,
|
||||
pub phone_number: Option<Secret<String>>,
|
||||
pub line1: Option<Encryption>,
|
||||
pub line2: Option<Encryption>,
|
||||
pub line3: Option<Encryption>,
|
||||
pub state: Option<Encryption>,
|
||||
pub zip: Option<Encryption>,
|
||||
pub first_name: Option<Encryption>,
|
||||
pub last_name: Option<Encryption>,
|
||||
pub phone_number: Option<Encryption>,
|
||||
pub country_code: Option<String>,
|
||||
#[serde(skip_serializing)]
|
||||
#[serde(with = "custom_serde::iso8601")]
|
||||
pub created_at: PrimitiveDateTime,
|
||||
#[serde(skip_serializing)]
|
||||
#[serde(with = "custom_serde::iso8601")]
|
||||
pub modified_at: PrimitiveDateTime,
|
||||
pub customer_id: String,
|
||||
pub merchant_id: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, frunk::LabelledGeneric)]
|
||||
pub enum AddressUpdate {
|
||||
Update {
|
||||
city: Option<String>,
|
||||
country: Option<enums::CountryAlpha2>,
|
||||
line1: Option<Secret<String>>,
|
||||
line2: Option<Secret<String>>,
|
||||
line3: Option<Secret<String>>,
|
||||
state: Option<Secret<String>>,
|
||||
zip: Option<Secret<String>>,
|
||||
first_name: Option<Secret<String>>,
|
||||
last_name: Option<Secret<String>>,
|
||||
phone_number: Option<Secret<String>>,
|
||||
country_code: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)]
|
||||
#[diesel(table_name = address)]
|
||||
pub struct AddressUpdateInternal {
|
||||
city: Option<String>,
|
||||
country: Option<enums::CountryAlpha2>,
|
||||
line1: Option<Secret<String>>,
|
||||
line2: Option<Secret<String>>,
|
||||
line3: Option<Secret<String>>,
|
||||
state: Option<Secret<String>>,
|
||||
zip: Option<Secret<String>>,
|
||||
first_name: Option<Secret<String>>,
|
||||
last_name: Option<Secret<String>>,
|
||||
phone_number: Option<Secret<String>>,
|
||||
country_code: Option<String>,
|
||||
modified_at: PrimitiveDateTime,
|
||||
pub city: Option<String>,
|
||||
pub country: Option<enums::CountryAlpha2>,
|
||||
pub line1: Option<Encryption>,
|
||||
pub line2: Option<Encryption>,
|
||||
pub line3: Option<Encryption>,
|
||||
pub state: Option<Encryption>,
|
||||
pub zip: Option<Encryption>,
|
||||
pub first_name: Option<Encryption>,
|
||||
pub last_name: Option<Encryption>,
|
||||
pub phone_number: Option<Encryption>,
|
||||
pub country_code: Option<String>,
|
||||
pub modified_at: PrimitiveDateTime,
|
||||
}
|
||||
|
||||
impl AddressUpdateInternal {
|
||||
@ -108,57 +83,3 @@ impl AddressUpdateInternal {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AddressUpdate> for AddressUpdateInternal {
|
||||
fn from(address_update: AddressUpdate) -> Self {
|
||||
match address_update {
|
||||
AddressUpdate::Update {
|
||||
city,
|
||||
country,
|
||||
line1,
|
||||
line2,
|
||||
line3,
|
||||
state,
|
||||
zip,
|
||||
first_name,
|
||||
last_name,
|
||||
phone_number,
|
||||
country_code,
|
||||
} => Self {
|
||||
city,
|
||||
country,
|
||||
line1,
|
||||
line2,
|
||||
line3,
|
||||
state,
|
||||
zip,
|
||||
first_name,
|
||||
last_name,
|
||||
phone_number,
|
||||
country_code,
|
||||
modified_at: date_time::convert_to_pdt(OffsetDateTime::now_utc()),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AddressNew {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
address_id: generate_id(consts::ID_LENGTH, "add"),
|
||||
city: None,
|
||||
country: None,
|
||||
line1: None,
|
||||
line2: None,
|
||||
line3: None,
|
||||
state: None,
|
||||
zip: None,
|
||||
first_name: None,
|
||||
last_name: None,
|
||||
phone_number: None,
|
||||
country_code: None,
|
||||
customer_id: String::default(),
|
||||
merchant_id: String::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,22 +1,23 @@
|
||||
use common_utils::{pii, pii::Email};
|
||||
use common_utils::pii;
|
||||
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
|
||||
use masking::Secret;
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
use crate::schema::customers;
|
||||
use crate::{encryption::Encryption, schema::customers};
|
||||
|
||||
#[derive(Default, Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
|
||||
#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
|
||||
#[diesel(table_name = customers)]
|
||||
pub struct CustomerNew {
|
||||
pub customer_id: String,
|
||||
pub merchant_id: String,
|
||||
pub name: Option<String>,
|
||||
pub email: Option<Email>,
|
||||
pub phone: Option<Secret<String>>,
|
||||
pub name: Option<Encryption>,
|
||||
pub email: Option<Encryption>,
|
||||
pub phone: Option<Encryption>,
|
||||
pub description: Option<String>,
|
||||
pub phone_country_code: Option<String>,
|
||||
pub metadata: Option<pii::SecretSerdeValue>,
|
||||
pub connector_customer: Option<serde_json::Value>,
|
||||
pub created_at: PrimitiveDateTime,
|
||||
pub modified_at: PrimitiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Identifiable, Queryable)]
|
||||
@ -25,9 +26,9 @@ pub struct Customer {
|
||||
pub id: i32,
|
||||
pub customer_id: String,
|
||||
pub merchant_id: String,
|
||||
pub name: Option<String>,
|
||||
pub email: Option<Email>,
|
||||
pub phone: Option<Secret<String>>,
|
||||
pub name: Option<Encryption>,
|
||||
pub email: Option<Encryption>,
|
||||
pub phone: Option<Encryption>,
|
||||
pub phone_country_code: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub created_at: PrimitiveDateTime,
|
||||
@ -36,61 +37,15 @@ pub struct Customer {
|
||||
pub modified_at: PrimitiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CustomerUpdate {
|
||||
Update {
|
||||
name: Option<String>,
|
||||
email: Option<Email>,
|
||||
phone: Option<Secret<String>>,
|
||||
description: Option<String>,
|
||||
phone_country_code: Option<String>,
|
||||
metadata: Option<pii::SecretSerdeValue>,
|
||||
connector_customer: Option<serde_json::Value>,
|
||||
},
|
||||
ConnectorCustomer {
|
||||
connector_customer: Option<serde_json::Value>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
|
||||
#[diesel(table_name = customers)]
|
||||
pub struct CustomerUpdateInternal {
|
||||
name: Option<String>,
|
||||
email: Option<Email>,
|
||||
phone: Option<Secret<String>>,
|
||||
description: Option<String>,
|
||||
phone_country_code: Option<String>,
|
||||
metadata: Option<pii::SecretSerdeValue>,
|
||||
connector_customer: Option<serde_json::Value>,
|
||||
modified_at: Option<PrimitiveDateTime>,
|
||||
}
|
||||
|
||||
impl From<CustomerUpdate> for CustomerUpdateInternal {
|
||||
fn from(customer_update: CustomerUpdate) -> Self {
|
||||
match customer_update {
|
||||
CustomerUpdate::Update {
|
||||
name,
|
||||
email,
|
||||
phone,
|
||||
description,
|
||||
phone_country_code,
|
||||
metadata,
|
||||
connector_customer,
|
||||
} => Self {
|
||||
name,
|
||||
email,
|
||||
phone,
|
||||
description,
|
||||
phone_country_code,
|
||||
metadata,
|
||||
connector_customer,
|
||||
modified_at: Some(common_utils::date_time::now()),
|
||||
},
|
||||
CustomerUpdate::ConnectorCustomer { connector_customer } => Self {
|
||||
connector_customer,
|
||||
modified_at: Some(common_utils::date_time::now()),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
pub name: Option<Encryption>,
|
||||
pub email: Option<Encryption>,
|
||||
pub phone: Option<Encryption>,
|
||||
pub description: Option<String>,
|
||||
pub phone_country_code: Option<String>,
|
||||
pub metadata: Option<pii::SecretSerdeValue>,
|
||||
pub modified_at: Option<PrimitiveDateTime>,
|
||||
pub connector_customer: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
69
crates/storage_models/src/encryption.rs
Normal file
69
crates/storage_models/src/encryption.rs
Normal file
@ -0,0 +1,69 @@
|
||||
use diesel::{
|
||||
backend::Backend,
|
||||
deserialize::{self, FromSql, Queryable},
|
||||
serialize::ToSql,
|
||||
sql_types, AsExpression,
|
||||
};
|
||||
|
||||
#[derive(Debug, AsExpression, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[diesel(sql_type = diesel::sql_types::Binary)]
|
||||
#[repr(transparent)]
|
||||
pub struct Encryption {
|
||||
inner: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<T: Clone> From<common_utils::crypto::Encryptable<T>> for Encryption {
|
||||
fn from(value: common_utils::crypto::Encryptable<T>) -> Self {
|
||||
Self::new(value.into_encrypted())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encryption {
|
||||
pub fn new(item: Vec<u8>) -> Self {
|
||||
Self { inner: item }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_inner(self) -> Vec<u8> {
|
||||
self.inner
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_inner(&self) -> &Vec<u8> {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB> FromSql<sql_types::Binary, DB> for Encryption
|
||||
where
|
||||
DB: Backend,
|
||||
Vec<u8>: FromSql<sql_types::Binary, DB>,
|
||||
{
|
||||
fn from_sql(bytes: DB::RawValue<'_>) -> diesel::deserialize::Result<Self> {
|
||||
<Vec<u8>>::from_sql(bytes).map(Self::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB> ToSql<sql_types::Binary, DB> for Encryption
|
||||
where
|
||||
DB: Backend,
|
||||
Vec<u8>: ToSql<sql_types::Binary, DB>,
|
||||
{
|
||||
fn to_sql<'b>(
|
||||
&'b self,
|
||||
out: &mut diesel::serialize::Output<'b, '_, DB>,
|
||||
) -> diesel::serialize::Result {
|
||||
self.get_inner().to_sql(out)
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB> Queryable<sql_types::Binary, DB> for Encryption
|
||||
where
|
||||
DB: Backend,
|
||||
Vec<u8>: FromSql<sql_types::Binary, DB>,
|
||||
{
|
||||
type Row = Vec<u8>;
|
||||
fn build(row: Self::Row) -> deserialize::Result<Self> {
|
||||
Ok(Self { inner: row })
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@ pub mod configs;
|
||||
pub mod connector_response;
|
||||
pub mod customers;
|
||||
pub mod dispute;
|
||||
pub mod encryption;
|
||||
pub mod enums;
|
||||
pub mod ephemeral_key;
|
||||
pub mod errors;
|
||||
@ -16,6 +17,7 @@ pub mod locker_mock_up;
|
||||
pub mod mandate;
|
||||
pub mod merchant_account;
|
||||
pub mod merchant_connector_account;
|
||||
pub mod merchant_key_store;
|
||||
pub mod payment_attempt;
|
||||
pub mod payment_intent;
|
||||
pub mod payment_method;
|
||||
|
||||
@ -1,15 +1,13 @@
|
||||
use common_utils::pii;
|
||||
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
|
||||
|
||||
use crate::{enums as storage_enums, schema::merchant_account};
|
||||
use crate::{encryption::Encryption, enums as storage_enums, schema::merchant_account};
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
serde::Deserialize,
|
||||
serde::Serialize,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Identifiable,
|
||||
Queryable,
|
||||
router_derive::DebugAsDisplay,
|
||||
@ -22,8 +20,8 @@ pub struct MerchantAccount {
|
||||
pub enable_payment_response_hash: bool,
|
||||
pub payment_response_hash_key: Option<String>,
|
||||
pub redirect_to_merchant_with_http_post: bool,
|
||||
pub merchant_name: Option<String>,
|
||||
pub merchant_details: Option<serde_json::Value>,
|
||||
pub merchant_name: Option<Encryption>,
|
||||
pub merchant_details: Option<Encryption>,
|
||||
pub webhook_details: Option<serde_json::Value>,
|
||||
pub sub_merchants_enabled: Option<bool>,
|
||||
pub parent_merchant_id: Option<String>,
|
||||
@ -39,12 +37,12 @@ pub struct MerchantAccount {
|
||||
pub frm_routing_algorithm: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)]
|
||||
#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
|
||||
#[diesel(table_name = merchant_account)]
|
||||
pub struct MerchantAccountNew {
|
||||
pub merchant_id: String,
|
||||
pub merchant_name: Option<String>,
|
||||
pub merchant_details: Option<serde_json::Value>,
|
||||
pub merchant_name: Option<Encryption>,
|
||||
pub merchant_details: Option<Encryption>,
|
||||
pub return_url: Option<String>,
|
||||
pub webhook_details: Option<serde_json::Value>,
|
||||
pub sub_merchants_enabled: Option<bool>,
|
||||
@ -58,101 +56,30 @@ pub struct MerchantAccountNew {
|
||||
pub routing_algorithm: Option<serde_json::Value>,
|
||||
pub primary_business_details: serde_json::Value,
|
||||
pub intent_fulfillment_time: Option<i64>,
|
||||
pub created_at: time::PrimitiveDateTime,
|
||||
pub modified_at: time::PrimitiveDateTime,
|
||||
pub frm_routing_algorithm: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MerchantAccountUpdate {
|
||||
Update {
|
||||
merchant_name: Option<String>,
|
||||
merchant_details: Option<serde_json::Value>,
|
||||
return_url: Option<String>,
|
||||
webhook_details: Option<serde_json::Value>,
|
||||
sub_merchants_enabled: Option<bool>,
|
||||
parent_merchant_id: Option<String>,
|
||||
enable_payment_response_hash: Option<bool>,
|
||||
payment_response_hash_key: Option<String>,
|
||||
redirect_to_merchant_with_http_post: Option<bool>,
|
||||
publishable_key: Option<String>,
|
||||
locker_id: Option<String>,
|
||||
metadata: Option<pii::SecretSerdeValue>,
|
||||
routing_algorithm: Option<serde_json::Value>,
|
||||
primary_business_details: Option<serde_json::Value>,
|
||||
intent_fulfillment_time: Option<i64>,
|
||||
frm_routing_algorithm: Option<serde_json::Value>,
|
||||
},
|
||||
StorageSchemeUpdate {
|
||||
storage_scheme: storage_enums::MerchantStorageScheme,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
|
||||
#[diesel(table_name = merchant_account)]
|
||||
pub struct MerchantAccountUpdateInternal {
|
||||
merchant_name: Option<String>,
|
||||
merchant_details: Option<serde_json::Value>,
|
||||
return_url: Option<String>,
|
||||
webhook_details: Option<serde_json::Value>,
|
||||
sub_merchants_enabled: Option<bool>,
|
||||
parent_merchant_id: Option<String>,
|
||||
enable_payment_response_hash: Option<bool>,
|
||||
payment_response_hash_key: Option<String>,
|
||||
redirect_to_merchant_with_http_post: Option<bool>,
|
||||
publishable_key: Option<String>,
|
||||
storage_scheme: Option<storage_enums::MerchantStorageScheme>,
|
||||
locker_id: Option<String>,
|
||||
metadata: Option<pii::SecretSerdeValue>,
|
||||
routing_algorithm: Option<serde_json::Value>,
|
||||
primary_business_details: Option<serde_json::Value>,
|
||||
modified_at: Option<time::PrimitiveDateTime>,
|
||||
intent_fulfillment_time: Option<i64>,
|
||||
frm_routing_algorithm: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
impl From<MerchantAccountUpdate> for MerchantAccountUpdateInternal {
|
||||
fn from(merchant_account_update: MerchantAccountUpdate) -> Self {
|
||||
match merchant_account_update {
|
||||
MerchantAccountUpdate::Update {
|
||||
merchant_name,
|
||||
merchant_details,
|
||||
return_url,
|
||||
webhook_details,
|
||||
routing_algorithm,
|
||||
sub_merchants_enabled,
|
||||
parent_merchant_id,
|
||||
enable_payment_response_hash,
|
||||
payment_response_hash_key,
|
||||
redirect_to_merchant_with_http_post,
|
||||
publishable_key,
|
||||
locker_id,
|
||||
metadata,
|
||||
primary_business_details,
|
||||
intent_fulfillment_time,
|
||||
frm_routing_algorithm,
|
||||
} => Self {
|
||||
merchant_name,
|
||||
merchant_details,
|
||||
return_url,
|
||||
webhook_details,
|
||||
routing_algorithm,
|
||||
sub_merchants_enabled,
|
||||
parent_merchant_id,
|
||||
enable_payment_response_hash,
|
||||
payment_response_hash_key,
|
||||
redirect_to_merchant_with_http_post,
|
||||
publishable_key,
|
||||
locker_id,
|
||||
metadata,
|
||||
primary_business_details,
|
||||
modified_at: Some(common_utils::date_time::now()),
|
||||
intent_fulfillment_time,
|
||||
frm_routing_algorithm,
|
||||
..Default::default()
|
||||
},
|
||||
MerchantAccountUpdate::StorageSchemeUpdate { storage_scheme } => Self {
|
||||
storage_scheme: Some(storage_scheme),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
pub merchant_name: Option<Encryption>,
|
||||
pub merchant_details: Option<Encryption>,
|
||||
pub return_url: Option<String>,
|
||||
pub webhook_details: Option<serde_json::Value>,
|
||||
pub sub_merchants_enabled: Option<bool>,
|
||||
pub parent_merchant_id: Option<String>,
|
||||
pub enable_payment_response_hash: Option<bool>,
|
||||
pub payment_response_hash_key: Option<String>,
|
||||
pub redirect_to_merchant_with_http_post: Option<bool>,
|
||||
pub publishable_key: Option<String>,
|
||||
pub storage_scheme: Option<storage_enums::MerchantStorageScheme>,
|
||||
pub locker_id: Option<String>,
|
||||
pub metadata: Option<pii::SecretSerdeValue>,
|
||||
pub routing_algorithm: Option<serde_json::Value>,
|
||||
pub primary_business_details: Option<serde_json::Value>,
|
||||
pub modified_at: Option<time::PrimitiveDateTime>,
|
||||
pub intent_fulfillment_time: Option<i64>,
|
||||
pub frm_routing_algorithm: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
@ -1,16 +1,13 @@
|
||||
use common_utils::pii;
|
||||
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
|
||||
use masking::Secret;
|
||||
|
||||
use crate::{enums as storage_enums, schema::merchant_connector_account};
|
||||
use crate::{encryption::Encryption, enums as storage_enums, schema::merchant_connector_account};
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
Eq,
|
||||
serde::Serialize,
|
||||
serde::Deserialize,
|
||||
PartialEq,
|
||||
Identifiable,
|
||||
Queryable,
|
||||
router_derive::DebugAsDisplay,
|
||||
@ -20,7 +17,7 @@ pub struct MerchantConnectorAccount {
|
||||
pub id: i32,
|
||||
pub merchant_id: String,
|
||||
pub connector_name: String,
|
||||
pub connector_account_details: serde_json::Value,
|
||||
pub connector_account_details: Encryption,
|
||||
pub test_mode: Option<bool>,
|
||||
pub disabled: Option<bool>,
|
||||
pub merchant_connector_id: String,
|
||||
@ -32,7 +29,7 @@ pub struct MerchantConnectorAccount {
|
||||
pub business_country: storage_enums::CountryAlpha2,
|
||||
pub business_label: String,
|
||||
pub business_sub_label: Option<String>,
|
||||
pub frm_configs: Option<Secret<serde_json::Value>>,
|
||||
pub frm_configs: Option<masking::Secret<serde_json::Value>>,
|
||||
pub created_at: time::PrimitiveDateTime,
|
||||
pub modified_at: time::PrimitiveDateTime,
|
||||
}
|
||||
@ -43,7 +40,7 @@ pub struct MerchantConnectorAccountNew {
|
||||
pub merchant_id: Option<String>,
|
||||
pub connector_type: Option<storage_enums::ConnectorType>,
|
||||
pub connector_name: Option<String>,
|
||||
pub connector_account_details: Option<Secret<serde_json::Value>>,
|
||||
pub connector_account_details: Option<Encryption>,
|
||||
pub test_mode: Option<bool>,
|
||||
pub disabled: Option<bool>,
|
||||
pub merchant_connector_id: String,
|
||||
@ -53,65 +50,23 @@ pub struct MerchantConnectorAccountNew {
|
||||
pub business_country: storage_enums::CountryAlpha2,
|
||||
pub business_label: String,
|
||||
pub business_sub_label: Option<String>,
|
||||
pub frm_configs: Option<Secret<serde_json::Value>>,
|
||||
pub frm_configs: Option<masking::Secret<serde_json::Value>>,
|
||||
pub created_at: time::PrimitiveDateTime,
|
||||
pub modified_at: time::PrimitiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MerchantConnectorAccountUpdate {
|
||||
Update {
|
||||
merchant_id: Option<String>,
|
||||
connector_type: Option<storage_enums::ConnectorType>,
|
||||
connector_account_details: Option<Secret<serde_json::Value>>,
|
||||
test_mode: Option<bool>,
|
||||
disabled: Option<bool>,
|
||||
merchant_connector_id: Option<String>,
|
||||
payment_methods_enabled: Option<Vec<serde_json::Value>>,
|
||||
metadata: Option<pii::SecretSerdeValue>,
|
||||
frm_configs: Option<Secret<serde_json::Value>>,
|
||||
},
|
||||
}
|
||||
#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)]
|
||||
#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
|
||||
#[diesel(table_name = merchant_connector_account)]
|
||||
pub struct MerchantConnectorAccountUpdateInternal {
|
||||
merchant_id: Option<String>,
|
||||
connector_type: Option<storage_enums::ConnectorType>,
|
||||
connector_account_details: Option<Secret<serde_json::Value>>,
|
||||
test_mode: Option<bool>,
|
||||
disabled: Option<bool>,
|
||||
merchant_connector_id: Option<String>,
|
||||
payment_methods_enabled: Option<Vec<serde_json::Value>>,
|
||||
metadata: Option<pii::SecretSerdeValue>,
|
||||
frm_configs: Option<Secret<serde_json::Value>>,
|
||||
modified_at: time::PrimitiveDateTime,
|
||||
}
|
||||
|
||||
impl From<MerchantConnectorAccountUpdate> for MerchantConnectorAccountUpdateInternal {
|
||||
fn from(merchant_connector_account_update: MerchantConnectorAccountUpdate) -> Self {
|
||||
match merchant_connector_account_update {
|
||||
MerchantConnectorAccountUpdate::Update {
|
||||
merchant_id,
|
||||
connector_type,
|
||||
connector_account_details,
|
||||
test_mode,
|
||||
disabled,
|
||||
merchant_connector_id,
|
||||
payment_methods_enabled,
|
||||
metadata,
|
||||
frm_configs,
|
||||
} => Self {
|
||||
merchant_id,
|
||||
connector_type,
|
||||
connector_account_details,
|
||||
test_mode,
|
||||
disabled,
|
||||
merchant_connector_id,
|
||||
payment_methods_enabled,
|
||||
metadata,
|
||||
frm_configs,
|
||||
modified_at: common_utils::date_time::now(),
|
||||
},
|
||||
}
|
||||
}
|
||||
pub merchant_id: Option<String>,
|
||||
pub connector_type: Option<storage_enums::ConnectorType>,
|
||||
pub connector_name: Option<String>,
|
||||
pub connector_account_details: Option<Encryption>,
|
||||
pub test_mode: Option<bool>,
|
||||
pub disabled: Option<bool>,
|
||||
pub merchant_connector_id: Option<String>,
|
||||
pub payment_methods_enabled: Option<Vec<serde_json::Value>>,
|
||||
pub metadata: Option<pii::SecretSerdeValue>,
|
||||
pub frm_configs: Option<masking::Secret<serde_json::Value>>,
|
||||
pub modified_at: Option<time::PrimitiveDateTime>,
|
||||
}
|
||||
|
||||
42
crates/storage_models/src/merchant_key_store.rs
Normal file
42
crates/storage_models/src/merchant_key_store.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use common_utils::custom_serde;
|
||||
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
|
||||
use time::PrimitiveDateTime;
|
||||
|
||||
use crate::{encryption::Encryption, schema::merchant_key_store};
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
serde::Serialize,
|
||||
serde::Deserialize,
|
||||
Identifiable,
|
||||
Queryable,
|
||||
router_derive::DebugAsDisplay,
|
||||
)]
|
||||
#[diesel(table_name = merchant_key_store)]
|
||||
#[diesel(primary_key(merchant_id))]
|
||||
pub struct MerchantKeyStore {
|
||||
pub merchant_id: String,
|
||||
pub key: Encryption,
|
||||
#[serde(with = "custom_serde::iso8601")]
|
||||
pub created_at: PrimitiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, serde::Serialize, serde::Deserialize, Insertable, router_derive::DebugAsDisplay,
|
||||
)]
|
||||
#[diesel(table_name = merchant_key_store)]
|
||||
pub struct MerchantKeyStoreNew {
|
||||
pub merchant_id: String,
|
||||
pub key: Encryption,
|
||||
pub created_at: PrimitiveDateTime,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone, Debug, serde::Serialize, serde::Deserialize, AsChangeset, router_derive::DebugAsDisplay,
|
||||
)]
|
||||
#[diesel(table_name = merchant_key_store)]
|
||||
pub struct MerchantKeyStoreUpdateInternal {
|
||||
pub merchant_id: String,
|
||||
pub key: Encryption,
|
||||
}
|
||||
@ -12,6 +12,7 @@ pub mod locker_mock_up;
|
||||
pub mod mandate;
|
||||
pub mod merchant_account;
|
||||
pub mod merchant_connector_account;
|
||||
pub mod merchant_key_store;
|
||||
pub mod payment_attempt;
|
||||
pub mod payment_intent;
|
||||
pub mod payment_method;
|
||||
|
||||
@ -3,7 +3,7 @@ use router_env::{instrument, tracing};
|
||||
|
||||
use super::generics;
|
||||
use crate::{
|
||||
address::{Address, AddressNew, AddressUpdate, AddressUpdateInternal},
|
||||
address::{Address, AddressNew, AddressUpdateInternal},
|
||||
errors,
|
||||
schema::address::dsl,
|
||||
PgPooledConn, StorageResult,
|
||||
@ -21,12 +21,12 @@ impl Address {
|
||||
pub async fn update_by_address_id(
|
||||
conn: &PgPooledConn,
|
||||
address_id: String,
|
||||
address: AddressUpdate,
|
||||
address: AddressUpdateInternal,
|
||||
) -> StorageResult<Self> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
address_id.clone(),
|
||||
AddressUpdateInternal::from(address),
|
||||
address,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -63,14 +63,14 @@ impl Address {
|
||||
conn: &PgPooledConn,
|
||||
customer_id: &str,
|
||||
merchant_id: &str,
|
||||
address: AddressUpdate,
|
||||
address: AddressUpdateInternal,
|
||||
) -> StorageResult<Vec<Self>> {
|
||||
generics::generic_update_with_results::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
dsl::merchant_id
|
||||
.eq(merchant_id.to_owned())
|
||||
.and(dsl::customer_id.eq(customer_id.to_owned())),
|
||||
AddressUpdateInternal::from(address),
|
||||
address,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use router_env::{instrument, tracing};
|
||||
|
||||
use super::generics;
|
||||
use crate::{
|
||||
customers::{Customer, CustomerNew, CustomerUpdate, CustomerUpdateInternal},
|
||||
customers::{Customer, CustomerNew, CustomerUpdateInternal},
|
||||
errors,
|
||||
schema::customers::dsl,
|
||||
PgPooledConn, StorageResult,
|
||||
@ -22,12 +22,12 @@ impl Customer {
|
||||
conn: &PgPooledConn,
|
||||
customer_id: String,
|
||||
merchant_id: String,
|
||||
customer: CustomerUpdate,
|
||||
customer: CustomerUpdateInternal,
|
||||
) -> StorageResult<Self> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
(customer_id.clone(), merchant_id.clone()),
|
||||
CustomerUpdateInternal::from(customer),
|
||||
customer,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@ -4,9 +4,7 @@ use router_env::{instrument, tracing};
|
||||
use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
merchant_account::{
|
||||
MerchantAccount, MerchantAccountNew, MerchantAccountUpdate, MerchantAccountUpdateInternal,
|
||||
},
|
||||
merchant_account::{MerchantAccount, MerchantAccountNew, MerchantAccountUpdateInternal},
|
||||
schema::merchant_account::dsl,
|
||||
PgPooledConn, StorageResult,
|
||||
};
|
||||
@ -23,12 +21,12 @@ impl MerchantAccount {
|
||||
pub async fn update(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
merchant_account: MerchantAccountUpdate,
|
||||
merchant_account: MerchantAccountUpdateInternal,
|
||||
) -> StorageResult<Self> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
self.id,
|
||||
MerchantAccountUpdateInternal::from(merchant_account),
|
||||
merchant_account,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@ -43,7 +41,7 @@ impl MerchantAccount {
|
||||
pub async fn update_with_specific_fields(
|
||||
conn: &PgPooledConn,
|
||||
merchant_id: &str,
|
||||
merchant_account: MerchantAccountUpdate,
|
||||
merchant_account: MerchantAccountUpdateInternal,
|
||||
) -> StorageResult<Self> {
|
||||
generics::generic_update_with_unique_predicate_get_result::<
|
||||
<Self as HasTable>::Table,
|
||||
@ -53,7 +51,7 @@ impl MerchantAccount {
|
||||
>(
|
||||
conn,
|
||||
dsl::merchant_id.eq(merchant_id.to_owned()),
|
||||
MerchantAccountUpdateInternal::from(merchant_account),
|
||||
merchant_account,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ use super::generics;
|
||||
use crate::{
|
||||
errors,
|
||||
merchant_connector_account::{
|
||||
MerchantConnectorAccount, MerchantConnectorAccountNew, MerchantConnectorAccountUpdate,
|
||||
MerchantConnectorAccount, MerchantConnectorAccountNew,
|
||||
MerchantConnectorAccountUpdateInternal,
|
||||
},
|
||||
schema::merchant_connector_account::dsl,
|
||||
@ -24,12 +24,12 @@ impl MerchantConnectorAccount {
|
||||
pub async fn update(
|
||||
self,
|
||||
conn: &PgPooledConn,
|
||||
merchant_connector_account: MerchantConnectorAccountUpdate,
|
||||
merchant_connector_account: MerchantConnectorAccountUpdateInternal,
|
||||
) -> StorageResult<Self> {
|
||||
match generics::generic_update_by_id::<<Self as HasTable>::Table, _, _, _>(
|
||||
conn,
|
||||
self.id,
|
||||
MerchantConnectorAccountUpdateInternal::from(merchant_connector_account),
|
||||
merchant_connector_account,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
30
crates/storage_models/src/query/merchant_key_store.rs
Normal file
30
crates/storage_models/src/query/merchant_key_store.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use diesel::{associations::HasTable, ExpressionMethods};
|
||||
use router_env::{instrument, tracing};
|
||||
|
||||
use super::generics;
|
||||
use crate::{
|
||||
merchant_key_store::{MerchantKeyStore, MerchantKeyStoreNew},
|
||||
schema::merchant_key_store::dsl,
|
||||
PgPooledConn, StorageResult,
|
||||
};
|
||||
|
||||
impl MerchantKeyStoreNew {
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn insert(self, conn: &PgPooledConn) -> StorageResult<MerchantKeyStore> {
|
||||
generics::generic_insert(conn, self).await
|
||||
}
|
||||
}
|
||||
|
||||
impl MerchantKeyStore {
|
||||
#[instrument(skip(conn))]
|
||||
pub async fn find_by_merchant_id(
|
||||
conn: &PgPooledConn,
|
||||
merchant_id: &str,
|
||||
) -> StorageResult<Self> {
|
||||
generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
|
||||
conn,
|
||||
dsl::merchant_id.eq(merchant_id.to_owned()),
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
@ -11,22 +11,14 @@ diesel::table! {
|
||||
#[max_length = 128]
|
||||
city -> Nullable<Varchar>,
|
||||
country -> Nullable<CountryAlpha2>,
|
||||
#[max_length = 255]
|
||||
line1 -> Nullable<Varchar>,
|
||||
#[max_length = 255]
|
||||
line2 -> Nullable<Varchar>,
|
||||
#[max_length = 255]
|
||||
line3 -> Nullable<Varchar>,
|
||||
#[max_length = 128]
|
||||
state -> Nullable<Varchar>,
|
||||
#[max_length = 16]
|
||||
zip -> Nullable<Varchar>,
|
||||
#[max_length = 255]
|
||||
first_name -> Nullable<Varchar>,
|
||||
#[max_length = 255]
|
||||
last_name -> Nullable<Varchar>,
|
||||
#[max_length = 32]
|
||||
phone_number -> Nullable<Varchar>,
|
||||
line1 -> Nullable<Bytea>,
|
||||
line2 -> Nullable<Bytea>,
|
||||
line3 -> Nullable<Bytea>,
|
||||
state -> Nullable<Bytea>,
|
||||
zip -> Nullable<Bytea>,
|
||||
first_name -> Nullable<Bytea>,
|
||||
last_name -> Nullable<Bytea>,
|
||||
phone_number -> Nullable<Bytea>,
|
||||
#[max_length = 8]
|
||||
country_code -> Nullable<Varchar>,
|
||||
created_at -> Timestamp,
|
||||
@ -130,12 +122,9 @@ diesel::table! {
|
||||
customer_id -> Varchar,
|
||||
#[max_length = 64]
|
||||
merchant_id -> Varchar,
|
||||
#[max_length = 255]
|
||||
name -> Nullable<Varchar>,
|
||||
#[max_length = 255]
|
||||
email -> Nullable<Varchar>,
|
||||
#[max_length = 32]
|
||||
phone -> Nullable<Varchar>,
|
||||
name -> Nullable<Bytea>,
|
||||
email -> Nullable<Bytea>,
|
||||
phone -> Nullable<Bytea>,
|
||||
#[max_length = 8]
|
||||
phone_country_code -> Nullable<Varchar>,
|
||||
#[max_length = 255]
|
||||
@ -321,9 +310,8 @@ diesel::table! {
|
||||
#[max_length = 255]
|
||||
payment_response_hash_key -> Nullable<Varchar>,
|
||||
redirect_to_merchant_with_http_post -> Bool,
|
||||
#[max_length = 128]
|
||||
merchant_name -> Nullable<Varchar>,
|
||||
merchant_details -> Nullable<Json>,
|
||||
merchant_name -> Nullable<Bytea>,
|
||||
merchant_details -> Nullable<Bytea>,
|
||||
webhook_details -> Nullable<Json>,
|
||||
sub_merchants_enabled -> Nullable<Bool>,
|
||||
#[max_length = 64]
|
||||
@ -353,7 +341,7 @@ diesel::table! {
|
||||
merchant_id -> Varchar,
|
||||
#[max_length = 64]
|
||||
connector_name -> Varchar,
|
||||
connector_account_details -> Json,
|
||||
connector_account_details -> Bytea,
|
||||
test_mode -> Nullable<Bool>,
|
||||
disabled -> Nullable<Bool>,
|
||||
#[max_length = 128]
|
||||
@ -374,6 +362,18 @@ diesel::table! {
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
use diesel::sql_types::*;
|
||||
use crate::enums::diesel_exports::*;
|
||||
|
||||
merchant_key_store (merchant_id) {
|
||||
#[max_length = 255]
|
||||
merchant_id -> Varchar,
|
||||
key -> Bytea,
|
||||
created_at -> Timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
use diesel::sql_types::*;
|
||||
use crate::enums::diesel_exports::*;
|
||||
@ -618,6 +618,7 @@ diesel::allow_tables_to_appear_in_same_query!(
|
||||
mandate,
|
||||
merchant_account,
|
||||
merchant_connector_account,
|
||||
merchant_key_store,
|
||||
payment_attempt,
|
||||
payment_intent,
|
||||
payment_methods,
|
||||
|
||||
Reference in New Issue
Block a user