refactor: incorporate hyperswitch_interface into router (#3669)

Co-authored-by: Narayan Bhat <narayan.bhat@juspay.in>
This commit is contained in:
Chethan Rao
2024-02-26 19:18:18 +05:30
committed by GitHub
parent c117f8ec63
commit 2185cd38c1
48 changed files with 671 additions and 1613 deletions

View File

@ -2,6 +2,4 @@
pub mod core;
pub mod decrypt;
pub mod implementers;

View File

@ -7,23 +7,9 @@ use aws_sdk_kms::{config::Region, primitives::Blob, Client};
use base64::Engine;
use common_utils::errors::CustomResult;
use error_stack::{IntoReport, ResultExt};
use masking::{PeekInterface, Secret};
use router_env::logger;
#[cfg(feature = "hashicorp-vault")]
use crate::hashicorp_vault;
use crate::{aws_kms::decrypt::AwsKmsDecrypt, consts, metrics};
pub(crate) static AWS_KMS_CLIENT: tokio::sync::OnceCell<AwsKmsClient> =
tokio::sync::OnceCell::const_new();
/// Returns a shared AWS KMS client, or initializes a new one if not previously initialized.
#[inline]
pub async fn get_aws_kms_client(config: &AwsKmsConfig) -> &'static AwsKmsClient {
AWS_KMS_CLIENT
.get_or_init(|| AwsKmsClient::new(config))
.await
}
use crate::{consts, metrics};
/// Configuration parameters required for constructing a [`AwsKmsClient`].
#[derive(Clone, Debug, Default, serde::Deserialize)]
@ -188,69 +174,6 @@ impl AwsKmsConfig {
}
}
/// A wrapper around a AWS KMS value that can be decrypted.
#[derive(Clone, Debug, Default, serde::Deserialize, Eq, PartialEq)]
#[serde(transparent)]
pub struct AwsKmsValue(Secret<String>);
impl common_utils::ext_traits::ConfigExt for AwsKmsValue {
fn is_empty_after_trim(&self) -> bool {
self.0.peek().is_empty_after_trim()
}
}
impl From<String> for AwsKmsValue {
fn from(value: String) -> Self {
Self(Secret::new(value))
}
}
impl From<Secret<String>> for AwsKmsValue {
fn from(value: Secret<String>) -> Self {
Self(value)
}
}
#[cfg(feature = "hashicorp-vault")]
#[async_trait::async_trait]
impl hashicorp_vault::decrypt::VaultFetch for AwsKmsValue {
async fn fetch_inner<En>(
self,
client: &hashicorp_vault::core::HashiCorpVault,
) -> error_stack::Result<Self, hashicorp_vault::core::HashiCorpError>
where
for<'a> En: hashicorp_vault::core::Engine<
ReturnType<'a, String> = std::pin::Pin<
Box<
dyn std::future::Future<
Output = error_stack::Result<
String,
hashicorp_vault::core::HashiCorpError,
>,
> + Send
+ 'a,
>,
>,
> + 'a,
{
self.0.fetch_inner::<En>(client).await.map(AwsKmsValue)
}
}
#[async_trait::async_trait]
impl AwsKmsDecrypt for &AwsKmsValue {
type Output = String;
async fn decrypt_inner(
self,
aws_kms_client: &AwsKmsClient,
) -> CustomResult<Self::Output, AwsKmsError> {
aws_kms_client
.decrypt(self.0.peek())
.await
.attach_printable("Failed to decrypt AWS KMS value")
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::expect_used)]

View File

@ -1,29 +0,0 @@
//! Decrypting data using the AWS KMS SDK.
use common_utils::errors::CustomResult;
use crate::aws_kms::core::{AwsKmsClient, AwsKmsError, AWS_KMS_CLIENT};
#[async_trait::async_trait]
/// This trait performs in place decryption of the structure on which this is implemented
pub trait AwsKmsDecrypt {
/// The output type of the decryption
type Output;
/// Decrypts the structure given a AWS KMS client
async fn decrypt_inner(
self,
aws_kms_client: &AwsKmsClient,
) -> CustomResult<Self::Output, AwsKmsError>
where
Self: Sized;
/// Tries to use the Singleton client to decrypt the structure
async fn try_decrypt_inner(self) -> CustomResult<Self::Output, AwsKmsError>
where
Self: Sized,
{
let client = AWS_KMS_CLIENT
.get()
.ok_or(AwsKmsError::AwsKmsClientNotInitialized)?;
self.decrypt_inner(client).await
}
}

View File

@ -2,6 +2,4 @@
pub mod core;
pub mod decrypt;
pub mod implementers;

View File

@ -1,54 +0,0 @@
//! Utilities for supporting decryption of data
use std::{future::Future, pin::Pin};
use masking::ExposeInterface;
use crate::hashicorp_vault::core::{Engine, HashiCorpError, HashiCorpVault};
/// A trait for types that can be asynchronously fetched and decrypted from HashiCorp Vault.
#[async_trait::async_trait]
pub trait VaultFetch: Sized {
/// Asynchronously decrypts the inner content of the type.
///
/// # Returns
///
/// An `Result<Self, super::HashiCorpError>` representing the decrypted instance if successful,
/// or an `super::HashiCorpError` with details about the encountered error.
///
async fn fetch_inner<En>(
self,
client: &HashiCorpVault,
) -> error_stack::Result<Self, HashiCorpError>
where
for<'a> En: Engine<
ReturnType<'a, String> = Pin<
Box<
dyn Future<Output = error_stack::Result<String, HashiCorpError>>
+ Send
+ 'a,
>,
>,
> + 'a;
}
#[async_trait::async_trait]
impl VaultFetch for masking::Secret<String> {
async fn fetch_inner<En>(
self,
client: &HashiCorpVault,
) -> error_stack::Result<Self, HashiCorpError>
where
for<'a> En: Engine<
ReturnType<'a, String> = Pin<
Box<
dyn Future<Output = error_stack::Result<String, HashiCorpError>>
+ Send
+ 'a,
>,
>,
> + 'a,
{
client.fetch::<En, Self>(self.expose()).await
}
}