authorizenet 1.9.6 → 1.9.7

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.
Files changed (71) hide show
  1. checksums.yaml +5 -5
  2. data/lib/app/helpers/authorize_net_helper.rb +23 -23
  3. data/lib/authorize_net.rb +107 -107
  4. data/lib/authorize_net/addresses/address.rb +25 -25
  5. data/lib/authorize_net/addresses/shipping_address.rb +22 -22
  6. data/lib/authorize_net/aim/response.rb +120 -120
  7. data/lib/authorize_net/aim/transaction.rb +171 -171
  8. data/lib/authorize_net/api/LogHelper.rb +97 -0
  9. data/lib/authorize_net/api/SensitiveDataFilter.rb +92 -0
  10. data/lib/authorize_net/api/api_transaction.rb +129 -119
  11. data/lib/authorize_net/api/constants.yml +1 -1
  12. data/lib/authorize_net/api/schema.rb +5421 -5165
  13. data/lib/authorize_net/api/transaction.rb +265 -261
  14. data/lib/authorize_net/arb/fields.rb +24 -24
  15. data/lib/authorize_net/arb/paging.rb +29 -29
  16. data/lib/authorize_net/arb/response.rb +26 -26
  17. data/lib/authorize_net/arb/sorting.rb +39 -39
  18. data/lib/authorize_net/arb/subscription.rb +68 -68
  19. data/lib/authorize_net/arb/subscription_detail.rb +10 -10
  20. data/lib/authorize_net/arb/subscription_list_response.rb +36 -36
  21. data/lib/authorize_net/arb/transaction.rb +171 -171
  22. data/lib/authorize_net/authorize_net.rb +154 -154
  23. data/lib/authorize_net/cim/customer_profile.rb +15 -15
  24. data/lib/authorize_net/cim/payment_profile.rb +35 -35
  25. data/lib/authorize_net/cim/response.rb +111 -111
  26. data/lib/authorize_net/cim/transaction.rb +721 -721
  27. data/lib/authorize_net/customer.rb +24 -24
  28. data/lib/authorize_net/email_receipt.rb +20 -20
  29. data/lib/authorize_net/fields.rb +760 -760
  30. data/lib/authorize_net/key_value_response.rb +109 -109
  31. data/lib/authorize_net/key_value_transaction.rb +281 -281
  32. data/lib/authorize_net/line_item.rb +21 -21
  33. data/lib/authorize_net/order.rb +38 -38
  34. data/lib/authorize_net/payment_methods/credit_card.rb +61 -61
  35. data/lib/authorize_net/payment_methods/echeck.rb +70 -70
  36. data/lib/authorize_net/reporting/batch.rb +16 -16
  37. data/lib/authorize_net/reporting/batch_statistics.rb +15 -15
  38. data/lib/authorize_net/reporting/fds_filter.rb +8 -8
  39. data/lib/authorize_net/reporting/response.rb +157 -157
  40. data/lib/authorize_net/reporting/returned_item.rb +45 -45
  41. data/lib/authorize_net/reporting/transaction.rb +131 -131
  42. data/lib/authorize_net/reporting/transaction_details.rb +22 -22
  43. data/lib/authorize_net/response.rb +25 -25
  44. data/lib/authorize_net/sim/hosted_payment_form.rb +34 -34
  45. data/lib/authorize_net/sim/hosted_receipt_page.rb +32 -32
  46. data/lib/authorize_net/sim/response.rb +133 -133
  47. data/lib/authorize_net/sim/transaction.rb +128 -128
  48. data/lib/authorize_net/transaction.rb +66 -66
  49. data/lib/authorize_net/xml_response.rb +154 -154
  50. data/lib/authorize_net/xml_transaction.rb +279 -279
  51. data/lib/authorizenet.rb +4 -4
  52. data/lib/generators/authorize_net/direct_post/direct_post_generator.rb +52 -52
  53. data/lib/generators/authorize_net/direct_post/templates/README-AuthorizeNet +48 -48
  54. data/lib/generators/authorize_net/direct_post/templates/config.yml.erb +8 -8
  55. data/lib/generators/authorize_net/direct_post/templates/config.yml.rails3.erb +8 -8
  56. data/lib/generators/authorize_net/direct_post/templates/controller.rb.erb +30 -30
  57. data/lib/generators/authorize_net/direct_post/templates/initializer.rb +4 -4
  58. data/lib/generators/authorize_net/direct_post/templates/layout.erb +17 -17
  59. data/lib/generators/authorize_net/direct_post/templates/payment.erb +9 -9
  60. data/lib/generators/authorize_net/direct_post/templates/payment.rails3.erb +9 -9
  61. data/lib/generators/authorize_net/sim/sim_generator.rb +46 -46
  62. data/lib/generators/authorize_net/sim/templates/README-AuthorizeNet +51 -51
  63. data/lib/generators/authorize_net/sim/templates/config.yml.erb +8 -8
  64. data/lib/generators/authorize_net/sim/templates/config.yml.rails3.erb +8 -8
  65. data/lib/generators/authorize_net/sim/templates/controller.rb.erb +20 -20
  66. data/lib/generators/authorize_net/sim/templates/initializer.rb +4 -4
  67. data/lib/generators/authorize_net/sim/templates/layout.erb +17 -17
  68. data/lib/generators/authorize_net/sim/templates/payment.erb +5 -5
  69. data/lib/generators/authorize_net/sim/templates/payment.rails3.erb +5 -5
  70. data/lib/generators/generator_extensions.rb +73 -73
  71. metadata +5 -3
