onlinepayments-sdk-ruby 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +140 -0
- data/Rakefile +34 -0
- data/lib/onlinepayments/sdk/api_exception.rb +42 -0
- data/lib/onlinepayments/sdk/api_resource.rb +115 -0
- data/lib/onlinepayments/sdk/authenticator.rb +16 -0
- data/lib/onlinepayments/sdk/authorization_exception.rb +13 -0
- data/lib/onlinepayments/sdk/call_context.rb +26 -0
- data/lib/onlinepayments/sdk/client.rb +82 -0
- data/lib/onlinepayments/sdk/communication_exception.rb +16 -0
- data/lib/onlinepayments/sdk/communicator.rb +300 -0
- data/lib/onlinepayments/sdk/communicator_configuration.rb +59 -0
- data/lib/onlinepayments/sdk/connection.rb +41 -0
- data/lib/onlinepayments/sdk/data_object.rb +31 -0
- data/lib/onlinepayments/sdk/declined_payment_exception.rb +30 -0
- data/lib/onlinepayments/sdk/declined_payout_exception.rb +32 -0
- data/lib/onlinepayments/sdk/declined_refund_exception.rb +32 -0
- data/lib/onlinepayments/sdk/declined_transaction_exception.rb +16 -0
- data/lib/onlinepayments/sdk/defaultimpl/authorization_type.rb +24 -0
- data/lib/onlinepayments/sdk/defaultimpl/default_authenticator.rb +108 -0
- data/lib/onlinepayments/sdk/defaultimpl/default_connection.rb +295 -0
- data/lib/onlinepayments/sdk/defaultimpl/default_marshaller.rb +32 -0
- data/lib/onlinepayments/sdk/defaultimpl.rb +6 -0
- data/lib/onlinepayments/sdk/domain/account_on_file.rb +49 -0
- data/lib/onlinepayments/sdk/domain/account_on_file_attribute.rb +38 -0
- data/lib/onlinepayments/sdk/domain/account_on_file_display_hints.rb +37 -0
- data/lib/onlinepayments/sdk/domain/additional_order_input.rb +54 -0
- data/lib/onlinepayments/sdk/domain/address.rb +50 -0
- data/lib/onlinepayments/sdk/domain/address_personal.rb +58 -0
- data/lib/onlinepayments/sdk/domain/airline_data.rb +128 -0
- data/lib/onlinepayments/sdk/domain/airline_flight_leg.rb +102 -0
- data/lib/onlinepayments/sdk/domain/airline_passenger.rb +38 -0
- data/lib/onlinepayments/sdk/domain/amount_breakdown.rb +30 -0
- data/lib/onlinepayments/sdk/domain/amount_of_money.rb +30 -0
- data/lib/onlinepayments/sdk/domain/api_error.rb +46 -0
- data/lib/onlinepayments/sdk/domain/bank_account_iban.rb +26 -0
- data/lib/onlinepayments/sdk/domain/browser_data.rb +42 -0
- data/lib/onlinepayments/sdk/domain/cancel_payment_response.rb +30 -0
- data/lib/onlinepayments/sdk/domain/capture.rb +46 -0
- data/lib/onlinepayments/sdk/domain/capture_output.rb +82 -0
- data/lib/onlinepayments/sdk/domain/capture_payment_request.rb +38 -0
- data/lib/onlinepayments/sdk/domain/capture_response.rb +46 -0
- data/lib/onlinepayments/sdk/domain/capture_status_output.rb +26 -0
- data/lib/onlinepayments/sdk/domain/captures_response.rb +33 -0
- data/lib/onlinepayments/sdk/domain/card.rb +38 -0
- data/lib/onlinepayments/sdk/domain/card_essentials.rb +34 -0
- data/lib/onlinepayments/sdk/domain/card_fraud_results.rb +34 -0
- data/lib/onlinepayments/sdk/domain/card_payment_method_specific_input.rb +98 -0
- data/lib/onlinepayments/sdk/domain/card_payment_method_specific_input_base.rb +86 -0
- data/lib/onlinepayments/sdk/domain/card_payment_method_specific_input_for_hosted_checkout.rb +26 -0
- data/lib/onlinepayments/sdk/domain/card_payment_method_specific_output.rb +78 -0
- data/lib/onlinepayments/sdk/domain/card_payout_method_specific_input.rb +38 -0
- data/lib/onlinepayments/sdk/domain/card_recurrence_details.rb +26 -0
- data/lib/onlinepayments/sdk/domain/card_without_cvv.rb +34 -0
- data/lib/onlinepayments/sdk/domain/company_information.rb +26 -0
- data/lib/onlinepayments/sdk/domain/complete_payment_card_payment_method_specific_input.rb +30 -0
- data/lib/onlinepayments/sdk/domain/complete_payment_request.rb +38 -0
- data/lib/onlinepayments/sdk/domain/complete_payment_response.rb +46 -0
- data/lib/onlinepayments/sdk/domain/contact_details.rb +42 -0
- data/lib/onlinepayments/sdk/domain/create_hosted_checkout_request.rb +78 -0
- data/lib/onlinepayments/sdk/domain/create_hosted_checkout_response.rb +48 -0
- data/lib/onlinepayments/sdk/domain/create_hosted_tokenization_request.rb +38 -0
- data/lib/onlinepayments/sdk/domain/create_hosted_tokenization_response.rb +50 -0
- data/lib/onlinepayments/sdk/domain/create_mandate_request.rb +58 -0
- data/lib/onlinepayments/sdk/domain/create_mandate_response.rb +38 -0
- data/lib/onlinepayments/sdk/domain/create_mandate_with_return_url.rb +58 -0
- data/lib/onlinepayments/sdk/domain/create_payment_request.rb +74 -0
- data/lib/onlinepayments/sdk/domain/create_payment_response.rb +46 -0
- data/lib/onlinepayments/sdk/domain/create_payout_request.rb +46 -0
- data/lib/onlinepayments/sdk/domain/create_token_request.rb +34 -0
- data/lib/onlinepayments/sdk/domain/created_payment_output.rb +34 -0
- data/lib/onlinepayments/sdk/domain/created_token_response.rb +50 -0
- data/lib/onlinepayments/sdk/domain/customer.rb +86 -0
- data/lib/onlinepayments/sdk/domain/customer_account.rb +70 -0
- data/lib/onlinepayments/sdk/domain/customer_account_authentication.rb +30 -0
- data/lib/onlinepayments/sdk/domain/customer_device.rb +50 -0
- data/lib/onlinepayments/sdk/domain/customer_payment_activity.rb +34 -0
- data/lib/onlinepayments/sdk/domain/customer_token.rb +46 -0
- data/lib/onlinepayments/sdk/domain/decrypted_payment_data.rb +42 -0
- data/lib/onlinepayments/sdk/domain/directory_entry.rb +34 -0
- data/lib/onlinepayments/sdk/domain/empty_validator.rb +12 -0
- data/lib/onlinepayments/sdk/domain/error_response.rb +37 -0
- data/lib/onlinepayments/sdk/domain/external_cardholder_authentication_data.rb +58 -0
- data/lib/onlinepayments/sdk/domain/external_token_linked.rb +34 -0
- data/lib/onlinepayments/sdk/domain/fixed_list_validator.rb +32 -0
- data/lib/onlinepayments/sdk/domain/fraud_fields.rb +30 -0
- data/lib/onlinepayments/sdk/domain/fraud_results.rb +26 -0
- data/lib/onlinepayments/sdk/domain/g_pay_three_d_secure.rb +46 -0
- data/lib/onlinepayments/sdk/domain/get_hosted_checkout_response.rb +34 -0
- data/lib/onlinepayments/sdk/domain/get_hosted_tokenization_response.rb +34 -0
- data/lib/onlinepayments/sdk/domain/get_iin_details_request.rb +34 -0
- data/lib/onlinepayments/sdk/domain/get_iin_details_response.rb +45 -0
- data/lib/onlinepayments/sdk/domain/get_mandate_response.rb +30 -0
- data/lib/onlinepayments/sdk/domain/get_payment_product_groups_response.rb +33 -0
- data/lib/onlinepayments/sdk/domain/get_payment_products_response.rb +33 -0
- data/lib/onlinepayments/sdk/domain/gift_card_purchase.rb +34 -0
- data/lib/onlinepayments/sdk/domain/hosted_checkout_specific_input.rb +66 -0
- data/lib/onlinepayments/sdk/domain/hosted_checkout_specific_output.rb +30 -0
- data/lib/onlinepayments/sdk/domain/iin_detail.rb +30 -0
- data/lib/onlinepayments/sdk/domain/label_template_element.rb +30 -0
- data/lib/onlinepayments/sdk/domain/length_validator.rb +30 -0
- data/lib/onlinepayments/sdk/domain/line_item.rb +46 -0
- data/lib/onlinepayments/sdk/domain/line_item_invoice_data.rb +26 -0
- data/lib/onlinepayments/sdk/domain/loan_recipient.rb +42 -0
- data/lib/onlinepayments/sdk/domain/lodging_data.rb +26 -0
- data/lib/onlinepayments/sdk/domain/mandate_address.rb +42 -0
- data/lib/onlinepayments/sdk/domain/mandate_contact_details.rb +26 -0
- data/lib/onlinepayments/sdk/domain/mandate_customer.rb +58 -0
- data/lib/onlinepayments/sdk/domain/mandate_merchant_action.rb +34 -0
- data/lib/onlinepayments/sdk/domain/mandate_personal_information.rb +34 -0
- data/lib/onlinepayments/sdk/domain/mandate_personal_name.rb +30 -0
- data/lib/onlinepayments/sdk/domain/mandate_redirect_data.rb +30 -0
- data/lib/onlinepayments/sdk/domain/mandate_response.rb +50 -0
- data/lib/onlinepayments/sdk/domain/merchant_action.rb +34 -0
- data/lib/onlinepayments/sdk/domain/mobile_payment_data.rb +30 -0
- data/lib/onlinepayments/sdk/domain/mobile_payment_method_hosted_checkout_specific_input.rb +30 -0
- data/lib/onlinepayments/sdk/domain/mobile_payment_method_specific_input.rb +62 -0
- data/lib/onlinepayments/sdk/domain/mobile_payment_method_specific_output.rb +58 -0
- data/lib/onlinepayments/sdk/domain/mobile_payment_product320_specific_input.rb +30 -0
- data/lib/onlinepayments/sdk/domain/operation_output.rb +58 -0
- data/lib/onlinepayments/sdk/domain/order.rb +70 -0
- data/lib/onlinepayments/sdk/domain/order_line_details.rb +54 -0
- data/lib/onlinepayments/sdk/domain/order_references.rb +34 -0
- data/lib/onlinepayments/sdk/domain/order_status_output.rb +49 -0
- data/lib/onlinepayments/sdk/domain/order_type_information.rb +30 -0
- data/lib/onlinepayments/sdk/domain/payment_account_on_file.rb +30 -0
- data/lib/onlinepayments/sdk/domain/payment_context.rb +38 -0
- data/lib/onlinepayments/sdk/domain/payment_creation_output.rb +38 -0
- data/lib/onlinepayments/sdk/domain/payment_details_response.rb +65 -0
- data/lib/onlinepayments/sdk/domain/payment_error_response.rb +45 -0
- data/lib/onlinepayments/sdk/domain/payment_output.rb +82 -0
- data/lib/onlinepayments/sdk/domain/payment_product.rb +102 -0
- data/lib/onlinepayments/sdk/domain/payment_product130_specific_input.rb +30 -0
- data/lib/onlinepayments/sdk/domain/payment_product130_specific_three_d_secure.rb +38 -0
- data/lib/onlinepayments/sdk/domain/payment_product302_specific_data.rb +32 -0
- data/lib/onlinepayments/sdk/domain/payment_product320_specific_data.rb +36 -0
- data/lib/onlinepayments/sdk/domain/payment_product5100_specific_input.rb +26 -0
- data/lib/onlinepayments/sdk/domain/payment_product5402_specific_output.rb +26 -0
- data/lib/onlinepayments/sdk/domain/payment_product5500_specific_output.rb +34 -0
- data/lib/onlinepayments/sdk/domain/payment_product771_specific_output.rb +26 -0
- data/lib/onlinepayments/sdk/domain/payment_product840_customer_account.rb +54 -0
- data/lib/onlinepayments/sdk/domain/payment_product840_specific_output.rb +53 -0
- data/lib/onlinepayments/sdk/domain/payment_product_display_hints.rb +34 -0
- data/lib/onlinepayments/sdk/domain/payment_product_field.rb +46 -0
- data/lib/onlinepayments/sdk/domain/payment_product_field_data_restrictions.rb +34 -0
- data/lib/onlinepayments/sdk/domain/payment_product_field_display_element.rb +38 -0
- data/lib/onlinepayments/sdk/domain/payment_product_field_display_hints.rb +70 -0
- data/lib/onlinepayments/sdk/domain/payment_product_field_form_element.rb +37 -0
- data/lib/onlinepayments/sdk/domain/payment_product_field_tooltip.rb +30 -0
- data/lib/onlinepayments/sdk/domain/payment_product_field_validators.rb +90 -0
- data/lib/onlinepayments/sdk/domain/payment_product_filter.rb +42 -0
- data/lib/onlinepayments/sdk/domain/payment_product_filters_hosted_checkout.rb +37 -0
- data/lib/onlinepayments/sdk/domain/payment_product_group.rb +52 -0
- data/lib/onlinepayments/sdk/domain/payment_product_networks_response.rb +32 -0
- data/lib/onlinepayments/sdk/domain/payment_references.rb +30 -0
- data/lib/onlinepayments/sdk/domain/payment_response.rb +54 -0
- data/lib/onlinepayments/sdk/domain/payment_status_output.rb +57 -0
- data/lib/onlinepayments/sdk/domain/payout_error_response.rb +45 -0
- data/lib/onlinepayments/sdk/domain/payout_output.rb +30 -0
- data/lib/onlinepayments/sdk/domain/payout_response.rb +46 -0
- data/lib/onlinepayments/sdk/domain/payout_result.rb +46 -0
- data/lib/onlinepayments/sdk/domain/payout_status_output.rb +34 -0
- data/lib/onlinepayments/sdk/domain/personal_information.rb +38 -0
- data/lib/onlinepayments/sdk/domain/personal_information_token.rb +30 -0
- data/lib/onlinepayments/sdk/domain/personal_name.rb +34 -0
- data/lib/onlinepayments/sdk/domain/personal_name_token.rb +30 -0
- data/lib/onlinepayments/sdk/domain/product_directory.rb +33 -0
- data/lib/onlinepayments/sdk/domain/protection_eligibility.rb +30 -0
- data/lib/onlinepayments/sdk/domain/range_validator.rb +30 -0
- data/lib/onlinepayments/sdk/domain/redirect_data.rb +30 -0
- data/lib/onlinepayments/sdk/domain/redirect_payment_method_specific_input.rb +66 -0
- data/lib/onlinepayments/sdk/domain/redirect_payment_method_specific_output.rb +66 -0
- data/lib/onlinepayments/sdk/domain/redirect_payment_product809_specific_input.rb +26 -0
- data/lib/onlinepayments/sdk/domain/redirect_payment_product840_specific_input.rb +26 -0
- data/lib/onlinepayments/sdk/domain/redirection_data.rb +26 -0
- data/lib/onlinepayments/sdk/domain/refund_card_method_specific_output.rb +30 -0
- data/lib/onlinepayments/sdk/domain/refund_e_wallet_method_specific_output.rb +38 -0
- data/lib/onlinepayments/sdk/domain/refund_error_response.rb +45 -0
- data/lib/onlinepayments/sdk/domain/refund_mobile_method_specific_output.rb +34 -0
- data/lib/onlinepayments/sdk/domain/refund_output.rb +82 -0
- data/lib/onlinepayments/sdk/domain/refund_payment_product840_customer_account.rb +34 -0
- data/lib/onlinepayments/sdk/domain/refund_payment_product840_specific_output.rb +30 -0
- data/lib/onlinepayments/sdk/domain/refund_redirect_method_specific_output.rb +30 -0
- data/lib/onlinepayments/sdk/domain/refund_request.rb +38 -0
- data/lib/onlinepayments/sdk/domain/refund_response.rb +46 -0
- data/lib/onlinepayments/sdk/domain/refunds_response.rb +33 -0
- data/lib/onlinepayments/sdk/domain/regular_expression_validator.rb +26 -0
- data/lib/onlinepayments/sdk/domain/sepa_direct_debit_payment_method_specific_input.rb +34 -0
- data/lib/onlinepayments/sdk/domain/sepa_direct_debit_payment_method_specific_input_base.rb +34 -0
- data/lib/onlinepayments/sdk/domain/sepa_direct_debit_payment_method_specific_output.rb +42 -0
- data/lib/onlinepayments/sdk/domain/sepa_direct_debit_payment_product771_specific_input.rb +34 -0
- data/lib/onlinepayments/sdk/domain/sepa_direct_debit_payment_product771_specific_input_base.rb +34 -0
- data/lib/onlinepayments/sdk/domain/session_request.rb +32 -0
- data/lib/onlinepayments/sdk/domain/session_response.rb +48 -0
- data/lib/onlinepayments/sdk/domain/shipping.rb +58 -0
- data/lib/onlinepayments/sdk/domain/shopping_cart.rb +64 -0
- data/lib/onlinepayments/sdk/domain/shopping_cart_extension.rb +52 -0
- data/lib/onlinepayments/sdk/domain/test_connection.rb +26 -0
- data/lib/onlinepayments/sdk/domain/three_d_secure.rb +78 -0
- data/lib/onlinepayments/sdk/domain/three_d_secure_base.rb +58 -0
- data/lib/onlinepayments/sdk/domain/three_d_secure_data.rb +34 -0
- data/lib/onlinepayments/sdk/domain/three_d_secure_results.rb +30 -0
- data/lib/onlinepayments/sdk/domain/token_card.rb +34 -0
- data/lib/onlinepayments/sdk/domain/token_card_data.rb +30 -0
- data/lib/onlinepayments/sdk/domain/token_card_specific_input.rb +30 -0
- data/lib/onlinepayments/sdk/domain/token_data.rb +30 -0
- data/lib/onlinepayments/sdk/domain/token_e_wallet.rb +34 -0
- data/lib/onlinepayments/sdk/domain/token_response.rb +58 -0
- data/lib/onlinepayments/sdk/domain/value_mapping_element.rb +37 -0
- data/lib/onlinepayments/sdk/endpoint_configuration.rb +127 -0
- data/lib/onlinepayments/sdk/exceptions.rb +8 -0
- data/lib/onlinepayments/sdk/factory.rb +136 -0
- data/lib/onlinepayments/sdk/idempotence_exception.rb +24 -0
- data/lib/onlinepayments/sdk/logging/communicator_logger.rb +22 -0
- data/lib/onlinepayments/sdk/logging/log_message_builder.rb +56 -0
- data/lib/onlinepayments/sdk/logging/logging_capable.rb +17 -0
- data/lib/onlinepayments/sdk/logging/logging_util.rb +286 -0
- data/lib/onlinepayments/sdk/logging/request_log_message_builder.rb +39 -0
- data/lib/onlinepayments/sdk/logging/response_log_message_builder.rb +34 -0
- data/lib/onlinepayments/sdk/logging/ruby_communicator_logger.rb +57 -0
- data/lib/onlinepayments/sdk/logging/stdout_communicator_logger.rb +34 -0
- data/lib/onlinepayments/sdk/logging.rb +10 -0
- data/lib/onlinepayments/sdk/marshaller.rb +24 -0
- data/lib/onlinepayments/sdk/marshaller_syntax_exception.rb +6 -0
- data/lib/onlinepayments/sdk/merchant/hostedcheckout/hosted_checkout_client.rb +86 -0
- data/lib/onlinepayments/sdk/merchant/hostedtokenization/hosted_tokenization_client.rb +86 -0
- data/lib/onlinepayments/sdk/merchant/mandates/mandates_client.rb +182 -0
- data/lib/onlinepayments/sdk/merchant/merchant_client.rb +89 -0
- data/lib/onlinepayments/sdk/merchant/payments/payments_client.rb +322 -0
- data/lib/onlinepayments/sdk/merchant/payouts/payouts_client.rb +86 -0
- data/lib/onlinepayments/sdk/merchant/productgroups/get_product_group_params.rb +57 -0
- data/lib/onlinepayments/sdk/merchant/productgroups/get_product_groups_params.rb +57 -0
- data/lib/onlinepayments/sdk/merchant/productgroups/product_groups_client.rb +87 -0
- data/lib/onlinepayments/sdk/merchant/products/get_payment_product_networks_params.rb +38 -0
- data/lib/onlinepayments/sdk/merchant/products/get_payment_product_params.rb +57 -0
- data/lib/onlinepayments/sdk/merchant/products/get_payment_products_params.rb +57 -0
- data/lib/onlinepayments/sdk/merchant/products/get_product_directory_params.rb +30 -0
- data/lib/onlinepayments/sdk/merchant/products/products_client.rb +155 -0
- data/lib/onlinepayments/sdk/merchant/services/services_client.rb +82 -0
- data/lib/onlinepayments/sdk/merchant/sessions/sessions_client.rb +54 -0
- data/lib/onlinepayments/sdk/merchant/tokens/tokens_client.rb +116 -0
- data/lib/onlinepayments/sdk/meta_data_provider.rb +150 -0
- data/lib/onlinepayments/sdk/modules.rb +62 -0
- data/lib/onlinepayments/sdk/not_found_exception.rb +16 -0
- data/lib/onlinepayments/sdk/param_request.rb +11 -0
- data/lib/onlinepayments/sdk/payment_platform_exception.rb +15 -0
- data/lib/onlinepayments/sdk/pooled_connection.rb +21 -0
- data/lib/onlinepayments/sdk/proxy_configuration.rb +74 -0
- data/lib/onlinepayments/sdk/reference_exception.rb +14 -0
- data/lib/onlinepayments/sdk/request_header.rb +50 -0
- data/lib/onlinepayments/sdk/request_param.rb +23 -0
- data/lib/onlinepayments/sdk/response_exception.rb +47 -0
- data/lib/onlinepayments/sdk/response_header.rb +42 -0
- data/lib/onlinepayments/sdk/validation_exception.rb +14 -0
- data/lib/onlinepayments/sdk/webhooks/api_version_mismatch_exception.rb +20 -0
- data/lib/onlinepayments/sdk/webhooks/in_memory_secret_key_store.rb +56 -0
- data/lib/onlinepayments/sdk/webhooks/secret_key_not_available_exception.rb +17 -0
- data/lib/onlinepayments/sdk/webhooks/secret_key_store.rb +16 -0
- data/lib/onlinepayments/sdk/webhooks/signature_validation_exception.rb +19 -0
- data/lib/onlinepayments/sdk/webhooks/webhooks.rb +22 -0
- data/lib/onlinepayments/sdk/webhooks/webhooks_event.rb +58 -0
- data/lib/onlinepayments/sdk/webhooks/webhooks_helper.rb +100 -0
- data/lib/onlinepayments/sdk/webhooks/webhooks_helper_builder.rb +25 -0
- data/lib/onlinepayments/sdk/webhooks.rb +11 -0
- data/lib/onlinepayments/sdk.rb +26 -0
- data/onlinepayments-sdk-ruby.gemspec +28 -0
- metadata +416 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
|
|
3
|
+
module OnlinePayments::SDK
|
|
4
|
+
|
|
5
|
+
# Base class for configuration classes in the SDK.
|
|
6
|
+
#
|
|
7
|
+
# @attr [String] api_endpoint The base URL to the Online Payments platform.
|
|
8
|
+
# @attr [Integer] connect_timeout The number of seconds before a connection attempt with the Online Payments platform times out.
|
|
9
|
+
# @attr [Integer] socket_timeout The number of seconds before a timeout occurs when transmitting data to or from the Online Payments platform.
|
|
10
|
+
# @attr [Integer] max_connections The number of connections with the Online Payments platform that are kept alive in the connection pool.
|
|
11
|
+
# These connections will be reused when possible.
|
|
12
|
+
# @attr [OnlinePayments::SDK::ProxyConfiguration] proxy_configuration Proxy settings.
|
|
13
|
+
# @attr [String] integrator Name of the integrator
|
|
14
|
+
# @attr [OnlinePayments::SDK::Domain::ShoppingCartExtension] shopping_cart_extension Shopping cart-related metadata.
|
|
15
|
+
class EndpointConfiguration
|
|
16
|
+
DEFAULT_CONNECT_TIMEOUT = 10
|
|
17
|
+
DEFAULT_SOCKET_TIMEOUT = 10
|
|
18
|
+
DEFAULT_MAX_CONNECTIONS = 10
|
|
19
|
+
|
|
20
|
+
# The default number of seconds before a connection attempt with the Online Payments platform times out.
|
|
21
|
+
# Used if _connectTimeout_ is not present in the properties.
|
|
22
|
+
def self.default_connect_timeout
|
|
23
|
+
DEFAULT_CONNECT_TIMEOUT
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# The default number of seconds before a timeout occurs when transmitting data to or from the Online Payments platform.
|
|
27
|
+
# Used if _socketTimeout_ is not present in the properties.
|
|
28
|
+
def self.default_socket_timeout
|
|
29
|
+
DEFAULT_SOCKET_TIMEOUT
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# The default number of connections that are kept alive in the connection pool.
|
|
33
|
+
# Used if _maxConnections_ is not present in the properties.
|
|
34
|
+
def self.default_max_connections
|
|
35
|
+
DEFAULT_MAX_CONNECTIONS
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Initializes a new EndpointConfiguration.
|
|
39
|
+
#
|
|
40
|
+
# The given _properties_ is searched for settings using properties[prefix + '.setting_name']
|
|
41
|
+
# The following settings are searched:
|
|
42
|
+
#
|
|
43
|
+
# endpoint:: This property is searched for *endpoint.host*, *endpoint.scheme* and *endpoint.port*.
|
|
44
|
+
# The found host, scheme and port are used to construct the base URL to the Online Payments platform.
|
|
45
|
+
# connectTimeout:: The number of seconds before a connection attempt with the Online Payments platform times out.
|
|
46
|
+
# socketTimeout:: The number of seconds before a timeout occurs when transmitting data to or from the Online Payments platform.
|
|
47
|
+
# maxConnections:: The number of connections with the Online Payments platform
|
|
48
|
+
# that are kept alive in the connection pool. These connections will be reused when possible.
|
|
49
|
+
# proxy:: This property is searched for *proxy.uri*, *proxy.username* and *proxy.password*.
|
|
50
|
+
# The found URI, username and password are used
|
|
51
|
+
# for connecting to the Online Payments platform using a proxy.
|
|
52
|
+
# integrator:: Name of the integrator
|
|
53
|
+
# shoppingCartExtension:: Will be used to initialize a {OnlinePayments::SDK::Domain::ShoppingCartExtension}.
|
|
54
|
+
def initialize(properties = nil, prefix = nil)
|
|
55
|
+
return unless properties
|
|
56
|
+
|
|
57
|
+
@api_endpoint = get_endpoint(properties, prefix)
|
|
58
|
+
@connect_timeout = get_property(properties, "#{prefix}.connectTimeout", DEFAULT_CONNECT_TIMEOUT)
|
|
59
|
+
@socket_timeout = get_property(properties, "#{prefix}.socketTimeout", DEFAULT_SOCKET_TIMEOUT)
|
|
60
|
+
@max_connections = get_property(properties, "#{prefix}.maxConnections", DEFAULT_MAX_CONNECTIONS)
|
|
61
|
+
|
|
62
|
+
proxy_uri = properties["#{prefix}.proxy.uri"]
|
|
63
|
+
if proxy_uri
|
|
64
|
+
proxy_user = properties["#{prefix}.proxy.username"]
|
|
65
|
+
proxy_pass = properties["#{prefix}.proxy.password"]
|
|
66
|
+
@proxy_configuration = ProxyConfiguration.new(address: URI(proxy_uri),
|
|
67
|
+
username: proxy_user,
|
|
68
|
+
password: proxy_pass)
|
|
69
|
+
end
|
|
70
|
+
@integrator = properties["#{prefix}.integrator"]
|
|
71
|
+
@shopping_cart_extension = get_shopping_cart_extension(properties, prefix)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
protected
|
|
75
|
+
|
|
76
|
+
def set_endpoint(endpoint)
|
|
77
|
+
if endpoint
|
|
78
|
+
raise ArgumentError, 'endpoint should not contain a path' if endpoint.path
|
|
79
|
+
if endpoint.userinfo || endpoint.query || endpoint.fragment
|
|
80
|
+
raise ArgumentError('endpoint should not contain user info, query or fragment')
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
@api_endpoint = endpoint
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
private
|
|
87
|
+
|
|
88
|
+
def get_property(properties, key, default_value)
|
|
89
|
+
property_value = properties[key]
|
|
90
|
+
property_value.nil? ? default_value : property_value
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def get_endpoint(properties, prefix)
|
|
94
|
+
host = properties["#{prefix}.endpoint.host"]
|
|
95
|
+
scheme = properties["#{prefix}.endpoint.scheme"] || 'https'
|
|
96
|
+
port = properties["#{prefix}.endpoint.port"] || -1
|
|
97
|
+
create_uri(scheme, host, port)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def create_uri(scheme, host, port)
|
|
101
|
+
port == -1 ? "#{scheme}://#{host}" : "#{scheme}://#{host}:#{port}"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def get_shopping_cart_extension(properties, prefix)
|
|
105
|
+
creator = properties["#{prefix}.shoppingCartExtension.creator"]
|
|
106
|
+
name = properties["#{prefix}.shoppingCartExtension.name"]
|
|
107
|
+
version = properties["#{prefix}.shoppingCartExtension.version"]
|
|
108
|
+
extension_id = properties["#{prefix}.shoppingCartExtension.extensionId"]
|
|
109
|
+
(creator || name || version || extension_id) ?
|
|
110
|
+
Domain::ShoppingCartExtension.new(creator, name, version, extension_id) :
|
|
111
|
+
nil
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
public
|
|
115
|
+
|
|
116
|
+
attr_reader :api_endpoint
|
|
117
|
+
|
|
118
|
+
attr_accessor :connect_timeout
|
|
119
|
+
attr_accessor :socket_timeout
|
|
120
|
+
attr_accessor :max_connections
|
|
121
|
+
|
|
122
|
+
attr_accessor :proxy_configuration
|
|
123
|
+
|
|
124
|
+
attr_accessor :integrator
|
|
125
|
+
attr_accessor :shopping_cart_extension
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
prefix = 'onlinepayments/sdk/'
|
|
2
|
+
suffix = '_exception'
|
|
3
|
+
exception_types = %w[api authorization communication declined_transaction
|
|
4
|
+
declined_payment declined_refund
|
|
5
|
+
payment_platform idempotence marshaller_syntax not_found
|
|
6
|
+
reference response validation]
|
|
7
|
+
|
|
8
|
+
exception_types.each { |type| require prefix + type + suffix }
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
module OnlinePayments::SDK
|
|
4
|
+
|
|
5
|
+
# Convenience class that constructs instances of several other classes in the SDK.
|
|
6
|
+
# Provides methods to construct
|
|
7
|
+
# {OnlinePayments::SDK::CommunicatorConfiguration}, {OnlinePayments::SDK::Communicator} and {OnlinePayments::SDK::Client} instances.
|
|
8
|
+
class Factory
|
|
9
|
+
|
|
10
|
+
# Creates and returns a {OnlinePayments::SDK::CommunicatorConfiguration} based on the configuration in the file located at _configuration_file_name_.
|
|
11
|
+
#
|
|
12
|
+
# @param config_file_name [String] Path to the configuration file to use, should be in YAML format.
|
|
13
|
+
# @param api_key_id [String] Key id for the OnlinePayments service.
|
|
14
|
+
# @param secret_api_key [String] Secret key used for authentication to the OnlinePayments service.
|
|
15
|
+
# @return [OnlinePayments::SDK::CommunicatorConfiguration] The created communicator configuration
|
|
16
|
+
def self.create_configuration(config_file_name, api_key_id, secret_api_key)
|
|
17
|
+
properties = YAML::load_file(config_file_name)
|
|
18
|
+
CommunicatorConfiguration.new(properties: properties,
|
|
19
|
+
api_key_id: api_key_id,
|
|
20
|
+
secret_api_key: secret_api_key)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Creates and returns an {OnlinePayments::SDK::Communicator} that can be used for communication with the OnlinePayments service.
|
|
24
|
+
#
|
|
25
|
+
# @param configuration [OnlinePayments::SDK::CommunicatorConfiguration] contains configuration settings to be used by the client.
|
|
26
|
+
# @param meta_data_provider [OnlinePayments::SDK::MetaDataProvider,nil] stores the metadata for the communicating client.
|
|
27
|
+
# @param connection [OnlinePayments::SDK::Connection,nil] connection that can be used to communicate with the Online Payments platform.
|
|
28
|
+
# @param authenticator [OnlinePayments::SDK::Authenticator,nil] authenticator that can authenticate messages sent to the Online Payments platform.
|
|
29
|
+
# @param marshaller [OnlinePayments::SDK::Marshaller,nil] marshaller that marshalls and unmarshalls messages sent to the Online Payments platform.
|
|
30
|
+
# @return [OnlinePayments::SDK::Communicator] The created communicator
|
|
31
|
+
def self.create_communicator_from_configuration(configuration, meta_data_provider: nil, connection: nil, authenticator: nil, marshaller: DefaultImpl::DefaultMarshaller.INSTANCE)
|
|
32
|
+
meta_data_provider ||= MetaDataProvider.new(configuration.integrator, shopping_cart_extension: configuration.shopping_cart_extension)
|
|
33
|
+
connection ||= DefaultImpl::DefaultConnection.new({ connect_timeout: configuration.connect_timeout,
|
|
34
|
+
socket_timeout: configuration.socket_timeout,
|
|
35
|
+
max_connections: configuration.max_connections,
|
|
36
|
+
proxy_configuration: configuration.proxy_configuration })
|
|
37
|
+
authenticator ||= DefaultImpl::DefaultAuthenticator.new(configuration.api_key_id,
|
|
38
|
+
configuration.secret_api_key,
|
|
39
|
+
configuration.authorization_type)
|
|
40
|
+
Communicator.new(configuration.api_endpoint, connection, authenticator, meta_data_provider, marshaller)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Creates and returns an {OnlinePayments::SDK::Communicator} that is used for communication with the OnlinePayments service.
|
|
44
|
+
#
|
|
45
|
+
# @param config_file_name [String] Path to the configuration file to use, should be in YAML format.
|
|
46
|
+
# @param api_key_id [String] Key id for the OnlinePayments service.
|
|
47
|
+
# @param secret_api_key [String] Secret key used for authentication to the OnlinePayments service.
|
|
48
|
+
# @param meta_data_provider [OnlinePayments::SDK::MetaDataProvider,nil] stores the metadata for the communicating client.
|
|
49
|
+
# @param connection [OnlinePayments::SDK::Connection,nil] connection that can be used to communicate with the Online Payments platform.
|
|
50
|
+
# @param authenticator [OnlinePayments::SDK::Authenticator,nil] authenticator that can authenticate messages sent to the Online Payments platform.
|
|
51
|
+
# @return [OnlinePayments::SDK::Communicator] The created communicator
|
|
52
|
+
def self.create_communicator_from_file(config_file_name, api_key_id, secret_api_key,
|
|
53
|
+
meta_data_provider: nil, connection: nil, authenticator: nil,
|
|
54
|
+
marshaller: DefaultImpl::DefaultMarshaller.INSTANCE)
|
|
55
|
+
configuration = create_configuration(config_file_name, api_key_id, secret_api_key)
|
|
56
|
+
create_communicator_from_configuration(configuration, meta_data_provider: meta_data_provider, connection: connection,
|
|
57
|
+
authenticator: authenticator, marshaller: marshaller)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Creates and returns an {OnlinePayments::SDK::Client} that provides the a high-level interface with the OnlinePayments service.
|
|
61
|
+
# If a code block is given, the created client is returned to the code block and closed afterwards.
|
|
62
|
+
#
|
|
63
|
+
# @example Providing a code block
|
|
64
|
+
# Factory.create_client_from_configuration(configuration) do |client|
|
|
65
|
+
# client.merchant(merchant_id).services.testconnection
|
|
66
|
+
# end
|
|
67
|
+
# # client is closed here
|
|
68
|
+
#
|
|
69
|
+
# @param configuration [OnlinePayments::SDK::CommunicatorConfiguration] contains configuration settings to be used by the client.
|
|
70
|
+
# @return [OnlinePayments::SDK::Client] The created client
|
|
71
|
+
def self.create_client_from_configuration(configuration)
|
|
72
|
+
communicator = create_communicator_from_configuration(configuration)
|
|
73
|
+
client = Client.new(communicator)
|
|
74
|
+
if block_given?
|
|
75
|
+
begin
|
|
76
|
+
yield client
|
|
77
|
+
ensure
|
|
78
|
+
client.close
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
return client
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Creates and returns an {OnlinePayments::SDK::Client} that provides the a high-level interface with the OnlinePayments service.
|
|
86
|
+
# If a code block is given, the created client is returned to the code block and closed afterwards.
|
|
87
|
+
#
|
|
88
|
+
# @example Providing a code block
|
|
89
|
+
# Factory.create_client_from_communicator(communicator) do |client|
|
|
90
|
+
# client.merchant(merchant_id).services.testconnection
|
|
91
|
+
# end
|
|
92
|
+
# # client is closed here
|
|
93
|
+
#
|
|
94
|
+
# @param communicator [OnlinePayments::SDK::Communicator] provides network communication service for the Client
|
|
95
|
+
# @return [OnlinePayments::SDK::Client] The created client
|
|
96
|
+
def self.create_client_from_communicator(communicator)
|
|
97
|
+
client = Client.new(communicator)
|
|
98
|
+
if block_given?
|
|
99
|
+
begin
|
|
100
|
+
yield client
|
|
101
|
+
ensure
|
|
102
|
+
client.close
|
|
103
|
+
end
|
|
104
|
+
else
|
|
105
|
+
return client
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Creates and returns an {OnlinePayments::SDK::Client} that provides the a high-level interface with the OnlinePayments service.
|
|
110
|
+
# If a code block is given, the created client is returned to the code block and closed afterwards.
|
|
111
|
+
#
|
|
112
|
+
# @example Providing a code block
|
|
113
|
+
# Factory.create_client_from_file(config_file_name, api_key_id, secret_api_key) do |client|
|
|
114
|
+
# client.merchant(merchant_id).services.testconnection
|
|
115
|
+
# end
|
|
116
|
+
# # client is closed here
|
|
117
|
+
#
|
|
118
|
+
# @param config_file_name [String] Path to the configuration file to use, should be in YAML format.
|
|
119
|
+
# @param api_key_id [String] Key id for the OnlinePayments service.
|
|
120
|
+
# @param secret_api_key [String] Secret key used for authentication to the OnlinePayments service.
|
|
121
|
+
# @return [OnlinePayments::SDK::Client] The created client
|
|
122
|
+
def self.create_client_from_file(config_file_name, api_key_id, secret_api_key)
|
|
123
|
+
communicator = create_communicator_from_file(config_file_name, api_key_id, secret_api_key)
|
|
124
|
+
client = Client.new(communicator)
|
|
125
|
+
if block_given?
|
|
126
|
+
begin
|
|
127
|
+
yield client
|
|
128
|
+
ensure
|
|
129
|
+
client.close
|
|
130
|
+
end
|
|
131
|
+
else
|
|
132
|
+
return client
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module OnlinePayments::SDK
|
|
2
|
+
|
|
3
|
+
# This exception is thrown when a response from the Online Payments platform indicates
|
|
4
|
+
# a request with the same _idempotence_key_ was received earlier.
|
|
5
|
+
# The _idempotence_request_timestamp_ indicates the time when the first request with this _idempotence_key_ arrived.
|
|
6
|
+
#
|
|
7
|
+
# @attr_reader [String] idempotence_key The idempotence key used in the request.
|
|
8
|
+
# @attr_reader [Integer] idempotence_request_timestamp A timestamp indicating the arrival time of the request that conflicts with the request just sent.
|
|
9
|
+
class IdempotenceException < ApiException
|
|
10
|
+
|
|
11
|
+
# Create a new IdempotenceException
|
|
12
|
+
# @see ApiException#initialize
|
|
13
|
+
def initialize(status_code, response_body, error_id, errors, idempotence_key,
|
|
14
|
+
idempotence_request_timestamp,
|
|
15
|
+
message = 'the Online Payments platform returned a duplicate request error response')
|
|
16
|
+
super(status_code, response_body, error_id, errors, message)
|
|
17
|
+
@idempotence_key = idempotence_key
|
|
18
|
+
@idempotence_request_timestamp = idempotence_request_timestamp
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
attr_reader :idempotence_key
|
|
22
|
+
attr_reader :idempotence_request_timestamp
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module OnlinePayments::SDK
|
|
2
|
+
module Logging
|
|
3
|
+
|
|
4
|
+
# Base logger class used in this SDK. This class is an interface and cannot be instantiated.
|
|
5
|
+
class CommunicatorLogger
|
|
6
|
+
# Interface, no instantiation
|
|
7
|
+
# @see OnlinePayments::SDK::Logging::StdoutCommunicatorLogger
|
|
8
|
+
# @see OnlinePayments::SDK::Logging::RubyCommunicatorLogger
|
|
9
|
+
def initialize
|
|
10
|
+
raise NotImplementedError, "#{self.class.name} is not implemented."
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Logs a message with or without exception
|
|
14
|
+
#
|
|
15
|
+
# @param message [String] the message to log
|
|
16
|
+
# @param thrown [Exception, false] the exception to log, or false to log no exception
|
|
17
|
+
def log(message, thrown = false)
|
|
18
|
+
raise NotImplementedError, "#{self.class.name}#log() is not implemented."
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module OnlinePayments::SDK
|
|
2
|
+
module Logging
|
|
3
|
+
|
|
4
|
+
# Abstract class used to construct a message describing a request or response.
|
|
5
|
+
#
|
|
6
|
+
# @attr_reader [String] request_id An identifier assigned to the request and response
|
|
7
|
+
# @attr_reader [String] headers Request or response headers in string form
|
|
8
|
+
# @attr_reader [String] body Request or response body as a string
|
|
9
|
+
# @attr_reader [String] content_type Content type of the body, generally 'application/json' or 'text/html'
|
|
10
|
+
class LogMessageBuilder
|
|
11
|
+
|
|
12
|
+
attr_reader :request_id
|
|
13
|
+
attr_reader :headers
|
|
14
|
+
attr_reader :body
|
|
15
|
+
attr_reader :content_type
|
|
16
|
+
|
|
17
|
+
# Create a new LogMessageBuilder
|
|
18
|
+
def initialize(request_id)
|
|
19
|
+
raise ArgumentError if request_id.nil? || request_id.empty?
|
|
20
|
+
@request_id = request_id
|
|
21
|
+
@headers = ''
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Adds a single header to the #headers string
|
|
25
|
+
def add_headers(name, value)
|
|
26
|
+
@headers += ', ' unless @headers.empty?
|
|
27
|
+
@headers += "#{name}='#{LoggingUtil.obfuscate_header(name, value)}'"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Sets the body of this message to the parameter body.
|
|
31
|
+
|
|
32
|
+
# @param body [String] the message body
|
|
33
|
+
# @param content_type [String] the content type of the body
|
|
34
|
+
def set_body(body, content_type)
|
|
35
|
+
@body = LoggingUtil.obfuscate_body(body)
|
|
36
|
+
@content_type = content_type
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Constructs and returns the log message as a string.
|
|
40
|
+
def get_message
|
|
41
|
+
raise NotImplementedError, "#{self.class.name}#get_message() is not implemented."
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_s
|
|
45
|
+
self.class == LogMessageBuilder ?
|
|
46
|
+
super.to_s :
|
|
47
|
+
get_message
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Returns an empty string if the parameter is nil, and returns the parameter itself otherwise
|
|
51
|
+
protected def empty_if_null(value)
|
|
52
|
+
value.nil? ? '' : value
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module OnlinePayments
|
|
2
|
+
module SDK
|
|
3
|
+
module Logging
|
|
4
|
+
|
|
5
|
+
# Abstract mixin module that allows loggers to be registered to an object.
|
|
6
|
+
module LoggingCapable
|
|
7
|
+
def enable_logging(communicator_logger)
|
|
8
|
+
raise NotImplementedError
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def disable_logging
|
|
12
|
+
raise NotImplementedError
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
module OnlinePayments::SDK
|
|
2
|
+
module Logging
|
|
3
|
+
|
|
4
|
+
# Class responsible for obfuscating sensitive data in a message body.
|
|
5
|
+
class ValueObfuscator
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
|
|
9
|
+
alias_method :private_new, :new
|
|
10
|
+
|
|
11
|
+
protected :private_new, :new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
public
|
|
15
|
+
|
|
16
|
+
def self.INSTANCE
|
|
17
|
+
# use lazy instantiation
|
|
18
|
+
@@INSTANCE ||= ValueObfuscator.new
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Obfuscates the parameter value.
|
|
22
|
+
def obfuscate_value(value)
|
|
23
|
+
(value.nil? or value.empty?) ? value : "*#{value.length}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# end of ValueObfuscator
|
|
28
|
+
|
|
29
|
+
# Class responsible for obfuscating sensitive data.
|
|
30
|
+
class SensitiveValueObfuscator
|
|
31
|
+
|
|
32
|
+
class << self
|
|
33
|
+
|
|
34
|
+
alias_method :private_new, :new
|
|
35
|
+
|
|
36
|
+
protected :private_new, :new
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
public
|
|
40
|
+
|
|
41
|
+
def self.INSTANCE
|
|
42
|
+
# use lazy instantiation
|
|
43
|
+
@@INSTANCE ||= SensitiveValueObfuscator.new
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return an arbitrary number of '*', or null/empty if the value is null/empty.
|
|
47
|
+
def obfuscate_value(value)
|
|
48
|
+
value.nil? or value.empty? ? value : "***"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# end of SensitiveValueObfuscator
|
|
53
|
+
|
|
54
|
+
class Obfuscator
|
|
55
|
+
def initialize(obfuscators, case_insensitive)
|
|
56
|
+
raise ArgumentError unless obfuscators.is_a? Hash
|
|
57
|
+
@obfuscators = copy(obfuscators, case_insensitive)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
# case insensitive hash
|
|
63
|
+
# @private
|
|
64
|
+
class HashClod < Hash
|
|
65
|
+
|
|
66
|
+
def initialize(other)
|
|
67
|
+
other.each { |k, v| self.[]=(k, v) }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def [](key)
|
|
71
|
+
super _insensitive(key)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def []=(key, value)
|
|
75
|
+
super _insensitive(key), value
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
protected
|
|
79
|
+
|
|
80
|
+
def _insensitive(key)
|
|
81
|
+
key.respond_to?(:upcase) ? key.upcase : key
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# end of HashClod
|
|
86
|
+
|
|
87
|
+
def copy(obfuscators, case_insensitive)
|
|
88
|
+
cp = case_insensitive ? HashClod.new(obfuscators) : obfuscators
|
|
89
|
+
Marshal.load(Marshal.dump(cp)) # deep copy
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
public
|
|
93
|
+
|
|
94
|
+
def obfuscate_value(key, value)
|
|
95
|
+
obfuscator = @obfuscators[key]
|
|
96
|
+
if obfuscator.nil?
|
|
97
|
+
value
|
|
98
|
+
else
|
|
99
|
+
obfuscator.obfuscate_value(value)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# A convenient wrapper to build obfuscators
|
|
104
|
+
class Builder
|
|
105
|
+
attr_accessor :obfuscators
|
|
106
|
+
|
|
107
|
+
def initialize
|
|
108
|
+
raise NotImplementedError, "#{self.class.name} is not implemented."
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def with_field(key)
|
|
112
|
+
@obfuscators[key] = ValueObfuscator.INSTANCE
|
|
113
|
+
self
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def with_sensitive_field(key)
|
|
117
|
+
@obfuscators[key] = SensitiveValueObfuscator.INSTANCE
|
|
118
|
+
self
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def build
|
|
122
|
+
raise NotImplementedError, "#{self.class.name}#build() is not implemented."
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Builder
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Obfuscator
|
|
130
|
+
|
|
131
|
+
# Class that obfuscates headers of a message
|
|
132
|
+
class HeaderObfuscator < Obfuscator
|
|
133
|
+
def initialize(obfuscators)
|
|
134
|
+
# case insensitive
|
|
135
|
+
super(obfuscators, true)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def self.builder
|
|
139
|
+
Builder.new
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
class Builder < Obfuscator::Builder
|
|
143
|
+
def initialize
|
|
144
|
+
@obfuscators = {}
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def with_field(name)
|
|
148
|
+
raise ArgumentError unless name.is_a? String
|
|
149
|
+
super(name)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def with_sensitive_field(name)
|
|
153
|
+
raise ArgumentError unless name.is_a? String
|
|
154
|
+
super(name)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def build
|
|
158
|
+
HeaderObfuscator.new(obfuscators)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# end of HeadObfuscator
|
|
164
|
+
|
|
165
|
+
# Class that obfuscates properties in the JSON body of a message
|
|
166
|
+
class PropertyObfuscator < Obfuscator
|
|
167
|
+
def initialize(obfuscators)
|
|
168
|
+
# case sensitive
|
|
169
|
+
super(obfuscators, false)
|
|
170
|
+
@property_pattern = build_property_pattern(obfuscators.keys)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
private
|
|
174
|
+
|
|
175
|
+
def build_property_pattern(pn)
|
|
176
|
+
return /$^/ if pn.empty? # no possible match
|
|
177
|
+
# Regex to create:
|
|
178
|
+
# (["'])(X|Y|Z)\1\s*:\s*(?:(["'])(.*?)(?<!\\)\3|([^"'\s\[\{]\S*))
|
|
179
|
+
# Groups:
|
|
180
|
+
# 1: opening " or ' for the property name
|
|
181
|
+
# 2: property name
|
|
182
|
+
# 3: opening " or ' for the value
|
|
183
|
+
# 4: quoted value
|
|
184
|
+
# 5: non-quoted-value
|
|
185
|
+
# The negative lookbehind is to allow escaped quotes to be part of
|
|
186
|
+
# the value. What this does not allow currently is having values end
|
|
187
|
+
# with a \ (which would be escaped to \\).
|
|
188
|
+
regex = pn.inject("([\"'])(") { |r, p| "#{r}#{Regexp.quote(p)}|" }.chop <<
|
|
189
|
+
")\\1\\s*:\\s*(?:([\"'])(.*?)(?<!\\\\)\\3|([^\"'\\s\\[\\{]((?!,)\\S)*))"
|
|
190
|
+
/#{regex}/m # dotall mode
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
public
|
|
194
|
+
|
|
195
|
+
def obfuscate(body)
|
|
196
|
+
return nil if body.nil?
|
|
197
|
+
return "" if body.empty?
|
|
198
|
+
|
|
199
|
+
body.gsub(@property_pattern) do
|
|
200
|
+
m = Regexp.last_match
|
|
201
|
+
property_name = m[2]
|
|
202
|
+
value = m[4] || m[5]
|
|
203
|
+
# copy value 'cause it's part of m[0]
|
|
204
|
+
m[0].sub(value, obfuscate_value(property_name, value.dup))
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def self.builder
|
|
209
|
+
Builder.new
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
class Builder < Obfuscator::Builder
|
|
213
|
+
def initialize
|
|
214
|
+
@obfuscators = {}
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def with_field(property)
|
|
218
|
+
raise ArgumentError unless property.is_a? String
|
|
219
|
+
super(property)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def with_sensitive_field(property)
|
|
223
|
+
raise ArgumentError unless property.is_a? String
|
|
224
|
+
super(property)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def build
|
|
228
|
+
PropertyObfuscator.new(obfuscators)
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# end of property obfuscator
|
|
234
|
+
|
|
235
|
+
module LoggingUtil
|
|
236
|
+
@@PROPERTY_OBFUSCATOR = PropertyObfuscator.builder
|
|
237
|
+
.with_field("cardNumber")
|
|
238
|
+
.with_field("expiryDate")
|
|
239
|
+
.with_field("cvv")
|
|
240
|
+
.with_field("iban")
|
|
241
|
+
.with_field("accountNumber")
|
|
242
|
+
.with_field("reformattedAccountNumber")
|
|
243
|
+
.with_field("additionalInfo")
|
|
244
|
+
.with_field("cardholderName")
|
|
245
|
+
.with_field("dateOfBirth")
|
|
246
|
+
.with_field("emailAddress")
|
|
247
|
+
.with_field("faxNumber")
|
|
248
|
+
.with_field("firstName")
|
|
249
|
+
.with_field("houseNumber")
|
|
250
|
+
.with_field("mobilePhoneNumber")
|
|
251
|
+
.with_field("passengerName")
|
|
252
|
+
.with_field("phoneNumber")
|
|
253
|
+
.with_field("street")
|
|
254
|
+
.with_field("surname")
|
|
255
|
+
.with_field("workPhoneNumber")
|
|
256
|
+
.with_field("zip")
|
|
257
|
+
.with_field("bin")
|
|
258
|
+
.with_field("value")
|
|
259
|
+
.with_sensitive_field("keyId")
|
|
260
|
+
.with_sensitive_field("secretKey")
|
|
261
|
+
.with_sensitive_field("publicKey")
|
|
262
|
+
.with_sensitive_field("userAuthenticationToken")
|
|
263
|
+
.with_sensitive_field("encryptedPayload")
|
|
264
|
+
.with_sensitive_field("decryptedPayload")
|
|
265
|
+
.with_sensitive_field("encryptedCustomerInput")
|
|
266
|
+
.build
|
|
267
|
+
|
|
268
|
+
@@HEADER_OBFUSCATOR = HeaderObfuscator.builder
|
|
269
|
+
.with_sensitive_field("Authorization")
|
|
270
|
+
.with_sensitive_field("WWW-Authenticate")
|
|
271
|
+
.with_sensitive_field("Proxy-Authenticate")
|
|
272
|
+
.with_sensitive_field("Proxy-Authorization")
|
|
273
|
+
.with_sensitive_field("X-GCS-Authentication-Token")
|
|
274
|
+
.with_sensitive_field("X-GCS-CallerPassword")
|
|
275
|
+
.build
|
|
276
|
+
|
|
277
|
+
def self.obfuscate_body(body)
|
|
278
|
+
@@PROPERTY_OBFUSCATOR.obfuscate(body)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def self.obfuscate_header(name, value)
|
|
282
|
+
@@HEADER_OBFUSCATOR.obfuscate_value(name, value)
|
|
283
|
+
end
|
|
284
|
+
end # end of LoggingUtil
|
|
285
|
+
end
|
|
286
|
+
end
|