diff --git a/mdx-gateway-generator/gradle.lockfile b/mdx-gateway-generator/gradle.lockfile index 96e0915d..2b6b19af 100644 --- a/mdx-gateway-generator/gradle.lockfile +++ b/mdx-gateway-generator/gradle.lockfile @@ -60,7 +60,7 @@ org.apache.bcel:bcel:6.6.1=spotbugs org.apache.commons:commons-lang3:3.13.0=spotbugs org.apache.commons:commons-lang3:3.17.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.commons:commons-text:1.10.0=spotbugs -org.apache.commons:commons-text:1.13.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.commons:commons-text:1.13.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy-bom:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.httpcomponents.client5:httpclient5:5.1.3=spotbugs diff --git a/mdx-gateways/gradle.lockfile b/mdx-gateways/gradle.lockfile index ff83f693..1500f726 100644 --- a/mdx-gateways/gradle.lockfile +++ b/mdx-gateways/gradle.lockfile @@ -75,7 +75,7 @@ org.apache.commons:commons-lang3:3.13.0=spotbugs org.apache.commons:commons-lang3:3.17.0=annotationProcessor,compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.commons:commons-lang3:3.8.1=pmd org.apache.commons:commons-text:1.10.0=spotbugs -org.apache.commons:commons-text:1.13.1=annotationProcessor,compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.commons:commons-text:1.13.0=annotationProcessor,compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy-bom:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.httpcomponents.client5:httpclient5:5.1.3=spotbugs diff --git a/mdx-models/gradle.lockfile b/mdx-models/gradle.lockfile index cf76fca6..385e3c0e 100644 --- a/mdx-models/gradle.lockfile +++ b/mdx-models/gradle.lockfile @@ -69,7 +69,7 @@ org.apache.commons:commons-lang3:3.13.0=spotbugs org.apache.commons:commons-lang3:3.17.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.commons:commons-lang3:3.8.1=pmd org.apache.commons:commons-text:1.10.0=spotbugs -org.apache.commons:commons-text:1.13.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.commons:commons-text:1.13.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy-bom:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.httpcomponents.client5:httpclient5:5.1.3=spotbugs diff --git a/mdx-models/src/main/java/com/mx/path/model/mdx/model/MdxLogMasker.java b/mdx-models/src/main/java/com/mx/path/model/mdx/model/MdxLogMasker.java deleted file mode 100644 index e4ebbda7..00000000 --- a/mdx-models/src/main/java/com/mx/path/model/mdx/model/MdxLogMasker.java +++ /dev/null @@ -1,427 +0,0 @@ -package com.mx.path.model.mdx.model; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.mx.path.core.common.lang.Strings; -import com.mx.path.core.common.security.LogValueRegex; - -public class MdxLogMasker { - - private static final HashSet MDX_PAYLOAD_REGEX = new HashSet<>(); - private static final HashSet HEADER_KEY_SET = new HashSet<>(); - private static final List PAYLOAD_PATTERN_SET = new ArrayList<>(); - private static final String MASK = "**MASKED**"; - - public static String maskHeaderValue(String header, String value) { - if (HEADER_KEY_SET.contains(header.toLowerCase(Locale.ENGLISH))) { - return MASK; - } - - return value; - } - - public static String maskPayload(String payload) { - return applyPatternsToPayload(payload); - } - - private static void registerHeaderKeys() { - HEADER_KEY_SET.add("mdx-session-key"); - HEADER_KEY_SET.add("mx-auth-token"); - HEADER_KEY_SET.add("mx-refresh-token"); - HEADER_KEY_SET.add("mx-session-key"); - HEADER_KEY_SET.add("x-csrf-token"); - HEADER_KEY_SET.add("x-request-token"); - } - - private static void registerPayloadPatterns() { - buildAccountPayloadPatterns(); - buildAchTransferPayloadPatterns(); - buildAuthorizationPayloadPatterns(); - buildChallengesPayloadPatterns(); - buildCheckPayloadPatterns(); - buildCreditReportPayloadPatterns(); - buildCrossAccountTransferPayloadPatterns(); - buildDevicePayloadPatterns(); - buildDisputePayloadPatterns(); - buildDocumentPayloadPatterns(); - buildIdentificationPayloadPatterns(); - buildManagedCardsPayloadPatterns(); - buildOriginationPayloadPatterns(); - buildPaymentPayloadPatterns(); - buildPayoutPayloadPatterns(); - buildProfilePayloadPatterns(); - buildRemoteDepositPayloadPatterns(); - buildTransferPayloadPatterns(); - - for (String regex : MDX_PAYLOAD_REGEX) { - Pattern mask = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); - PAYLOAD_PATTERN_SET.add(mask); - } - } - - private static void buildAccountPayloadPatterns() { - // Account - https://developer.mx.com/mdx/v5/#mdx-data-models-account-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("nickname")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("routing_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("routing_transit_number")); - - // Account - MDX v5 - MDX_PAYLOAD_REGEX.add(xmlElementRegex("account_number")); - MDX_PAYLOAD_REGEX.add(xmlElementRegex("id")); - MDX_PAYLOAD_REGEX.add(xmlElementRegex("name")); - MDX_PAYLOAD_REGEX.add(xmlElementRegex("nickname")); - MDX_PAYLOAD_REGEX.add(xmlElementRegex("routing_number")); - MDX_PAYLOAD_REGEX.add(xmlElementRegex("routing_transit_number")); - - // AccountDetails - https://developer.mx.com/drafts/mdx/accounts/#accounts-account-details-additional - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonArray("extended_fields")); - - // AccountNumbers - https://developer.mx.com/drafts/mdx/accounts/#accounts-retrieve-full-account-and-routing-numbers - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("routing_number")); - - // AccountOwnerDetails - https://developer.mx.com/mdx/v5/index.html#mdx-data-models-account-owners - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("address")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("city")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("email")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("owner_name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("phone")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("state")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("zip_code")); - - // DeliveryMethod (Alert) - https://developer.mx.com/drafts/mdx/accounts/#accounts-alerts-delivery-method - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("description")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("target")); - - // Transaction - https://developer.mx.com/mdx/v5/#mdx-data-models-transaction-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("check_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("description")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - - // Transaction - MDX v5 - MDX_PAYLOAD_REGEX.add(xmlElementRegex("account_id")); - MDX_PAYLOAD_REGEX.add(xmlElementRegex("check_number")); - MDX_PAYLOAD_REGEX.add(xmlElementRegex("description")); - MDX_PAYLOAD_REGEX.add(xmlElementRegex("id")); - MDX_PAYLOAD_REGEX.add(xmlElementRegex("memo")); - } - - private static void buildAchTransferPayloadPatterns() { - // AccountListOptions|AchAccountListOptions - https://developer.mx.com/drafts/mdx/ach_transfer/#accounts-ach-accounts-list-ach-accounts - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("ach_account_id")); - - // AchAccount - https://developer.mx.com/drafts/mdx/ach_transfer/#accounts-ach-accounts-vs-held-accounts - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("bank_name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("nickname")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("routing_number")); - - // AchScheduledTransfer - https://developer.mx.com/drafts/mdx/ach_transfer/#ach-scheduled-transfers - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_ach_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("to_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("to_ach_account_id")); - - // AchTransfer - https://developer.mx.com/drafts/mdx/ach_transfer/#ach-transfers - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_ach_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("to_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("to_ach_account_id")); - } - - private static void buildAuthorizationPayloadPatterns() { - // Authorization - https://developer.mx.com/drafts/mdx/authorization/#authorizations - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonArray("cookies")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("device_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonArray("headers")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("token")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonArray("tokens")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("url")); - } - - private static void buildChallengesPayloadPatterns() { - // Question - https://developer.mx.com/drafts/mdx/challenge/#draft-documentation-question-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("answer")); - } - - private static void buildCheckPayloadPatterns() { - // CheckImage - https://developer.mx.com/drafts/mdx/accounts/index.html#check-images-check-image-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("back_image")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("check_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("front_image")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("transaction_id")); - } - - private static void buildCreditReportPayloadPatterns() { - // CreditReportSettings - https://developer.mx.com/drafts/mdx/credit_report/index.html#credit-report-settings-credit-report-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("first_name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("last_name")); - } - - private static void buildCrossAccountTransferPayloadPatterns() { - // CrossAccountRecurringTransfer - https://developer.mx.com/drafts/mdx/cross_account_transfer/index.html#recurring-cross-account-transfers-delete-a-destination-data-flow - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("destination_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - - // CrossAccountTransfer - https://developer.mx.com/drafts/mdx/cross_account_transfer/index.html#cross-account-transfers-cross-account-transfer-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("destination_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - - // DestinationAccount - https://developer.mx.com/drafts/mdx/cross_account_transfer/index.html#destinations - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_holder")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("id")); - - // FeeListOptions - https://developer.mx.com/drafts/mdx/cross_account_transfer/index.html#fees-list-cross-account-transfer-fees - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("destination_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_account_id")); - } - - private static void buildDevicePayloadPatterns() { - // VerificationMethod - https://developer.mx.com/drafts/mdx/device/index.html#verification-methods - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("email_address")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("phone_number")); - } - - private static void buildDisputePayloadPatterns() { - // Dispute - https://developer.mx.com/drafts/mdx/accounts/index.html#disputes-dispute - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("card_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("case_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("contact_phone")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("member_name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("source_image")); - } - - private static void buildDocumentPayloadPatterns() { - // DeliveryPreferences - https://developer.mx.com/drafts/mdx/documents/index.html#documents-update-delivery-preferences - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - - // Document - https://developer.mx.com/drafts/mdx/documents/index.html#documents-document-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("file_data")); - - // DocumentSearch - https://developer.mx.com/drafts/mdx/documents/index.html#documents-list-documents - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - } - - private static void buildIdentificationPayloadPatterns() { - // Authentication - https://developer.mx.com/drafts/mdx/id/#authentications-authenticate - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("access_token")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("client_device_token")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("device_make")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("device_model")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("device_operating_system")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("device_operating_system_version")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonNumber("device_latitude")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonNumber("device_longitude")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("device_iovation_token")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("login")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("password")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("refresh_token")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("token")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("userkey")); - - // MfaChallenge - https://developer.mx.com/drafts/mdx/id/#authentications-multi-factor-authentication-version-20240213-mfa-challenge-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("answer")); - - // MfaChallengeQuestion - https://developer.mx.com/drafts/mdx/id/#authentications-multi-factor-authentication-version-20240213-question-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("answer")); - } - - private static void buildManagedCardsPayloadPatterns() { - // ManagedCard - https://developer.mx.com/drafts/mdx/managed_cards/index.html#managed-cards - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("expiration_on_card")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("image_url")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("name_on_card")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("new_pin")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("pin")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("unmasked_cvv")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("unmasked_number_on_card")); - - // TravelSchedule - https://developer.mx.com/drafts/mdx/managed_cards/index.html#destinations-list-global-destinations - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonArray("card_ids")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("email_address")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("primary_phone_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("secondary_phone_number")); - } - - private static void buildOriginationPayloadPatterns() { - // Origination - https://developer.mx.com/drafts/mdx/origination/index.html#mdx-origination-origination-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("login_token")); - } - - private static void buildPaymentPayloadPatterns() { - // Payee - https://developer.mx.com/drafts/mdx/payment/#payees-payee-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_number")); - - // Payment - https://developer.mx.com/drafts/mdx/payment/#payments - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("routing_transit_number")); - - // RecurringPayment - https://developer.mx.com/drafts/mdx/payment/#recurring-payments-recurring-payment-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - } - - private static void buildPayoutPayloadPatterns() { - // ChallengeAnswer - https://developer.mx.com/drafts/mdx/payout/#dealing-with-challenges-answer-a-challenge - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("answer")); - - // Payout - https://developer.mx.com/drafts/mdx/payout/#payouts-payout-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("challenge_answer")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("sender_name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("token")); - - // PayoutContactMethod - https://developer.mx.com/drafts/mdx/payout/#payout-contact-methods-payout-contact-method-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("email_address")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("phone_number")); - - // PayoutMethod - https://developer.mx.com/drafts/mdx/payout/#payout-methods-payout-method-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("routing_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("send_to")); - - // PayoutRequest - https://developer.mx.com/drafts/mdx/payout/#payout-requests-payout-request-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - - // PayoutSettings - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("email_address")); - - // Question - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("answer")); - - // Recipient - https://developer.mx.com/drafts/mdx/payout/#recipients-recipient-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("first_name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("last_name")); - - // RecurringPayout - https://developer.mx.com/drafts/mdx/payout/#recurring-payouts-recurring-payout-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("challenge_answer")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("token")); - } - - private static void buildProfilePayloadPatterns() { - // Address - https://developer.mx.com/drafts/mdx/profile/#addresses-address-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("address_line_one")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("address_line_two")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("city")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("country")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("postal_code")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("state")); - - // Email - https://developer.mx.com/drafts/mdx/profile/#email-addresses-email-address-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("email_address")); - - // NewPassword - https://developer.mx.com/drafts/mdx/profile/#update-password-new-update-password-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("current_password")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("new_password")); - - // NewUserName - https://developer.mx.com/drafts/mdx/profile/#update-username-update-username-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("new_username")); - - // Phone - https://developer.mx.com/drafts/mdx/profile/#phone-numbers-phone-number-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("phone_number")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("work_extension")); - - // Profile - https://developer.mx.com/drafts/mdx/profile/#profile-profile-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("birth_date_on")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("first_name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("gender")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("last_name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("middle_name")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("ssn")); - } - - private static void buildRemoteDepositPayloadPatterns() { - // RemoteDeposit - https://developer.mx.com/drafts/mdx/remote_deposit/#remote-deposits-remote-deposit-fields - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("back_of_check_image")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("front_of_check_image")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - } - - private static void buildTransferPayloadPatterns() { - // AccountListOptions - https://developer.mx.com/drafts/mdx/transfer/#transfer-accounts-list-accounts - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("account_id")); - - // FeeListOptions - https://developer.mx.com/drafts/mdx/transfer/#fees-list-transfer-fees - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("to_account_id")); - - // RecurringTransfer - https://developer.mx.com/drafts/mdx/transfer/#recurring-transfers-data-flows - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("to_account_id")); - - // Transfer - https://developer.mx.com/drafts/mdx/transfer/#transfers-data-flows - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("from_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("memo")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("repayment_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("to_account_id")); - - // TransferAmountOptionListOptions - https://developer.mx.com/drafts/mdx/transfer/#transfer-amount-options-list-all-transfer-amount-options - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("destination_account_id")); - MDX_PAYLOAD_REGEX.add(LogValueRegex.jsonString("source_account_id")); - } - - private static String xmlElementRegex(String fieldName) { - return String.format("\\<[\\w:]*%1$s\\>([\\s\\S]+?)\\<\\/[\\w:]*%1$s\\>", fieldName); - } - - private static String applyPatternsToPayload(String payload) { - for (Pattern p : PAYLOAD_PATTERN_SET) { - Matcher m = p.matcher(payload); - int start = 0; - - while (m.find(start)) { - String patternMatch = m.group(); - - // Apply masking to all matching groups - for (int i = 1; i <= m.groupCount(); i++) { - if (!Strings.isBlank(m.group(i))) { - patternMatch = patternMatch.replace(m.group(i), MASK); - } - } - payload = payload.replace(m.group(), patternMatch); - start = m.start() + 1; - } - } - - return payload; - } - - static { - registerHeaderKeys(); - registerPayloadPatterns(); - } -} diff --git a/mdx-models/src/test/groovy/com/mx/path/model/mdx/model/MdxLogMaskerTest.groovy b/mdx-models/src/test/groovy/com/mx/path/model/mdx/model/MdxLogMaskerTest.groovy deleted file mode 100644 index c38788e0..00000000 --- a/mdx-models/src/test/groovy/com/mx/path/model/mdx/model/MdxLogMaskerTest.groovy +++ /dev/null @@ -1,878 +0,0 @@ -package com.mx.path.model.mdx.model - -import spock.lang.Specification -import spock.lang.Unroll - -class MdxLogMaskerTest extends Specification { - @Unroll - def "maskHeaderValue() masks #header to #expectedResult"() { - when: - String result = MdxLogMasker.maskHeaderValue(header, "something_sensitive") - - then: - result == expectedResult - - where: - header || expectedResult - "mx-refresh-token" || "**MASKED**" - } - - @Unroll - def "maskPayload() masks Account JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_number\":\"1234567890\"" || "\"account_number\":\"**MASKED**\"" - "\"id\":\"ACCOUNT-123\"" || "\"id\":\"**MASKED**\"" - "\"name\":\"Checking Account\"" || "\"name\":\"**MASKED**\"" - "\"nickname\":\"My Checking\"" || "\"nickname\":\"**MASKED**\"" - "\"routing_number\":\"121122676\"" || "\"routing_number\":\"**MASKED**\"" - "\"routing_transit_number\":\"0260-0959-3\"" || "\"routing_transit_number\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Account XML fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "1234567890" || "**MASKED**" - "ACCOUNT-123" || "**MASKED**" - "Checking Account" || "**MASKED**" - "My Checking" || "**MASKED**" - "121122676" || "**MASKED**" - "0260-0959-3" || "**MASKED**" - } - - @Unroll - def "maskPayload() masks AccountDetails JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"extended_fields\":[{\n \"type\": \"STRING\",\n \"name\": \"secret field\",\n \"string_value\": \"secret value\"\n}]" || "\"extended_fields\":[**MASKED**]" - } - - @Unroll - def "maskPayload() masks AccountNumbers JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_number\":\"1234567890\"" || "\"account_number\":\"**MASKED**\"" - "\"routing_number\":\"121122676\"" || "\"routing_number\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks AccountOwnerDetails JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"address\":\"3401 N Thanksgiving Way #500\"" || "\"address\":\"**MASKED**\"" - "\"city\":\"Lehi\"" || "\"city\":\"**MASKED**\"" - "\"email\":\"john.doe@example.com\"" || "\"email\":\"**MASKED**\"" - "\"owner_name\":\"John Doe\"" || "\"owner_name\":\"**MASKED**\"" - "\"phone\":\"1-222-333-4444\"" || "\"phone\":\"**MASKED**\"" - "\"zip_code\":\"84043\"" || "\"zip_code\":\"**MASKED**\"" - "\"state\":\"UT\"" || "\"state\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks DeliveryMethod JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"description\":\"3401 N Thanksgiving Way #500\"" || "\"description\":\"**MASKED**\"" - "\"target\":\"Email - *1@example.com\"" || "\"target\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Transaction JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"check_number\":\"1234\"" || "\"check_number\":\"**MASKED**\"" - "\"description\":\"Test transaction\"" || "\"description\":\"**MASKED**\"" - "\"id\":\"TRANSACTION-123\"" || "\"id\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Transaction XML fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "ACCOUNT-123" || "**MASKED**" - "1234" || "**MASKED**" - "Test transaction" || "**MASKED**" - "TRANSACTION-123" || "**MASKED**" - "Test memo" || "**MASKED**" - } - - @Unroll - def "maskPayload() masks AccountListOptions JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"ach_account_id\":\"ACCOUNT-456\"" || "\"ach_account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks AchAccount JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"account_number\":\"1234567890\"" || "\"account_number\":\"**MASKED**\"" - "\"bank_name\":\"Test Credit Union\"" || "\"bank_name\":\"**MASKED**\"" - "\"id\":\"ACH-ACCOUNT-123\"" || "\"id\":\"**MASKED**\"" - "\"name\":\"Test Name\"" || "\"name\":\"**MASKED**\"" - "\"nickname\":\"Test Nickname\"" || "\"nickname\":\"**MASKED**\"" - "\"routing_number\":\"121122676\"" || "\"routing_number\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks AchScheduledTransfer JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"from_account_id\":\"ACCOUNT-1\"" || "\"from_account_id\":\"**MASKED**\"" - "\"from_ach_account_id\":\"ACH-ACCOUNT-1\"" || "\"from_ach_account_id\":\"**MASKED**\"" - "\"id\":\"ACH-TRANSFER-1\"" || "\"id\":\"**MASKED**\"" - "\"memo\":\"Test ACH Transfer\"" || "\"memo\":\"**MASKED**\"" - "\"to_account_id\":\"ACCOUNT-2\"" || "\"to_account_id\":\"**MASKED**\"" - "\"to_ach_account_id\":\"ACH-ACCOUNT-2\"" || "\"to_ach_account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks AchTransfer JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"from_account_id\":\"ACCOUNT-1\"" || "\"from_account_id\":\"**MASKED**\"" - "\"from_ach_account_id\":\"ACH-ACCOUNT-1\"" || "\"from_ach_account_id\":\"**MASKED**\"" - "\"id\":\"ACH-TRANSFER-1\"" || "\"id\":\"**MASKED**\"" - "\"memo\":\"Test ACH Transfer\"" || "\"memo\":\"**MASKED**\"" - "\"to_account_id\":\"ACCOUNT-2\"" || "\"to_account_id\":\"**MASKED**\"" - "\"to_ach_account_id\":\"ACH-ACCOUNT-2\"" || "\"to_ach_account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Authorization JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-1\"" || "\"account_id\":\"**MASKED**\"" - "\"cookies\":[{\n \"cookie1\": \"value1\",\n \"cookie2\": \"value2\"\n}]" || "\"cookies\":[**MASKED**]" - "\"device_id\":\"ACH-TRANSFER-1\"" || "\"device_id\":\"**MASKED**\"" - "\"headers\":[{\n \"header1\": \"value1\",\n \"header2\": \"value2\"\n}]" || "\"headers\":[**MASKED**]" - "\"token\":\"j8tGkb0STI827r0aMBOvJN9tBU08nFsc8gSivZLIfBw=\"" || "\"token\":\"**MASKED**\"" - "\"tokens\":[{\n \"token1\": \"value1\",\n \"token2\": \"value2\"\n}]" || "\"tokens\":[**MASKED**]" - "\"url\":\"http:/test.example.com/sso?token=b1d36291310644fe921b8bdff8d08d61\"" || "\"url\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Question JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"answer\":\"Test answer\"" || "\"answer\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks CheckImage JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-1\"" || "\"account_id\":\"**MASKED**\"" - "\"back_image\":\"data:image/png;base64,iVBORw0KGAAAUAAAAFCJggg==\"" || "\"back_image\":\"**MASKED**\"" - "\"check_number\":\"1234\"" || "\"check_number\":\"**MASKED**\"" - "\"front_image\":\"data:image/png;base64,iVBORw0KGAAAUAAAAFCJggg==\"" || "\"front_image\":\"**MASKED**\"" - "\"transaction_id\":\"TRANSACTION-1\"" || "\"transaction_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks CreditReportSettings JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"first_name\":\"John\"" || "\"first_name\":\"**MASKED**\"" - "\"last_name\":\"Doe\"" || "\"last_name\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks CrossAccountRecurringTransfer JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"destination_id\":\"DESTINATION-123\"" || "\"destination_id\":\"**MASKED**\"" - "\"from_account_id\":\"ACCOUNT-123\"" || "\"from_account_id\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks CrossAccountRecurringTransfer JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"destination_id\":\"DESTINATION-123\"" || "\"destination_id\":\"**MASKED**\"" - "\"from_account_id\":\"ACCOUNT-123\"" || "\"from_account_id\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks CrossAccountTransfer JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"destination_id\":\"DESTINATION-123\"" || "\"destination_id\":\"**MASKED**\"" - "\"from_account_id\":\"ACCOUNT-123\"" || "\"from_account_id\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks DestinationAccount JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_holder\":\"Test account holder\"" || "\"account_holder\":\"**MASKED**\"" - "\"account_number\":\"1234567890\"" || "\"account_number\":\"**MASKED**\"" - "\"id\":\"ACCOUNT-123\"" || "\"id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks FeeListOptions JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"destination_id\":\"DESTINATION-123\"" || "\"destination_id\":\"**MASKED**\"" - "\"from_account_id\":\"ACCOUNT-123\"" || "\"from_account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks VerificationMethod JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"email_address\":\"john.doe@example.com\"" || "\"email_address\":\"**MASKED**\"" - "\"phone_number\":\"1-222-333-4444\"" || "\"phone_number\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Dispute JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"card_id\":\"CARD-123\"" || "\"card_id\":\"**MASKED**\"" - "\"case_number\":\"182744AAQ093\"" || "\"case_number\":\"**MASKED**\"" - "\"contact_phone\":\"1-222-333-4444\"" || "\"contact_phone\":\"**MASKED**\"" - "\"member_name\":\"John Doe\"" || "\"member_name\":\"**MASKED**\"" - "\"source_image\":\"data:image/png;base64,iVBORw0KGAAAUAAAAFCJggg==\"" || "\"source_image\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks DeliveryPreferences JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Document JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"file_data\":\"data:application/pdf;base64,iVBORw0KGAAAUAAAAFCJggg==\"" || "\"file_data\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks DocumentSearch JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Authentication JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"access_token\":\"167f0a358b054953ae7c9527e2d273a9\"" || "\"access_token\":\"**MASKED**\"" - "\"client_device_token\":\"UNIQUE_TOKEN_FOR_THIS_DEVICE\"" || "\"client_device_token\":\"**MASKED**\"" - "\"device_make\":\"Apple\"" || "\"device_make\":\"**MASKED**\"" - "\"device_model\":\"iPhone X\"" || "\"device_model\":\"**MASKED**\"" - "\"device_operating_system\":\"iOS\"" || "\"device_operating_system\":\"**MASKED**\"" - "\"device_operating_system_version\":\"11.4.1\"" || "\"device_operating_system_version\":\"**MASKED**\"" - "\"device_latitude\":40.4296944" || "\"device_latitude\":**MASKED**" - "\"device_longitude\":-111.8931454" || "\"device_longitude\":**MASKED**" - "\"device_iovation_token\":\"ac1d3a2455a9444ebc942c7842660ed2\"" || "\"device_iovation_token\":\"**MASKED**\"" - "\"login\":\"johndoe\"" || "\"login\":\"**MASKED**\"" - "\"password\":\"topsecret\"" || "\"password\":\"**MASKED**\"" - "\"refresh_token\":\"2ed7c86985d0404a8728fe4c621711b5\"" || "\"refresh_token\":\"**MASKED**\"" - "\"token\":\"b43cac3cfbcc45d4abecef87064b63ce\"" || "\"token\":\"**MASKED**\"" - "\"userkey\":\"25ff030acfba4cdf91618dc23b4795e4\"" || "\"userkey\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks MfaChallenge JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"answer\":\"12345\"" || "\"answer\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks MfaChallengeQuestion JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"answer\":\"12345\"" || "\"answer\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks ManagedCard JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"expiration_on_card\":\"06/97\"" || "\"expiration_on_card\":\"**MASKED**\"" - "\"image_url\":\"https://logos.co/customers/123/card_image.jpg\"" || "\"image_url\":\"**MASKED**\"" - "\"name_on_card\":\"John Doe\"" || "\"name_on_card\":\"**MASKED**\"" - "\"new_pin\":\"12345\"" || "\"new_pin\":\"**MASKED**\"" - "\"pin\":\"12345\"" || "\"pin\":\"**MASKED**\"" - "\"unmasked_cvv\":\"123\"" || "\"unmasked_cvv\":\"**MASKED**\"" - "\"unmasked_number_on_card\":\"1111222233334444\"" || "\"unmasked_number_on_card\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks TravelSchedule JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"card_ids\":[\"CARD_ID_1\", \"CARD_ID_2\"]" || "\"card_ids\":[**MASKED**]" - "\"email_address\":\"john.doe@example.com\"" || "\"email_address\":\"**MASKED**\"" - "\"primary_phone_number\":\"1-222-333-4444\"" || "\"primary_phone_number\":\"**MASKED**\"" - "\"secondary_phone_number\":\"1-333-444-5555\"" || "\"secondary_phone_number\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Origination JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"login_token\":\"123456789\"" || "\"login_token\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Payee JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_number\":\"123456789\"" || "\"account_number\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Payment JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - "\"routing_transit_number\":\"0260-0959-3\"" || "\"routing_transit_number\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks RecurringPayment JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks ChallengeAnswer (Payout) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"answer\":\"Test answer\"" || "\"answer\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Payout JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"challenge_answer\":\"Test answer\"" || "\"challenge_answer\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - "\"sender_name\":\"John Doe\"" || "\"sender_name\":\"**MASKED**\"" - "\"token\":\"f48c8aa0e66d4d53979b36c4c46c8abc\"" || "\"token\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks PayoutContactMethod JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"email_address\":\"john.doe@example.com\"" || "\"email_address\":\"**MASKED**\"" - "\"phone_number\":\"1-222-333-4444\"" || "\"phone_number\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks PayoutMethod JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_number\":\"1234567890\"" || "\"account_number\":\"**MASKED**\"" - "\"routing_number\":\"121122676\"" || "\"routing_number\":\"**MASKED**\"" - "\"send_to\":\"john.doe@example.com\"" || "\"send_to\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks PayoutRequest JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks PayoutSettings JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"email_address\":\"john.doe@example.com\"" || "\"email_address\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Question (Payout) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"answer\":\"Test answer\"" || "\"answer\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Recipient (Payout) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"first_name\":\"John\"" || "\"first_name\":\"**MASKED**\"" - "\"last_name\":\"Doe\"" || "\"last_name\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks RecurringPayout JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"challenge_answer\":\"Test answer\"" || "\"challenge_answer\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - "\"token\":\"41bb602a0ab44896ad28d7de270e24ce\"" || "\"token\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Address (Profile) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"ACCOUNT-123\"" || "\"account_id\":\"**MASKED**\"" - "\"address_line_one\":\"3401 N Thanksgiving Way #500\"" || "\"address_line_one\":\"**MASKED**\"" - "\"address_line_two\":\"Test address line 2\"" || "\"address_line_two\":\"**MASKED**\"" - "\"city\":\"Lehi\"" || "\"city\":\"**MASKED**\"" - "\"country\":\"US\"" || "\"country\":\"**MASKED**\"" - "\"postal_code\":\"84043\"" || "\"postal_code\":\"**MASKED**\"" - "\"state\":\"UT\"" || "\"state\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Email (Profile) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"email_address\":\"john.doe@example.com\"" || "\"email_address\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks NewPassword (Profile) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"current_password\":\"topsecret1\"" || "\"current_password\":\"**MASKED**\"" - "\"new_password\":\"topsecret2\"" || "\"new_password\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks NewUserName (Profile) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"new_username\":\"johndoe\"" || "\"new_username\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Phone (Profile) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"phone_number\":\"1-222-333-4444\"" || "\"phone_number\":\"**MASKED**\"" - "\"work_extension\":\"1234\"" || "\"work_extension\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Profile JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"birth_date_on\":\"2015-01-01\"" || "\"birth_date_on\":\"**MASKED**\"" - "\"first_name\":\"John\"" || "\"first_name\":\"**MASKED**\"" - "\"gender\":\"MALE\"" || "\"gender\":\"**MASKED**\"" - "\"last_name\":\"Doe\"" || "\"last_name\":\"**MASKED**\"" - "\"middle_name\":\"William\"" || "\"middle_name\":\"**MASKED**\"" - "\"ssn\":\"123456789\"" || "\"ssn\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks RemoteDeposit JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"Account-123\"" || "\"account_id\":\"**MASKED**\"" - "\"back_of_check_image\":\"data:image/png;base64,iVBORw0KGAAAUAAAAFCJggg==\"" || "\"back_of_check_image\":\"**MASKED**\"" - "\"front_of_check_image\":\"data:image/png;base64,iVBORw0KGAAAUAAAAFCJggg==\"" || "\"front_of_check_image\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks AccountListOptions (Transfer) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"account_id\":\"Account-123\"" || "\"account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks FeeListOptions (Transfer) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"from_account_id\":\"Account-123\"" || "\"from_account_id\":\"**MASKED**\"" - "\"to_account_id\":\"Account-456\"" || "\"to_account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks RecurringTransfer JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"from_account_id\":\"Account-123\"" || "\"from_account_id\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - "\"to_account_id\":\"Account-456\"" || "\"to_account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks Transfer JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"from_account_id\":\"Account-123\"" || "\"from_account_id\":\"**MASKED**\"" - "\"memo\":\"Test memo\"" || "\"memo\":\"**MASKED**\"" - "\"repayment_account_id\":\"Account-456\"" || "\"repayment_account_id\":\"**MASKED**\"" - "\"to_account_id\":\"Account-789\"" || "\"to_account_id\":\"**MASKED**\"" - } - - @Unroll - def "maskPayload() masks TransferAmountOptionListOptions (Transfer) JSON fields"() { - when: - String result = MdxLogMasker.maskPayload(payload) - - then: - result == expectedResult - - where: - payload || expectedResult - "\"destination_account_id\":\"Account-123\"" || "\"destination_account_id\":\"**MASKED**\"" - "\"source_account_id\":\"Account-456\"" || "\"source_account_id\":\"**MASKED**\"" - } -} diff --git a/mdx-web/build.gradle b/mdx-web/build.gradle index 5b83f38d..40cbde56 100644 --- a/mdx-web/build.gradle +++ b/mdx-web/build.gradle @@ -14,6 +14,7 @@ dependencies { //testing dependencies testImplementation "com.mx.path-core:testing" + testImplementation "org.slf4j:slf4j-simple:1.7.30" testImplementation "io.opentracing:opentracing-mock:0.33.0" testImplementation "org.springframework.boot:spring-boot-starter-test" testImplementation "org.mockito:mockito-inline:[4.0,5.0)" diff --git a/mdx-web/gradle.lockfile b/mdx-web/gradle.lockfile index 246aca70..efe8a367 100644 --- a/mdx-web/gradle.lockfile +++ b/mdx-web/gradle.lockfile @@ -79,7 +79,7 @@ org.apache.commons:commons-lang3:3.13.0=spotbugs org.apache.commons:commons-lang3:3.17.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.commons:commons-lang3:3.8.1=pmd org.apache.commons:commons-text:1.10.0=spotbugs -org.apache.commons:commons-text:1.13.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.commons:commons-text:1.13.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy-bom:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.httpcomponents.client5:httpclient5:5.1.3=spotbugs @@ -140,6 +140,7 @@ org.slf4j:jul-to-slf4j:1.7.36=compileClasspath,runtimeClasspath,testCompileClass org.slf4j:slf4j-api:1.7.36=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-api:2.0.0=spotbugsSlf4j org.slf4j:slf4j-api:2.0.9=spotbugs +org.slf4j:slf4j-simple:1.7.36=testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-simple:2.0.0=spotbugsSlf4j org.spockframework:spock-core:2.4-M1-groovy-4.0=testCompileClasspath,testRuntimeClasspath org.spockframework:spock-junit4:2.4-M1-groovy-4.0=testCompileClasspath,testRuntimeClasspath diff --git a/mdx-web/src/main/java/com/mx/path/model/mdx/web/filter/FilterOrderSequence.java b/mdx-web/src/main/java/com/mx/path/model/mdx/web/filter/FilterOrderSequence.java index 4ebb9072..59be1c13 100644 --- a/mdx-web/src/main/java/com/mx/path/model/mdx/web/filter/FilterOrderSequence.java +++ b/mdx-web/src/main/java/com/mx/path/model/mdx/web/filter/FilterOrderSequence.java @@ -2,10 +2,9 @@ public class FilterOrderSequence { public static final int REQUEST_CONTEXT_FILTER = 1; - public static final int REQUEST_LOGGING_FILTER = 2; - public static final int ERROR_FILTER = 3; - public static final int HMAC_FILTER = 4; - public static final int SESSION_FILTER = 5; - public static final int AUTH_FILTER = 6; - public static final int REPO_FILTER = 7; + public static final int ERROR_FILTER = 2; + public static final int HMAC_FILTER = 3; + public static final int SESSION_FILTER = 4; + public static final int AUTH_FILTER = 5; + public static final int REPO_FILTER = 6; } diff --git a/mdx-web/src/main/java/com/mx/path/model/mdx/web/filter/PathRequestLoggingFilter.java b/mdx-web/src/main/java/com/mx/path/model/mdx/web/filter/PathRequestLoggingFilter.java deleted file mode 100644 index 36ff3017..00000000 --- a/mdx-web/src/main/java/com/mx/path/model/mdx/web/filter/PathRequestLoggingFilter.java +++ /dev/null @@ -1,297 +0,0 @@ -package com.mx.path.model.mdx.web.filter; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import com.google.gson.FieldNamingPolicy; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.mx.path.core.context.RequestContext; -import com.mx.path.gateway.util.LoggingExceptionFormatter; -import com.mx.path.model.mdx.model.MdxLogMasker; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.MDC; -import org.springframework.core.annotation.Order; -import org.springframework.stereotype.Component; -import org.springframework.web.filter.OncePerRequestFilter; -import org.springframework.web.util.ContentCachingRequestWrapper; -import org.springframework.web.util.ContentCachingResponseWrapper; - -/** - * Request logging filter - *

- * This filter logs incoming requests. - * These values are inserted into the MDC. - */ -@Component -@Order(FilterOrderSequence.REQUEST_LOGGING_FILTER) -public class PathRequestLoggingFilter extends OncePerRequestFilter { - - // Statics - private static final Gson GSON; - private static Logger logger; - - public static void setLogger(Logger logger) { - PathRequestLoggingFilter.logger = logger; - } - - public static void resetLogger() { - logger = LoggerFactory.getLogger(PathRequestLoggingFilter.class); - } - - // Protected - @Override - protected final void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - ContentCachingRequestWrapper requestWrapper; - ContentCachingResponseWrapper responseWrapper; - - try { - requestWrapper = new ContentCachingRequestWrapper(request); - responseWrapper = new ContentCachingResponseWrapper(response); - } catch (Exception ex) { - MDC.put("exception", LoggingExceptionFormatter.formatLoggingExceptionWithStacktrace(ex)); - logger.error("Failed to create request/response wrappers for logging purposes. Passing request through.", ex); - filterChain.doFilter(request, response); - return; - } - - final long requestStartTimeMillis = System.currentTimeMillis(); - - try { - // Pass request to next filter with wrappers to support logging request and response bodies - filterChain.doFilter(requestWrapper, responseWrapper); - } finally { - try { - this.logRequest(requestWrapper, responseWrapper, requestStartTimeMillis); - } catch (Exception ex) { - MDC.put("exception", LoggingExceptionFormatter.formatLoggingExceptionWithStacktrace(ex)); - logger.error("Failed to log incoming request", ex); - } finally { - resetMDC(); - } - - responseWrapper.copyBodyToResponse(); - } - } - - @SuppressWarnings("PMD.CyclomaticComplexity") - private void logRequest(ContentCachingRequestWrapper request, ContentCachingResponseWrapper response, - long requestStartTimeMillis) throws IOException { - final long elapsedTime = System.currentTimeMillis() - requestStartTimeMillis; - final RequestContext requestContext = RequestContext.current(); - - MDC.put("log_guid", UUID.randomUUID().toString()); - MDC.put("client_guid", requestContext.getClientGuid()); - MDC.put("client_id", requestContext.getClientId()); - MDC.put("path", requestContext.getPath()); - - if (requestContext.getUserGuid() != null) { - MDC.put("user_guid", requestContext.getUserGuid()); - } else { - MDC.remove("user_guid"); - } - - if (requestContext.getFeature() != null) { - MDC.put("feature", requestContext.getFeature()); - } else { - MDC.remove("feature"); - } - - if (requestContext.getOriginatingIP() != null) { - MDC.put("ip_address", requestContext.getOriginatingIP()); - } else { - MDC.remove("ip_address"); - } - - if (requestContext.getSessionTraceId() != null) { - MDC.put("session_trace_id", requestContext.getSessionTraceId()); - } else { - MDC.remove("session_trace_id"); - } - - if (requestContext.getDeviceTraceId() != null) { - MDC.put("device_trace_id", requestContext.getDeviceTraceId()); - } else { - MDC.remove("device_trace_id"); - } - - MDC.put("request_method", request.getMethod()); - MDC.put("request_uri", String.valueOf(request.getRequestURL())); - - if (request.getQueryString() != null) { - final Map queryParams = this.buildQueryStringMap(request.getQueryString()); - MDC.put("query_params", this.buildHeaderString(this.maskHeaders(queryParams))); - } else { - MDC.remove("query_params"); - } - - if (request.getHeaderNames() != null) { - final Map requestHeaders = this.buildRequestHeadersMap(request); - final Map maskedRequestHeaders = this.maskHeaders(requestHeaders); - MDC.put("request_headers_json", GSON.toJson(maskedRequestHeaders)); - MDC.put("request_headers", this.buildHeaderString(maskedRequestHeaders)); - } else { - MDC.remove("request_headers_json"); - MDC.remove("request_headers"); - } - - final String requestBody = new String(request.getContentAsByteArray(), StandardCharsets.UTF_8); - if (!requestBody.isEmpty()) { - MDC.put("request_body", MdxLogMasker.maskPayload(requestBody)); - } else { - MDC.remove("request_body"); - } - - MDC.put("request_duration", String.valueOf(elapsedTime)); - MDC.put("status", String.valueOf(response.getStatus())); - - if (response.getHeaderNames() != null) { - final Map responseHeaders = this.buildResponseHeadersMap(response); - final Map maskedResponseHeaders = this.maskHeaders(responseHeaders); - - if (response.getContentType() != null) { - maskedResponseHeaders.put("Content-Type", response.getContentType()); - } - - if (!maskedResponseHeaders.isEmpty()) { - MDC.put("response_headers_json", GSON.toJson(maskedResponseHeaders)); - MDC.put("response_headers", this.buildHeaderString(maskedResponseHeaders)); - } - } else { - MDC.remove("response_headers_json"); - MDC.remove("response_headers"); - } - - final String responseBody = new String(response.getContentAsByteArray(), StandardCharsets.UTF_8); - if (!responseBody.isEmpty()) { - MDC.put("response_body", MdxLogMasker.maskPayload(responseBody)); - } else { - MDC.remove("response_body"); - } - - logger.info("Incoming request"); - } - - /** - * Resets the MDC by just cleaning up what we place there. - */ - protected void resetMDC() { - MDC.remove("client_guid"); - MDC.remove("client_id"); - MDC.remove("device_trace_id"); - MDC.remove("exception"); - MDC.remove("feature"); - MDC.remove("ip_address"); - MDC.remove("log_guid"); - MDC.remove("path"); - MDC.remove("query_params"); - MDC.remove("request_body"); - MDC.remove("request_duration"); - MDC.remove("request_headers"); - MDC.remove("request_headers_json"); - MDC.remove("request_method"); - MDC.remove("response_body"); - MDC.remove("response_headers"); - MDC.remove("response_headers_json"); - MDC.remove("session_trace_id"); - MDC.remove("status"); - MDC.remove("user_guid"); - } - - private Map buildRequestHeadersMap(HttpServletRequest request) { - final Enumeration headerNames = request.getHeaderNames(); - final Map headerMap = new HashMap<>(); - - if (headerNames == null) { - return headerMap; - } - - while (headerNames.hasMoreElements()) { - final String headerName = headerNames.nextElement(); - final String headerValue = request.getHeader(headerName); - headerMap.put(headerName, headerValue); - } - - return headerMap; - } - - private Map buildResponseHeadersMap(HttpServletResponse response) { - final Collection headerNames = response.getHeaderNames(); - final Map headerMap = new HashMap<>(); - - if (headerNames == null) { - return headerMap; - } - - for (String headerName : headerNames) { - final Collection headerValues = response.getHeaders(headerName); - String headerValuesFlattened = ""; - - if (headerValues != null) { - final List headerValuesList = new ArrayList<>(headerValues); - headerValuesFlattened = String.join(", ", headerValuesList); - } - - headerMap.put(headerName, headerValuesFlattened); - } - - return headerMap; - } - - private Map buildQueryStringMap(String queryString) { - final Map querystringMap = new HashMap<>(); - final String[] parameters = queryString.split("&"); - - for (String parameter : parameters) { - final String[] keyValuePair = parameter.split("="); - if (keyValuePair.length == 2) { - querystringMap.put(keyValuePair[0], keyValuePair[1]); - } - } - - return querystringMap; - } - - private String buildHeaderString(Map headers) { - final StringBuilder headerStr = new StringBuilder(); - headers.forEach((name, value) -> { - headerStr.append(name); - headerStr.append(": "); - headerStr.append(value); - headerStr.append("\n"); - }); - return headerStr.toString(); - } - - private Map maskHeaders(Map headers) { - if (headers == null) { - return null; - } - - final Map maskedHeaders = new HashMap<>(); - headers.forEach((name, value) -> { - maskedHeaders.put(name, MdxLogMasker.maskHeaderValue(name, value)); - }); - return maskedHeaders; - } - - static { - GSON = new GsonBuilder().disableHtmlEscaping().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create(); - logger = LoggerFactory.getLogger(PathRequestLoggingFilter.class); - } -} diff --git a/mdx-web/src/test/groovy/com/mx/path/model/mdx/web/filter/PathRequestLoggingFilterTest.groovy b/mdx-web/src/test/groovy/com/mx/path/model/mdx/web/filter/PathRequestLoggingFilterTest.groovy deleted file mode 100644 index 4721e722..00000000 --- a/mdx-web/src/test/groovy/com/mx/path/model/mdx/web/filter/PathRequestLoggingFilterTest.groovy +++ /dev/null @@ -1,207 +0,0 @@ -package com.mx.path.model.mdx.web.filter - -import static org.mockito.Mockito.mock -import static org.mockito.Mockito.verify -import static org.mockito.Mockito.when - -import javax.servlet.FilterChain -import javax.servlet.http.HttpServletRequest -import javax.servlet.http.HttpServletResponse - -import com.mx.path.core.context.RequestContext - -import org.slf4j.Logger -import org.slf4j.MDC - -import spock.lang.Specification - -class PathRequestLoggingFilterTest extends Specification { - HttpServletRequest request - HttpServletResponse response - FilterChain filterChain - PathRequestLoggingFilter subject - Logger logger - - def setup() { - logger = mock(Logger.class) - PathRequestLoggingFilter.setLogger(logger) - - subject = new PathRequestLoggingFilter() - request = mock(HttpServletRequest) - response = mock(HttpServletResponse) - filterChain = mock(FilterChain) - - RequestContext.builder() - .clientId("client-id") - .clientGuid("3a1a8ff6-778e-40e0-995a-72d6bf6ccb35") - .userGuid("a851008c-d85a-4dcf-87f0-b1e2a69adaf3") - .path("/testing") - .deviceTraceId("device123") - .sessionTraceId("ebebebe") - .originatingIP("10.10.10.1") - .feature("feature") - .build() - .register() - } - - def cleanup() { - PathRequestLoggingFilter.resetLogger() - MDC.clear() - RequestContext.clear() - } - - def "interacts with the logger"() { - when: - subject.doFilterInternal(request, response, filterChain) - verify(logger).info("Incoming request") - - then: - MDC.get("client_guid") == null - MDC.get("client_id") == null - MDC.get("device_trace_id") == null - MDC.get("exception") == null - MDC.get("feature") == null - MDC.get("ip_address") == null - MDC.get("log_guid") == null - MDC.get("path") == null - MDC.get("query_params") == null - MDC.get("request_body") == null - MDC.get("request_duration") == null - MDC.get("request_headers") == null - MDC.get("request_headers_json") == null - MDC.get("request_method") == null - MDC.get("response_body") == null - MDC.get("response_headers") == null - MDC.get("response_headers_json") == null - MDC.get("session_trace_id") == null - MDC.get("status") == null - MDC.get("user_guid") == null - } - - def "with empty request context and response"() { - given: - RequestContext.builder() - .build() - .register() - - when: - subject.doFilterInternal(request, response, filterChain) - verify(logger).info("Incoming request") - - then: - MDC.get("client_guid") == null - MDC.get("client_id") == null - MDC.get("device_trace_id") == null - MDC.get("exception") == null - MDC.get("feature") == null - MDC.get("ip_address") == null - MDC.get("log_guid") == null - MDC.get("path") == null - MDC.get("query_params") == null - MDC.get("request_body") == null - MDC.get("request_duration") == null - MDC.get("request_headers") == null - MDC.get("request_headers_json") == null - MDC.get("request_method") == null - MDC.get("response_body") == null - MDC.get("response_headers") == null - MDC.get("response_headers_json") == null - MDC.get("session_trace_id") == null - MDC.get("status") == null - MDC.get("user_guid") == null - } - - def "exception during logging caught and logged"() { - given: - def testException = new RuntimeException("Test Exception") - when(request.getMethod()).thenThrow(testException) - - when: - subject.doFilterInternal(request, response, filterChain) - verify(logger).error("Failed to log incoming request", testException) - - then: - notThrown(Exception) - MDC.get("client_guid") == null - MDC.get("client_id") == null - MDC.get("device_trace_id") == null - MDC.get("exception") == null - MDC.get("feature") == null - MDC.get("ip_address") == null - MDC.get("log_guid") == null - MDC.get("path") == null - MDC.get("query_params") == null - MDC.get("request_body") == null - MDC.get("request_duration") == null - MDC.get("request_headers") == null - MDC.get("request_headers_json") == null - MDC.get("request_method") == null - MDC.get("response_body") == null - MDC.get("response_headers") == null - MDC.get("response_headers_json") == null - MDC.get("session_trace_id") == null - MDC.get("status") == null - MDC.get("user_guid") == null - } - - def "captures expected data in MDC"() { - given: - def testNoMDCClearingSubject = new PathRequestLoggingFilterWithNoMDCClearing() - when(request.getRequestURL()).thenReturn(new StringBuffer("https://localhost:13024/testing")) - when(request.getQueryString()).thenReturn("param1=value1¶m2=value2") - when(request.getMethod()).thenReturn("GET") - - def requestHeadersList = new ArrayList().tap { - add("Accept") - add("mx-device-ip-address") - add("x-request-token") - } - when(request.getHeaderNames()).thenReturn(Collections.enumeration(requestHeadersList)) - when(request.getHeader("Accept")).thenReturn("application/vnd.mx.mdx.v6+json") - when(request.getHeader("mx-device-ip-address")).thenReturn("10.10.10.1") - when(request.getHeader("x-request-token")).thenReturn("12345") - - def responseHeadersList = [ - "Content-Type", - "Content-Length", - "mx-session-key" - ] - when(response.getHeaderNames()).thenReturn(responseHeadersList) - when(response.getHeaders("Content-Type")).thenReturn([ - "application/vnd.mx.mdx.v6+json" - ]) - when(response.getHeaders("Content-Length")).thenReturn(["50"]) - when(response.getHeaders("mx-session-key")).thenReturn([ - "f3a370a8-397b-417b-992d-cc324819e311" - ]) - - when: - testNoMDCClearingSubject.doFilterInternal(request, response, filterChain) - - then: - MDC.get("log_guid") != null - MDC.get("client_guid") == "3a1a8ff6-778e-40e0-995a-72d6bf6ccb35" - MDC.get("client_id") == "client-id" - MDC.get("path") == "/testing" - MDC.get("user_guid") == "a851008c-d85a-4dcf-87f0-b1e2a69adaf3" - MDC.get("feature") == "feature" - MDC.get("ip_address") == "10.10.10.1" - MDC.get("session_trace_id") == "ebebebe" - MDC.get("device_trace_id") == "device123" - MDC.get("request_method") == "GET" - MDC.get("request_uri") == "https://localhost:13024/testing" - MDC.get("query_params") == "param1: value1\nparam2: value2\n" - MDC.get("request_headers_json") == "{\"Accept\":\"application/vnd.mx.mdx.v6+json\",\"x-request-token\":\"**MASKED**\",\"mx-device-ip-address\":\"10.10.10.1\"}" - MDC.get("request_headers") == "Accept: application/vnd.mx.mdx.v6+json\nx-request-token: **MASKED**\nmx-device-ip-address: 10.10.10.1\n" - MDC.get("request_body") == null - MDC.get("request_duration") != null - MDC.get("response_headers_json") == "{\"Content-Length\":\"50\",\"mx-session-key\":\"**MASKED**\",\"Content-Type\":\"application/vnd.mx.mdx.v6+json\"}" - MDC.get("response_headers") == "Content-Length: 50\nmx-session-key: **MASKED**\nContent-Type: application/vnd.mx.mdx.v6+json\n" - } - - private class PathRequestLoggingFilterWithNoMDCClearing extends PathRequestLoggingFilter { - @Override - protected void resetMDC() { - } - } -} diff --git a/realtime/gradle.lockfile b/realtime/gradle.lockfile index 8973cd3b..5f42c470 100644 --- a/realtime/gradle.lockfile +++ b/realtime/gradle.lockfile @@ -70,7 +70,7 @@ org.apache.commons:commons-lang3:3.13.0=spotbugs org.apache.commons:commons-lang3:3.17.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.commons:commons-lang3:3.8.1=pmd org.apache.commons:commons-text:1.10.0=spotbugs -org.apache.commons:commons-text:1.13.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.commons:commons-text:1.13.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy-bom:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.groovy:groovy:4.0.6=testCompileClasspath,testRuntimeClasspath org.apache.httpcomponents.client5:httpclient5:5.1.3=spotbugs