minfraud 1.0.3 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/rubocop.yml +12 -0
  3. data/.github/workflows/test.yml +32 -0
  4. data/.gitignore +2 -0
  5. data/.rubocop.yml +108 -0
  6. data/CHANGELOG.md +70 -2
  7. data/CODE_OF_CONDUCT.md +4 -4
  8. data/Gemfile +11 -2
  9. data/LICENSE.txt +2 -1
  10. data/README.dev.md +4 -0
  11. data/README.md +245 -59
  12. data/Rakefile +9 -3
  13. data/bin/console +4 -3
  14. data/lib/maxmind/geoip2/model/city.rb +99 -0
  15. data/lib/maxmind/geoip2/model/country.rb +94 -0
  16. data/lib/maxmind/geoip2/model/insights.rb +38 -0
  17. data/lib/maxmind/geoip2/record/abstract.rb +46 -0
  18. data/lib/maxmind/geoip2/record/city.rb +62 -0
  19. data/lib/maxmind/geoip2/record/continent.rb +61 -0
  20. data/lib/maxmind/geoip2/record/country.rb +78 -0
  21. data/lib/maxmind/geoip2/record/location.rb +97 -0
  22. data/lib/maxmind/geoip2/record/maxmind.rb +41 -0
  23. data/lib/maxmind/geoip2/record/place.rb +52 -0
  24. data/lib/maxmind/geoip2/record/postal.rb +54 -0
  25. data/lib/maxmind/geoip2/record/represented_country.rb +47 -0
  26. data/lib/maxmind/geoip2/record/subdivision.rb +72 -0
  27. data/lib/maxmind/geoip2/record/traits.rb +233 -0
  28. data/lib/minfraud.rb +48 -8
  29. data/lib/minfraud/assessments.rb +118 -49
  30. data/lib/minfraud/components/account.rb +31 -9
  31. data/lib/minfraud/components/addressable.rb +73 -26
  32. data/lib/minfraud/components/base.rb +35 -11
  33. data/lib/minfraud/components/billing.rb +5 -0
  34. data/lib/minfraud/components/credit_card.rb +64 -20
  35. data/lib/minfraud/components/custom_inputs.rb +25 -0
  36. data/lib/minfraud/components/device.rb +51 -10
  37. data/lib/minfraud/components/email.rb +29 -7
  38. data/lib/minfraud/components/event.rb +60 -13
  39. data/lib/minfraud/components/order.rb +60 -22
  40. data/lib/minfraud/components/payment.rb +166 -21
  41. data/lib/minfraud/components/report/transaction.rb +80 -0
  42. data/lib/minfraud/components/shipping.rb +14 -5
  43. data/lib/minfraud/components/shopping_cart.rb +19 -12
  44. data/lib/minfraud/components/shopping_cart_item.rb +42 -13
  45. data/lib/minfraud/enum.rb +22 -8
  46. data/lib/minfraud/error_handler.rb +45 -18
  47. data/lib/minfraud/errors.rb +22 -2
  48. data/lib/minfraud/http_service.rb +22 -8
  49. data/lib/minfraud/http_service/request.rb +19 -18
  50. data/lib/minfraud/http_service/response.rb +49 -12
  51. data/lib/minfraud/model/abstract.rb +20 -0
  52. data/lib/minfraud/model/address.rb +52 -0
  53. data/lib/minfraud/model/billing_address.rb +11 -0
  54. data/lib/minfraud/model/credit_card.rb +75 -0
  55. data/lib/minfraud/model/device.rb +54 -0
  56. data/lib/minfraud/model/disposition.rb +35 -0
  57. data/lib/minfraud/model/email.rb +54 -0
  58. data/lib/minfraud/model/email_domain.rb +24 -0
  59. data/lib/minfraud/model/error.rb +28 -0
  60. data/lib/minfraud/model/factors.rb +24 -0
  61. data/lib/minfraud/model/geoip2_location.rb +25 -0
  62. data/lib/minfraud/model/insights.rb +68 -0
  63. data/lib/minfraud/model/ip_address.rb +82 -0
  64. data/lib/minfraud/model/issuer.rb +49 -0
  65. data/lib/minfraud/model/score.rb +76 -0
  66. data/lib/minfraud/model/score_ip_address.rb +23 -0
  67. data/lib/minfraud/model/shipping_address.rb +30 -0
  68. data/lib/minfraud/model/subscores.rb +178 -0
  69. data/lib/minfraud/model/warning.rb +63 -0
  70. data/lib/minfraud/report.rb +58 -0
  71. data/lib/minfraud/resolver.rb +25 -16
  72. data/lib/minfraud/validates.rb +187 -0
  73. data/lib/minfraud/version.rb +4 -1
  74. data/minfraud.gemspec +23 -18
  75. metadata +113 -39
  76. data/.travis.yml +0 -5
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model with information about the device.
8
+ #
9
+ # In order to receive device output from minFraud Insights or minFraud
10
+ # Factors, you must be using the Device Tracking Add-on
11
+ # (https://dev.maxmind.com/minfraud/device/).
12
+ class Device < Abstract
13
+ # This number represents our confidence that the device_id refers to a
14
+ # unique device as opposed to a cluster of similar devices. A confidence
15
+ # of 0.01 indicates very low confidence that the device is unique,
16
+ # whereas 99 indicates very high confidence.
17
+ #
18
+ # @return [Float, nil]
19
+ attr_reader :confidence
20
+
21
+ # A UUID that MaxMind uses for the device associated with this IP
22
+ # address. Note that many devices cannot be uniquely identified because
23
+ # they are too common (for example, all iPhones of a given model and OS
24
+ # release). In these cases, the minFraud service will simply not return a
25
+ # UUID for that device.
26
+ #
27
+ # @return [String, nil]
28
+ attr_reader :id
29
+
30
+ # This is the date and time of the last sighting of the device. This is
31
+ # an RFC 3339 date-time.
32
+ #
33
+ # @return [String, nil]
34
+ attr_reader :last_seen
35
+
36
+ # This is the local date and time of the transaction in the time zone of
37
+ # the device. This is determined by using the UTC offset associated with
38
+ # the device. This is an RFC 3339 date-time
39
+ #
40
+ # @return [String, nil]
41
+ attr_reader :local_time
42
+
43
+ # @!visibility private
44
+ def initialize(record)
45
+ super(record)
46
+
47
+ @confidence = get('confidence')
48
+ @id = get('id')
49
+ @last_seen = get('last_seen')
50
+ @local_time = get('local_time')
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model with the disposition set by custom rules.
8
+ #
9
+ # In order to receive a disposition, you must be using minFraud custom
10
+ # rules.
11
+ class Disposition < Abstract
12
+ # The action to take on the transaction as defined by your custom rules.
13
+ # The current set of values are "accept", "manual_review", and "reject".
14
+ # If you do not have custom rules set up, this will be nil.
15
+ #
16
+ # @return [String, nil]
17
+ attr_reader :action
18
+
19
+ # The reason for the action. The current possible values are
20
+ # "custom_rule", "block_list", and "default". If you do not have custom
21
+ # rules set up, this will be nil.
22
+ #
23
+ # @return [String, nil]
24
+ attr_reader :reason
25
+
26
+ # @!visibility private
27
+ def initialize(record)
28
+ super(record)
29
+
30
+ @action = get('action')
31
+ @reason = get('reason')
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+ require 'minfraud/model/email_domain'
5
+
6
+ module Minfraud
7
+ module Model
8
+ # Model containing information about the email address.
9
+ class Email < Abstract
10
+ # An object containing information about the email domain.
11
+ #
12
+ # @return [Minfraud::Model::EmailDomain]
13
+ attr_reader :domain
14
+
15
+ # A date string (e.g. 2017-04-24) to identify the date an email address
16
+ # was first seen by MaxMind. This is expressed using the ISO 8601 date
17
+ # format.
18
+ #
19
+ # @return [String, nil]
20
+ attr_reader :first_seen
21
+
22
+ # Whether this email address is from a disposable email provider. The
23
+ # value will be nil when no email address or email domain has been passed
24
+ # as an input.
25
+ #
26
+ # @return [Boolean, nil]
27
+ attr_reader :is_disposable
28
+
29
+ # This property is true if MaxMind believes that this email is hosted by
30
+ # a free email provider such as Gmail or Yahoo! Mail.
31
+ #
32
+ # @return [Boolean, nil]
33
+ attr_reader :is_free
34
+
35
+ # This field is true if MaxMind believes that this email is likely to be
36
+ # used for fraud. Note that this is also factored into the overall
37
+ # risk_score in the response as well.
38
+ #
39
+ # @return [Boolean, nil]
40
+ attr_reader :is_high_risk
41
+
42
+ # @!visibility private
43
+ def initialize(record)
44
+ super(record)
45
+
46
+ @domain = Minfraud::Model::EmailDomain.new(get('domain'))
47
+ @first_seen = get('first_seen')
48
+ @is_disposable = get('is_disposable')
49
+ @is_free = get('is_free')
50
+ @is_high_risk = get('is_high_risk')
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model containing information about the email domain.
8
+ class EmailDomain < Abstract
9
+ # A date string (e.g. 2017-04-24) to identify the date an email domain
10
+ # was first seen by MaxMind. This is expressed using the ISO 8601 date
11
+ # format.
12
+ #
13
+ # @return [String, nil]
14
+ attr_reader :first_seen
15
+
16
+ # @!visibility private
17
+ def initialize(record)
18
+ super(record)
19
+
20
+ @first_seen = get('first_seen')
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model with information about an error.
8
+ class Error < Abstract
9
+ # An error code for machine use.
10
+ #
11
+ # @return [String]
12
+ attr_reader :code
13
+
14
+ # A human readable error message.
15
+ #
16
+ # @return [String]
17
+ attr_reader :error
18
+
19
+ # @!visibility private
20
+ def initialize(record)
21
+ super(record)
22
+
23
+ @code = get('code')
24
+ @error = get('error')
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/insights'
4
+ require 'minfraud/model/subscores'
5
+
6
+ module Minfraud
7
+ module Model
8
+ # Model representing the Factors response.
9
+ class Factors < Insights
10
+ # An object containing subscores for many of the individual components
11
+ # that are used to calculate the overall risk score.
12
+ #
13
+ # @return [Minfraud::Model::Subscores]
14
+ attr_reader :subscores
15
+
16
+ # @!visibility private
17
+ def initialize(record, locales)
18
+ super(record, locales)
19
+
20
+ @subscores = Minfraud::Model::Subscores.new(get('subscores'))
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/record/location'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model of the GeoIP2 location information, including the local time.
8
+ class GeoIP2Location < MaxMind::GeoIP2::Record::Location
9
+ # The date and time of the transaction in the time zone associated with
10
+ # the IP address. The value is formatted according to RFC 3339. For
11
+ # instance, the local time in Boston might be returned as
12
+ # 2015-04-27T19:17:24-04:00.
13
+ #
14
+ # @return [String]
15
+ attr_reader :local_time
16
+
17
+ # @!visibility private
18
+ def initialize(record)
19
+ super(record)
20
+
21
+ @local_time = get('local_time')
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/billing_address'
4
+ require 'minfraud/model/credit_card'
5
+ require 'minfraud/model/device'
6
+ require 'minfraud/model/email'
7
+ require 'minfraud/model/ip_address'
8
+ require 'minfraud/model/score'
9
+ require 'minfraud/model/shipping_address'
10
+
11
+ module Minfraud
12
+ module Model
13
+ # Model of the Insights response.
14
+ class Insights < Score
15
+ # An object containing minFraud data related to the billing address used
16
+ # in the transaction.
17
+ #
18
+ # @return [Minfraud::Model::BillingAddress]
19
+ attr_reader :billing_address
20
+
21
+ # An object containing minFraud data about the credit card used in the
22
+ # transaction.
23
+ #
24
+ # @return [Minfraud::Model::CreditCard]
25
+ attr_reader :credit_card
26
+
27
+ # This object contains information about the device that MaxMind believes
28
+ # is associated with the IP address passed in the request.
29
+ #
30
+ # @return [Minfraud::Model::Device]
31
+ attr_reader :device
32
+
33
+ # This object contains information about the email address passed in the
34
+ # request.
35
+ #
36
+ # @return [Minfraud::Model::Email]
37
+ attr_reader :email
38
+
39
+ # An object containing GeoIP2 and minFraud Insights information about the
40
+ # geolocated IP address.
41
+ #
42
+ # @return [Minfraud::Model::IPAddress]
43
+ attr_reader :ip_address
44
+
45
+ # An object containing minFraud data related to the shipping address used
46
+ # in the transaction.
47
+ #
48
+ # @return [Minfraud::Model::ShippingAddress]
49
+ attr_reader :shipping_address
50
+
51
+ # @!visibility private
52
+ def initialize(record, locales)
53
+ super(record, locales)
54
+
55
+ @billing_address = Minfraud::Model::BillingAddress.new(
56
+ get('billing_address')
57
+ )
58
+ @credit_card = Minfraud::Model::CreditCard.new(get('credit_card'))
59
+ @device = Minfraud::Model::Device.new(get('device'))
60
+ @email = Minfraud::Model::Email.new(get('email'))
61
+ @ip_address = Minfraud::Model::IPAddress.new(get('ip_address'), locales)
62
+ @shipping_address = Minfraud::Model::ShippingAddress.new(
63
+ get('shipping_address')
64
+ )
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/model/insights'
4
+ require 'minfraud/model/geoip2_location'
5
+
6
+ module Minfraud
7
+ module Model
8
+ # Model containing GeoIP2 data and the risk for the IP address.
9
+ class IPAddress < MaxMind::GeoIP2::Model::Insights
10
+ # This field contains the risk associated with the IP address. The value
11
+ # ranges from 0.01 to 99. A higher score indicates a higher risk.
12
+ #
13
+ # @return [Float]
14
+ attr_reader :risk
15
+
16
+ # @!visibility private
17
+ def initialize(record, locales)
18
+ super(record, locales)
19
+
20
+ if record
21
+ @location = Minfraud::Model::GeoIP2Location.new(record.fetch('location', nil))
22
+ else
23
+ @location = Minfraud::Model::GeoIP2Location.new(nil)
24
+ end
25
+ if record
26
+ @risk = record.fetch('risk', nil)
27
+ else
28
+ @risk = nil
29
+ end
30
+
31
+ # Decorate objects with deprecated attributes and names for backwards
32
+ # compatibility. Do this here rather than with the overhead of
33
+ # subclasses/modules for them in the hope that one day we can delete
34
+ # them.
35
+
36
+ # These are named differently in maxmind-geoip2.
37
+ @country.define_singleton_method(:is_in_european_union) { in_european_union? }
38
+ @registered_country.define_singleton_method(:is_in_european_union) { in_european_union? }
39
+ @represented_country.define_singleton_method(:is_in_european_union) { in_european_union? }
40
+ @traits.define_singleton_method(:is_anonymous) { anonymous? }
41
+ @traits.define_singleton_method(:is_anonymous_vpn) { anonymous_vpn? }
42
+ @traits.define_singleton_method(:is_hosting_provider) { hosting_provider? }
43
+ @traits.define_singleton_method(:is_public_proxy) { public_proxy? }
44
+ @traits.define_singleton_method(:is_tor_exit_node) { tor_exit_node? }
45
+
46
+ # Mashify turned each language code into an attribute, but
47
+ # maxmind-geoip2 exposes the names as a hash.
48
+ LANGUAGE_CODES.each do |c|
49
+ if @city.names
50
+ @city.names.define_singleton_method(c) { fetch(c.to_s, nil) }
51
+ end
52
+ if @continent.names
53
+ @continent.names.define_singleton_method(c) { fetch(c.to_s, nil) }
54
+ end
55
+ if @country.names
56
+ @country.names.define_singleton_method(c) { fetch(c.to_s, nil) }
57
+ end
58
+ if @registered_country.names
59
+ @registered_country.names.define_singleton_method(c) { fetch(c.to_s, nil) }
60
+ end
61
+ if @represented_country.names
62
+ @represented_country.names.define_singleton_method(c) { fetch(c.to_s, nil) }
63
+ end
64
+ @subdivisions.each do |s|
65
+ if s.names
66
+ s.names.define_singleton_method(c) { fetch(c.to_s, nil) }
67
+ end
68
+ end
69
+ end
70
+
71
+ # This attribute is deprecated.
72
+ @country.define_singleton_method(:is_high_risk) { get('is_high_risk') }
73
+
74
+ # These attributes are deprecated and aren't in maxmind-geoip2.
75
+ @traits.define_singleton_method(:is_anonymous_proxy) { get('is_anonymous_proxy') }
76
+ @traits.define_singleton_method(:is_satellite_provider) { get('is_satellite_provider') }
77
+ end
78
+
79
+ LANGUAGE_CODES = [:de, :en, :es, :fr, :ja, :'pt-BR', :ru, :'zh-CN'].freeze
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model containing information about the card issuer.
8
+ class Issuer < Abstract
9
+ # The name of the bank which issued the credit card.
10
+ #
11
+ # @return [String, nil]
12
+ attr_reader :name
13
+
14
+ # This property is true if the name matches the name provided in the
15
+ # request for the card issuer. It is false if the name does not match.
16
+ # The property is nil if either no name or issuer ID number (IIN) was
17
+ # provided in the request or if MaxMind does not have a name associated
18
+ # with the IIN.
19
+ #
20
+ # @return [Boolean, nil]
21
+ attr_reader :matches_provided_name
22
+
23
+ # This property is true if the phone number matches the number provided
24
+ # in the request for the card issuer. It is false if the number does not
25
+ # match. It is nil if either no phone number was provided or issuer ID
26
+ # number (IIN) was provided in the request or if MaxMind does not have a
27
+ # phone number associated with the IIN.
28
+ #
29
+ # @return [Boolean, nil]
30
+ attr_reader :matches_provided_phone_number
31
+
32
+ # The phone number of the bank which issued the credit card. In some
33
+ # cases the phone number we return may be out of date.
34
+ #
35
+ # @return [String, nil]
36
+ attr_reader :phone_number
37
+
38
+ # @!visibility private
39
+ def initialize(record)
40
+ super(record)
41
+
42
+ @name = get('name')
43
+ @phone_number = get('phone_number')
44
+ @matches_provided_name = get('matches_provided_name')
45
+ @matches_provided_phone_number = get('matches_provided_phone_number')
46
+ end
47
+ end
48
+ end
49
+ end