refactor(core): move authentication data fields to authentication table (#4093)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: sai-harsha-vardhan <harsha111hero@gmail.com>
Co-authored-by: Sai Harsha Vardhan <56996463+sai-harsha-vardhan@users.noreply.github.com>
This commit is contained in:
Hrithikesh
2024-03-19 15:10:18 +05:30
committed by GitHub
parent ab1ec2ad4e
commit a3dec0b6bc
29 changed files with 1175 additions and 895 deletions

View File

@ -1,12 +1,9 @@
use common_enums::DecoupledAuthenticationType;
use common_utils::ext_traits::{Encode, ValueExt};
use error_stack::ResultExt;
use super::types::{AuthenticationData, ThreeDsMethodData};
use crate::{
consts,
core::{
errors::{ApiErrorResponse, ConnectorErrorExt, StorageErrorExt},
errors::{self, ConnectorErrorExt, StorageErrorExt},
payments,
},
errors::RouterResult,
@ -14,12 +11,11 @@ use crate::{
services::{self, execute_connector_processing_step},
types::{
api::{self, ConnectorCallType},
authentication::{AuthNFlowType, AuthenticationResponseData},
authentication::AuthenticationResponseData,
storage,
transformers::ForeignFrom,
RouterData,
},
utils::OptionExt,
};
pub fn get_connector_name_if_separate_authn_supported(
@ -56,19 +52,8 @@ pub async fn update_trackers<F: Clone, Req>(
authentication: storage::Authentication,
token: Option<String>,
acquirer_details: Option<super::types::AcquirerDetails>,
) -> RouterResult<(storage::Authentication, Option<AuthenticationData>)> {
let authentication_data_option = authentication
.authentication_data
.as_ref()
.map(|authentication_data| {
authentication_data
.to_owned()
.parse_value::<AuthenticationData>("AuthenticationData")
.change_context(ApiErrorResponse::InternalServerError)
})
.transpose()?;
let (authentication_update, updated_authentication_data) = match router_data.response {
) -> RouterResult<storage::Authentication> {
let authentication_update = match router_data.response {
Ok(response) => match response {
AuthenticationResponseData::PreAuthNResponse {
threeds_server_transaction_id,
@ -78,132 +63,70 @@ pub async fn update_trackers<F: Clone, Req>(
three_ds_method_url,
message_version,
connector_metadata,
} => {
let three_ds_method_data = ThreeDsMethodData {
three_ds_method_data,
three_ds_method_data_submission: three_ds_method_url.is_some(),
three_ds_method_url,
};
let authentication_data = AuthenticationData {
maximum_supported_version: maximum_supported_3ds_version,
threeds_server_transaction_id,
three_ds_method_data,
message_version,
acquirer_details,
..Default::default()
};
(
storage::AuthenticationUpdate::AuthenticationDataUpdate {
authentication_data: Some(
Encode::encode_to_value(&authentication_data)
.change_context(ApiErrorResponse::InternalServerError)?,
),
connector_authentication_id: Some(connector_authentication_id),
payment_method_id: token.map(|token| format!("eph_{}", token)),
authentication_type: None,
authentication_status: Some(common_enums::AuthenticationStatus::Started),
authentication_lifecycle_status: None,
connector_metadata,
},
Some(authentication_data),
)
}
} => storage::AuthenticationUpdate::PreAuthenticationUpdate {
threeds_server_transaction_id,
maximum_supported_3ds_version,
connector_authentication_id,
three_ds_method_data,
three_ds_method_url,
message_version,
connector_metadata,
authentication_status: common_enums::AuthenticationStatus::Pending,
payment_method_id: token.map(|token| format!("eph_{}", token)),
acquirer_bin: acquirer_details
.as_ref()
.map(|acquirer_details| acquirer_details.acquirer_bin.clone()),
acquirer_merchant_id: acquirer_details
.map(|acquirer_details| acquirer_details.acquirer_merchant_id),
},
AuthenticationResponseData::AuthNResponse {
authn_flow_type,
authentication_value: cavv,
authentication_value,
trans_status,
} => {
let authentication_data = authentication_data_option
.get_required_value("authentication_data")
.attach_printable(
"AuthenticationData is required to make Authentication call",
)?;
let authentication_data = AuthenticationData {
authn_flow_type: Some(authn_flow_type.clone()),
cavv,
trans_status: trans_status.clone(),
..authentication_data
};
(
storage::AuthenticationUpdate::AuthenticationDataUpdate {
authentication_data: Some(
Encode::encode_to_value(&authentication_data)
.change_context(ApiErrorResponse::InternalServerError)?,
),
connector_authentication_id: None,
payment_method_id: None,
authentication_type: Some(match authn_flow_type {
AuthNFlowType::Challenge { .. } => {
DecoupledAuthenticationType::Challenge
}
AuthNFlowType::Frictionless => {
DecoupledAuthenticationType::Frictionless
}
}),
authentication_status: Some(
common_enums::AuthenticationStatus::foreign_from(trans_status),
),
authentication_lifecycle_status: None,
connector_metadata: None,
},
Some(authentication_data),
)
let authentication_status =
common_enums::AuthenticationStatus::foreign_from(trans_status.clone());
storage::AuthenticationUpdate::AuthenticationUpdate {
authentication_value,
trans_status,
acs_url: authn_flow_type.get_acs_url(),
challenge_request: authn_flow_type.get_challenge_request(),
acs_reference_number: authn_flow_type.get_acs_reference_number(),
acs_trans_id: authn_flow_type.get_acs_trans_id(),
acs_signed_content: authn_flow_type.get_acs_signed_content(),
authentication_type: authn_flow_type.get_decoupled_authentication_type(),
authentication_status,
}
}
AuthenticationResponseData::PostAuthNResponse {
trans_status,
authentication_value,
eci,
} => {
let authentication_data = authentication_data_option
.get_required_value("authentication_data")
.attach_printable(
"AuthenticationData is required to make Post Authentication call",
)?;
let authentication_data = AuthenticationData {
cavv: authentication_value,
eci,
trans_status: trans_status.clone(),
..authentication_data
};
(
storage::AuthenticationUpdate::AuthenticationDataUpdate {
authentication_data: Some(
Encode::encode_to_value(&authentication_data)
.change_context(ApiErrorResponse::InternalServerError)?,
),
connector_authentication_id: None,
payment_method_id: None,
authentication_type: None,
authentication_status: Some(
common_enums::AuthenticationStatus::foreign_from(trans_status),
),
authentication_lifecycle_status: None,
connector_metadata: None,
},
Some(authentication_data),
)
}
},
Err(error) => (
storage::AuthenticationUpdate::ErrorUpdate {
connector_authentication_id: error.connector_transaction_id,
authentication_status: common_enums::AuthenticationStatus::Failed,
error_message: Some(error.message),
error_code: Some(error.code),
} => storage::AuthenticationUpdate::PostAuthenticationUpdate {
authentication_status: common_enums::AuthenticationStatus::foreign_from(
trans_status.clone(),
),
trans_status,
authentication_value,
eci,
},
authentication_data_option,
),
},
Err(error) => storage::AuthenticationUpdate::ErrorUpdate {
connector_authentication_id: error.connector_transaction_id,
authentication_status: common_enums::AuthenticationStatus::Failed,
error_message: Some(error.message),
error_code: Some(error.code),
},
};
let authentication_result = state
state
.store
.update_authentication_by_merchant_id_authentication_id(
authentication,
authentication_update,
)
.await
.change_context(ApiErrorResponse::InternalServerError)
.attach_printable("Error while updating authentication");
authentication_result.map(|authentication| (authentication, updated_authentication_data))
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Error while updating authentication")
}
impl ForeignFrom<common_enums::AuthenticationStatus> for common_enums::AttemptStatus {
@ -229,7 +152,6 @@ pub async fn create_new_authentication(
merchant_id,
authentication_connector,
connector_authentication_id: None,
authentication_data: None,
payment_method_id: "".into(),
authentication_type: None,
authentication_status: common_enums::AuthenticationStatus::Started,
@ -237,12 +159,29 @@ pub async fn create_new_authentication(
error_message: None,
error_code: None,
connector_metadata: None,
maximum_supported_version: None,
threeds_server_transaction_id: None,
cavv: None,
authentication_flow_type: None,
message_version: None,
eci: None,
trans_status: None,
acquirer_bin: None,
acquirer_merchant_id: None,
three_ds_method_data: None,
three_ds_method_url: None,
acs_url: None,
challenge_request: None,
acs_reference_number: None,
acs_trans_id: None,
three_dsserver_trans_id: None,
acs_signed_content: None,
};
state
.store
.insert_authentication(new_authorization)
.await
.to_duplicate_response(ApiErrorResponse::GenericDuplicateError {
.to_duplicate_response(errors::ApiErrorResponse::GenericDuplicateError {
message: format!(
"Authentication with authentication_id {} already exists",
authentication_id