@@ -1,171 +1,171 @@
1
- module AuthorizeNet::AIM
2
- # The AIM transaction class. Handles building the transaction payload and
3
- # transmitting it to the gateway.
4
- class Transaction < AuthorizeNet::KeyValueTransaction
5
- # The default options for the constructor.
6
- @@option_defaults = {
7
- transaction_type: Type::AUTHORIZE_AND_CAPTURE,
8
- gateway: :production,
9
- test: false,
10
- allow_split: false,
11
- delimiter: ',',
12
- encapsulation_character: nil,
13
- verify_ssl: true,
14
- device_type: DeviceType::UNKNOWN,
15
- market_type: MarketType::RETAIL
16
- }
17
-
18
- # Fields to convert to/from booleans.
19
- @@boolean_fields = %i[tax_exempt test_request recurring_billing allow_partial_auth delim_data email_customer relay_response]
20
-
21
- # Fields to convert to/from BigDecimal.
22
- @@decimal_fields = [:amount]
23
-
24
- # Constructs an AIM transaction. You can use the new AIM transaction object
25
- # to issue a request to the payment gateway and parse the response into a new
26
- # AuthorizeNet::AIM::Response object.
27
- #
28
- # +api_login_id+:: Your API login ID, as a string.
29
- # +api_transaction_key+:: Your API transaction key, as a string.
30
- # +options+:: A hash of options. See below for values.
31
- #
32
- # Options
33
- # +transaction_type+:: The type of transaction to perform. Defaults to AuthorizeNet::Type::AUTHORIZE_AND_CAPTURE. This value is only used if run is called directly.
34
- # +gateway+:: The gateway to submit the transaction to. Can be a URL string, an AuthorizeNet::AIM::Transaction::Gateway constant, or one of the convenience symbols :sandbox, :test, :card_present_test, :card_present_live, :card_present_sandbox, :card_present_production, :production, or :live (:test is an alias for :sandbox, :card_present_test is an alias for :card_present_sandbox, :card_present_production is an alias for :card_present_live, and :live is an alias for :production).
35
- # +test+:: A boolean indicating if the transaction should be run in test mode or not (defaults to false).
36
- # +allow_split+:: A boolean indicating if split transactions should be allowed (defaults to false).
37
- # +delimiter+:: A single character (as a string) that will be used to delimit the response from the gateway. Defaults to ','.
38
- # +encapsulation_character+:: A single character (as a string) that will be used to encapsulate each field in the response from the gateway. Defaults to nil.
39
- # +verify_ssl+:: A boolean indicating if the SSL certificate of the +gateway+ should be verified. Defaults to true.
40
- # +device_type+:: A constant from DeviceType indicating the type of POS device used in a card present transaction. Defaults to DeviceType::UNKNOWN.
41
- # +market_type+:: A constant from MarketType indicating your industry. Used for card present transactions. Defaults to MarketType::RETAIL.
42
- #
43
- def initialize(api_login_id, api_transaction_key, options = {})
44
- ActiveSupport::Deprecation.warn "use AuthorizeNet::API::Transaction"
45
- super()
46
- options = @@option_defaults.merge(options)
47
- @api_login_id = api_login_id
48
- @api_transaction_key = api_transaction_key
49
- @test_mode = options[:test]
50
- @response ||= nil
51
- @delimiter = options[:delimiter]
52
- @type = options[:transaction_type]
53
- @cp_version = nil
54
- case options[:gateway]
55
- when :sandbox, :test
56
- @gateway = Gateway::TEST
57
- when :production, :live
58
- @gateway = Gateway::LIVE
59
- when :card_present_live, :card_present_production
60
- @gateway = Gateway::CARD_PRESENT_LIVE
61
- @cp_version = '1.0'
62
- when :card_present_test, :card_present_sandbox
63
- @gateway = Gateway::CARD_PRESENT_TEST
64
- @cp_version = '1.0'
65
- else
66
- @gateway = options[:gateway]
67
- end
68
- @allow_split_transaction = options[:allow_split]
69
- @encapsulation_character = options[:encapsulation_character]
70
- @verify_ssl = options[:verify_ssl]
71
- @market_type = options[:market_type]
72
- @device_type = options[:device_type]
73
- @solution_id = options[:solution_id]
74
- end
75
-
76
- # Checks if the transaction has been configured for test mode or not. Return TRUE if the
77
- # transaction is a test transaction, FALSE otherwise. All transactions run against the sandbox
78
- # are considered test transactions.
79
- def test?
80
- super || @gateway == Gateway::TEST
81
- end
82
-
83
- # Returns TRUE if split transactions are allowed, FALSE otherwise.
84
- def split_transaction_allowed?
85
- !!@allow_split_transaction
86
- end
87
-
88
- # Returns the current encapsulation character unless there is none, in which case Nil is returned.
89
- attr_reader :encapsulation_character
90
-
91
- # Returns the gateway to be used for this transaction.
92
- attr_reader :gateway
93
-
94
- # Checks to see if the transaction has a response (meaning it has been submitted to the gateway).
95
- # Returns TRUE if a response is present, FALSE otherwise.
96
- def has_response?
97
- !@response.nil?
98
- end
99
-
100
- # Retrieve the response object (or Nil if transaction hasn't been sent to the gateway).
101
- attr_reader :response
102
-
103
- # Returns the current delimiter we are using to parse the fields returned by the
104
- # gateway.
105
- attr_reader :delimiter
106
-
107
- # Sets the delimiter used to parse the response from the gateway.
108
- attr_writer :delimiter
109
-
110
- # Submits the transaction to the gateway for processing. Returns a response object. If the transaction
111
- # has already been run, it will return nil.
112
- def run
113
- make_request
114
- end
115
-
116
- # Returns the current card present API version that we are adhering to.
117
- attr_reader :cp_version
118
-
119
- attr_reader :solution_id
120
-
121
- #:enddoc:
122
- protected
123
-
124
- # An internal method that builds the POST body, submits it to the gateway, and constructs a Response object with the response.
125
- def make_request
126
- return nil if has_response?
127
- url = URI.parse(@gateway)
128
- fields = @fields.merge(type: @type, delim_char: @delimiter, delim_data: "TRUE", login: @api_login_id, tran_key: @api_transaction_key, relay_response: "FALSE")
129
-
130
- if @cp_version.nil?
131
- fields[:version] = @version
132
- else
133
- fields.merge!(cp_version: @cp_version, market_type: @market_type, device_type: @device_type, response_format: "1")
134
- end
135
- fields[:test_request] = boolean_to_value(@test_mode)
136
- fields[:allow_partial_auth] = 'TRUE' if @allow_split_transaction
137
- fields[:encap_char] = @encapsulation_character unless @encapsulation_character.nil?
138
- fields[:solution_id] = @solution_id unless @solution_id.nil?
139
- fields.each do |k, v|
140
- if @@boolean_fields.include?(k)
141
- fields[k] = boolean_to_value(v)
142
- elsif @@decimal_fields.include?(k)
143
- fields[k] = decimal_to_value(v)
144
- end
145
- end
146
- data = fields.collect do |key, val|
147
- to_param(key, val)
148
- end
149
- custom_field_keys = @custom_fields.keys.collect(&:to_s).sort.collect(&:to_sym)
150
- for key in custom_field_keys
151
- data += [to_param(key, @custom_fields[key.to_sym], '')]
152
- end
153
- data.flatten!
154
- request = Net::HTTP::Post.new(url.path)
155
- request.content_type = 'application/x-www-form-urlencoded'
156
- request.body = data.join("&")
157
- connection = Net::HTTP.new(url.host, url.port)
158
- connection.use_ssl = true
159
- if @verify_ssl
160
- connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
161
- else
162
- connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
163
- end
164
- begin
165
- @response = AuthorizeNet::AIM::Response.new((connection.start { |http| http.request(request) }), self)
166
- rescue StandardError
167
- @response = AuthorizeNet::AIM::Response.new($ERROR_INFO, self)
168
- end
169
- end
170
- end
171
- end
1
+ module AuthorizeNet::AIM
2
+ # The AIM transaction class. Handles building the transaction payload and
3
+ # transmitting it to the gateway.
4
+ class Transaction < AuthorizeNet::KeyValueTransaction
5
+ # The default options for the constructor.
6
+ @@option_defaults = {
7
+ transaction_type: Type::AUTHORIZE_AND_CAPTURE,
8
+ gateway: :production,
9
+ test: false,
10
+ allow_split: false,
11
+ delimiter: ',',
12
+ encapsulation_character: nil,
13
+ verify_ssl: true,
14
+ device_type: DeviceType::UNKNOWN,
15
+ market_type: MarketType::RETAIL
16
+ }
17
+
18
+ # Fields to convert to/from booleans.
19
+ @@boolean_fields = %i[tax_exempt test_request recurring_billing allow_partial_auth delim_data email_customer relay_response]
20
+
21
+ # Fields to convert to/from BigDecimal.
22
+ @@decimal_fields = [:amount]
23
+
24
+ # Constructs an AIM transaction. You can use the new AIM transaction object
25
+ # to issue a request to the payment gateway and parse the response into a new
26
+ # AuthorizeNet::AIM::Response object.
27
+ #
28
+ # +api_login_id+:: Your API login ID, as a string.
29
+ # +api_transaction_key+:: Your API transaction key, as a string.
30
+ # +options+:: A hash of options. See below for values.
31
+ #
32
+ # Options
33
+ # +transaction_type+:: The type of transaction to perform. Defaults to AuthorizeNet::Type::AUTHORIZE_AND_CAPTURE. This value is only used if run is called directly.
34
+ # +gateway+:: The gateway to submit the transaction to. Can be a URL string, an AuthorizeNet::AIM::Transaction::Gateway constant, or one of the convenience symbols :sandbox, :test, :card_present_test, :card_present_live, :card_present_sandbox, :card_present_production, :production, or :live (:test is an alias for :sandbox, :card_present_test is an alias for :card_present_sandbox, :card_present_production is an alias for :card_present_live, and :live is an alias for :production).
35
+ # +test+:: A boolean indicating if the transaction should be run in test mode or not (defaults to false).
36
+ # +allow_split+:: A boolean indicating if split transactions should be allowed (defaults to false).
37
+ # +delimiter+:: A single character (as a string) that will be used to delimit the response from the gateway. Defaults to ','.
38
+ # +encapsulation_character+:: A single character (as a string) that will be used to encapsulate each field in the response from the gateway. Defaults to nil.
39
+ # +verify_ssl+:: A boolean indicating if the SSL certificate of the +gateway+ should be verified. Defaults to true.
40
+ # +device_type+:: A constant from DeviceType indicating the type of POS device used in a card present transaction. Defaults to DeviceType::UNKNOWN.
41
+ # +market_type+:: A constant from MarketType indicating your industry. Used for card present transactions. Defaults to MarketType::RETAIL.
42
+ #
43
+ def initialize(api_login_id, api_transaction_key, options = {})
44
+ ActiveSupport::Deprecation.warn "use AuthorizeNet::API::Transaction"
45
+ super()
46
+ options = @@option_defaults.merge(options)
47
+ @api_login_id = api_login_id
48
+ @api_transaction_key = api_transaction_key
49
+ @test_mode = options[:test]
50
+ @response ||= nil
51
+ @delimiter = options[:delimiter]
52
+ @type = options[:transaction_type]
53
+ @cp_version = nil
54
+ case options[:gateway]
55
+ when :sandbox, :test
56
+ @gateway = Gateway::TEST
57
+ when :production, :live
58
+ @gateway = Gateway::LIVE
59
+ when :card_present_live, :card_present_production
60
+ @gateway = Gateway::CARD_PRESENT_LIVE
61
+ @cp_version = '1.0'
62
+ when :card_present_test, :card_present_sandbox
63
+ @gateway = Gateway::CARD_PRESENT_TEST
64
+ @cp_version = '1.0'
65
+ else
66
+ @gateway = options[:gateway]
67
+ end
68
+ @allow_split_transaction = options[:allow_split]
69
+ @encapsulation_character = options[:encapsulation_character]
70
+ @verify_ssl = options[:verify_ssl]
71
+ @market_type = options[:market_type]
72
+ @device_type = options[:device_type]
73
+ @solution_id = options[:solution_id]
74
+ end
75
+
76
+ # Checks if the transaction has been configured for test mode or not. Return TRUE if the
77
+ # transaction is a test transaction, FALSE otherwise. All transactions run against the sandbox
78
+ # are considered test transactions.
79
+ def test?
80
+ super || @gateway == Gateway::TEST
81
+ end
82
+
83
+ # Returns TRUE if split transactions are allowed, FALSE otherwise.
84
+ def split_transaction_allowed?
85
+ !!@allow_split_transaction
86
+ end
87
+
88
+ # Returns the current encapsulation character unless there is none, in which case Nil is returned.
89
+ attr_reader :encapsulation_character
90
+
91
+ # Returns the gateway to be used for this transaction.
92
+ attr_reader :gateway
93
+
94
+ # Checks to see if the transaction has a response (meaning it has been submitted to the gateway).
95
+ # Returns TRUE if a response is present, FALSE otherwise.
96
+ def has_response?
97
+ !@response.nil?
98
+ end
99
+
100
+ # Retrieve the response object (or Nil if transaction hasn't been sent to the gateway).
101
+ attr_reader :response
102
+
103
+ # Returns the current delimiter we are using to parse the fields returned by the
104
+ # gateway.
105
+ attr_reader :delimiter
106
+
107
+ # Sets the delimiter used to parse the response from the gateway.
108
+ attr_writer :delimiter
109
+
110
+ # Submits the transaction to the gateway for processing. Returns a response object. If the transaction
111
+ # has already been run, it will return nil.
112
+ def run
113
+ make_request
114
+ end
115
+
116
+ # Returns the current card present API version that we are adhering to.
117
+ attr_reader :cp_version
118
+
119
+ attr_reader :solution_id
120
+
121
+ #:enddoc:
122
+ protected
123
+
124
+ # An internal method that builds the POST body, submits it to the gateway, and constructs a Response object with the response.
125
+ def make_request
126
+ return nil if has_response?
127
+ url = URI.parse(@gateway)
128
+ fields = @fields.merge(type: @type, delim_char: @delimiter, delim_data: "TRUE", login: @api_login_id, tran_key: @api_transaction_key, relay_response: "FALSE")
129
+
130
+ if @cp_version.nil?
131
+ fields[:version] = @version
132
+ else
133
+ fields.merge!(cp_version: @cp_version, market_type: @market_type, device_type: @device_type, response_format: "1")
134
+ end
135
+ fields[:test_request] = boolean_to_value(@test_mode)
136
+ fields[:allow_partial_auth] = 'TRUE' if @allow_split_transaction
137
+ fields[:encap_char] = @encapsulation_character unless @encapsulation_character.nil?
138
+ fields[:solution_id] = @solution_id unless @solution_id.nil?
139
+ fields.each do |k, v|
140
+ if @@boolean_fields.include?(k)
141
+ fields[k] = boolean_to_value(v)
142
+ elsif @@decimal_fields.include?(k)
143
+ fields[k] = decimal_to_value(v)
144
+ end
145
+ end
146
+ data = fields.collect do |key, val|
147
+ to_param(key, val)
148
+ end
149
+ custom_field_keys = @custom_fields.keys.collect(&:to_s).sort.collect(&:to_sym)
150
+ for key in custom_field_keys
151
+ data += [to_param(key, @custom_fields[key.to_sym], '')]
152
+ end
153
+ data.flatten!
154
+ request = Net::HTTP::Post.new(url.path)
155
+ request.content_type = 'application/x-www-form-urlencoded'
156
+ request.body = data.join("&")
157
+ connection = Net::HTTP.new(url.host, url.port)
158
+ connection.use_ssl = true
159
+ if @verify_ssl
160
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
161
+ else
162
+ connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
163
+ end
164
+ begin
165
+ @response = AuthorizeNet::AIM::Response.new((connection.start { |http| http.request(request) }), self)
166
+ rescue StandardError
167
+ @response = AuthorizeNet::AIM::Response.new($ERROR_INFO, self)
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,97 @@
1
+ require 'logger'
2
+ require 'yaml'
3
+ require File.join File.dirname(__FILE__), 'SensitiveDataFilter'
4
+
5
+ module AuthorizeNet::API
6
+ class Log
7
+ @@shouldLog = false
8
+ @@loglevels = ['debug','info','warn','error']
9
+ def initialize()
10
+ begin
11
+ filepath = './LogConfig.yml'
12
+ if(File.file?(filepath))
13
+ cnf = YAML::load(File.open(filepath))
14
+ if(@@loglevels.include? cnf['loglevel'].downcase)
15
+ @@shouldLog = true
16
+ @logger = Logger.new(cnf['filepath'])
17
+ @logger.level = LogLevelMapper(cnf['loglevel'].downcase)
18
+ if(cnf['maskSensitiveData'])
19
+ @logger.formatter = SensitiveDataFilter.new
20
+ else
21
+ constants = YAML.load_file(File.dirname(__FILE__) + "/constants.yml")
22
+ @logger.formatter = proc do |severity, datetime, progname, msg|
23
+ progname = constants['clientId']
24
+ date_format = datetime.strftime("%Y-%m-%d %H:%M:%S")
25
+ if severity == "INFO" or severity == "WARN"
26
+ "[#{date_format}] #{severity} (#{progname}): #{msg}\n"
27
+ else
28
+ "[#{date_format}] #{severity} (#{progname}): #{msg}\n"
29
+ end
30
+ end
31
+ end
32
+ else
33
+ raise "Invalid log levels"
34
+ end
35
+ else
36
+ @@shouldLog = false
37
+ end
38
+ rescue
39
+ @@shouldLog = false
40
+ end
41
+ end
42
+ def debug(message)
43
+ if(@@shouldLog)
44
+ begin
45
+ @logger.debug message
46
+ rescue Exception => ex
47
+ ex
48
+ end
49
+ end
50
+ end
51
+ def info(message)
52
+ if(@@shouldLog)
53
+ begin
54
+ @logger.info message
55
+ rescue Exception => ex
56
+ ex
57
+ end
58
+ end
59
+ end
60
+ def warn(message)
61
+ if(@@shouldLog)
62
+ begin
63
+ @logger.warn message
64
+ rescue Exception => ex
65
+ ex
66
+ end
67
+ end
68
+ end
69
+ def error(message)
70
+ if(@@shouldLog)
71
+ begin
72
+ @logger.error message
73
+ rescue Exception => ex
74
+ ex
75
+ end
76
+ end
77
+ end
78
+ def LogLevelMapper(loglevel)
79
+ case loglevel
80
+ when 'debug'
81
+ Logger::DEBUG
82
+ when 'info'
83
+ Logger::INFO
84
+ when 'warn'
85
+ Logger::WARN
86
+ when 'error'
87
+ Logger::ERROR
88
+ end
89
+ end
90
+ end
91
+
92
+ class LogHelper
93
+ def self.log
94
+ Log.new
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,92 @@
1
+ require 'logger'
2
+
3
+ module AuthorizeNet::API
4
+ class SensitiveTag
5
+ attr_accessor :tagName, :pattern, :replacement, :disableMask
6
+ def initialize(tagName, pattern, replacement, disableMask)
7
+ @tagName = tagName
8
+ @pattern = pattern
9
+ @replacement = replacement
10
+ @disableMask = disableMask
11
+ end
12
+ end
13
+
14
+ class SensitiveDataConfigType
15
+ attr_accessor :sensitiveTags, :sensitiveStringRegexes
16
+ def initialize
17
+ @sensitiveTags = Array.new([SensitiveTag.new("cardCode", "", "XXX", false),
18
+ SensitiveTag.new("cardNumber", "(\\p{N}+)(\\p{N}{4})", "XXXX-\\2", false),
19
+ SensitiveTag.new("expirationDate", "", "XXX", false),
20
+ SensitiveTag.new("accountNumber", "(\\p{N}+)(\\p{N}{4})", "XXXX-\\2", false),
21
+ SensitiveTag.new("nameOnAccount", "", "XXX", false),
22
+ SensitiveTag.new("transactionKey", "", "XXX", false)]).freeze
23
+ @sensitiveStringRegexes = ["4\\p{N}{3}([\\ \\-]?)\\p{N}{4}\\1\\p{N}{4}\\1\\p{N}{4}",
24
+ "4\\p{N}{3}([\\ \\-]?)(?:\\p{N}{4}\\1){2}\\p{N}(?:\\p{N}{3})?",
25
+ "5[1-5]\\p{N}{2}([\\ \\-]?)\\p{N}{4}\\1\\p{N}{4}\\1\\p{N}{4}",
26
+ "6(?:011|22(?:1(?=[\\ \\-]?(?:2[6-9]|[3-9]))|[2-8]|9(?=[\\ \\-]?(?:[01]|2[0-5])))|4[4-9]\\p{N}|5\\p{N}\\p{N})([\\ \\-]?)\\p{N}{4}\\1\\p{N}{4}\\1\\p{N}{4}",
27
+ "35(?:2[89]|[3-8]\\p{N})([\\ \\-]?)\\p{N}{4}\\1\\p{N}{4}\\1\\p{N}{4}",
28
+ "3[47]\\p{N}\\p{N}([\\ \\-]?)\\p{N}{6}\\1\\p{N}{5}"].freeze
29
+ end
30
+ end
31
+
32
+ class SensitiveDataFilter < Logger::Formatter
33
+ @@sensitiveTagConfig = nil
34
+ @@tagPatterns = nil
35
+ @@tagReplacements = nil
36
+ @@cardPatterns = nil
37
+
38
+ def initialize
39
+ @@sensitiveTagConfig = SensitiveDataConfigType.new
40
+ @@cardPatterns = @@sensitiveTagConfig.sensitiveStringRegexes
41
+ @@tagPatterns = Array.new(@@sensitiveTagConfig.sensitiveStringRegexes.length)
42
+ @@tagReplacements = Array.new(@@sensitiveTagConfig.sensitiveTags.length)
43
+
44
+ @@sensitiveTagConfig.sensitiveTags.each_with_index do |sensitiveTag, index|
45
+ tagName = sensitiveTag.tagName
46
+ replacement = sensitiveTag.replacement
47
+
48
+ if sensitiveTag.pattern.nil? || sensitiveTag.pattern.empty?
49
+ pattern = "(.*)"
50
+ else
51
+ pattern = sensitiveTag.pattern
52
+ end
53
+
54
+ @@tagPatterns[index] = "<"+tagName+">"+pattern+"</"+tagName+">"
55
+ @@tagReplacements[index] = "<"+tagName+">"+replacement+"</"+tagName+">"
56
+ end
57
+ end
58
+
59
+ def call(severity, time, progname, msg)
60
+ xmlMaskedLog = maskSensitiveXmlString(msg)
61
+ ccMasked = maskCreditCards(xmlMaskedLog)
62
+ return formatLogEntry(severity, time, progname, ccMasked)
63
+ end
64
+
65
+ def maskCreditCards(input)
66
+ input = input.force_encoding("UTF-8")
67
+ @@cardPatterns.each {|cardNumberRegex|
68
+ input = input.gsub(/#{cardNumberRegex}/, "XXX")
69
+ }
70
+ return input
71
+ end
72
+
73
+ def maskSensitiveXmlString(input)
74
+ input = input.force_encoding("UTF-8")
75
+ @@tagPatterns.each_with_index do |item, index|
76
+ input = input.gsub(/#{item}/,@@tagReplacements[index])
77
+ end
78
+ return input
79
+ end
80
+
81
+ def formatLogEntry(severity, time, progname, msg)
82
+ constants = YAML.load_file(File.dirname(__FILE__) + "/constants.yml")
83
+ progname = constants['clientId']
84
+ date_format = time.strftime("%Y-%m-%d %H:%M:%S")
85
+ if severity == "INFO" or severity == "WARN"
86
+ "[#{date_format}] #{severity} (#{progname}): #{msg}\n"
87
+ else
88
+ "[#{date_format}] #{severity} (#{progname}): #{msg}\n"
89
+ end
90
+ end
91
+ end
92
+ end