mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 11:06:50 +08:00
feat(core): Add mTLS certificates for each request (#5636)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -1617,9 +1617,11 @@ merchant_secret="Source verification key"
|
|||||||
[itaubank]
|
[itaubank]
|
||||||
[[itaubank.bank_transfer]]
|
[[itaubank.bank_transfer]]
|
||||||
payment_method_type = "pix"
|
payment_method_type = "pix"
|
||||||
[itaubank.connector_auth.BodyKey]
|
[itaubank.connector_auth.MultiAuthKey]
|
||||||
key1="Client Id"
|
key1="Client Id"
|
||||||
api_key="Client Secret"
|
api_key="Client Secret"
|
||||||
|
api_secret="Certificates"
|
||||||
|
key2="Certificate Key"
|
||||||
|
|
||||||
[klarna]
|
[klarna]
|
||||||
[[klarna.pay_later]]
|
[[klarna.pay_later]]
|
||||||
|
|||||||
@ -1373,9 +1373,11 @@ merchant_secret="Source verification key"
|
|||||||
[itaubank]
|
[itaubank]
|
||||||
[[itaubank.bank_transfer]]
|
[[itaubank.bank_transfer]]
|
||||||
payment_method_type = "pix"
|
payment_method_type = "pix"
|
||||||
[itaubank.connector_auth.BodyKey]
|
[itaubank.connector_auth.MultiAuthKey]
|
||||||
key1="Client Id"
|
key1="Client Id"
|
||||||
api_key="Client Secret"
|
api_key="Client Secret"
|
||||||
|
api_secret="Certificates"
|
||||||
|
key2="Certificate Key"
|
||||||
|
|
||||||
[klarna]
|
[klarna]
|
||||||
[[klarna.pay_later]]
|
[[klarna.pay_later]]
|
||||||
|
|||||||
@ -1615,9 +1615,11 @@ merchant_secret="Source verification key"
|
|||||||
[itaubank]
|
[itaubank]
|
||||||
[[itaubank.bank_transfer]]
|
[[itaubank.bank_transfer]]
|
||||||
payment_method_type = "pix"
|
payment_method_type = "pix"
|
||||||
[itaubank.connector_auth.BodyKey]
|
[itaubank.connector_auth.MultiAuthKey]
|
||||||
key1="Client Id"
|
key1="Client Id"
|
||||||
api_key="Client Secret"
|
api_key="Client Secret"
|
||||||
|
api_secret="Certificates"
|
||||||
|
key2="Certificate Key"
|
||||||
|
|
||||||
[klarna]
|
[klarna]
|
||||||
[[klarna.pay_later]]
|
[[klarna.pay_later]]
|
||||||
|
|||||||
@ -93,7 +93,7 @@ rand = "0.8.5"
|
|||||||
rand_chacha = "0.3.1"
|
rand_chacha = "0.3.1"
|
||||||
rdkafka = "0.36.2"
|
rdkafka = "0.36.2"
|
||||||
regex = "1.10.4"
|
regex = "1.10.4"
|
||||||
reqwest = { version = "0.11.27", features = ["json", "native-tls", "__rustls", "gzip", "multipart"] }
|
reqwest = { version = "0.11.27", features = ["json", "rustls-tls", "gzip", "multipart"] }
|
||||||
ring = "0.17.8"
|
ring = "0.17.8"
|
||||||
roxmltree = "0.19.0"
|
roxmltree = "0.19.0"
|
||||||
rust_decimal = { version = "1.35.0", features = ["serde-with-float", "serde-with-str"] }
|
rust_decimal = { version = "1.35.0", features = ["serde-with-float", "serde-with-str"] }
|
||||||
|
|||||||
@ -197,12 +197,15 @@ impl ConnectorIntegration<api::AccessTokenAuth, types::AccessTokenRequestData, t
|
|||||||
req: &types::RefreshTokenRouterData,
|
req: &types::RefreshTokenRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||||
|
let auth_details = itaubank::ItaubankAuthType::try_from(&req.connector_auth_type)?;
|
||||||
let req = Some(
|
let req = Some(
|
||||||
services::RequestBuilder::new()
|
services::RequestBuilder::new()
|
||||||
.method(services::Method::Post)
|
.method(services::Method::Post)
|
||||||
.attach_default_headers()
|
.attach_default_headers()
|
||||||
.headers(types::RefreshTokenType::get_headers(self, req, connectors)?)
|
.headers(types::RefreshTokenType::get_headers(self, req, connectors)?)
|
||||||
.url(&types::RefreshTokenType::get_url(self, req, connectors)?)
|
.url(&types::RefreshTokenType::get_url(self, req, connectors)?)
|
||||||
|
.add_certificate(auth_details.certificate)
|
||||||
|
.add_certificate_key(auth_details.certificate_key)
|
||||||
.set_body(types::RefreshTokenType::get_request_body(
|
.set_body(types::RefreshTokenType::get_request_body(
|
||||||
self, req, connectors,
|
self, req, connectors,
|
||||||
)?)
|
)?)
|
||||||
@ -326,6 +329,7 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
|
|||||||
req: &types::PaymentsAuthorizeRouterData,
|
req: &types::PaymentsAuthorizeRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||||
|
let auth_details = itaubank::ItaubankAuthType::try_from(&req.connector_auth_type)?;
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
services::RequestBuilder::new()
|
services::RequestBuilder::new()
|
||||||
.method(services::Method::Post)
|
.method(services::Method::Post)
|
||||||
@ -336,6 +340,8 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
|
|||||||
.headers(types::PaymentsAuthorizeType::get_headers(
|
.headers(types::PaymentsAuthorizeType::get_headers(
|
||||||
self, req, connectors,
|
self, req, connectors,
|
||||||
)?)
|
)?)
|
||||||
|
.add_certificate(auth_details.certificate)
|
||||||
|
.add_certificate_key(auth_details.certificate_key)
|
||||||
.set_body(types::PaymentsAuthorizeType::get_request_body(
|
.set_body(types::PaymentsAuthorizeType::get_request_body(
|
||||||
self, req, connectors,
|
self, req, connectors,
|
||||||
)?)
|
)?)
|
||||||
@ -406,12 +412,15 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
|
|||||||
req: &types::PaymentsSyncRouterData,
|
req: &types::PaymentsSyncRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||||
|
let auth_details = itaubank::ItaubankAuthType::try_from(&req.connector_auth_type)?;
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
services::RequestBuilder::new()
|
services::RequestBuilder::new()
|
||||||
.method(services::Method::Get)
|
.method(services::Method::Get)
|
||||||
.url(&types::PaymentsSyncType::get_url(self, req, connectors)?)
|
.url(&types::PaymentsSyncType::get_url(self, req, connectors)?)
|
||||||
.attach_default_headers()
|
.attach_default_headers()
|
||||||
.headers(types::PaymentsSyncType::get_headers(self, req, connectors)?)
|
.headers(types::PaymentsSyncType::get_headers(self, req, connectors)?)
|
||||||
|
.add_certificate(auth_details.certificate)
|
||||||
|
.add_certificate_key(auth_details.certificate_key)
|
||||||
.build(),
|
.build(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -480,6 +489,7 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
|
|||||||
req: &types::PaymentsCaptureRouterData,
|
req: &types::PaymentsCaptureRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||||
|
let auth_details = itaubank::ItaubankAuthType::try_from(&req.connector_auth_type)?;
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
services::RequestBuilder::new()
|
services::RequestBuilder::new()
|
||||||
.method(services::Method::Post)
|
.method(services::Method::Post)
|
||||||
@ -488,6 +498,8 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
|
|||||||
.headers(types::PaymentsCaptureType::get_headers(
|
.headers(types::PaymentsCaptureType::get_headers(
|
||||||
self, req, connectors,
|
self, req, connectors,
|
||||||
)?)
|
)?)
|
||||||
|
.add_certificate(auth_details.certificate)
|
||||||
|
.add_certificate_key(auth_details.certificate_key)
|
||||||
.set_body(types::PaymentsCaptureType::get_request_body(
|
.set_body(types::PaymentsCaptureType::get_request_body(
|
||||||
self, req, connectors,
|
self, req, connectors,
|
||||||
)?)
|
)?)
|
||||||
@ -597,6 +609,7 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
|
|||||||
req: &types::RefundsRouterData<api::Execute>,
|
req: &types::RefundsRouterData<api::Execute>,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||||
|
let auth_details = itaubank::ItaubankAuthType::try_from(&req.connector_auth_type)?;
|
||||||
let request = services::RequestBuilder::new()
|
let request = services::RequestBuilder::new()
|
||||||
.method(services::Method::Put)
|
.method(services::Method::Put)
|
||||||
.url(&types::RefundExecuteType::get_url(self, req, connectors)?)
|
.url(&types::RefundExecuteType::get_url(self, req, connectors)?)
|
||||||
@ -604,6 +617,8 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
|
|||||||
.headers(types::RefundExecuteType::get_headers(
|
.headers(types::RefundExecuteType::get_headers(
|
||||||
self, req, connectors,
|
self, req, connectors,
|
||||||
)?)
|
)?)
|
||||||
|
.add_certificate(auth_details.certificate)
|
||||||
|
.add_certificate_key(auth_details.certificate_key)
|
||||||
.set_body(types::RefundExecuteType::get_request_body(
|
.set_body(types::RefundExecuteType::get_request_body(
|
||||||
self, req, connectors,
|
self, req, connectors,
|
||||||
)?)
|
)?)
|
||||||
@ -679,12 +694,15 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
|
|||||||
req: &types::RefundSyncRouterData,
|
req: &types::RefundSyncRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||||
|
let auth_details = itaubank::ItaubankAuthType::try_from(&req.connector_auth_type)?;
|
||||||
Ok(Some(
|
Ok(Some(
|
||||||
services::RequestBuilder::new()
|
services::RequestBuilder::new()
|
||||||
.method(services::Method::Get)
|
.method(services::Method::Get)
|
||||||
.url(&types::RefundSyncType::get_url(self, req, connectors)?)
|
.url(&types::RefundSyncType::get_url(self, req, connectors)?)
|
||||||
.attach_default_headers()
|
.attach_default_headers()
|
||||||
.headers(types::RefundSyncType::get_headers(self, req, connectors)?)
|
.headers(types::RefundSyncType::get_headers(self, req, connectors)?)
|
||||||
|
.add_certificate(auth_details.certificate)
|
||||||
|
.add_certificate_key(auth_details.certificate_key)
|
||||||
.set_body(types::RefundSyncType::get_request_body(
|
.set_body(types::RefundSyncType::get_request_body(
|
||||||
self, req, connectors,
|
self, req, connectors,
|
||||||
)?)
|
)?)
|
||||||
|
|||||||
@ -133,15 +133,30 @@ impl TryFrom<&ItaubankRouterData<&types::PaymentsAuthorizeRouterData>> for Itaub
|
|||||||
pub struct ItaubankAuthType {
|
pub struct ItaubankAuthType {
|
||||||
pub(super) client_id: Secret<String>,
|
pub(super) client_id: Secret<String>,
|
||||||
pub(super) client_secret: Secret<String>,
|
pub(super) client_secret: Secret<String>,
|
||||||
|
pub(super) certificate: Option<Secret<String>>,
|
||||||
|
pub(super) certificate_key: Option<Secret<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&types::ConnectorAuthType> for ItaubankAuthType {
|
impl TryFrom<&types::ConnectorAuthType> for ItaubankAuthType {
|
||||||
type Error = error_stack::Report<errors::ConnectorError>;
|
type Error = error_stack::Report<errors::ConnectorError>;
|
||||||
fn try_from(auth_type: &types::ConnectorAuthType) -> Result<Self, Self::Error> {
|
fn try_from(auth_type: &types::ConnectorAuthType) -> Result<Self, Self::Error> {
|
||||||
match auth_type {
|
match auth_type {
|
||||||
|
types::ConnectorAuthType::MultiAuthKey {
|
||||||
|
api_key,
|
||||||
|
key1,
|
||||||
|
api_secret,
|
||||||
|
key2,
|
||||||
|
} => Ok(Self {
|
||||||
|
client_secret: api_key.to_owned(),
|
||||||
|
client_id: key1.to_owned(),
|
||||||
|
certificate: Some(api_secret.to_owned()),
|
||||||
|
certificate_key: Some(key2.to_owned()),
|
||||||
|
}),
|
||||||
types::ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self {
|
types::ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self {
|
||||||
client_secret: api_key.to_owned(),
|
client_secret: api_key.to_owned(),
|
||||||
client_id: key1.to_owned(),
|
client_id: key1.to_owned(),
|
||||||
|
certificate: None,
|
||||||
|
certificate_key: None,
|
||||||
}),
|
}),
|
||||||
_ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
|
_ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ use api_models::{
|
|||||||
admin::{self as admin_types},
|
admin::{self as admin_types},
|
||||||
enums as api_enums, routing as routing_types,
|
enums as api_enums, routing as routing_types,
|
||||||
};
|
};
|
||||||
use base64::Engine;
|
|
||||||
use common_utils::{
|
use common_utils::{
|
||||||
date_time,
|
date_time,
|
||||||
ext_traits::{AsyncExt, Encode, OptionExt, ValueExt},
|
ext_traits::{AsyncExt, Encode, OptionExt, ValueExt},
|
||||||
@ -24,7 +23,7 @@ use uuid::Uuid;
|
|||||||
#[cfg(any(feature = "v1", feature = "v2"))]
|
#[cfg(any(feature = "v1", feature = "v2"))]
|
||||||
use crate::types::transformers::ForeignFrom;
|
use crate::types::transformers::ForeignFrom;
|
||||||
use crate::{
|
use crate::{
|
||||||
consts::{self, BASE64_ENGINE},
|
consts,
|
||||||
core::{
|
core::{
|
||||||
encryption::transfer_encryption_key,
|
encryption::transfer_encryption_key,
|
||||||
errors::{self, RouterResponse, RouterResult, StorageErrorExt},
|
errors::{self, RouterResponse, RouterResult, StorageErrorExt},
|
||||||
@ -35,7 +34,11 @@ use crate::{
|
|||||||
},
|
},
|
||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
routes::{metrics, SessionState},
|
routes::{metrics, SessionState},
|
||||||
services::{self, api as service_api, authentication, pm_auth as payment_initiation_service},
|
services::{
|
||||||
|
self,
|
||||||
|
api::{self as service_api, client},
|
||||||
|
authentication, pm_auth as payment_initiation_service,
|
||||||
|
},
|
||||||
types::{
|
types::{
|
||||||
self,
|
self,
|
||||||
api::{self, admin},
|
api::{self, admin},
|
||||||
@ -198,6 +201,10 @@ pub async fn create_merchant_account(
|
|||||||
let identifier = km_types::Identifier::Merchant(merchant_id.clone());
|
let identifier = km_types::Identifier::Merchant(merchant_id.clone());
|
||||||
#[cfg(feature = "keymanager_create")]
|
#[cfg(feature = "keymanager_create")]
|
||||||
{
|
{
|
||||||
|
use base64::Engine;
|
||||||
|
|
||||||
|
use crate::consts::BASE64_ENGINE;
|
||||||
|
|
||||||
keymanager::transfer_key_to_key_manager(
|
keymanager::transfer_key_to_key_manager(
|
||||||
key_manager_state,
|
key_manager_state,
|
||||||
EncryptionTransferRequest {
|
EncryptionTransferRequest {
|
||||||
@ -1604,7 +1611,7 @@ impl<'a> ConnectorAuthTypeValidation<'a> {
|
|||||||
certificate,
|
certificate,
|
||||||
private_key,
|
private_key,
|
||||||
} => {
|
} => {
|
||||||
helpers::create_identity_from_certificate_and_key(
|
client::create_identity_from_certificate_and_key(
|
||||||
certificate.to_owned(),
|
certificate.to_owned(),
|
||||||
private_key.to_owned(),
|
private_key.to_owned(),
|
||||||
)
|
)
|
||||||
@ -1695,34 +1702,6 @@ impl<'a> PaymentMethodsEnabled<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CertificateAndCertificateKey<'a> {
|
|
||||||
certificate: &'a Secret<String>,
|
|
||||||
certificate_key: &'a Secret<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> CertificateAndCertificateKey<'a> {
|
|
||||||
pub fn create_identity_from_certificate_and_key(
|
|
||||||
&self,
|
|
||||||
) -> Result<reqwest::Identity, error_stack::Report<errors::ApiClientError>> {
|
|
||||||
let decoded_certificate = BASE64_ENGINE
|
|
||||||
.decode(self.certificate.clone().expose())
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
|
|
||||||
let decoded_certificate_key = BASE64_ENGINE
|
|
||||||
.decode(self.certificate_key.clone().expose())
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
|
|
||||||
let certificate = String::from_utf8(decoded_certificate)
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
|
|
||||||
let certificate_key = String::from_utf8(decoded_certificate_key)
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
|
|
||||||
reqwest::Identity::from_pkcs8_pem(certificate.as_bytes(), certificate_key.as_bytes())
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ConnectorMetadata<'a> {
|
struct ConnectorMetadata<'a> {
|
||||||
connector_metadata: &'a Option<pii::SecretSerdeValue>,
|
connector_metadata: &'a Option<pii::SecretSerdeValue>,
|
||||||
}
|
}
|
||||||
@ -1739,11 +1718,7 @@ impl<'a> ConnectorMetadata<'a> {
|
|||||||
})?
|
})?
|
||||||
.and_then(|metadata| metadata.get_apple_pay_certificates())
|
.and_then(|metadata| metadata.get_apple_pay_certificates())
|
||||||
.map(|(certificate, certificate_key)| {
|
.map(|(certificate, certificate_key)| {
|
||||||
let certificate_and_certificate_key = CertificateAndCertificateKey {
|
client::create_identity_from_certificate_and_key(certificate, certificate_key)
|
||||||
certificate: &certificate,
|
|
||||||
certificate_key: &certificate_key,
|
|
||||||
};
|
|
||||||
certificate_and_certificate_key.create_identity_from_certificate_and_key()
|
|
||||||
})
|
})
|
||||||
.transpose()
|
.transpose()
|
||||||
.change_context(errors::ApiErrorResponse::InvalidDataValue {
|
.change_context(errors::ApiErrorResponse::InvalidDataValue {
|
||||||
|
|||||||
@ -99,41 +99,6 @@ use crate::{
|
|||||||
core::payment_methods::cards::create_encrypted_data, types::storage::CustomerUpdate::Update,
|
core::payment_methods::cards::create_encrypted_data, types::storage::CustomerUpdate::Update,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create_identity_from_certificate_and_key(
|
|
||||||
encoded_certificate: masking::Secret<String>,
|
|
||||||
encoded_certificate_key: masking::Secret<String>,
|
|
||||||
) -> Result<reqwest::Identity, error_stack::Report<errors::ApiClientError>> {
|
|
||||||
let decoded_certificate = BASE64_ENGINE
|
|
||||||
.decode(encoded_certificate.expose())
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
|
|
||||||
let decoded_certificate_key = BASE64_ENGINE
|
|
||||||
.decode(encoded_certificate_key.expose())
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
|
|
||||||
let certificate = String::from_utf8(decoded_certificate)
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
|
|
||||||
let certificate_key = String::from_utf8(decoded_certificate_key)
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
|
|
||||||
reqwest::Identity::from_pkcs8_pem(certificate.as_bytes(), certificate_key.as_bytes())
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_certificate(
|
|
||||||
encoded_certificate: masking::Secret<String>,
|
|
||||||
) -> Result<Vec<reqwest::Certificate>, error_stack::Report<errors::ApiClientError>> {
|
|
||||||
let decoded_certificate = BASE64_ENGINE
|
|
||||||
.decode(encoded_certificate.expose())
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
|
|
||||||
let certificate = String::from_utf8(decoded_certificate)
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)?;
|
|
||||||
reqwest::Certificate::from_pem_bundle(certificate.as_bytes())
|
|
||||||
.change_context(errors::ApiClientError::CertificateDecodeFailed)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn filter_mca_based_on_profile_and_connector_type(
|
pub fn filter_mca_based_on_profile_and_connector_type(
|
||||||
merchant_connector_accounts: Vec<domain::MerchantConnectorAccount>,
|
merchant_connector_accounts: Vec<domain::MerchantConnectorAccount>,
|
||||||
profile_id: &id_type::ProfileId,
|
profile_id: &id_type::ProfileId,
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use base64::Engine;
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
use http::{HeaderValue, Method};
|
use http::{HeaderValue, Method};
|
||||||
use masking::PeekInterface;
|
use masking::{ExposeInterface, PeekInterface};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use reqwest::multipart::Form;
|
use reqwest::multipart::Form;
|
||||||
use router_env::tracing_actix_web::RequestId;
|
use router_env::tracing_actix_web::RequestId;
|
||||||
@ -10,11 +11,8 @@ use router_env::tracing_actix_web::RequestId;
|
|||||||
use super::{request::Maskable, Request};
|
use super::{request::Maskable, Request};
|
||||||
use crate::{
|
use crate::{
|
||||||
configs::settings::{Locker, Proxy},
|
configs::settings::{Locker, Proxy},
|
||||||
consts::LOCKER_HEALTH_CALL_PATH,
|
consts::{BASE64_ENGINE, LOCKER_HEALTH_CALL_PATH},
|
||||||
core::{
|
core::errors::{ApiClientError, CustomResult},
|
||||||
errors::{ApiClientError, CustomResult},
|
|
||||||
payments,
|
|
||||||
},
|
|
||||||
routes::{app::settings::KeyManagerConfig, SessionState},
|
routes::{app::settings::KeyManagerConfig, SessionState},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,11 +88,11 @@ pub fn create_client(
|
|||||||
(Some(encoded_certificate), Some(encoded_certificate_key)) => {
|
(Some(encoded_certificate), Some(encoded_certificate_key)) => {
|
||||||
let client_builder = get_client_builder(proxy_config, should_bypass_proxy)?;
|
let client_builder = get_client_builder(proxy_config, should_bypass_proxy)?;
|
||||||
|
|
||||||
let identity = payments::helpers::create_identity_from_certificate_and_key(
|
let identity = create_identity_from_certificate_and_key(
|
||||||
encoded_certificate.clone(),
|
encoded_certificate.clone(),
|
||||||
encoded_certificate_key,
|
encoded_certificate_key,
|
||||||
)?;
|
)?;
|
||||||
let certificate_list = payments::helpers::create_certificate(encoded_certificate)?;
|
let certificate_list = create_certificate(encoded_certificate)?;
|
||||||
let client_builder = certificate_list
|
let client_builder = certificate_list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.fold(client_builder, |client_builder, certificate| {
|
.fold(client_builder, |client_builder, certificate| {
|
||||||
@ -102,6 +100,7 @@ pub fn create_client(
|
|||||||
});
|
});
|
||||||
client_builder
|
client_builder
|
||||||
.identity(identity)
|
.identity(identity)
|
||||||
|
.use_rustls_tls()
|
||||||
.build()
|
.build()
|
||||||
.change_context(ApiClientError::ClientConstructionFailed)
|
.change_context(ApiClientError::ClientConstructionFailed)
|
||||||
.attach_printable("Failed to construct client with certificate and certificate key")
|
.attach_printable("Failed to construct client with certificate and certificate key")
|
||||||
@ -110,6 +109,42 @@ pub fn create_client(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_identity_from_certificate_and_key(
|
||||||
|
encoded_certificate: masking::Secret<String>,
|
||||||
|
encoded_certificate_key: masking::Secret<String>,
|
||||||
|
) -> Result<reqwest::Identity, error_stack::Report<ApiClientError>> {
|
||||||
|
let decoded_certificate = BASE64_ENGINE
|
||||||
|
.decode(encoded_certificate.expose())
|
||||||
|
.change_context(ApiClientError::CertificateDecodeFailed)?;
|
||||||
|
|
||||||
|
let decoded_certificate_key = BASE64_ENGINE
|
||||||
|
.decode(encoded_certificate_key.expose())
|
||||||
|
.change_context(ApiClientError::CertificateDecodeFailed)?;
|
||||||
|
|
||||||
|
let certificate = String::from_utf8(decoded_certificate)
|
||||||
|
.change_context(ApiClientError::CertificateDecodeFailed)?;
|
||||||
|
|
||||||
|
let certificate_key = String::from_utf8(decoded_certificate_key)
|
||||||
|
.change_context(ApiClientError::CertificateDecodeFailed)?;
|
||||||
|
|
||||||
|
let key_chain = format!("{}{}", certificate_key, certificate);
|
||||||
|
reqwest::Identity::from_pem(key_chain.as_bytes())
|
||||||
|
.change_context(ApiClientError::CertificateDecodeFailed)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_certificate(
|
||||||
|
encoded_certificate: masking::Secret<String>,
|
||||||
|
) -> Result<Vec<reqwest::Certificate>, error_stack::Report<ApiClientError>> {
|
||||||
|
let decoded_certificate = BASE64_ENGINE
|
||||||
|
.decode(encoded_certificate.expose())
|
||||||
|
.change_context(ApiClientError::CertificateDecodeFailed)?;
|
||||||
|
|
||||||
|
let certificate = String::from_utf8(decoded_certificate)
|
||||||
|
.change_context(ApiClientError::CertificateDecodeFailed)?;
|
||||||
|
reqwest::Certificate::from_pem_bundle(certificate.as_bytes())
|
||||||
|
.change_context(ApiClientError::CertificateDecodeFailed)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn proxy_bypass_urls(
|
pub fn proxy_bypass_urls(
|
||||||
key_manager: &KeyManagerConfig,
|
key_manager: &KeyManagerConfig,
|
||||||
locker: &Locker,
|
locker: &Locker,
|
||||||
@ -245,10 +280,8 @@ impl ProxyClient {
|
|||||||
(Some(certificate), Some(certificate_key)) => {
|
(Some(certificate), Some(certificate_key)) => {
|
||||||
let client_builder =
|
let client_builder =
|
||||||
reqwest::Client::builder().redirect(reqwest::redirect::Policy::none());
|
reqwest::Client::builder().redirect(reqwest::redirect::Policy::none());
|
||||||
let identity = payments::helpers::create_identity_from_certificate_and_key(
|
let identity =
|
||||||
certificate,
|
create_identity_from_certificate_and_key(certificate, certificate_key)?;
|
||||||
certificate_key,
|
|
||||||
)?;
|
|
||||||
Ok(client_builder
|
Ok(client_builder
|
||||||
.identity(identity)
|
.identity(identity)
|
||||||
.build()
|
.build()
|
||||||
|
|||||||
@ -44,7 +44,7 @@ pub struct ConnectorAuthentication {
|
|||||||
pub gpayments: Option<HeaderKey>,
|
pub gpayments: Option<HeaderKey>,
|
||||||
pub helcim: Option<HeaderKey>,
|
pub helcim: Option<HeaderKey>,
|
||||||
pub iatapay: Option<SignatureKey>,
|
pub iatapay: Option<SignatureKey>,
|
||||||
pub itaubank: Option<HeaderKey>,
|
pub itaubank: Option<MultiAuthKey>,
|
||||||
pub mifinity: Option<HeaderKey>,
|
pub mifinity: Option<HeaderKey>,
|
||||||
pub mollie: Option<BodyKey>,
|
pub mollie: Option<BodyKey>,
|
||||||
pub multisafepay: Option<HeaderKey>,
|
pub multisafepay: Option<HeaderKey>,
|
||||||
|
|||||||
Reference in New Issue
Block a user