authorizenet 1.9.6 → 1.9.7

Sign up to get free protection for your applications and to get access to all the features.
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