diff --git a/crates/common_utils/src/keymanager.rs b/crates/common_utils/src/keymanager.rs index a21eaa918b3..94495d3cf2e 100644 --- a/crates/common_utils/src/keymanager.rs +++ b/crates/common_utils/src/keymanager.rs @@ -235,10 +235,19 @@ impl ConvertRaw for TransientBatchDecryptDataRequest { pub async fn create_key_in_key_manager( state: &KeyManagerState, request_body: EncryptionCreateRequest, -) -> errors::CustomResult { - call_encryption_service(state, Method::POST, "key/create", request_body) - .await - .change_context(errors::KeyManagerError::KeyAddFailed) +) -> errors::CustomResult, errors::KeyManagerError> { + if !state.is_encryption_service_enabled() { + logger::info!( + "Encryption service is disabled, skipping key creation for identifier: {:?}", + request_body.identifier + ); + Ok(None) + } else { + call_encryption_service(state, Method::POST, "key/create", request_body) + .await + .map(Some) + .change_context(errors::KeyManagerError::KeyAddFailed) + } } /// A function to transfer the key in keymanager @@ -246,8 +255,17 @@ pub async fn create_key_in_key_manager( pub async fn transfer_key_to_key_manager( state: &KeyManagerState, request_body: EncryptionTransferRequest, -) -> errors::CustomResult { - call_encryption_service(state, Method::POST, "key/transfer", request_body) - .await - .change_context(errors::KeyManagerError::KeyTransferFailed) +) -> errors::CustomResult, errors::KeyManagerError> { + if !state.is_encryption_service_enabled() { + logger::info!( + "Encryption service is disabled, skipping key transfer for identifier: {:?}", + request_body.identifier + ); + Ok(None) + } else { + call_encryption_service(state, Method::POST, "key/transfer", request_body) + .await + .map(Some) + .change_context(errors::KeyManagerError::KeyTransferFailed) + } } diff --git a/crates/common_utils/src/types/keymanager.rs b/crates/common_utils/src/types/keymanager.rs index fb0a074ade1..a28a6e600a7 100644 --- a/crates/common_utils/src/types/keymanager.rs +++ b/crates/common_utils/src/types/keymanager.rs @@ -75,6 +75,7 @@ impl KeyManagerState { infra_values: Default::default(), } } + pub fn add_confirm_value_in_infra_values( &self, is_confirm_operation: bool, @@ -91,6 +92,17 @@ impl KeyManagerState { infra_values }) } + + pub fn is_encryption_service_enabled(&self) -> bool { + #[cfg(feature = "encryption_service")] + { + self.enabled + } + #[cfg(not(feature = "encryption_service"))] + { + false + } + } } pub trait GetKeymanagerTenant { diff --git a/crates/hyperswitch_domain_models/Cargo.toml b/crates/hyperswitch_domain_models/Cargo.toml index 1503ebe07db..6d3ef7efeeb 100644 --- a/crates/hyperswitch_domain_models/Cargo.toml +++ b/crates/hyperswitch_domain_models/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true [features] default = ["olap", "frm"] -encryption_service = [] +encryption_service = ["common_utils/encryption_service"] olap = [] payouts = ["api_models/payouts"] frm = ["api_models/frm"] @@ -24,7 +24,7 @@ revenue_recovery= [] api_models = { version = "0.1.0", path = "../api_models", features = ["errors"] } cards = { version = "0.1.0", path = "../cards" } common_enums = { version = "0.1.0", path = "../common_enums" } -common_utils = { version = "0.1.0", path = "../common_utils", features = ["async_ext", "metrics", "encryption_service", "keymanager"] } +common_utils = { version = "0.1.0", path = "../common_utils", features = ["async_ext", "metrics", "keymanager"] } common_types = { version = "0.1.0", path = "../common_types" } diesel_models = { version = "0.1.0", path = "../diesel_models", features = ["kv_store"], default-features = false } masking = { version = "0.1.0", path = "../masking" } diff --git a/crates/hyperswitch_domain_models/src/type_encryption.rs b/crates/hyperswitch_domain_models/src/type_encryption.rs index 8bb9ab9ac8d..da8c1f331f6 100644 --- a/crates/hyperswitch_domain_models/src/type_encryption.rs +++ b/crates/hyperswitch_domain_models/src/type_encryption.rs @@ -99,17 +99,6 @@ mod encrypt { ) -> CustomResult, errors::CryptoError>; } - fn is_encryption_service_enabled(_state: &KeyManagerState) -> bool { - #[cfg(feature = "encryption_service")] - { - _state.enabled - } - #[cfg(not(feature = "encryption_service"))] - { - false - } - } - #[async_trait] impl< V: crypto::DecodeMessage + crypto::EncodeMessage + Send + 'static, @@ -126,7 +115,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::encrypt(masked_data, key, crypt_algo).await } else { let result: Result< @@ -161,7 +150,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::decrypt(encrypted_data, key, crypt_algo).await } else { let result: Result< @@ -235,7 +224,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult, errors::CryptoError> { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::batch_encrypt(masked_data, key, crypt_algo).await } else { let result: Result< @@ -270,7 +259,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult, errors::CryptoError> { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::batch_decrypt(encrypted_data, key, crypt_algo).await } else { let result: Result< @@ -364,7 +353,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::encrypt(masked_data, key, crypt_algo).await } else { let result: Result< @@ -399,7 +388,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::decrypt(encrypted_data, key, crypt_algo).await } else { let result: Result< @@ -472,7 +461,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult, errors::CryptoError> { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::batch_encrypt(masked_data, key, crypt_algo).await } else { let result: Result< @@ -507,7 +496,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult, errors::CryptoError> { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::batch_decrypt(encrypted_data, key, crypt_algo).await } else { let result: Result< @@ -836,7 +825,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::encrypt(masked_data, key, crypt_algo).await } else { let result: Result< @@ -871,7 +860,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::decrypt(encrypted_data, key, crypt_algo).await } else { let result: Result< @@ -939,7 +928,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult, errors::CryptoError> { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::batch_encrypt(masked_data, key, crypt_algo).await } else { let result: Result< @@ -974,7 +963,7 @@ mod encrypt { crypt_algo: V, ) -> CustomResult, errors::CryptoError> { // If encryption service is not enabled, fall back to application encryption or else call encryption service - if !is_encryption_service_enabled(state) { + if !state.is_encryption_service_enabled() { Self::batch_decrypt(encrypted_data, key, crypt_algo).await } else { let result: Result< diff --git a/crates/payment_methods/Cargo.toml b/crates/payment_methods/Cargo.toml index 9e25a8375dc..001262636b6 100644 --- a/crates/payment_methods/Cargo.toml +++ b/crates/payment_methods/Cargo.toml @@ -23,7 +23,7 @@ api_models = { version = "0.1.0", path = "../api_models", features = ["errors", cards = { version = "0.1.0", path = "../cards" } common_types = { version = "0.1.0", path = "../common_types" } common_enums = { version = "0.1.0", path = "../common_enums" } -common_utils = { version = "0.1.0", path = "../common_utils", features = ["signals", "async_ext", "logs", "metrics", "keymanager", "encryption_service"] } +common_utils = { version = "0.1.0", path = "../common_utils", features = ["signals", "async_ext", "logs", "metrics", "keymanager"] } hyperswitch_domain_models = { version = "0.1.0", path = "../hyperswitch_domain_models", default-features = false } router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] } scheduler = { version = "0.1.0", path = "../scheduler", default-features = false } @@ -35,6 +35,7 @@ workspace = true [features] default = ["dummy_connector", "payouts"] +encryption_service = ["common_utils/encryption_service"] v1 = ["hyperswitch_domain_models/v1", "storage_impl/v1", "common_utils/v1", "scheduler/v1", "common_types/v1"] v2 = ["common_utils/v2", "scheduler/v2", "common_types/v2"] dummy_connector = ["api_models/dummy_connector", "hyperswitch_interfaces/dummy_connector"] diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml index 6cb1269e880..c1710d8f2f4 100644 --- a/crates/router/Cargo.toml +++ b/crates/router/Cargo.toml @@ -17,7 +17,7 @@ email = ["external_services/email", "scheduler/email", "olap"] # keymanager_create, keymanager_mtls, encryption_service should not be removed or added to default feature. Once this features were enabled it can't be disabled as these are breaking changes. keymanager_create = [] keymanager_mtls = ["reqwest/rustls-tls", "common_utils/keymanager_mtls"] -encryption_service = ["keymanager_create", "hyperswitch_domain_models/encryption_service", "common_utils/encryption_service"] +encryption_service = ["keymanager_create", "hyperswitch_domain_models/encryption_service", "common_utils/encryption_service", "subscriptions/encryption_service", "payment_methods/encryption_service"] km_forward_x_request_id = ["common_utils/km_forward_x_request_id"] frm = ["api_models/frm", "hyperswitch_domain_models/frm", "hyperswitch_connectors/frm", "hyperswitch_interfaces/frm"] stripe = [] @@ -121,7 +121,7 @@ analytics = { version = "0.1.0", path = "../analytics", optional = true, default api_models = { version = "0.1.0", path = "../api_models", features = ["errors", "control_center_theme"] } cards = { version = "0.1.0", path = "../cards" } common_enums = { version = "0.1.0", path = "../common_enums" } -common_utils = { version = "0.1.0", path = "../common_utils", features = ["signals", "async_ext", "logs", "metrics", "keymanager", "encryption_service"] } +common_utils = { version = "0.1.0", path = "../common_utils", features = ["signals", "async_ext", "logs", "metrics", "keymanager"] } common_types = { version = "0.1.0", path = "../common_types" } currency_conversion = { version = "0.1.0", path = "../currency_conversion" } diesel_models = { version = "0.1.0", path = "../diesel_models", features = ["kv_store", "tokenization_v2"], default-features = false } diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 06ecd103e89..7edff44be24 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -22,6 +22,11 @@ use hyperswitch_domain_models::merchant_connector_account::{ use masking::{ExposeInterface, PeekInterface, Secret}; use pm_auth::types as pm_auth_types; use uuid::Uuid; +#[cfg(feature = "olap")] +use { + base64::Engine, + common_utils::{keymanager, types::keymanager::EncryptionTransferRequest}, +}; use super::routing::helpers::redact_cgraph_cache; #[cfg(any(feature = "v1", feature = "v2"))] @@ -189,9 +194,6 @@ pub async fn create_merchant_account( req: api::MerchantAccountCreate, org_data_from_auth: Option, ) -> RouterResponse { - #[cfg(feature = "keymanager_create")] - use common_utils::{keymanager, types::keymanager::EncryptionTransferRequest}; - let db = state.store.as_ref(); let key = services::generate_aes256_key() .change_context(errors::ApiErrorResponse::InternalServerError) @@ -202,25 +204,16 @@ pub async fn create_merchant_account( let key_manager_state: &KeyManagerState = &(&state).into(); let merchant_id = req.get_merchant_reference_id(); let identifier = km_types::Identifier::Merchant(merchant_id.clone()); - #[cfg(feature = "keymanager_create")] - { - use base64::Engine; - - use crate::consts::BASE64_ENGINE; - - if key_manager_state.enabled { - keymanager::transfer_key_to_key_manager( - key_manager_state, - EncryptionTransferRequest { - identifier: identifier.clone(), - key: masking::StrongSecret::new(BASE64_ENGINE.encode(key)), - }, - ) - .await - .change_context(errors::ApiErrorResponse::DuplicateMerchantAccount) - .attach_printable("Failed to insert key to KeyManager")?; - } - } + keymanager::transfer_key_to_key_manager( + key_manager_state, + EncryptionTransferRequest { + identifier: identifier.clone(), + key: masking::StrongSecret::new(consts::BASE64_ENGINE.encode(key)), + }, + ) + .await + .change_context(errors::ApiErrorResponse::DuplicateMerchantAccount) + .attach_printable("Failed to insert key to KeyManager")?; let key_store = domain::MerchantKeyStore { merchant_id: merchant_id.clone(), diff --git a/crates/router/src/types/domain/user.rs b/crates/router/src/types/domain/user.rs index 6a1f4efdca5..a216dc211a4 100644 --- a/crates/router/src/types/domain/user.rs +++ b/crates/router/src/types/domain/user.rs @@ -8,10 +8,14 @@ use std::{ use api_models::{ admin as admin_api, organization as api_org, user as user_api, user_role as user_role_api, }; +use base64::Engine; use common_enums::EntityType; use common_utils::{ - crypto::Encryptable, id_type, new_type::MerchantName, pii, type_name, - types::keymanager::Identifier, + crypto::Encryptable, + id_type, + new_type::MerchantName, + pii, type_name, + types::keymanager::{EncryptionTransferRequest, Identifier}, }; use diesel_models::{ enums::{TotpStatus, UserRoleVersion, UserStatus}, @@ -25,8 +29,6 @@ use masking::{ExposeInterface, PeekInterface, Secret}; use rand::distributions::{Alphanumeric, DistString}; use time::PrimitiveDateTime; use unicode_segmentation::UnicodeSegmentation; -#[cfg(feature = "keymanager_create")] -use {base64::Engine, common_utils::types::keymanager::EncryptionTransferRequest}; use crate::{ consts, @@ -1213,18 +1215,15 @@ impl UserFromStorage { .change_context(UserErrors::InternalServerError) .attach_printable("Unable to generate aes 256 key")?; - #[cfg(feature = "keymanager_create")] - { - common_utils::keymanager::transfer_key_to_key_manager( - key_manager_state, - EncryptionTransferRequest { - identifier: Identifier::User(self.get_user_id().to_string()), - key: masking::StrongSecret::new(consts::BASE64_ENGINE.encode(key)), - }, - ) - .await - .change_context(UserErrors::InternalServerError)?; - } + common_utils::keymanager::transfer_key_to_key_manager( + key_manager_state, + EncryptionTransferRequest { + identifier: Identifier::User(self.get_user_id().to_string()), + key: masking::StrongSecret::new(consts::BASE64_ENGINE.encode(key)), + }, + ) + .await + .change_context(UserErrors::InternalServerError)?; let key_store = UserKeyStore { user_id: self.get_user_id().to_string(), diff --git a/crates/subscriptions/Cargo.toml b/crates/subscriptions/Cargo.toml index 08da62a4788..368d06b2488 100644 --- a/crates/subscriptions/Cargo.toml +++ b/crates/subscriptions/Cargo.toml @@ -17,7 +17,7 @@ time = { version = "0.3.41", features = ["serde", "std"] } api_models = { version = "0.1.0", path = "../api_models", features = ["errors", "control_center_theme"] } common_types = { version = "0.1.0", path = "../common_types" } common_enums = { version = "0.1.0", path = "../common_enums" } -common_utils = { version = "0.1.0", path = "../common_utils", features = ["signals", "async_ext", "logs", "metrics", "keymanager", "encryption_service"] } +common_utils = { version = "0.1.0", path = "../common_utils", features = ["signals", "async_ext", "logs", "metrics", "keymanager"] } hyperswitch_domain_models = { version = "0.1.0", path = "../hyperswitch_domain_models", default-features = false } router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] } scheduler = { version = "0.1.0", path = "../scheduler", default-features = false } @@ -29,5 +29,6 @@ workspace = true [features] default = ["v1"] +encryption_service = ["common_utils/encryption_service"] v1 = ["hyperswitch_domain_models/v1", "storage_impl/v1", "common_utils/v1", "scheduler/v1", "common_types/v1"] v2 = ["common_utils/v2", "scheduler/v2", "common_types/v2"]