fix(dashboard_metadata): mask poc_email and data_value for DashboardMetadata (#7130)

This commit is contained in:
Uzair Khan
2025-02-06 19:17:02 +05:30
committed by GitHub
parent e17ffd1257
commit 9b1b245564
5 changed files with 31 additions and 20 deletions

View File

@ -94,7 +94,7 @@ pub struct ProdIntent {
pub business_label: Option<String>, pub business_label: Option<String>,
pub business_location: Option<CountryAlpha2>, pub business_location: Option<CountryAlpha2>,
pub display_name: Option<String>, pub display_name: Option<String>,
pub poc_email: Option<String>, pub poc_email: Option<Secret<String>>,
pub business_type: Option<String>, pub business_type: Option<String>,
pub business_identifier: Option<String>, pub business_identifier: Option<String>,
pub business_website: Option<String>, pub business_website: Option<String>,

View File

@ -1,5 +1,6 @@
use common_utils::id_type; use common_utils::id_type;
use diesel::{query_builder::AsChangeset, Identifiable, Insertable, Queryable, Selectable}; use diesel::{query_builder::AsChangeset, Identifiable, Insertable, Queryable, Selectable};
use masking::Secret;
use time::PrimitiveDateTime; use time::PrimitiveDateTime;
use crate::{enums, schema::dashboard_metadata}; use crate::{enums, schema::dashboard_metadata};
@ -12,7 +13,7 @@ pub struct DashboardMetadata {
pub merchant_id: id_type::MerchantId, pub merchant_id: id_type::MerchantId,
pub org_id: id_type::OrganizationId, pub org_id: id_type::OrganizationId,
pub data_key: enums::DashboardMetadata, pub data_key: enums::DashboardMetadata,
pub data_value: serde_json::Value, pub data_value: Secret<serde_json::Value>,
pub created_by: String, pub created_by: String,
pub created_at: PrimitiveDateTime, pub created_at: PrimitiveDateTime,
pub last_modified_by: String, pub last_modified_by: String,
@ -28,7 +29,7 @@ pub struct DashboardMetadataNew {
pub merchant_id: id_type::MerchantId, pub merchant_id: id_type::MerchantId,
pub org_id: id_type::OrganizationId, pub org_id: id_type::OrganizationId,
pub data_key: enums::DashboardMetadata, pub data_key: enums::DashboardMetadata,
pub data_value: serde_json::Value, pub data_value: Secret<serde_json::Value>,
pub created_by: String, pub created_by: String,
pub created_at: PrimitiveDateTime, pub created_at: PrimitiveDateTime,
pub last_modified_by: String, pub last_modified_by: String,
@ -41,7 +42,7 @@ pub struct DashboardMetadataNew {
#[diesel(table_name = dashboard_metadata)] #[diesel(table_name = dashboard_metadata)]
pub struct DashboardMetadataUpdateInternal { pub struct DashboardMetadataUpdateInternal {
pub data_key: enums::DashboardMetadata, pub data_key: enums::DashboardMetadata,
pub data_value: serde_json::Value, pub data_value: Secret<serde_json::Value>,
pub last_modified_by: String, pub last_modified_by: String,
pub last_modified_at: PrimitiveDateTime, pub last_modified_at: PrimitiveDateTime,
} }
@ -50,7 +51,7 @@ pub struct DashboardMetadataUpdateInternal {
pub enum DashboardMetadataUpdate { pub enum DashboardMetadataUpdate {
UpdateData { UpdateData {
data_key: enums::DashboardMetadata, data_key: enums::DashboardMetadata,
data_value: serde_json::Value, data_value: Secret<serde_json::Value>,
last_modified_by: String, last_modified_by: String,
}, },
} }

View File

@ -1,12 +1,16 @@
use std::str::FromStr;
use api_models::user::dashboard_metadata::{self as api, GetMultipleMetaDataPayload}; use api_models::user::dashboard_metadata::{self as api, GetMultipleMetaDataPayload};
#[cfg(feature = "email")] #[cfg(feature = "email")]
use common_enums::EntityType; use common_enums::EntityType;
use common_utils::pii;
use diesel_models::{ use diesel_models::{
enums::DashboardMetadata as DBEnum, user::dashboard_metadata::DashboardMetadata, enums::DashboardMetadata as DBEnum, user::dashboard_metadata::DashboardMetadata,
}; };
use error_stack::{report, ResultExt}; use error_stack::{report, ResultExt};
#[cfg(feature = "email")] #[cfg(feature = "email")]
use masking::ExposeInterface; use masking::ExposeInterface;
use masking::PeekInterface;
#[cfg(feature = "email")] #[cfg(feature = "email")]
use router_env::logger; use router_env::logger;
@ -447,6 +451,11 @@ async fn insert_metadata(
metadata metadata
} }
types::MetaData::ProdIntent(data) => { types::MetaData::ProdIntent(data) => {
if let Some(poc_email) = &data.poc_email {
let inner_poc_email = poc_email.peek().as_str();
pii::Email::from_str(inner_poc_email)
.change_context(UserErrors::EmailParsingError)?;
}
let mut metadata = utils::insert_user_scoped_metadata_to_db( let mut metadata = utils::insert_user_scoped_metadata_to_db(
state, state,
user.user_id.clone(), user.user_id.clone(),

View File

@ -454,7 +454,7 @@ impl BizEmailProd {
settings: state.conf.clone(), settings: state.conf.clone(),
subject: consts::user::EMAIL_SUBJECT_NEW_PROD_INTENT, subject: consts::user::EMAIL_SUBJECT_NEW_PROD_INTENT,
user_name: data.poc_name.unwrap_or_default().into(), user_name: data.poc_name.unwrap_or_default().into(),
poc_email: data.poc_email.unwrap_or_default().into(), poc_email: data.poc_email.unwrap_or_default(),
legal_business_name: data.legal_business_name.unwrap_or_default(), legal_business_name: data.legal_business_name.unwrap_or_default(),
business_location: data business_location: data
.business_location .business_location

View File

@ -10,7 +10,7 @@ use diesel_models::{
user::dashboard_metadata::{DashboardMetadata, DashboardMetadataNew, DashboardMetadataUpdate}, user::dashboard_metadata::{DashboardMetadata, DashboardMetadataNew, DashboardMetadataUpdate},
}; };
use error_stack::{report, ResultExt}; use error_stack::{report, ResultExt};
use masking::Secret; use masking::{ExposeInterface, PeekInterface, Secret};
use router_env::logger; use router_env::logger;
use crate::{ use crate::{
@ -37,7 +37,7 @@ pub async fn insert_merchant_scoped_metadata_to_db(
merchant_id, merchant_id,
org_id, org_id,
data_key: metadata_key, data_key: metadata_key,
data_value, data_value: Secret::from(data_value),
created_by: user_id.clone(), created_by: user_id.clone(),
created_at: now, created_at: now,
last_modified_by: user_id, last_modified_by: user_id,
@ -70,7 +70,7 @@ pub async fn insert_user_scoped_metadata_to_db(
merchant_id, merchant_id,
org_id, org_id,
data_key: metadata_key, data_key: metadata_key,
data_value, data_value: Secret::from(data_value),
created_by: user_id.clone(), created_by: user_id.clone(),
created_at: now, created_at: now,
last_modified_by: user_id, last_modified_by: user_id,
@ -143,7 +143,7 @@ pub async fn update_merchant_scoped_metadata(
metadata_key, metadata_key,
DashboardMetadataUpdate::UpdateData { DashboardMetadataUpdate::UpdateData {
data_key: metadata_key, data_key: metadata_key,
data_value, data_value: Secret::from(data_value),
last_modified_by: user_id, last_modified_by: user_id,
}, },
) )
@ -171,7 +171,7 @@ pub async fn update_user_scoped_metadata(
metadata_key, metadata_key,
DashboardMetadataUpdate::UpdateData { DashboardMetadataUpdate::UpdateData {
data_key: metadata_key, data_key: metadata_key,
data_value, data_value: Secret::from(data_value),
last_modified_by: user_id, last_modified_by: user_id,
}, },
) )
@ -183,7 +183,7 @@ pub fn deserialize_to_response<T>(data: Option<&DashboardMetadata>) -> UserResul
where where
T: serde::de::DeserializeOwned, T: serde::de::DeserializeOwned,
{ {
data.map(|metadata| serde_json::from_value(metadata.data_value.clone())) data.map(|metadata| serde_json::from_value(metadata.data_value.clone().expose()))
.transpose() .transpose()
.change_context(UserErrors::InternalServerError) .change_context(UserErrors::InternalServerError)
.attach_printable("Error Serializing Metadata from DB") .attach_printable("Error Serializing Metadata from DB")
@ -278,17 +278,18 @@ pub fn parse_string_to_enums(query: String) -> UserResult<GetMultipleMetaDataPay
}) })
} }
fn not_contains_string(value: &Option<String>, value_to_be_checked: &str) -> bool { fn not_contains_string(value: Option<&str>, value_to_be_checked: &str) -> bool {
value value.is_some_and(|mail| !mail.contains(value_to_be_checked))
.as_ref()
.is_some_and(|mail| !mail.contains(value_to_be_checked))
} }
pub fn is_prod_email_required(data: &ProdIntent, user_email: String) -> bool { pub fn is_prod_email_required(data: &ProdIntent, user_email: String) -> bool {
let poc_email_check = not_contains_string(&data.poc_email, "juspay"); let poc_email_check = not_contains_string(
let business_website_check = not_contains_string(&data.business_website, "juspay") data.poc_email.as_ref().map(|email| email.peek().as_str()),
&& not_contains_string(&data.business_website, "hyperswitch"); "juspay",
let user_email_check = not_contains_string(&Some(user_email), "juspay"); );
let business_website_check = not_contains_string(data.business_website.as_deref(), "juspay")
&& not_contains_string(data.business_website.as_deref(), "hyperswitch");
let user_email_check = not_contains_string(Some(&user_email), "juspay");
if (poc_email_check && business_website_check && user_email_check).not() { if (poc_email_check && business_website_check && user_email_check).not() {
logger::info!(prod_intent_email = poc_email_check); logger::info!(prod_intent_email = poc_email_check);