Skip to content

Commit

Permalink
feat: add macro to generate ToEncryptable trait (#6313)
Browse files Browse the repository at this point in the history
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Sanchith Hegde <[email protected]>
  • Loading branch information
3 people authored Nov 4, 2024
1 parent adc5262 commit 19cf0f7
Show file tree
Hide file tree
Showing 19 changed files with 949 additions and 738 deletions.
90 changes: 2 additions & 88 deletions crates/api_models/src/customers.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
use common_utils::{
crypto, custom_serde,
encryption::Encryption,
id_type,
pii::{self, EmailStrategy},
types::{keymanager::ToEncryptable, Description},
};
use masking::{ExposeInterface, Secret, SwitchStrategy};
use rustc_hash::FxHashMap;
use common_utils::{crypto, custom_serde, id_type, pii, types::Description};
use masking::Secret;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;

Expand Down Expand Up @@ -129,85 +122,6 @@ impl CustomerRequest {
}
}

pub struct CustomerRequestWithEmail {
pub name: Option<Secret<String>>,
pub email: Option<pii::Email>,
pub phone: Option<Secret<String>>,
}

pub struct CustomerRequestWithEncryption {
pub name: Option<Encryption>,
pub phone: Option<Encryption>,
pub email: Option<Encryption>,
}

pub struct EncryptableCustomer {
pub name: crypto::OptionalEncryptableName,
pub phone: crypto::OptionalEncryptablePhone,
pub email: crypto::OptionalEncryptableEmail,
}

impl ToEncryptable<EncryptableCustomer, Secret<String>, Encryption>
for CustomerRequestWithEncryption
{
fn to_encryptable(self) -> FxHashMap<String, Encryption> {
let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
self.name.map(|x| map.insert("name".to_string(), x));
self.phone.map(|x| map.insert("phone".to_string(), x));
self.email.map(|x| map.insert("email".to_string(), x));
map
}

fn from_encryptable(
mut hashmap: FxHashMap<String, crypto::Encryptable<Secret<String>>>,
) -> common_utils::errors::CustomResult<EncryptableCustomer, common_utils::errors::ParsingError>
{
Ok(EncryptableCustomer {
name: hashmap.remove("name"),
phone: hashmap.remove("phone"),
email: hashmap.remove("email").map(|email| {
let encryptable: crypto::Encryptable<Secret<String, EmailStrategy>> =
crypto::Encryptable::new(
email.clone().into_inner().switch_strategy(),
email.into_encrypted(),
);
encryptable
}),
})
}
}

impl ToEncryptable<EncryptableCustomer, Secret<String>, Secret<String>>
for CustomerRequestWithEmail
{
fn to_encryptable(self) -> FxHashMap<String, Secret<String>> {
let mut map = FxHashMap::with_capacity_and_hasher(3, Default::default());
self.name.map(|x| map.insert("name".to_string(), x));
self.phone.map(|x| map.insert("phone".to_string(), x));
self.email
.map(|x| map.insert("email".to_string(), x.expose().switch_strategy()));
map
}

fn from_encryptable(
mut hashmap: FxHashMap<String, crypto::Encryptable<Secret<String>>>,
) -> common_utils::errors::CustomResult<EncryptableCustomer, common_utils::errors::ParsingError>
{
Ok(EncryptableCustomer {
name: hashmap.remove("name"),
email: hashmap.remove("email").map(|email| {
let encryptable: crypto::Encryptable<Secret<String, EmailStrategy>> =
crypto::Encryptable::new(
email.clone().into_inner().switch_strategy(),
email.into_encrypted(),
);
encryptable
}),
phone: hashmap.remove("phone"),
})
}
}

#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct CustomerResponse {
Expand Down
55 changes: 3 additions & 52 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ use common_utils::{
ext_traits::{ConfigExt, Encode, ValueExt},
hashing::HashedString,
id_type,
pii::{self, Email, EmailStrategy},
types::{keymanager::ToEncryptable, MinorUnit, StringMajorUnit},
pii::{self, Email},
types::{MinorUnit, StringMajorUnit},
};
use error_stack::ResultExt;
use masking::{ExposeInterface, PeekInterface, Secret, SwitchStrategy, WithType};
use masking::{PeekInterface, Secret, WithType};
use router_derive::Setter;
use rustc_hash::FxHashMap;
use serde::{de, ser::Serializer, Deserialize, Deserializer, Serialize};
use strum::Display;
use time::{Date, PrimitiveDateTime};
Expand Down Expand Up @@ -3818,54 +3817,6 @@ pub struct EncryptableAddressDetails {
pub email: crypto::OptionalEncryptableEmail,
}

