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:
Kartikeya Hegde
2023-05-30 13:43:17 +05:30
committed by GitHub
parent 77e60c82fa
commit fa392c40a8
107 changed files with 3818 additions and 1267 deletions

View File

@ -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(),
}
}
}

View File

@ -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>,
}

View 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 })
}
}

View File

@ -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;

View File

@ -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>,
}

View File

@ -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>,
}

View 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,
}

View File

@ -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;

View File

@ -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
}

View File

@ -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
{

View File

@ -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
}

View File

@ -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
{

View 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
}
}

View File

@ -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,