Skip to content

Commit

Permalink
feat: encrypt PII fields before saving it in the database (#1043)
Browse files Browse the repository at this point in the history
Co-authored-by: Nishant Joshi <nishant.joshi@juspay.in>
  • Loading branch information
dracarys18 and NishantJoshi00 committed May 30, 2023
1 parent 77e60c8 commit fa392c4
Show file tree
Hide file tree
Showing 107 changed files with 3,817 additions and 1,266 deletions.
2 changes: 2 additions & 0 deletions config/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ use_xray_generator = false # Set this to true for AWS

# This section provides some secret values.
[secrets]
master_enc_key = "sample_key" # Master Encryption key used to encrypt merchant wise encryption key. Should be 32-byte long.
admin_api_key = "test_admin" # admin API key for admin authentication. Only applicable when KMS is disabled.
kms_encrypted_admin_api_key = "" # Base64-encoded (KMS encrypted) ciphertext of the admin_api_key. Only applicable when KMS is enabled.
jwt_secret = "secret" # JWT secret used for user authentication. Only applicable when KMS is disabled.
kms_encrypted_jwt_secret = "" # Base64-encoded (KMS encrypted) ciphertext of the jwt_secret. Only applicable when KMS is enabled.
migration_encryption_timestamp = 0 # Timestamp to decide which entries are not encrypted in the database.

# Locker settings contain details for accessing a card locker, a
# PCI Compliant storage entity which stores payment method information
Expand Down
2 changes: 2 additions & 0 deletions config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ connection_timeout = 10

[secrets]
admin_api_key = "test_admin"
migration_encryption_timestamp = 1682425530
master_enc_key = "73ad7bbbbc640c845a150f67d058b279849370cd2c1f3c67c4dd6c869213e13a"

[locker]
host = ""
Expand Down
15 changes: 9 additions & 6 deletions crates/api_models/src/admin.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use common_utils::pii;
use common_utils::{
crypto::{Encryptable, OptionalEncryptableName},
pii,
};
use masking::Secret;
use serde::{Deserialize, Serialize};
use url;
Expand All @@ -15,8 +18,8 @@ pub struct MerchantAccountCreate {
pub merchant_id: String,

/// Name of the Merchant Account
#[schema(example = "NewAge Retailer")]
pub merchant_name: Option<String>,
#[schema(value_type= Option<String>,example = "NewAge Retailer")]
pub merchant_name: Option<Secret<String>>,

/// Merchant related details
pub merchant_details: Option<MerchantDetails>,
Expand Down Expand Up @@ -157,8 +160,8 @@ pub struct MerchantAccountResponse {
pub merchant_id: String,

/// Name of the Merchant Account
#[schema(example = "NewAge Retailer")]
pub merchant_name: Option<String>,
#[schema(value_type = Option<String>,example = "NewAge Retailer")]
pub merchant_name: OptionalEncryptableName,

/// The URL to redirect after the completion of the operation
#[schema(max_length = 255, example = "https://www.example.com/success")]
Expand All @@ -178,7 +181,7 @@ pub struct MerchantAccountResponse {

/// Merchant related details
#[schema(value_type = Option<MerchantDetails>)]
pub merchant_details: Option<serde_json::Value>,
pub merchant_details: Option<Encryptable<pii::SecretSerdeValue>>,

/// Webhook related details
#[schema(value_type = Option<WebhookDetails>)]
Expand Down
10 changes: 5 additions & 5 deletions crates/api_models/src/customers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use common_utils::{consts, custom_serde, pii};
use common_utils::{consts, crypto, custom_serde, pii};
use masking::Secret;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
Expand All @@ -16,7 +16,7 @@ pub struct CustomerRequest {
pub merchant_id: String,
/// The customer's name
#[schema(max_length = 255, example = "Jon Test")]
pub name: Option<String>,
pub name: Option<Secret<String>>,
/// The customer's email address
#[schema(value_type = Option<String>,max_length = 255, example = "JonTest@test.com")]
pub email: Option<pii::Email>,
Expand Down Expand Up @@ -56,13 +56,13 @@ pub struct CustomerResponse {
pub customer_id: String,
/// The customer's name
#[schema(max_length = 255, example = "Jon Test")]
pub name: Option<String>,
pub name: crypto::OptionalEncryptableName,
/// The customer's email address
#[schema(value_type = Option<String>,max_length = 255, example = "JonTest@test.com")]
pub email: Option<pii::Email>,
pub email: crypto::OptionalEncryptableEmail,
/// The customer's phone number
#[schema(value_type = Option<String>,max_length = 255, example = "9999999999")]
pub phone: Option<Secret<String>>,
pub phone: crypto::OptionalEncryptablePhone,
/// The country code for the customer phone number
#[schema(max_length = 255, example = "+65")]
pub phone_country_code: Option<String>,
Expand Down
39 changes: 12 additions & 27 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::{collections::HashMap, num::NonZeroI64};

use cards::CardNumber;
use common_utils::{pii, pii::Email};
use common_utils::{
crypto,
pii::{self, Email},
};
use masking::{PeekInterface, Secret};
use router_derive::Setter;
use time::PrimitiveDateTime;
Expand Down Expand Up @@ -1124,7 +1127,7 @@ pub struct ReceiverDetails {
amount_remaining: Option<i64>,
}

#[derive(Setter, Clone, Default, Debug, Eq, PartialEq, serde::Serialize, ToSchema)]
#[derive(Setter, Clone, Default, Debug, PartialEq, serde::Serialize, ToSchema)]
pub struct PaymentsResponse {
/// Unique identifier for the payment. This ensures idempotency for multiple payments
/// that have been done by a single merchant.
Expand Down Expand Up @@ -1240,15 +1243,15 @@ pub struct PaymentsResponse {

/// description: The customer's email address
#[schema(max_length = 255, value_type = Option<String>, example = "johntest@test.com")]
pub email: Option<Email>,
pub email: crypto::OptionalEncryptableEmail,

/// description: The customer's name
#[schema(value_type = Option<String>, max_length = 255, example = "John Test")]
pub name: Option<Secret<String>>,
pub name: crypto::OptionalEncryptableName,

/// The customer's phone number
#[schema(value_type = Option<String>, max_length = 255, example = "3141592653")]
pub phone: Option<Secret<String>>,
pub phone: crypto::OptionalEncryptablePhone,

/// The URL to redirect after the completion of the operation
#[schema(example = "https://hyperswitch.io")]
Expand Down Expand Up @@ -1377,16 +1380,16 @@ pub struct PaymentListResponse {
pub data: Vec<PaymentsResponse>,
}

#[derive(Setter, Clone, Default, Debug, serde::Serialize)]
#[derive(Setter, Clone, Default, Debug, PartialEq, serde::Serialize)]
pub struct VerifyResponse {
pub verify_id: Option<String>,
pub merchant_id: Option<String>,
// pub status: enums::VerifyStatus,
pub client_secret: Option<Secret<String>>,
pub customer_id: Option<String>,
pub email: Option<Email>,
pub name: Option<Secret<String>>,
pub phone: Option<Secret<String>>,
pub email: crypto::OptionalEncryptableEmail,
pub name: crypto::OptionalEncryptableName,
pub phone: crypto::OptionalEncryptablePhone,
pub mandate_id: Option<String>,
#[auth_based]
pub payment_method: Option<api_enums::PaymentMethod>,
Expand Down Expand Up @@ -1441,24 +1444,6 @@ impl From<&VerifyRequest> for MandateValidationFields {
}
}

impl From<VerifyRequest> for VerifyResponse {
fn from(item: VerifyRequest) -> Self {
Self {
merchant_id: item.merchant_id,
customer_id: item.customer_id,
email: item.email,
name: item.name,
phone: item.phone,
payment_method: item.payment_method,
payment_method_data: item
.payment_method_data
.map(PaymentMethodDataResponse::from),
payment_token: item.payment_token,
..Default::default()
}
}
}

impl From<PaymentsSessionRequest> for PaymentsSessionResponse {
fn from(item: PaymentsSessionRequest) -> Self {
let client_secret: Secret<String, pii::ClientSecret> = Secret::new(item.client_secret);
Expand Down
7 changes: 5 additions & 2 deletions crates/common_utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ once_cell = "1.17.1"
quick-xml = { version = "0.28.2", features = ["serialize"] }
rand = "0.8.5"
regex = "1.7.3"
ring = "0.16.20"
ring = { version = "0.16.20", features = ["std"] }
serde = { version = "1.0.160", features = ["derive"] }
serde_json = "1.0.96"
serde_urlencoded = "0.7.1"
signal-hook = { version = "0.3.15", optional = true }
tokio = { version = "1.27.0", features = ["macros", "rt-multi-thread"], optional = true }
tokio = { version = "1.27.0", features = [
"macros",
"rt-multi-thread",
], optional = true }
thiserror = "1.0.40"
time = { version = "0.3.20", features = ["serde", "serde-well-known", "std"] }
md5 = "0.7.0"
Expand Down
Loading

0 comments on commit fa392c4

Please sign in to comment.