Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add macro to generate ToEncryptable trait #6313

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -3606,54 +3605,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
Loading