use std::{collections::HashMap, env}; use masking::Secret; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct ConnectorAuthentication { pub aci: Option, #[cfg(not(feature = "payouts"))] pub adyen: Option, #[cfg(feature = "payouts")] pub adyenplatform: Option, #[cfg(feature = "payouts")] pub adyen: Option, #[cfg(not(feature = "payouts"))] pub adyen_uk: Option, #[cfg(feature = "payouts")] pub adyen_uk: Option, pub airwallex: Option, pub amazonpay: Option, pub authorizedotnet: Option, pub bambora: Option, pub bamboraapac: Option, pub bankofamerica: Option, pub billwerk: Option, pub bitpay: Option, pub bluesnap: Option, pub boku: Option, pub cashtocode: Option, pub checkout: Option, pub coinbase: Option, pub cryptopay: Option, pub cybersource: Option, pub datatrans: Option, pub deutschebank: Option, pub digitalvirgo: Option, pub dlocal: Option, #[cfg(feature = "dummy_connector")] pub dummyconnector: Option, pub ebanx: Option, pub elavon: Option, pub fiserv: Option, pub fiservemea: Option, pub fiuu: Option, pub forte: Option, pub globalpay: Option, pub globepay: Option, pub gocardless: Option, pub gpayments: Option, pub helcim: Option, pub iatapay: Option, pub inespay: Option, pub itaubank: Option, pub jpmorgan: Option, pub mifinity: Option, pub mollie: Option, pub multisafepay: Option, pub netcetera: Option, pub nexinets: Option, pub nexixpay: Option, pub nomupay: Option, pub noon: Option, pub novalnet: Option, pub nmi: Option, pub nuvei: Option, pub opayo: Option, pub opennode: Option, pub paybox: Option, pub payeezy: Option, pub payme: Option, pub payone: Option, pub paypal: Option, pub payu: Option, pub placetopay: Option, pub plaid: Option, pub powertranz: Option, pub prophetpay: Option, pub rapyd: Option, pub razorpay: Option, pub redsys: Option, pub shift4: Option, pub square: Option, pub stax: Option, pub stripe: Option, pub taxjar: Option, pub threedsecureio: Option, pub thunes: Option, pub stripe_au: Option, pub stripe_uk: Option, pub trustpay: Option, pub tsys: Option, pub volt: Option, pub wellsfargo: Option, // pub wellsfargopayout: Option, pub wise: Option, pub worldpay: Option, pub xendit: Option, pub worldline: Option, pub zen: Option, pub zsl: Option, pub automation_configs: Option, pub users: Option, } impl Default for ConnectorAuthentication { fn default() -> Self { Self::new() } } #[allow(dead_code)] impl ConnectorAuthentication { /// # Panics /// /// Will panic if `CONNECTOR_AUTH_FILE_PATH` env is not set #[allow(clippy::expect_used)] pub fn new() -> Self { // Do `export CONNECTOR_AUTH_FILE_PATH="/hyperswitch/crates/router/tests/connectors/sample_auth.toml"` // before running tests in shell let path = env::var("CONNECTOR_AUTH_FILE_PATH") .expect("Connector authentication file path not set"); toml::from_str( &std::fs::read_to_string(path).expect("connector authentication config file not found"), ) .expect("Failed to read connector authentication config file") } } #[derive(Clone, Debug, Deserialize)] pub struct ConnectorAuthenticationMap(HashMap); impl Default for ConnectorAuthenticationMap { fn default() -> Self { Self::new() } } // This is a temporary solution to avoid rust compiler from complaining about unused function #[allow(dead_code)] impl ConnectorAuthenticationMap { pub fn inner(&self) -> &HashMap { &self.0 } /// # Panics /// /// Will panic if `CONNECTOR_AUTH_FILE_PATH` env is not set #[allow(clippy::expect_used)] pub fn new() -> Self { // Do `export CONNECTOR_AUTH_FILE_PATH="/hyperswitch/crates/router/tests/connectors/sample_auth.toml"` // before running tests in shell let path = env::var("CONNECTOR_AUTH_FILE_PATH") .expect("connector authentication file path not set"); // Read the file contents to a JsonString let contents = &std::fs::read_to_string(path).expect("Failed to read connector authentication file"); // Deserialize the JsonString to a HashMap let auth_config: HashMap = toml::from_str(contents).expect("Failed to deserialize TOML file"); // auth_config contains the data in below given format: // { // "connector_name": Table( // { // "api_key": String( // "API_Key", // ), // "api_secret": String( // "Secret key", // ), // "key1": String( // "key1", // ), // "key2": String( // "key2", // ), // }, // ), // "connector_name": Table( // ... // } // auth_map refines and extracts required information let auth_map = auth_config .into_iter() .map(|(connector_name, config)| { let auth_type = match config { toml::Value::Table(table) => { match ( table.get("api_key"), table.get("key1"), table.get("api_secret"), table.get("key2"), ) { (Some(api_key), None, None, None) => ConnectorAuthType::HeaderKey { api_key: Secret::new( api_key.as_str().unwrap_or_default().to_string(), ), }, (Some(api_key), Some(key1), None, None) => ConnectorAuthType::BodyKey { api_key: Secret::new( api_key.as_str().unwrap_or_default().to_string(), ), key1: Secret::new(key1.as_str().unwrap_or_default().to_string()), }, (Some(api_key), Some(key1), Some(api_secret), None) => { ConnectorAuthType::SignatureKey { api_key: Secret::new( api_key.as_str().unwrap_or_default().to_string(), ), key1: Secret::new( key1.as_str().unwrap_or_default().to_string(), ), api_secret: Secret::new( api_secret.as_str().unwrap_or_default().to_string(), ), } } (Some(api_key), Some(key1), Some(api_secret), Some(key2)) => { ConnectorAuthType::MultiAuthKey { api_key: Secret::new( api_key.as_str().unwrap_or_default().to_string(), ), key1: Secret::new( key1.as_str().unwrap_or_default().to_string(), ), api_secret: Secret::new( api_secret.as_str().unwrap_or_default().to_string(), ), key2: Secret::new( key2.as_str().unwrap_or_default().to_string(), ), } } _ => ConnectorAuthType::NoKey, } } _ => ConnectorAuthType::NoKey, }; (connector_name, auth_type) }) .collect(); Self(auth_map) } } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct HeaderKey { pub api_key: Secret, } impl From for ConnectorAuthType { fn from(key: HeaderKey) -> Self { Self::HeaderKey { api_key: key.api_key, } } } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct BodyKey { pub api_key: Secret, pub key1: Secret, } impl From for ConnectorAuthType { fn from(key: BodyKey) -> Self { Self::BodyKey { api_key: key.api_key, key1: key.key1, } } } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct SignatureKey { pub api_key: Secret, pub key1: Secret, pub api_secret: Secret, } impl From for ConnectorAuthType { fn from(key: SignatureKey) -> Self { Self::SignatureKey { api_key: key.api_key, key1: key.key1, api_secret: key.api_secret, } } } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct MultiAuthKey { pub api_key: Secret, pub key1: Secret, pub api_secret: Secret, pub key2: Secret, } impl From for ConnectorAuthType { fn from(key: MultiAuthKey) -> Self { Self::MultiAuthKey { api_key: key.api_key, key1: key.key1, api_secret: key.api_secret, key2: key.key2, } } } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct AutomationConfigs { pub hs_base_url: Option, pub hs_api_key: Option, pub hs_api_keys: Option, pub hs_webhook_url: Option, pub hs_test_env: Option, pub hs_test_browser: Option, pub chrome_profile_path: Option, pub firefox_profile_path: Option, pub pypl_email: Option, pub pypl_pass: Option, pub gmail_email: Option, pub gmail_pass: Option, pub clearpay_email: Option, pub clearpay_pass: Option, pub configs_url: Option, pub stripe_pub_key: Option, pub testcases_path: Option, pub bluesnap_gateway_merchant_id: Option, pub globalpay_gateway_merchant_id: Option, pub authorizedotnet_gateway_merchant_id: Option, pub run_minimum_steps: Option, pub airwallex_merchant_name: Option, pub adyen_bancontact_username: Option, pub adyen_bancontact_pass: Option, } #[derive(Default, Debug, Clone, serde::Deserialize)] #[serde(tag = "auth_type")] pub enum ConnectorAuthType { HeaderKey { api_key: Secret, }, BodyKey { api_key: Secret, key1: Secret, }, SignatureKey { api_key: Secret, key1: Secret, api_secret: Secret, }, MultiAuthKey { api_key: Secret, key1: Secret, api_secret: Secret, key2: Secret, }, #[default] NoKey, } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct UsersConfigs { pub user_email: String, pub user_password: String, pub wrong_password: String, pub user_base_email_for_signup: String, pub user_domain_for_signup: String, }