impl ToEncryptable<EncryptableAddressDetails, Secret<String>, Secret<String>>
for AddressDetailsWithPhone
{
fn from_encryptable(
mut hashmap: FxHashMap<String, crypto::Encryptable<Secret<String>>>,
) -> common_utils::errors::CustomResult<
EncryptableAddressDetails,
common_utils::errors::ParsingError,
> {
Ok(EncryptableAddressDetails {
line1: hashmap.remove("line1"),
line2: hashmap.remove("line2"),
line3: hashmap.remove("line3"),
state: hashmap.remove("state"),
zip: hashmap.remove("zip"),
first_name: hashmap.remove("first_name"),
last_name: hashmap.remove("last_name"),
phone_number: hashmap.remove("phone_number"),
email: hashmap.remove("email").map(|x| {
let inner: Secret<String, EmailStrategy> = x.clone().into_inner().switch_strategy();
crypto::Encryptable::new(inner, x.into_encrypted())
}),
})
}

fn to_encryptable(self) -> FxHashMap<String, Secret<String>> {
let mut map = FxHashMap::with_capacity_and_hasher(9, Default::default());
self.address.map(|address| {
address.line1.map(|x| map.insert("line1".to_string(), x));
address.line2.map(|x| map.insert("line2".to_string(), x));
address.line3.map(|x| map.insert("line3".to_string(), x));
address.state.map(|x| map.insert("state".to_string(), x));
address.zip.map(|x| map.insert("zip".to_string(), x));
address
.first_name
.map(|x| map.insert("first_name".to_string(), x));
address
.last_name
.map(|x| map.insert("last_name".to_string(), x));
});
self.email
.map(|x| map.insert("email".to_string(), x.expose().switch_strategy()));
self.phone_number
.map(|x| map.insert("phone_number".to_string(), x));
map
}
}

#[derive(Debug, Clone, Default, Eq, PartialEq, ToSchema, serde::Deserialize, serde::Serialize)]
pub struct PhoneDetails {
/// The contact number
Expand Down
51 changes: 1 addition & 50 deletions crates/diesel_models/src/address.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
use common_utils::{
crypto::{self, Encryptable},
encryption::Encryption,
pii::EmailStrategy,
types::keymanager::ToEncryptable,
};
use common_utils::{crypto, encryption::Encryption};
use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
use masking::{Secret, SwitchStrategy};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime;

Expand Down Expand Up @@ -74,48 +67,6 @@ pub struct EncryptableAddress {
pub email: crypto::OptionalEncryptableEmail,
}

impl ToEncryptable<EncryptableAddress, Secret<String>, Encryption> for Address {
fn to_encryptable(self) -> FxHashMap<String, Encryption> {
let mut map = FxHashMap::with_capacity_and_hasher(9, Default::default());
self.line1.map(|x| map.insert("line1".to_string(), x));
self.line2.map(|x| map.insert("line2".to_string(), x));
self.line3.map(|x| map.insert("line3".to_string(), x));
self.zip.map(|x| map.insert("zip".to_string(), x));
self.state.map(|x| map.insert("state".to_string(), x));
self.first_name
.map(|x| map.insert("first_name".to_string(), x));
self.last_name
.map(|x| map.insert("last_name".to_string(), x));
self.phone_number
.map(|x| map.insert("phone_number".to_string(), x));
self.email.map(|x| map.insert("email".to_string(), x));
map
}

fn from_encryptable(
mut hashmap: FxHashMap<String, Encryptable<Secret<String>>>,
) -> common_utils::errors::CustomResult<EncryptableAddress, common_utils::errors::ParsingError>
{
Ok(EncryptableAddress {
line1: hashmap.remove("line1"),
line2: hashmap.remove("line2"),
line3: hashmap.remove("line3"),
zip: hashmap.remove("zip"),
state: hashmap.remove("state"),
first_name: hashmap.remove("first_name"),
last_name: hashmap.remove("last_name"),
phone_number: hashmap.remove("phone_number"),
email: hashmap.remove("email").map(|email| {
let encryptable: Encryptable<Secret<String, EmailStrategy>> = Encryptable::new(
email.clone().into_inner().switch_strategy(),
email.into_encrypted(),
);
encryptable
}),
})
}
}

#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay, Serialize, Deserialize)]
#[diesel(table_name = address)]
pub struct AddressUpdateInternal {
Expand Down
38 changes: 1 addition & 37 deletions crates/diesel_models/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use common_utils::{
crypto::OptionalEncryptableSecretString, custom_serde, encryption::Encryption,
types::keymanager::ToEncryptable,
};
use common_utils::{custom_serde, encryption::Encryption};
use diesel::{
expression::AsExpression, AsChangeset, Identifiable, Insertable, Queryable, Selectable,
};
use masking::Secret;
use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime;

Expand Down Expand Up @@ -63,38 +59,6 @@ pub struct Event {
pub metadata: Option<EventMetadata>,
}

pub struct EventWithEncryption {
pub request: Option<Encryption>,
pub response: Option<Encryption>,
}

pub struct EncryptableEvent {
pub request: OptionalEncryptableSecretString,
pub response: OptionalEncryptableSecretString,
}

impl ToEncryptable<EncryptableEvent, Secret<String>, Encryption> for EventWithEncryption {
fn to_encryptable(self) -> rustc_hash::FxHashMap<String, Encryption> {
let mut map = rustc_hash::FxHashMap::default();
self.request.map(|x| map.insert("request".to_string(), x));
self.response.map(|x| map.insert("response".to_string(), x));
map
}

fn from_encryptable(
mut hashmap: rustc_hash::FxHashMap<
String,
common_utils::crypto::Encryptable<Secret<String>>,
>,
) -> common_utils::errors::CustomResult<EncryptableEvent, common_utils::errors::ParsingError>
{
Ok(EncryptableEvent {
request: hashmap.remove("request"),
response: hashmap.remove("response"),
})
}
}

#[derive(Clone, Debug, Deserialize, Serialize, AsExpression, diesel::FromSqlRow)]
#[diesel(sql_type = diesel::sql_types::Jsonb)]
pub enum EventMetadata {
Expand Down
Loading

0 comments on commit 19cf0f7

Please sign in to comment.