mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 21:07:58 +08:00
fix: add validation for connector authentication type during mca create and update operation (#4932)
This commit is contained in:
@ -859,27 +859,7 @@ pub async fn create_payment_connector(
|
|||||||
expected_format: "auth_type and api_key".to_string(),
|
expected_format: "auth_type and api_key".to_string(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
validate_auth_and_metadata_type(req.connector_name, &auth, &req.metadata).map_err(|err| {
|
validate_auth_and_metadata_type(req.connector_name, &auth, &req.metadata)?;
|
||||||
match *err.current_context() {
|
|
||||||
errors::ConnectorError::InvalidConnectorName => {
|
|
||||||
err.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
|
||||||
message: "The connector name is invalid".to_string(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
errors::ConnectorError::InvalidConnectorConfig { config: field_name } => err
|
|
||||||
.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
|
||||||
message: format!("The {} is invalid", field_name),
|
|
||||||
}),
|
|
||||||
errors::ConnectorError::FailedToObtainAuthType => {
|
|
||||||
err.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
|
||||||
message: "The auth type is invalid for the connector".to_string(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => err.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
|
||||||
message: "The request body is invalid".to_string(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let frm_configs = get_frm_config_as_secret(req.frm_configs);
|
let frm_configs = get_frm_config_as_secret(req.frm_configs);
|
||||||
|
|
||||||
@ -1209,27 +1189,7 @@ pub async fn update_payment_connector(
|
|||||||
field_name: "connector",
|
field_name: "connector",
|
||||||
})
|
})
|
||||||
.attach_printable_lazy(|| format!("unable to parse connector name {connector_name:?}"))?;
|
.attach_printable_lazy(|| format!("unable to parse connector name {connector_name:?}"))?;
|
||||||
validate_auth_and_metadata_type(connector_enum, &auth, &metadata).map_err(|err| match *err
|
validate_auth_and_metadata_type(connector_enum, &auth, &metadata)?;
|
||||||
.current_context()
|
|
||||||
{
|
|
||||||
errors::ConnectorError::InvalidConnectorName => {
|
|
||||||
err.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
|
||||||
message: "The connector name is invalid".to_string(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
errors::ConnectorError::InvalidConnectorConfig { config: field_name } => err
|
|
||||||
.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
|
||||||
message: format!("The {} is invalid", field_name),
|
|
||||||
}),
|
|
||||||
errors::ConnectorError::FailedToObtainAuthType => {
|
|
||||||
err.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
|
||||||
message: "The auth type is invalid for the connector".to_string(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => err.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
|
||||||
message: "The request body is invalid".to_string(),
|
|
||||||
}),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let (connector_status, disabled) =
|
let (connector_status, disabled) =
|
||||||
validate_status_and_disabled(req.status, req.disabled, auth, mca.status)?;
|
validate_status_and_disabled(req.status, req.disabled, auth, mca.status)?;
|
||||||
@ -1819,7 +1779,35 @@ pub async fn connector_agnostic_mit_toggle(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn validate_auth_and_metadata_type(
|
pub fn validate_auth_and_metadata_type(
|
||||||
|
connector_name: api_models::enums::Connector,
|
||||||
|
auth_type: &types::ConnectorAuthType,
|
||||||
|
connector_meta_data: &Option<pii::SecretSerdeValue>,
|
||||||
|
) -> Result<(), error_stack::Report<errors::ApiErrorResponse>> {
|
||||||
|
validate_connector_auth_type(auth_type)?;
|
||||||
|
validate_auth_and_metadata_type_with_connector(connector_name, auth_type, connector_meta_data)
|
||||||
|
.map_err(|err| match *err.current_context() {
|
||||||
|
errors::ConnectorError::InvalidConnectorName => {
|
||||||
|
err.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
||||||
|
message: "The connector name is invalid".to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
errors::ConnectorError::InvalidConnectorConfig { config: field_name } => err
|
||||||
|
.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
||||||
|
message: format!("The {} is invalid", field_name),
|
||||||
|
}),
|
||||||
|
errors::ConnectorError::FailedToObtainAuthType => {
|
||||||
|
err.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
||||||
|
message: "The auth type is invalid for the connector".to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => err.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
||||||
|
message: "The request body is invalid".to_string(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn validate_auth_and_metadata_type_with_connector(
|
||||||
connector_name: api_models::enums::Connector,
|
connector_name: api_models::enums::Connector,
|
||||||
val: &types::ConnectorAuthType,
|
val: &types::ConnectorAuthType,
|
||||||
connector_meta_data: &Option<pii::SecretSerdeValue>,
|
connector_meta_data: &Option<pii::SecretSerdeValue>,
|
||||||
@ -2096,6 +2084,84 @@ pub(crate) fn validate_auth_and_metadata_type(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn validate_connector_auth_type(
|
||||||
|
auth_type: &types::ConnectorAuthType,
|
||||||
|
) -> Result<(), error_stack::Report<errors::ApiErrorResponse>> {
|
||||||
|
let validate_non_empty_field = |field_value: &str, field_name: &str| {
|
||||||
|
if field_value.trim().is_empty() {
|
||||||
|
Err(errors::ApiErrorResponse::InvalidDataFormat {
|
||||||
|
field_name: format!("connector_account_details.{}", field_name),
|
||||||
|
expected_format: "a non empty String".to_string(),
|
||||||
|
}
|
||||||
|
.into())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match auth_type {
|
||||||
|
hyperswitch_domain_models::router_data::ConnectorAuthType::TemporaryAuth => Ok(()),
|
||||||
|
hyperswitch_domain_models::router_data::ConnectorAuthType::HeaderKey { api_key } => {
|
||||||
|
validate_non_empty_field(api_key.peek(), "api_key")
|
||||||
|
}
|
||||||
|
hyperswitch_domain_models::router_data::ConnectorAuthType::BodyKey { api_key, key1 } => {
|
||||||
|
validate_non_empty_field(api_key.peek(), "api_key")?;
|
||||||
|
validate_non_empty_field(key1.peek(), "key1")
|
||||||
|
}
|
||||||
|
hyperswitch_domain_models::router_data::ConnectorAuthType::SignatureKey {
|
||||||
|
api_key,
|
||||||
|
key1,
|
||||||
|
api_secret,
|
||||||
|
} => {
|
||||||
|
validate_non_empty_field(api_key.peek(), "api_key")?;
|
||||||
|
validate_non_empty_field(key1.peek(), "key1")?;
|
||||||
|
validate_non_empty_field(api_secret.peek(), "api_secret")
|
||||||
|
}
|
||||||
|
hyperswitch_domain_models::router_data::ConnectorAuthType::MultiAuthKey {
|
||||||
|
api_key,
|
||||||
|
key1,
|
||||||
|
api_secret,
|
||||||
|
key2,
|
||||||
|
} => {
|
||||||
|
validate_non_empty_field(api_key.peek(), "api_key")?;
|
||||||
|
validate_non_empty_field(key1.peek(), "key1")?;
|
||||||
|
validate_non_empty_field(api_secret.peek(), "api_secret")?;
|
||||||
|
validate_non_empty_field(key2.peek(), "key2")
|
||||||
|
}
|
||||||
|
hyperswitch_domain_models::router_data::ConnectorAuthType::CurrencyAuthKey {
|
||||||
|
auth_key_map,
|
||||||
|
} => {
|
||||||
|
if auth_key_map.is_empty() {
|
||||||
|
Err(errors::ApiErrorResponse::InvalidDataFormat {
|
||||||
|
field_name: "connector_account_details.auth_key_map".to_string(),
|
||||||
|
expected_format: "a non empty map".to_string(),
|
||||||
|
}
|
||||||
|
.into())
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hyperswitch_domain_models::router_data::ConnectorAuthType::CertificateAuth {
|
||||||
|
certificate,
|
||||||
|
private_key,
|
||||||
|
} => {
|
||||||
|
helpers::create_identity_from_certificate_and_key(
|
||||||
|
certificate.to_owned(),
|
||||||
|
private_key.to_owned(),
|
||||||
|
)
|
||||||
|
.change_context(errors::ApiErrorResponse::InvalidDataFormat {
|
||||||
|
field_name:
|
||||||
|
"connector_account_details.certificate or connector_account_details.private_key"
|
||||||
|
.to_string(),
|
||||||
|
expected_format:
|
||||||
|
"a valid base64 encoded string of PEM encoded Certificate and Private Key"
|
||||||
|
.to_string(),
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
hyperswitch_domain_models::router_data::ConnectorAuthType::NoKey => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "dummy_connector")]
|
#[cfg(feature = "dummy_connector")]
|
||||||
pub async fn validate_dummy_connector_enabled(
|
pub async fn validate_dummy_connector_enabled(
|
||||||
state: &SessionState,
|
state: &SessionState,
|
||||||
|
|||||||
Reference in New Issue
Block a user