mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 13:30:39 +08:00
feat: create key in encryption service for merchant and user (#4910)
Co-authored-by: Arjun Karthik <m.arjunkarthik@gmail.com> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -9,6 +9,8 @@ use common_utils::{
|
||||
ext_traits::{AsyncExt, ConfigExt, Encode, ValueExt},
|
||||
pii,
|
||||
};
|
||||
#[cfg(all(feature = "keymanager_create", feature = "olap"))]
|
||||
use common_utils::{keymanager, types::keymanager as km_types};
|
||||
use diesel_models::configs;
|
||||
use error_stack::{report, FutureExt, ResultExt};
|
||||
use futures::future::try_join_all;
|
||||
@ -22,6 +24,7 @@ use crate::types::transformers::ForeignFrom;
|
||||
use crate::{
|
||||
consts,
|
||||
core::{
|
||||
encryption::transfer_encryption_key,
|
||||
errors::{self, RouterResponse, RouterResult, StorageErrorExt},
|
||||
payments::helpers,
|
||||
routing::helpers as routing_helpers,
|
||||
@ -125,6 +128,19 @@ pub async fn create_merchant_account(
|
||||
.create_domain_model_from_request(db, key_store.clone())
|
||||
.await?;
|
||||
|
||||
#[cfg(feature = "keymanager_create")]
|
||||
{
|
||||
keymanager::create_key_in_key_manager(
|
||||
&(&state).into(),
|
||||
km_types::EncryptionCreateRequest {
|
||||
identifier: km_types::Identifier::Merchant(merchant_id.clone()),
|
||||
},
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::DuplicateMerchantAccount)
|
||||
.attach_printable("Failed to insert key to KeyManager")?;
|
||||
}
|
||||
|
||||
db.insert_merchant_key_store(key_store.clone(), &master_key.to_vec().into())
|
||||
.await
|
||||
.to_duplicate_response(errors::ApiErrorResponse::DuplicateMerchantAccount)?;
|
||||
@ -2491,6 +2507,18 @@ pub(crate) fn validate_connector_auth_type(
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn transfer_key_store_to_key_manager(
|
||||
state: SessionState,
|
||||
) -> RouterResponse<admin_types::TransferKeyResponse> {
|
||||
let resp = transfer_encryption_key(&state).await?;
|
||||
|
||||
Ok(service_api::ApplicationResponse::Json(
|
||||
admin_types::TransferKeyResponse {
|
||||
total_transferred: resp,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
pub async fn validate_dummy_connector_enabled(
|
||||
state: &SessionState,
|
||||
|
||||
55
crates/router/src/core/encryption.rs
Normal file
55
crates/router/src/core/encryption.rs
Normal file
@ -0,0 +1,55 @@
|
||||
use base64::Engine;
|
||||
use common_utils::{
|
||||
keymanager::transfer_key_to_key_manager,
|
||||
types::keymanager::{EncryptionTransferRequest, Identifier},
|
||||
};
|
||||
use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::merchant_key_store::MerchantKeyStore;
|
||||
use masking::ExposeInterface;
|
||||
|
||||
use crate::{consts::BASE64_ENGINE, errors, types::domain::UserKeyStore, SessionState};
|
||||
|
||||
pub async fn transfer_encryption_key(
|
||||
state: &SessionState,
|
||||
) -> errors::CustomResult<usize, errors::ApiErrorResponse> {
|
||||
let db = &*state.store;
|
||||
let key_stores = db
|
||||
.get_all_key_stores(&db.get_master_key().to_vec().into())
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
send_request_to_key_service_for_merchant(state, key_stores).await
|
||||
}
|
||||
|
||||
pub async fn send_request_to_key_service_for_merchant(
|
||||
state: &SessionState,
|
||||
keys: Vec<MerchantKeyStore>,
|
||||
) -> errors::CustomResult<usize, errors::ApiErrorResponse> {
|
||||
futures::future::try_join_all(keys.into_iter().map(|key| async move {
|
||||
let key_encoded = BASE64_ENGINE.encode(key.key.clone().into_inner().expose());
|
||||
let req = EncryptionTransferRequest {
|
||||
identifier: Identifier::Merchant(key.merchant_id.clone()),
|
||||
key: key_encoded,
|
||||
};
|
||||
transfer_key_to_key_manager(&state.into(), req).await
|
||||
}))
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.map(|v| v.len())
|
||||
}
|
||||
|
||||
pub async fn send_request_to_key_service_for_user(
|
||||
state: &SessionState,
|
||||
keys: Vec<UserKeyStore>,
|
||||
) -> errors::CustomResult<usize, errors::ApiErrorResponse> {
|
||||
futures::future::try_join_all(keys.into_iter().map(|key| async move {
|
||||
let key_encoded = BASE64_ENGINE.encode(key.key.clone().into_inner().expose());
|
||||
let req = EncryptionTransferRequest {
|
||||
identifier: Identifier::User(key.user_id.clone()),
|
||||
key: key_encoded,
|
||||
};
|
||||
transfer_key_to_key_manager(&state.into(), req).await
|
||||
}))
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.map(|v| v.len())
|
||||
}
|
||||
@ -27,6 +27,7 @@ use super::errors::{StorageErrorExt, UserErrors, UserResponse, UserResult};
|
||||
use crate::services::email::types as email_types;
|
||||
use crate::{
|
||||
consts,
|
||||
core::encryption::send_request_to_key_service_for_user,
|
||||
db::domain::user_authentication_method::DEFAULT_USER_AUTH_METHOD,
|
||||
routes::{app::ReqState, SessionState},
|
||||
services::{authentication as auth, authorization::roles, openidconnect, ApplicationResponse},
|
||||
@ -1911,6 +1912,25 @@ pub async fn generate_recovery_codes(
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn transfer_user_key_store_keymanager(
|
||||
state: SessionState,
|
||||
) -> UserResponse<user_api::UserTransferKeyResponse> {
|
||||
let db = &state.global_store;
|
||||
|
||||
let key_stores = db
|
||||
.get_all_user_key_store(&state.store.get_master_key().to_vec().into())
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?;
|
||||
|
||||
Ok(ApplicationResponse::Json(
|
||||
user_api::UserTransferKeyResponse {
|
||||
total_transferred: send_request_to_key_service_for_user(&state, key_stores)
|
||||
.await
|
||||
.change_context(UserErrors::InternalServerError)?,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn verify_recovery_code(
|
||||
state: SessionState,
|
||||
user_token: auth::UserIdFromAuth,
|
||||
|
||||
Reference in New Issue
Block a user