From e79604bd4681a69802f3c3169dd94424e3688e42 Mon Sep 17 00:00:00 2001 From: Sahkal Poddar Date: Thu, 4 Jan 2024 19:18:56 +0530 Subject: [PATCH 1/5] fix(connector): [iatapay] change refund amount (#3244) Co-authored-by: Samraat Bansal --- crates/router/src/connector/iatapay.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/router/src/connector/iatapay.rs b/crates/router/src/connector/iatapay.rs index fcfdd44e636..0c156ef08b0 100644 --- a/crates/router/src/connector/iatapay.rs +++ b/crates/router/src/connector/iatapay.rs @@ -479,7 +479,7 @@ impl ConnectorIntegration Date: Fri, 5 Jan 2024 07:20:19 +0000 Subject: [PATCH 2/5] chore(version): v1.106.1 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30b7957272c..7f7a2ced4db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,17 @@ All notable changes to HyperSwitch will be documented here. - - - +## 1.106.1 (2024-01-05) + +### Bug Fixes + +- **connector:** [iatapay] change refund amount ([#3244](https://github.com/juspay/hyperswitch/pull/3244)) ([`e79604b`](https://github.com/juspay/hyperswitch/commit/e79604bd4681a69802f3c3169dd94424e3688e42)) + +**Full Changelog:** [`v1.106.0...v1.106.1`](https://github.com/juspay/hyperswitch/compare/v1.106.0...v1.106.1) + +- - - + + ## 1.106.0 (2024-01-04) ### Features From 3ab71fbd5ac86f12cf19d17561e428d33c51a4cf Mon Sep 17 00:00:00 2001 From: Apoorv Dixit <64925866+apoorvdixit88@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:10:26 +0530 Subject: [PATCH 3/5] fix(user): add integration_completed enum in metadata type (#3245) --- .../router/src/utils/user/dashboard_metadata.rs | 15 +++------------ .../down.sql | 2 ++ .../up.sql | 2 ++ 3 files changed, 7 insertions(+), 12 deletions(-) create mode 100644 migrations/2024-01-04-121733_add_dashboard_metadata_key_integration_completed/down.sql create mode 100644 migrations/2024-01-04-121733_add_dashboard_metadata_key_integration_completed/up.sql diff --git a/crates/router/src/utils/user/dashboard_metadata.rs b/crates/router/src/utils/user/dashboard_metadata.rs index 40594a6e49f..09fb5ccd24b 100644 --- a/crates/router/src/utils/user/dashboard_metadata.rs +++ b/crates/router/src/utils/user/dashboard_metadata.rs @@ -91,21 +91,12 @@ pub async fn get_merchant_scoped_metadata_from_db( org_id: String, metadata_keys: Vec, ) -> UserResult> { - match state + state .store .find_merchant_scoped_dashboard_metadata(&merchant_id, &org_id, metadata_keys) .await - { - Ok(data) => Ok(data), - Err(e) => { - if e.current_context().is_db_not_found() { - return Ok(Vec::with_capacity(0)); - } - Err(e - .change_context(UserErrors::InternalServerError) - .attach_printable("DB Error Fetching DashboardMetaData")) - } - } + .change_context(UserErrors::InternalServerError) + .attach_printable("DB Error Fetching DashboardMetaData") } pub async fn get_user_scoped_metadata_from_db( state: &AppState, diff --git a/migrations/2024-01-04-121733_add_dashboard_metadata_key_integration_completed/down.sql b/migrations/2024-01-04-121733_add_dashboard_metadata_key_integration_completed/down.sql new file mode 100644 index 00000000000..c7c9cbeb401 --- /dev/null +++ b/migrations/2024-01-04-121733_add_dashboard_metadata_key_integration_completed/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +SELECT 1; \ No newline at end of file diff --git a/migrations/2024-01-04-121733_add_dashboard_metadata_key_integration_completed/up.sql b/migrations/2024-01-04-121733_add_dashboard_metadata_key_integration_completed/up.sql new file mode 100644 index 00000000000..bb703fde397 --- /dev/null +++ b/migrations/2024-01-04-121733_add_dashboard_metadata_key_integration_completed/up.sql @@ -0,0 +1,2 @@ +-- Your SQL goes here +ALTER TYPE "DashboardMetadata" ADD VALUE IF NOT EXISTS 'integration_completed'; \ No newline at end of file From 000e64438838461ea930545405fb2ee0d3c4356c Mon Sep 17 00:00:00 2001 From: Mani Chandra <84711804+ThisIsMani@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:36:25 +0530 Subject: [PATCH 4/5] fix(users): Fix wrong redirection url in magic link (#3217) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- crates/router/src/services/email/types.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/router/src/services/email/types.rs b/crates/router/src/services/email/types.rs index 9e26c45ba6b..d5c28b1fd6a 100644 --- a/crates/router/src/services/email/types.rs +++ b/crates/router/src/services/email/types.rs @@ -77,7 +77,7 @@ pub fn get_link_with_token( token: impl std::fmt::Display, action: impl std::fmt::Display, ) -> String { - format!("{base_url}/user/{action}/?token={token}") + format!("{base_url}/user/{action}?token={token}") } pub struct VerifyEmail { @@ -153,7 +153,8 @@ impl EmailData for MagicLink { .await .change_context(EmailError::TokenGenerationFailure)?; - let magic_link_login = get_link_with_token(&self.settings.email.base_url, token, "login"); + let magic_link_login = + get_link_with_token(&self.settings.email.base_url, token, "verify_email"); let body = html::get_html_body(EmailBody::MagicLink { link: magic_link_login, From 34318bc1f12a1298e8993021a2d516cf86049980 Mon Sep 17 00:00:00 2001 From: Shankar Singh C <83439957+ShankarSinghC@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:47:37 +0530 Subject: [PATCH 5/5] refactor: address panics due to indexing and slicing (#3233) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- .cargo/config.toml | 11 +- Cargo.lock | 1 + crates/api_models/src/admin.rs | 16 ++- crates/cards/Cargo.toml | 1 + crates/cards/src/validate.rs | 8 +- crates/common_utils/src/crypto.rs | 5 +- crates/common_utils/src/pii.rs | 53 ++++++--- crates/connector_configs/Cargo.toml | 2 +- .../src/response_modifier.rs | 48 ++++---- crates/euclid/src/dssa/state_machine.rs | 8 +- crates/euclid/src/frontend/dir.rs | 5 +- crates/euclid_macros/src/inner/knowledge.rs | 5 +- .../router/src/connector/authorizedotnet.rs | 7 +- .../connector/authorizedotnet/transformers.rs | 25 ++-- .../src/connector/globalpay/transformers.rs | 2 +- .../src/connector/helcim/transformers.rs | 6 +- .../src/connector/mollie/transformers.rs | 2 +- .../connector/multisafepay/transformers.rs | 2 +- .../src/connector/nexinets/transformers.rs | 14 ++- .../router/src/connector/nmi/transformers.rs | 13 ++- .../src/connector/payeezy/transformers.rs | 2 +- .../src/connector/payme/transformers.rs | 4 +- .../src/connector/placetopay/transformers.rs | 2 +- .../src/connector/powertranz/transformers.rs | 2 +- .../src/connector/prophetpay/transformers.rs | 17 ++- .../router/src/connector/stax/transformers.rs | 2 +- .../src/connector/stripe/transformers.rs | 11 +- .../src/connector/trustpay/transformers.rs | 2 +- .../router/src/connector/tsys/transformers.rs | 2 +- crates/router/src/connector/utils.rs | 28 +++-- .../src/connector/worldline/transformers.rs | 4 +- .../router/src/connector/zen/transformers.rs | 28 ++--- crates/router/src/core/payments/helpers.rs | 8 +- crates/router/src/services/encryption.rs | 109 +----------------- crates/router/src/workflows/payment_sync.rs | 5 +- crates/router/tests/integration_demo.rs | 2 +- crates/router/tests/refunds.rs | 4 +- crates/router_env/src/logger/storage.rs | 15 ++- .../test_utils/tests/connectors/selenium.rs | 16 ++- 39 files changed, 244 insertions(+), 253 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 3082e9635cf..5b27955262a 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -3,9 +3,13 @@ rustflags = [ "-Funsafe_code", "-Wclippy::as_conversions", "-Wclippy::expect_used", + "-Wclippy::index_refutable_slice", + "-Wclippy::indexing_slicing", + "-Wclippy::match_on_vec_items", "-Wclippy::missing_panics_doc", - "-Wclippy::panic_in_result_fn", + "-Wclippy::out_of_bounds_indexing", "-Wclippy::panic", + "-Wclippy::panic_in_result_fn", "-Wclippy::panicking_unwrap", "-Wclippy::todo", "-Wclippy::unimplemented", @@ -23,10 +27,7 @@ rustflags = [ [build] -rustdocflags = [ - "--cfg", - "uuid_unstable" -] +rustdocflags = ["--cfg", "uuid_unstable"] [alias] gen-pg = "generate --path ../../../../connector-template -n" diff --git a/Cargo.lock b/Cargo.lock index be1e0c8a2a4..cd5960a68c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1425,6 +1425,7 @@ dependencies = [ "error-stack", "luhn", "masking", + "router_env", "serde", "serde_json", "thiserror", diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index d35b12152e9..ed49b6f27b5 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -359,7 +359,7 @@ pub mod payout_routing_algorithm { where A: de::MapAccess<'de>, { - let mut output = serde_json::Value::Object(Map::new()); + let mut output = Map::new(); let mut routing_data: String = "".to_string(); let mut routing_type: String = "".to_string(); @@ -367,14 +367,20 @@ pub mod payout_routing_algorithm { match key { "type" => { routing_type = map.next_value()?; - output["type"] = serde_json::Value::String(routing_type.to_owned()); + output.insert( + "type".to_string(), + serde_json::Value::String(routing_type.to_owned()), + ); } "data" => { routing_data = map.next_value()?; - output["data"] = serde_json::Value::String(routing_data.to_owned()); + output.insert( + "data".to_string(), + serde_json::Value::String(routing_data.to_owned()), + ); } f => { - output[f] = map.next_value()?; + output.insert(f.to_string(), map.next_value()?); } } } @@ -392,7 +398,7 @@ pub mod payout_routing_algorithm { } u => Err(de::Error::custom(format!("Unknown routing algorithm {u}"))), }?; - Ok(output) + Ok(serde_json::Value::Object(output)) } } diff --git a/crates/cards/Cargo.toml b/crates/cards/Cargo.toml index ae72a3d43ac..cf3e25459c6 100644 --- a/crates/cards/Cargo.toml +++ b/crates/cards/Cargo.toml @@ -19,6 +19,7 @@ time = "0.3.21" # First party crates common_utils = { version = "0.1.0", path = "../common_utils" } masking = { version = "0.1.0", path = "../masking" } +router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] } [dev-dependencies] serde_json = "1.0.108" diff --git a/crates/cards/src/validate.rs b/crates/cards/src/validate.rs index d083a420a1e..001eab3004d 100644 --- a/crates/cards/src/validate.rs +++ b/crates/cards/src/validate.rs @@ -1,6 +1,7 @@ use std::{fmt, ops::Deref, str::FromStr}; use masking::{PeekInterface, Strategy, StrongSecret, WithType}; +use router_env::logger; use serde::{Deserialize, Deserializer, Serialize}; use thiserror::Error; @@ -85,7 +86,12 @@ where return WithType::fmt(val, f); } - write!(f, "{}{}", &val_str[..6], "*".repeat(val_str.len() - 6)) + if let Some(value) = val_str.get(..6) { + write!(f, "{}{}", value, "*".repeat(val_str.len() - 6)) + } else { + logger::error!("Invalid card number {val_str}"); + WithType::fmt(val, f) + } } } diff --git a/crates/common_utils/src/crypto.rs b/crates/common_utils/src/crypto.rs index a0f365dd40d..c2c83a3589e 100644 --- a/crates/common_utils/src/crypto.rs +++ b/crates/common_utils/src/crypto.rs @@ -279,7 +279,10 @@ impl DecodeMessage for GcmAes256 { .change_context(errors::CryptoError::DecodingFailed)?; let nonce_sequence = NonceSequence::from_bytes( - msg[..ring::aead::NONCE_LEN] + msg.get(..ring::aead::NONCE_LEN) + .ok_or(errors::CryptoError::DecodingFailed) + .into_report() + .attach_printable("Failed to read the nonce form the encrypted ciphertext")? .try_into() .into_report() .change_context(errors::CryptoError::DecodingFailed)?, diff --git a/crates/common_utils/src/pii.rs b/crates/common_utils/src/pii.rs index 39793de5c2b..1889a5f3aee 100644 --- a/crates/common_utils/src/pii.rs +++ b/crates/common_utils/src/pii.rs @@ -12,6 +12,8 @@ use diesel::{ }; use error_stack::{IntoReport, ResultExt}; use masking::{ExposeInterface, Secret, Strategy, WithType}; +#[cfg(feature = "logs")] +use router_env::logger; use crate::{ crypto::Encryptable, @@ -41,13 +43,14 @@ where fn fmt(val: &T, f: &mut fmt::Formatter<'_>) -> fmt::Result { let val_str: &str = val.as_ref(); - // masks everything but the last 4 digits - write!( - f, - "{}{}", - "*".repeat(val_str.len() - 4), - &val_str[val_str.len() - 4..] - ) + if let Some(val_str) = val_str.get(val_str.len() - 4..) { + // masks everything but the last 4 digits + write!(f, "{}{}", "*".repeat(val_str.len() - 4), val_str) + } else { + #[cfg(feature = "logs")] + logger::error!("Invalid phone number: {val_str}"); + WithType::fmt(val, f) + } } } @@ -174,16 +177,26 @@ where { return WithType::fmt(val, f); } - write!( - f, - "{}_{}_{}", - client_secret_segments[0], - client_secret_segments[1], - "*".repeat( - val_str.len() - - (client_secret_segments[0].len() + client_secret_segments[1].len() + 2) + + if let Some((client_secret_segments_0, client_secret_segments_1)) = client_secret_segments + .first() + .zip(client_secret_segments.get(1)) + { + write!( + f, + "{}_{}_{}", + client_secret_segments_0, + client_secret_segments_1, + "*".repeat( + val_str.len() + - (client_secret_segments_0.len() + client_secret_segments_1.len() + 2) + ) ) - ) + } else { + #[cfg(feature = "logs")] + logger::error!("Invalid client secret: {val_str}"); + WithType::fmt(val, f) + } } } @@ -325,7 +338,13 @@ where } } - write!(f, "{}.**.**.**", segments[0]) + if let Some(segments) = segments.first() { + write!(f, "{}.**.**.**", segments) + } else { + #[cfg(feature = "logs")] + logger::error!("Invalid IP address: {val_str}"); + WithType::fmt(val, f) + } } } diff --git a/crates/connector_configs/Cargo.toml b/crates/connector_configs/Cargo.toml index f4df1e6a20b..083a741ef50 100644 --- a/crates/connector_configs/Cargo.toml +++ b/crates/connector_configs/Cargo.toml @@ -19,4 +19,4 @@ api_models = { version = "0.1.0", path = "../api_models", package = "api_models" serde = { version = "1.0.193", features = ["derive"] } serde_with = "3.4.0" toml = "0.7.3" -utoipa = { version = "3.3.0", features = ["preserve_order"] } +utoipa = { version = "3.3.0", features = ["preserve_order"] } \ No newline at end of file diff --git a/crates/connector_configs/src/response_modifier.rs b/crates/connector_configs/src/response_modifier.rs index 0eb447ace1a..6a09c58a75c 100644 --- a/crates/connector_configs/src/response_modifier.rs +++ b/crates/connector_configs/src/response_modifier.rs @@ -279,34 +279,28 @@ impl ConnectorApiIntegrationPayload { pub fn get_google_pay_metadata_response(response: Self) -> Option { match response.metadata { - Some(meta_data) => match meta_data.google_pay { - Some(google_pay) => match google_pay { - GoogleApiModelData::Standard(standard_data) => { - if standard_data.allowed_payment_methods.is_empty() { - None - } else { - let data = Some( - standard_data.allowed_payment_methods[0] - .tokenization_specification - .parameters - .clone(), - ); - match data { - Some(data) => Some(GooglePayData::Standard(GpayDashboardPayLoad { - gateway_merchant_id: data.gateway_merchant_id, - stripe_version: data.stripe_version, - stripe_publishable_key: data.stripe_publishable_key, - merchant_name: standard_data.merchant_info.merchant_name, - merchant_id: standard_data.merchant_info.merchant_id, - })), - None => None, - } + Some(meta_data) => { + match meta_data.google_pay { + Some(google_pay) => match google_pay { + GoogleApiModelData::Standard(standard_data) => { + let data = standard_data.allowed_payment_methods.first().map( + |allowed_pm| { + allowed_pm.tokenization_specification.parameters.clone() + }, + )?; + Some(GooglePayData::Standard(GpayDashboardPayLoad { + gateway_merchant_id: data.gateway_merchant_id, + stripe_version: data.stripe_version, + stripe_publishable_key: data.stripe_publishable_key, + merchant_name: standard_data.merchant_info.merchant_name, + merchant_id: standard_data.merchant_info.merchant_id, + })) } - } - GoogleApiModelData::Zen(data) => Some(GooglePayData::Zen(data)), - }, - None => None, - }, + GoogleApiModelData::Zen(data) => Some(GooglePayData::Zen(data)), + }, + None => None, + } + } None => None, } } diff --git a/crates/euclid/src/dssa/state_machine.rs b/crates/euclid/src/dssa/state_machine.rs index 4cd53911dfe..93d394eece9 100644 --- a/crates/euclid/src/dssa/state_machine.rs +++ b/crates/euclid/src/dssa/state_machine.rs @@ -678,7 +678,9 @@ mod tests { .collect::>(); assert_eq!( values, - expected_contexts[expected_idx] + expected_contexts + .get(expected_idx) + .expect("Error deriving contexts") .iter() .collect::>() ); @@ -702,7 +704,9 @@ mod tests { .collect::>(); assert_eq!( values, - expected_contexts[expected_idx] + expected_contexts + .get(expected_idx) + .expect("Error deriving contexts") .iter() .collect::>() ); diff --git a/crates/euclid/src/frontend/dir.rs b/crates/euclid/src/frontend/dir.rs index f8cef1f9295..dc81359c51d 100644 --- a/crates/euclid/src/frontend/dir.rs +++ b/crates/euclid/src/frontend/dir.rs @@ -722,7 +722,10 @@ mod test { }; let display_str = key.to_string(); - assert_eq!(&json_str[1..json_str.len() - 1], display_str); + assert_eq!( + json_str.get(1..json_str.len() - 1).expect("Value metadata"), + display_str + ); key_names.insert(key, display_str); } diff --git a/crates/euclid_macros/src/inner/knowledge.rs b/crates/euclid_macros/src/inner/knowledge.rs index 73b94919c90..9f33a6871c5 100644 --- a/crates/euclid_macros/src/inner/knowledge.rs +++ b/crates/euclid_macros/src/inner/knowledge.rs @@ -417,7 +417,10 @@ impl GenContext { .position(|v| *v == node_id) .ok_or_else(|| "Error deciding cycle order".to_string())?; - let cycle_order = order[position..].to_vec(); + let cycle_order = order + .get(position..) + .ok_or_else(|| "Error getting cycle order".to_string())? + .to_vec(); Ok(Some(cycle_order)) } else if visited.contains(&node_id) { Ok(None) diff --git a/crates/router/src/connector/authorizedotnet.rs b/crates/router/src/connector/authorizedotnet.rs index 9c8d2f47024..0686ee6a3b8 100644 --- a/crates/router/src/connector/authorizedotnet.rs +++ b/crates/router/src/connector/authorizedotnet.rs @@ -903,7 +903,12 @@ fn get_error_response( })), Some(authorizedotnet::TransactionResponse::AuthorizedotnetTransactionResponseError(_)) | None => { - let message = &response.messages.message[0].text; + let message = &response + .messages + .message + .first() + .ok_or(errors::ConnectorError::ResponseDeserializationFailed)? + .text; Ok(types::ErrorResponse { code: consts::NO_ERROR_CODE.to_string(), message: message.to_string(), diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs index 30323ca4ef2..96cf3b6ffc5 100644 --- a/crates/router/src/connector/authorizedotnet/transformers.rs +++ b/crates/router/src/connector/authorizedotnet/transformers.rs @@ -619,7 +619,7 @@ impl Some(TransactionResponse::AuthorizedotnetTransactionResponseError(_)) | None => { Ok(Self { status: enums::AttemptStatus::Failure, - response: Err(get_err_response(item.http_code, item.response.messages)), + response: Err(get_err_response(item.http_code, item.response.messages)?), ..item.data }) } @@ -689,7 +689,7 @@ impl } None => Ok(Self { status: enums::AttemptStatus::Failure, - response: Err(get_err_response(item.http_code, item.response.messages)), + response: Err(get_err_response(item.http_code, item.response.messages)?), ..item.data }), } @@ -944,7 +944,7 @@ impl TryFrom Ok(Self { - response: Err(get_err_response(item.http_code, item.response.messages)), + response: Err(get_err_response(item.http_code, item.response.messages)?), ..item.data }), } @@ -986,7 +986,7 @@ impl }) } None => Ok(Self { - response: Err(get_err_response(item.http_code, item.response.messages)), + response: Err(get_err_response(item.http_code, item.response.messages)?), ..item.data }), } @@ -1024,15 +1024,22 @@ impl From> for TransactionType { } } -fn get_err_response(status_code: u16, message: ResponseMessages) -> types::ErrorResponse { - types::ErrorResponse { - code: message.message[0].code.clone(), - message: message.message[0].text.clone(), +fn get_err_response( + status_code: u16, + message: ResponseMessages, +) -> Result { + let response_message = message + .message + .first() + .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?; + Ok(types::ErrorResponse { + code: response_message.code.clone(), + message: response_message.text.clone(), reason: None, status_code, attempt_status: None, connector_transaction_id: None, - } + }) } #[derive(Debug, Deserialize)] diff --git a/crates/router/src/connector/globalpay/transformers.rs b/crates/router/src/connector/globalpay/transformers.rs index 9cef564b379..3124501bd6e 100644 --- a/crates/router/src/connector/globalpay/transformers.rs +++ b/crates/router/src/connector/globalpay/transformers.rs @@ -385,7 +385,7 @@ fn get_payment_method_data( api::PaymentMethodData::Card(ccard) => Ok(PaymentMethodData::Card(requests::Card { number: ccard.card_number.clone(), expiry_month: ccard.card_exp_month.clone(), - expiry_year: ccard.get_card_expiry_year_2_digit(), + expiry_year: ccard.get_card_expiry_year_2_digit()?, cvv: ccard.card_cvc.clone(), account_type: None, authcode: None, diff --git a/crates/router/src/connector/helcim/transformers.rs b/crates/router/src/connector/helcim/transformers.rs index 823096d6648..599054163c3 100644 --- a/crates/router/src/connector/helcim/transformers.rs +++ b/crates/router/src/connector/helcim/transformers.rs @@ -126,7 +126,8 @@ impl TryFrom<(&types::SetupMandateRouterData, &api::Card)> for HelcimVerifyReque fn try_from(value: (&types::SetupMandateRouterData, &api::Card)) -> Result { let (item, req_card) = value; let card_data = HelcimCard { - card_expiry: req_card.get_card_expiry_month_year_2_digit_with_delimiter("".to_string()), + card_expiry: req_card + .get_card_expiry_month_year_2_digit_with_delimiter("".to_string())?, card_number: req_card.card_number.clone(), card_c_v_v: req_card.card_cvc.clone(), }; @@ -196,7 +197,8 @@ impl ) -> Result { let (item, req_card) = value; let card_data = HelcimCard { - card_expiry: req_card.get_card_expiry_month_year_2_digit_with_delimiter("".to_string()), + card_expiry: req_card + .get_card_expiry_month_year_2_digit_with_delimiter("".to_string())?, card_number: req_card.card_number.clone(), card_c_v_v: req_card.card_cvc.clone(), }; diff --git a/crates/router/src/connector/mollie/transformers.rs b/crates/router/src/connector/mollie/transformers.rs index 5960e9cdb8d..0fcb14d2cf5 100644 --- a/crates/router/src/connector/mollie/transformers.rs +++ b/crates/router/src/connector/mollie/transformers.rs @@ -292,7 +292,7 @@ impl TryFrom<&types::TokenizationRouterData> for MollieCardTokenRequest { .unwrap_or(Secret::new("".to_string())); let card_number = ccard.card_number.clone(); let card_expiry_date = - ccard.get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned()); + ccard.get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned())?; let card_cvv = ccard.card_cvc; let locale = item.request.get_browser_info()?.get_language()?; let testmode = diff --git a/crates/router/src/connector/multisafepay/transformers.rs b/crates/router/src/connector/multisafepay/transformers.rs index 0a034724a62..86096ed508b 100644 --- a/crates/router/src/connector/multisafepay/transformers.rs +++ b/crates/router/src/connector/multisafepay/transformers.rs @@ -426,7 +426,7 @@ impl TryFrom<&MultisafepayRouterData<&types::PaymentsAuthorizeRouterData>> card_expiry_date: Some( (format!( "{}{}", - ccard.get_card_expiry_year_2_digit().expose(), + ccard.get_card_expiry_year_2_digit()?.expose(), ccard.card_exp_month.clone().expose() )) .parse::() diff --git a/crates/router/src/connector/nexinets/transformers.rs b/crates/router/src/connector/nexinets/transformers.rs index 8875abdb786..698b2709a62 100644 --- a/crates/router/src/connector/nexinets/transformers.rs +++ b/crates/router/src/connector/nexinets/transformers.rs @@ -643,7 +643,7 @@ fn get_card_data( Some(true) => CardDataDetails::PaymentInstrument(Box::new(PaymentInstrument { payment_instrument_id: item.request.connector_mandate_id(), })), - _ => CardDataDetails::CardDetails(Box::new(get_card_details(card))), + _ => CardDataDetails::CardDetails(Box::new(get_card_details(card)?)), }; let cof_contract = Some(CofContract { recurring_type: RecurringType::Unscheduled, @@ -651,7 +651,7 @@ fn get_card_data( (card_data, cof_contract) } false => ( - CardDataDetails::CardDetails(Box::new(get_card_details(card))), + CardDataDetails::CardDetails(Box::new(get_card_details(card)?)), None, ), }; @@ -677,13 +677,15 @@ fn get_applepay_details( }) } -fn get_card_details(req_card: &api_models::payments::Card) -> CardDetails { - CardDetails { +fn get_card_details( + req_card: &api_models::payments::Card, +) -> Result { + Ok(CardDetails { card_number: req_card.card_number.clone(), expiry_month: req_card.card_exp_month.clone(), - expiry_year: req_card.get_card_expiry_year_2_digit(), + expiry_year: req_card.get_card_expiry_year_2_digit()?, verification: req_card.card_cvc.clone(), - } + }) } fn get_wallet_details( diff --git a/crates/router/src/connector/nmi/transformers.rs b/crates/router/src/connector/nmi/transformers.rs index 931dac5a966..b9ad5b8e188 100644 --- a/crates/router/src/connector/nmi/transformers.rs +++ b/crates/router/src/connector/nmi/transformers.rs @@ -127,7 +127,7 @@ fn get_card_details( utils::CardData::get_card_expiry_month_year_2_digit_with_delimiter( card_details, "".to_string(), - ), + )?, card_details.card_cvc.clone(), )), _ => Err(errors::ConnectorError::NotImplemented( @@ -459,7 +459,7 @@ impl TryFrom<&api_models::payments::PaymentMethodData> for PaymentMethod { payment_method_data: &api_models::payments::PaymentMethodData, ) -> Result { match &payment_method_data { - api::PaymentMethodData::Card(ref card) => Ok(Self::from(card)), + api::PaymentMethodData::Card(ref card) => Ok(Self::try_from(card)?), api::PaymentMethodData::Wallet(ref wallet_type) => match wallet_type { api_models::payments::WalletData::GooglePay(ref googlepay_data) => { Ok(Self::from(googlepay_data)) @@ -518,18 +518,19 @@ impl TryFrom<&api_models::payments::PaymentMethodData> for PaymentMethod { } } -impl From<&api_models::payments::Card> for PaymentMethod { - fn from(card: &api_models::payments::Card) -> Self { +impl TryFrom<&api_models::payments::Card> for PaymentMethod { + type Error = Error; + fn try_from(card: &api_models::payments::Card) -> Result { let ccexp = utils::CardData::get_card_expiry_month_year_2_digit_with_delimiter( card, "".to_string(), - ); + )?; let card = CardData { ccnumber: card.card_number.clone(), ccexp, cvv: card.card_cvc.clone(), }; - Self::Card(Box::new(card)) + Ok(Self::Card(Box::new(card))) } } diff --git a/crates/router/src/connector/payeezy/transformers.rs b/crates/router/src/connector/payeezy/transformers.rs index 7ae7feba68a..c633fd3d99f 100644 --- a/crates/router/src/connector/payeezy/transformers.rs +++ b/crates/router/src/connector/payeezy/transformers.rs @@ -246,7 +246,7 @@ fn get_payment_method_data( .clone() .unwrap_or(Secret::new("".to_string())), card_number: card.card_number.clone(), - exp_date: card.get_card_expiry_month_year_2_digit_with_delimiter("".to_string()), + exp_date: card.get_card_expiry_month_year_2_digit_with_delimiter("".to_string())?, cvv: card.card_cvc.clone(), }; Ok(PayeezyPaymentMethod::PayeezyCard(payeezy_card)) diff --git a/crates/router/src/connector/payme/transformers.rs b/crates/router/src/connector/payme/transformers.rs index a865b8fec3a..a7b21ce292d 100644 --- a/crates/router/src/connector/payme/transformers.rs +++ b/crates/router/src/connector/payme/transformers.rs @@ -648,7 +648,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PayRequest { let card = PaymeCard { credit_card_cvv: req_card.card_cvc.clone(), credit_card_exp: req_card - .get_card_expiry_month_year_2_digit_with_delimiter("".to_string()), + .get_card_expiry_month_year_2_digit_with_delimiter("".to_string())?, credit_card_number: req_card.card_number, }; let buyer_email = item.request.get_email()?; @@ -755,7 +755,7 @@ impl TryFrom<&types::TokenizationRouterData> for CaptureBuyerRequest { let card = PaymeCard { credit_card_cvv: req_card.card_cvc.clone(), credit_card_exp: req_card - .get_card_expiry_month_year_2_digit_with_delimiter("".to_string()), + .get_card_expiry_month_year_2_digit_with_delimiter("".to_string())?, credit_card_number: req_card.card_number, }; Ok(Self { diff --git a/crates/router/src/connector/placetopay/transformers.rs b/crates/router/src/connector/placetopay/transformers.rs index 7fef8b8954b..dfdd3f904df 100644 --- a/crates/router/src/connector/placetopay/transformers.rs +++ b/crates/router/src/connector/placetopay/transformers.rs @@ -131,7 +131,7 @@ impl TryFrom<&PlacetopayRouterData<&types::PaymentsAuthorizeRouterData>> number: req_card.card_number.clone(), expiration: req_card .clone() - .get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned()), + .get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned())?, cvv: req_card.card_cvc.clone(), }; Ok(Self { diff --git a/crates/router/src/connector/powertranz/transformers.rs b/crates/router/src/connector/powertranz/transformers.rs index 00549633200..8dc3688da9e 100644 --- a/crates/router/src/connector/powertranz/transformers.rs +++ b/crates/router/src/connector/powertranz/transformers.rs @@ -220,7 +220,7 @@ impl TryFrom<&Card> for Source { .clone() .unwrap_or(Secret::new("".to_string())), card_pan: card.card_number.clone(), - card_expiration: card.get_expiry_date_as_yymm(), + card_expiration: card.get_expiry_date_as_yymm()?, card_cvv: card.card_cvc.clone(), }; Ok(Self::Card(card)) diff --git a/crates/router/src/connector/prophetpay/transformers.rs b/crates/router/src/connector/prophetpay/transformers.rs index d05f2c3986a..23cffa3da22 100644 --- a/crates/router/src/connector/prophetpay/transformers.rs +++ b/crates/router/src/connector/prophetpay/transformers.rs @@ -293,10 +293,19 @@ fn get_card_token( let values = param.peek().split('&').collect::>(); for value in values { let pair = value.split('=').collect::>(); - queries.insert(pair[0].to_string(), pair[1].to_string()); + queries.insert( + pair.first() + .ok_or(errors::ConnectorError::ResponseDeserializationFailed)? + .to_string(), + pair.get(1) + .ok_or(errors::ConnectorError::ResponseDeserializationFailed)? + .to_string(), + ); } - queries + Ok(queries) }) + .transpose() + .into_report()? .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?; for (key, val) in queries_params { @@ -307,8 +316,8 @@ fn get_card_token( Err(errors::ConnectorError::MissingRequiredField { field_name: "card_token", - }) - .into_report() + } + .into()) } #[derive(Debug, Clone, Serialize)] diff --git a/crates/router/src/connector/stax/transformers.rs b/crates/router/src/connector/stax/transformers.rs index 081be000cf6..01ae751f748 100644 --- a/crates/router/src/connector/stax/transformers.rs +++ b/crates/router/src/connector/stax/transformers.rs @@ -225,7 +225,7 @@ impl TryFrom<&types::TokenizationRouterData> for StaxTokenRequest { api::PaymentMethodData::Card(card_data) => { let stax_card_data = StaxTokenizeData { card_exp: card_data - .get_card_expiry_month_year_2_digit_with_delimiter("".to_string()), + .get_card_expiry_month_year_2_digit_with_delimiter("".to_string())?, person_name: card_data .card_holder_name .unwrap_or(Secret::new("".to_string())), diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index 3a28f777907..b044331379a 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -3649,7 +3649,10 @@ mod test_validate_shipping_address_against_payment_method { assert!(result.is_err()); let missing_fields = get_missing_fields(result.unwrap_err().current_context()).to_owned(); assert_eq!(missing_fields.len(), 1); - assert_eq!(missing_fields[0], "shipping.address.first_name"); + assert_eq!( + *missing_fields.first().unwrap(), + "shipping.address.first_name" + ); } #[test] @@ -3674,7 +3677,7 @@ mod test_validate_shipping_address_against_payment_method { assert!(result.is_err()); let missing_fields = get_missing_fields(result.unwrap_err().current_context()).to_owned(); assert_eq!(missing_fields.len(), 1); - assert_eq!(missing_fields[0], "shipping.address.line1"); + assert_eq!(*missing_fields.first().unwrap(), "shipping.address.line1"); } #[test] @@ -3699,7 +3702,7 @@ mod test_validate_shipping_address_against_payment_method { assert!(result.is_err()); let missing_fields = get_missing_fields(result.unwrap_err().current_context()).to_owned(); assert_eq!(missing_fields.len(), 1); - assert_eq!(missing_fields[0], "shipping.address.country"); + assert_eq!(*missing_fields.first().unwrap(), "shipping.address.country"); } #[test] @@ -3723,7 +3726,7 @@ mod test_validate_shipping_address_against_payment_method { assert!(result.is_err()); let missing_fields = get_missing_fields(result.unwrap_err().current_context()).to_owned(); assert_eq!(missing_fields.len(), 1); - assert_eq!(missing_fields[0], "shipping.address.zip"); + assert_eq!(*missing_fields.first().unwrap(), "shipping.address.zip"); } #[test] diff --git a/crates/router/src/connector/trustpay/transformers.rs b/crates/router/src/connector/trustpay/transformers.rs index 8ae12622fb0..87d98c1b1be 100644 --- a/crates/router/src/connector/trustpay/transformers.rs +++ b/crates/router/src/connector/trustpay/transformers.rs @@ -297,7 +297,7 @@ fn get_card_request_data( currency: item.request.currency.to_string(), pan: ccard.card_number.clone(), cvv: ccard.card_cvc.clone(), - expiry_date: ccard.get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned()), + expiry_date: ccard.get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned())?, cardholder: get_full_name(params.billing_first_name, billing_last_name), reference: item.connector_request_reference_id.clone(), redirect_url: return_url, diff --git a/crates/router/src/connector/tsys/transformers.rs b/crates/router/src/connector/tsys/transformers.rs index 8c9c6cd43df..dd700d11bcb 100644 --- a/crates/router/src/connector/tsys/transformers.rs +++ b/crates/router/src/connector/tsys/transformers.rs @@ -52,7 +52,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for TsysPaymentsRequest { currency_code: item.request.currency, card_number: ccard.card_number.clone(), expiration_date: ccard - .get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned()), + .get_card_expiry_month_year_2_digit_with_delimiter("/".to_owned())?, cvv2: ccard.card_cvc, terminal_capability: "ICC_CHIP_READ_ONLY".to_string(), terminal_operating_environment: "ON_MERCHANT_PREMISES_ATTENDED".to_string(), diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 9a538a7207e..24def625372 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -757,23 +757,27 @@ pub enum CardIssuer { } pub trait CardData { - fn get_card_expiry_year_2_digit(&self) -> Secret; + fn get_card_expiry_year_2_digit(&self) -> Result, errors::ConnectorError>; fn get_card_issuer(&self) -> Result; fn get_card_expiry_month_year_2_digit_with_delimiter( &self, delimiter: String, - ) -> Secret; + ) -> Result, errors::ConnectorError>; fn get_expiry_date_as_yyyymm(&self, delimiter: &str) -> Secret; fn get_expiry_date_as_mmyyyy(&self, delimiter: &str) -> Secret; fn get_expiry_year_4_digit(&self) -> Secret; - fn get_expiry_date_as_yymm(&self) -> Secret; + fn get_expiry_date_as_yymm(&self) -> Result, errors::ConnectorError>; } impl CardData for api::Card { - fn get_card_expiry_year_2_digit(&self) -> Secret { + fn get_card_expiry_year_2_digit(&self) -> Result, errors::ConnectorError> { let binding = self.card_exp_year.clone(); let year = binding.peek(); - Secret::new(year[year.len() - 2..].to_string()) + Ok(Secret::new( + year.get(year.len() - 2..) + .ok_or(errors::ConnectorError::RequestEncodingFailed)? + .to_string(), + )) } fn get_card_issuer(&self) -> Result { get_card_issuer(self.card_number.peek()) @@ -781,14 +785,14 @@ impl CardData for api::Card { fn get_card_expiry_month_year_2_digit_with_delimiter( &self, delimiter: String, - ) -> Secret { - let year = self.get_card_expiry_year_2_digit(); - Secret::new(format!( + ) -> Result, errors::ConnectorError> { + let year = self.get_card_expiry_year_2_digit()?; + Ok(Secret::new(format!( "{}{}{}", self.card_exp_month.peek().clone(), delimiter, year.peek() - )) + ))) } fn get_expiry_date_as_yyyymm(&self, delimiter: &str) -> Secret { let year = self.get_expiry_year_4_digit(); @@ -815,10 +819,10 @@ impl CardData for api::Card { } Secret::new(year) } - fn get_expiry_date_as_yymm(&self) -> Secret { - let year = self.get_card_expiry_year_2_digit().expose(); + fn get_expiry_date_as_yymm(&self) -> Result, errors::ConnectorError> { + let year = self.get_card_expiry_year_2_digit()?.expose(); let month = self.card_exp_month.clone().expose(); - Secret::new(format!("{year}{month}")) + Ok(Secret::new(format!("{year}{month}"))) } } diff --git a/crates/router/src/connector/worldline/transformers.rs b/crates/router/src/connector/worldline/transformers.rs index b657756b6a8..c00913aa57d 100644 --- a/crates/router/src/connector/worldline/transformers.rs +++ b/crates/router/src/connector/worldline/transformers.rs @@ -346,7 +346,9 @@ fn make_card_request( let secret_value = format!( "{}{}", ccard.card_exp_month.peek(), - &expiry_year[expiry_year.len() - 2..] + &expiry_year + .get(expiry_year.len() - 2..) + .ok_or(errors::ConnectorError::RequestEncodingFailed)? ); let expiry_date: Secret = Secret::new(secret_value); let card = Card { diff --git a/crates/router/src/connector/zen/transformers.rs b/crates/router/src/connector/zen/transformers.rs index c66b098fe75..7ea6953a3f2 100644 --- a/crates/router/src/connector/zen/transformers.rs +++ b/crates/router/src/connector/zen/transformers.rs @@ -222,7 +222,7 @@ impl TryFrom<(&ZenRouterData<&types::PaymentsAuthorizeRouterData>, &Card)> for Z card: Some(ZenCardDetails { number: ccard.card_number.clone(), expiry_date: ccard - .get_card_expiry_month_year_2_digit_with_delimiter("".to_owned()), + .get_card_expiry_month_year_2_digit_with_delimiter("".to_owned())?, cvv: ccard.card_cvc.clone(), }), descriptor: item @@ -538,7 +538,7 @@ fn get_checkout_signature( .pay_wall_secret .clone() .ok_or(errors::ConnectorError::RequestEncodingFailed)?; - let mut signature_data = get_signature_data(checkout_request); + let mut signature_data = get_signature_data(checkout_request)?; signature_data.push_str(&pay_wall_secret); let payload_digest = digest::digest(&digest::SHA256, signature_data.as_bytes()); let mut signature = hex::encode(payload_digest); @@ -547,7 +547,9 @@ fn get_checkout_signature( } /// Fields should be in alphabetical order -fn get_signature_data(checkout_request: &CheckoutRequest) -> String { +fn get_signature_data( + checkout_request: &CheckoutRequest, +) -> Result { let specified_payment_channel = match checkout_request.specified_payment_channel { ZenPaymentChannels::PclCard => "pcl_card", ZenPaymentChannels::PclGooglepay => "pcl_googlepay", @@ -568,21 +570,19 @@ fn get_signature_data(checkout_request: &CheckoutRequest) -> String { ]; for index in 0..checkout_request.items.len() { let prefix = format!("items[{index}]."); + let checkout_request_items = checkout_request + .items + .get(index) + .ok_or(errors::ConnectorError::RequestEncodingFailed)?; signature_data.push(format!( "{prefix}lineamounttotal={}", - checkout_request.items[index].line_amount_total - )); - signature_data.push(format!( - "{prefix}name={}", - checkout_request.items[index].name - )); - signature_data.push(format!( - "{prefix}price={}", - checkout_request.items[index].price + checkout_request_items.line_amount_total )); + signature_data.push(format!("{prefix}name={}", checkout_request_items.name)); + signature_data.push(format!("{prefix}price={}", checkout_request_items.price)); signature_data.push(format!( "{prefix}quantity={}", - checkout_request.items[index].quantity + checkout_request_items.quantity )); } signature_data.push(format!( @@ -598,7 +598,7 @@ fn get_signature_data(checkout_request: &CheckoutRequest) -> String { )); signature_data.push(format!("urlredirect={}", checkout_request.url_redirect)); let signature = signature_data.join("&"); - signature.to_lowercase() + Ok(signature.to_lowercase()) } fn get_customer( diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 2cd62fbd491..08e2e5dab1a 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -3621,8 +3621,12 @@ impl ApplePayData { .into_report() .change_context(errors::ApplePayDecryptionError::Base64DecodingFailed)?; let iv = [0u8; 16]; //Initialization vector IV is typically used in AES-GCM (Galois/Counter Mode) encryption for randomizing the encryption process. - let ciphertext = &data[..data.len() - 16]; - let tag = &data[data.len() - 16..]; + let ciphertext = data + .get(..data.len() - 16) + .ok_or(errors::ApplePayDecryptionError::DecryptionFailed)?; + let tag = data + .get(data.len() - 16..) + .ok_or(errors::ApplePayDecryptionError::DecryptionFailed)?; let cipher = Cipher::aes_256_gcm(); let decrypted_data = decrypt_aead(cipher, symmetric_key, Some(&iv), &[], ciphertext, tag) .into_report() diff --git a/crates/router/src/services/encryption.rs b/crates/router/src/services/encryption.rs index acea96f8660..9a8a5f4af4a 100644 --- a/crates/router/src/services/encryption.rs +++ b/crates/router/src/services/encryption.rs @@ -1,9 +1,7 @@ -use std::{num::Wrapping, str}; +use std::str; use error_stack::{report, IntoReport, ResultExt}; use josekit::{jwe, jws}; -use rand; -use ring::{aead::*, error::Unspecified}; use serde::{Deserialize, Serialize}; use crate::{ @@ -11,44 +9,6 @@ use crate::{ utils, }; -struct NonceGen { - current: Wrapping, - start: u128, -} - -impl NonceGen { - fn new(start: [u8; 12]) -> Self { - let mut array = [0; 16]; - array[..12].copy_from_slice(&start); - let start = if cfg!(target_endian = "little") { - u128::from_le_bytes(array) - } else { - u128::from_be_bytes(array) - }; - Self { - current: Wrapping(start), - start, - } - } -} - -impl NonceSequence for NonceGen { - fn advance(&mut self) -> Result { - let n = self.current.0; - self.current += 1; - if self.current.0 == self.start { - return Err(Unspecified); - } - let value = if cfg!(target_endian = "little") { - n.to_le_bytes()[..12].try_into()? - } else { - n.to_be_bytes()[..12].try_into()? - }; - let nonce = Nonce::assume_unique_for_key(value); - Ok(nonce) - } -} - #[derive(Debug, Clone, Serialize, Deserialize)] pub struct JwsBody { pub header: String, @@ -66,57 +26,6 @@ pub struct JweBody { pub encrypted_key: String, } -pub fn encrypt(msg: &String, key: &[u8]) -> CustomResult, errors::EncryptionError> { - let nonce_seed = rand::random(); - let mut sealing_key = { - let key = UnboundKey::new(&AES_256_GCM, key) - .map_err(errors::EncryptionError::from) - .into_report() - .attach_printable("Unbound Key Error")?; - let nonce_gen = NonceGen::new(nonce_seed); - SealingKey::new(key, nonce_gen) - }; - let msg_byte = msg.as_bytes(); - let mut data = msg_byte.to_vec(); - - sealing_key - .seal_in_place_append_tag(Aad::empty(), &mut data) - .map_err(errors::EncryptionError::from) - .into_report() - .attach_printable("Error Encrypting")?; - let nonce_vec = nonce_seed.to_vec(); - data.splice(0..0, nonce_vec); //prepend nonce at the start - Ok(data) -} - -pub fn decrypt(mut data: Vec, key: &[u8]) -> CustomResult { - let nonce_seed = data[0..12] - .try_into() - .into_report() - .change_context(errors::EncryptionError) - .attach_printable("Error getting nonce")?; - data.drain(0..12); - - let mut opening_key = { - let key = UnboundKey::new(&AES_256_GCM, key) - .map_err(errors::EncryptionError::from) - .into_report() - .attach_printable("Unbound Key Error")?; - let nonce_gen = NonceGen::new(nonce_seed); - OpeningKey::new(key, nonce_gen) - }; - let res_byte = opening_key - .open_in_place(Aad::empty(), &mut data) - .map_err(errors::EncryptionError::from) - .into_report() - .attach_printable("Error Decrypting")?; - let response = str::from_utf8_mut(res_byte) - .into_report() - .change_context(errors::EncryptionError) - .attach_printable("Error from_utf8")?; - Ok(response.to_string()) -} - pub async fn encrypt_jwe( payload: &[u8], public_key: impl AsRef<[u8]>, @@ -220,7 +129,6 @@ mod tests { #![allow(clippy::unwrap_used, clippy::expect_used)] use super::*; - use crate::utils::{self, ValueExt}; // Keys used for tests // Can be generated using the following commands: @@ -308,21 +216,6 @@ VuY3OeNxi+dC2r7HppP3O/MJ4gX/RJJfSrcaGP8/Ke1W5+jE97Qy -----END RSA PRIVATE KEY----- "; - fn generate_key() -> [u8; 32] { - let key: [u8; 32] = rand::random(); - key - } - - #[test] - fn test_enc() { - let key = generate_key(); - let enc_data = encrypt(&"Test_Encrypt".to_string(), &key).unwrap(); - let card_info = utils::Encode::>::encode_to_value(&enc_data).unwrap(); - let data: Vec = card_info.parse_value("ParseEncryptedData").unwrap(); - let dec_data = decrypt(data, &key).unwrap(); - assert_eq!(dec_data, "Test_Encrypt".to_string()); - } - #[actix_rt::test] async fn test_jwe() { let jwt = encrypt_jwe("request_payload".as_bytes(), ENCRYPTION_KEY) diff --git a/crates/router/src/workflows/payment_sync.rs b/crates/router/src/workflows/payment_sync.rs index 43567ce27e2..b2296e17f70 100644 --- a/crates/router/src/workflows/payment_sync.rs +++ b/crates/router/src/workflows/payment_sync.rs @@ -301,7 +301,10 @@ mod tests { let cpt_default = process_data::ConnectorPTMapping::default().default_mapping; assert_eq!( vec![schedule_time_delta, first_retry_time_delta], - vec![cpt_default.start_after, cpt_default.frequency[0]] + vec![ + cpt_default.start_after, + *cpt_default.frequency.first().unwrap() + ] ); } } diff --git a/crates/router/tests/integration_demo.rs b/crates/router/tests/integration_demo.rs index 5d2c4a7943b..777e0a68298 100644 --- a/crates/router/tests/integration_demo.rs +++ b/crates/router/tests/integration_demo.rs @@ -153,7 +153,7 @@ async fn exceed_refund() { let message: serde_json::Value = user_client.create_refund(&server, &payment_id, 100).await; assert_eq!( - message["error"]["message"], + message.get("error").unwrap().get("message").unwrap(), "The refund amount exceeds the amount captured." ); } diff --git a/crates/router/tests/refunds.rs b/crates/router/tests/refunds.rs index 6b9dfd5ed4a..8d6a158cdff 100644 --- a/crates/router/tests/refunds.rs +++ b/crates/router/tests/refunds.rs @@ -19,7 +19,7 @@ async fn refund_create_fail_stripe() { let payment_id = format!("test_{}", uuid::Uuid::new_v4()); let refund: serde_json::Value = user_client.create_refund(&app, &payment_id, 10).await; - assert_eq!(refund["error"]["message"], "Access forbidden, invalid API key was used. Please create your new API key from the Dashboard Settings section."); + assert_eq!(refund.get("error").unwrap().get("message").unwrap(), "Access forbidden, invalid API key was used. Please create your new API key from the Dashboard Settings section."); } #[actix_web::test] @@ -33,7 +33,7 @@ async fn refund_create_fail_adyen() { let payment_id = format!("test_{}", uuid::Uuid::new_v4()); let refund: serde_json::Value = user_client.create_refund(&app, &payment_id, 10).await; - assert_eq!(refund["error"]["message"], "Access forbidden, invalid API key was used. Please create your new API key from the Dashboard Settings section."); + assert_eq!(refund.get("error").unwrap().get("message").unwrap(), "Access forbidden, invalid API key was used. Please create your new API key from the Dashboard Settings section."); } #[actix_web::test] diff --git a/crates/router_env/src/logger/storage.rs b/crates/router_env/src/logger/storage.rs index 04f00f71cb3..51e701213b9 100644 --- a/crates/router_env/src/logger/storage.rs +++ b/crates/router_env/src/logger/storage.rs @@ -77,8 +77,12 @@ impl Visit for Storage<'_> { // Skip fields which are already handled name if name.starts_with("log.") => (), name if name.starts_with("r#") => { - self.values - .insert(&name[2..], serde_json::Value::from(format!("{value:?}"))); + self.values.insert( + #[allow(clippy::expect_used)] + name.get(2..) + .expect("field name must have a minimum of two characters"), + serde_json::Value::from(format!("{value:?}")), + ); } name => { self.values @@ -88,12 +92,12 @@ impl Visit for Storage<'_> { } } -#[allow(clippy::expect_used)] impl tracing_subscriber::registry::LookupSpan<'a>> Layer for StorageSubscription { /// On new span. fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, ctx: Context<'_, S>) { + #[allow(clippy::expect_used)] let span = ctx.span(id).expect("No span"); let mut visitor = if let Some(parent_span) = span.parent() { @@ -113,8 +117,10 @@ impl tracing_subscriber::registry::LookupSpan<'a>> Layer /// On additional key value pairs store it. fn on_record(&self, span: &Id, values: &Record<'_>, ctx: Context<'_, S>) { + #[allow(clippy::expect_used)] let span = ctx.span(span).expect("No span"); let mut extensions = span.extensions_mut(); + #[allow(clippy::expect_used)] let visitor = extensions .get_mut::>() .expect("The span does not have storage"); @@ -123,6 +129,7 @@ impl tracing_subscriber::registry::LookupSpan<'a>> Layer /// On enter store time. fn on_enter(&self, span: &Id, ctx: Context<'_, S>) { + #[allow(clippy::expect_used)] let span = ctx.span(span).expect("No span"); let mut extensions = span.extensions_mut(); if extensions.get_mut::().is_none() { @@ -132,6 +139,7 @@ impl tracing_subscriber::registry::LookupSpan<'a>> Layer /// On close create an entry about how long did it take. fn on_close(&self, span: Id, ctx: Context<'_, S>) { + #[allow(clippy::expect_used)] let span = ctx.span(&span).expect("No span"); let elapsed_milliseconds = { @@ -143,6 +151,7 @@ impl tracing_subscriber::registry::LookupSpan<'a>> Layer }; let mut extensions_mut = span.extensions_mut(); + #[allow(clippy::expect_used)] let visitor = extensions_mut .get_mut::>() .expect("No visitor in extensions"); diff --git a/crates/test_utils/tests/connectors/selenium.rs b/crates/test_utils/tests/connectors/selenium.rs index 865cd950f76..303d4cd7ccb 100644 --- a/crates/test_utils/tests/connectors/selenium.rs +++ b/crates/test_utils/tests/connectors/selenium.rs @@ -397,7 +397,7 @@ pub trait SeleniumTest { ) -> Result<(), WebDriverError> { let config = self.get_configs().automation_configs.unwrap(); if config.run_minimum_steps.unwrap() { - self.complete_actions(&web_driver, actions[..3].to_vec()) + self.complete_actions(&web_driver, actions.get(..3).unwrap().to_vec()) .await } else { self.complete_actions(&web_driver, actions).await @@ -538,7 +538,7 @@ pub trait SeleniumTest { let response = client.get(outgoing_webhook_url).send().await.unwrap(); // get events from outgoing webhook endpoint let body_text = response.text().await.unwrap(); let data: WebhookResponse = serde_json::from_str(&body_text).unwrap(); - let last_three_events = &data.data[data.data.len().saturating_sub(3)..]; // Get the last three elements if available + let last_three_events = data.data.get(data.data.len().saturating_sub(3)..).unwrap(); // Get the last three elements if available for last_event in last_three_events { let last_event_body = &last_event.step.request.body; let decoded_bytes = base64::engine::general_purpose::STANDARD //decode the encoded outgoing webhook event @@ -762,7 +762,7 @@ macro_rules! function { std::any::type_name::() } let name = type_name_of(f); - &name[..name.len() - 3] + &name.get(..name.len() - 3).unwrap() }}; } @@ -812,8 +812,14 @@ pub fn should_ignore_test(name: &str) -> bool { let tests_to_ignore: HashSet = serde_json::from_value(conf).unwrap_or_else(|_| HashSet::new()); let modules: Vec<_> = name.split("::").collect(); - let file_match = format!("{}::*", <&str>::clone(&modules[1])); - let module_name = modules[1..3].join("::"); + let file_match = format!( + "{}::*", + <&str>::clone(modules.get(1).expect("Error obtaining module path segment")) + ); + let module_name = modules + .get(1..3) + .expect("Error obtaining module path segment") + .join("::"); // Ignore if it matches patterns like nuvei_ui::*, nuvei_ui::should_make_nuvei_eps_payment_test tests_to_ignore.contains(&file_match) || tests_to_ignore.contains(&module_name) }