refactor(merchant_id): create domain type for merchant_id (#5408)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
Narayan Bhat
2024-07-24 19:18:25 +05:30
committed by GitHub
parent e18ea7a7ba
commit 7068fbfbe2
406 changed files with 3168 additions and 2633 deletions

View File

@ -2,10 +2,12 @@
use std::fmt::Display;
use crate::id_type;
/// Create a key for fetching the access token from redis
pub fn create_access_token_key(
merchant_id: impl Display,
merchant_id: &id_type::MerchantId,
merchant_connector_id_or_connector_name: impl Display,
) -> String {
format!("access_token_{merchant_id}_{merchant_connector_id_or_connector_name}")
merchant_id.get_access_token_key(merchant_connector_id_or_connector_name)
}

View File

@ -105,8 +105,13 @@ impl_api_event_type!(
Miscellaneous,
(
String,
id_type::MerchantId,
(id_type::MerchantId, String),
(&id_type::MerchantId, String),
(&id_type::MerchantId, &String),
(&String, &String),
(Option<i64>, Option<i64>, String),
(Option<i64>, Option<i64>, id_type::MerchantId),
bool
)
);

View File

@ -3,7 +3,10 @@
//! Ids for merchant account are derived from the merchant name
//! If there are any special characters, they are removed
use std::{borrow::Cow, fmt::Debug};
use std::{
borrow::Cow,
fmt::{Debug, Display},
};
use diesel::{
backend::Backend,
@ -14,17 +17,20 @@ use diesel::{
};
use error_stack::{Result, ResultExt};
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use crate::{
consts::{MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH},
errors, generate_id_with_default_len, generate_ref_id_with_default_length,
date_time, errors, generate_id_with_default_len, generate_ref_id_with_default_length,
id_type::{AlphaNumericId, LengthId},
new_type::MerchantName,
types::keymanager,
};
/// A type for merchant_id that can be used for merchant ids
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, AsExpression)]
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, AsExpression, Hash, ToSchema)]
#[diesel(sql_type = sql_types::Text)]
#[schema(value_type = String)]
pub struct MerchantId(
LengthId<MAX_ALLOWED_MERCHANT_REFERENCE_ID_LENGTH, MIN_REQUIRED_MERCHANT_REFERENCE_ID_LENGTH>,
);
@ -36,6 +42,22 @@ impl Debug for MerchantId {
}
}
/// This should be temporary, we should not have direct impl of Display for merchant id
impl Display for MerchantId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.get_string_repr())
}
}
#[cfg(feature = "metrics")]
/// This is implemented so that we can use merchant id directly as attribute in metrics
impl From<MerchantId> for router_env::opentelemetry::Value {
fn from(val: MerchantId) -> Self {
let string_value = val.0 .0 .0;
Self::String(router_env::opentelemetry::StringValue::from(string_value))
}
}
impl<DB> Queryable<sql_types::Text, DB> for MerchantId
where
DB: Backend,
@ -83,6 +105,43 @@ impl MerchantId {
Self(length_id)
}
/// Get a merchant id with the const value of `MERCHANT_ID_NOT_FOUND`
pub fn get_merchant_id_not_found() -> Self {
let alphanumeric_id = AlphaNumericId::new_unchecked("MERCHANT_ID_NOT_FOUND".to_string());
let length_id = LengthId::new_unchecked(alphanumeric_id);
Self(length_id)
}
/// Get a merchant id for internal use only
pub fn get_internal_user_merchant_id(merchant_id: &str) -> Self {
let alphanumeric_id = AlphaNumericId::new_unchecked(merchant_id.to_string());
let length_id = LengthId::new_unchecked(alphanumeric_id);
Self(length_id)
}
/// Create a new merchant_id from unix timestamp, of the format `merchant_{timestamp}`
pub fn new_from_unix_timestamp() -> Self {
let merchant_id = format!("merchant_{}", date_time::now_unix_timestamp());
let alphanumeric_id = AlphaNumericId::new_unchecked(merchant_id);
let length_id = LengthId::new_unchecked(alphanumeric_id);
Self(length_id)
}
/// Get a merchant id with a value of `irrelevant_merchant_id`
pub fn get_irrelevant_merchant_id() -> Self {
let alphanumeric_id = AlphaNumericId::new_unchecked("irrelevant_merchant_id".to_string());
let length_id = LengthId::new_unchecked(alphanumeric_id);
Self(length_id)
}
}
impl From<MerchantId> for keymanager::Identifier {
fn from(value: MerchantId) -> Self {
Self::Merchant(value)
}
}
impl masking::SerializableSecret for MerchantId {}
@ -112,3 +171,129 @@ where
.map(Self)
}
}
/// All the keys that can be formed from merchant id
impl MerchantId {
/// get step up enabled key
pub fn get_step_up_enabled_key(&self) -> String {
format!("step_up_enabled_{}", self.get_string_repr())
}
/// get_max_auto_retries_enabled key
pub fn get_max_auto_retries_enabled(&self) -> String {
format!("max_auto_retries_enabled_{}", self.get_string_repr())
}
/// get_requires_cvv_key
pub fn get_requires_cvv_key(&self) -> String {
format!("{}_requires_cvv", self.get_string_repr())
}
/// get_pm_filters_cgraph_key
pub fn get_pm_filters_cgraph_key(&self) -> String {
format!("pm_filters_cgraph_{}", self.get_string_repr())
}
/// get_blocklist_enabled_key
pub fn get_blocklist_guard_key(&self) -> String {
format!("guard_blocklist_for_{}", self.get_string_repr())
}
/// get_merchant_fingerprint_secret_key
pub fn get_merchant_fingerprint_secret_key(&self) -> String {
format!("fingerprint_secret_{}", self.get_string_repr())
}
/// get_surcharge_dsk_key
pub fn get_surcharge_dsk_key(&self) -> String {
format!("surcharge_dsl_{}", self.get_string_repr())
}
/// get_dsk_key
pub fn get_dsl_config(&self) -> String {
format!("dsl_{}", self.get_string_repr())
}
/// get_creds_identifier_key
pub fn get_creds_identifier_key(&self, creds_identifier: &str) -> String {
format!("mcd_{}_{creds_identifier}", self.get_string_repr())
}
/// get_poll_id
pub fn get_poll_id(&self, unique_id: &str) -> String {
format!("poll_{}_{unique_id}", self.get_string_repr())
}
/// get_access_token_key
pub fn get_access_token_key(
&self,
merchant_connector_id_or_connector_name: impl Display,
) -> String {
format!(
"access_token_{}_{merchant_connector_id_or_connector_name}",
self.get_string_repr()
)
}
/// get_skip_saving_wallet_at_connector_key
pub fn get_skip_saving_wallet_at_connector_key(&self) -> String {
format!("skip_saving_wallet_at_connector_{}", self.get_string_repr())
}
/// get_payment_config_routing_id
pub fn get_payment_config_routing_id(&self) -> String {
format!("payment_config_id_{}", self.get_string_repr())
}
/// get_payment_method_surcharge_routing_id
pub fn get_payment_method_surcharge_routing_id(&self) -> String {
format!("payment_method_surcharge_id_{}", self.get_string_repr())
}
/// get_webhook_config_disabled_events_key
pub fn get_webhook_config_disabled_events_key(&self, connector_id: &str) -> String {
format!(
"whconf_disabled_events_{}_{connector_id}",
self.get_string_repr()
)
}
/// get_should_call_gsm_payout_key
pub fn get_should_call_gsm_payout_key(
&self,
payout_retry_type: common_enums::PayoutRetryType,
) -> String {
match payout_retry_type {
common_enums::PayoutRetryType::SingleConnector => format!(
"should_call_gsm_single_connector_payout_{}",
self.get_string_repr()
),
common_enums::PayoutRetryType::MultiConnector => format!(
"should_call_gsm_multiple_connector_payout_{}",
self.get_string_repr()
),
}
}
/// Get should call gsm key for payment
pub fn get_should_call_gsm_key(&self) -> String {
format!("should_call_gsm_{}", self.get_string_repr())
}
/// get_max_auto_single_connector_payout_retries_enabled_
pub fn get_max_auto_single_connector_payout_retries_enabled(
&self,
payout_retry_type: common_enums::PayoutRetryType,
) -> String {
match payout_retry_type {
common_enums::PayoutRetryType::SingleConnector => format!(
"max_auto_single_connector_payout_retries_enabled_{}",
self.get_string_repr()
),
common_enums::PayoutRetryType::MultiConnector => format!(
"max_auto_multiple_connector_payout_retries_enabled_{}",
self.get_string_repr()
),
}
}
}

View File

@ -17,6 +17,7 @@ use crate::{
crypto::Encryptable,
encryption::Encryption,
errors::{self, CustomResult},
id_type,
transformers::{ForeignFrom, ForeignTryFrom},
};
@ -33,7 +34,7 @@ pub struct KeyManagerState {
#[serde(tag = "data_identifier", content = "key_identifier")]
pub enum Identifier {
User(String),
Merchant(String),
Merchant(id_type::MerchantId),
UserAuth(String),
}