minfraud 1.1.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.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +22 -0
  5. data/CHANGELOG.md +42 -0
  6. data/CODE_OF_CONDUCT.md +49 -0
  7. data/Gemfile +12 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.dev.md +4 -0
  10. data/README.md +178 -0
  11. data/Rakefile +6 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  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 +224 -0
  28. data/lib/minfraud.rb +51 -0
  29. data/lib/minfraud/assessments.rb +101 -0
  30. data/lib/minfraud/components/account.rb +23 -0
  31. data/lib/minfraud/components/addressable.rb +67 -0
  32. data/lib/minfraud/components/base.rb +35 -0
  33. data/lib/minfraud/components/billing.rb +5 -0
  34. data/lib/minfraud/components/credit_card.rb +52 -0
  35. data/lib/minfraud/components/custom_inputs.rb +14 -0
  36. data/lib/minfraud/components/device.rb +38 -0
  37. data/lib/minfraud/components/email.rb +21 -0
  38. data/lib/minfraud/components/event.rb +44 -0
  39. data/lib/minfraud/components/order.rb +52 -0
  40. data/lib/minfraud/components/payment.rb +152 -0
  41. data/lib/minfraud/components/report/transaction.rb +69 -0
  42. data/lib/minfraud/components/shipping.rb +18 -0
  43. data/lib/minfraud/components/shopping_cart.rb +30 -0
  44. data/lib/minfraud/components/shopping_cart_item.rb +33 -0
  45. data/lib/minfraud/enum.rb +34 -0
  46. data/lib/minfraud/error_handler.rb +65 -0
  47. data/lib/minfraud/errors.rb +10 -0
  48. data/lib/minfraud/http_service.rb +30 -0
  49. data/lib/minfraud/http_service/request.rb +37 -0
  50. data/lib/minfraud/http_service/response.rb +64 -0
  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 +156 -0
  69. data/lib/minfraud/model/warning.rb +63 -0
  70. data/lib/minfraud/report.rb +38 -0
  71. data/lib/minfraud/resolver.rb +33 -0
  72. data/lib/minfraud/version.rb +3 -0
  73. data/minfraud.gemspec +29 -0
  74. metadata +198 -0
@@ -0,0 +1,10 @@
1
+ module Minfraud
2
+ # A list of Minfraud custom errors
3
+ class BaseError < StandardError; end
4
+
5
+ class NotEnumValueError < BaseError; end
6
+ class RequestFormatError < BaseError; end
7
+ class ClientError < BaseError; end
8
+ class AuthorizationError < BaseError; end
9
+ class ServerError < BaseError; end
10
+ end
@@ -0,0 +1,30 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module Minfraud
5
+ module HTTPService
6
+ class << self
7
+ # @return [Hash] default HTTPService configuration
8
+ def configuration
9
+ {
10
+ middleware: DEFAULT_MIDDLEWARE,
11
+ server: DEFAULT_SERVER
12
+ }
13
+ end
14
+ end
15
+
16
+ # Minfraud default middleware stack
17
+ DEFAULT_MIDDLEWARE = Proc.new do |builder|
18
+ builder.request :json
19
+
20
+ builder.basic_auth *::Minfraud.configuration.values
21
+
22
+ builder.response :json, content_type: /\bjson$/
23
+
24
+ builder.adapter Faraday.default_adapter
25
+ end
26
+
27
+ # Minfraud default server
28
+ DEFAULT_SERVER = 'https://minfraud.maxmind.com/minfraud/v2.0'.freeze
29
+ end
30
+ end
@@ -0,0 +1,37 @@
1
+ require 'faraday'
2
+
3
+ module Minfraud
4
+ module HTTPService
5
+ class Request
6
+ # @attribute middleware
7
+ # @return [Proc] A proc containing Faraday configuration
8
+ attr_reader :middleware
9
+
10
+ # @attribute server
11
+ # @return [String] an API endpoint
12
+ attr_reader :server
13
+
14
+ # Creates Minfraud::HTTPService::Request instance
15
+ # @param [Hash] params hash of parameters
16
+ # @return [Minfraud::HTTPService::Request] Request instance
17
+ def initialize(params = {})
18
+ @middleware = params[:middleware]
19
+ @server = params[:server]
20
+ end
21
+
22
+ # Performs an HTTP request to the specified endpoint with given body
23
+ # @param [Hash] params hash of parameters.
24
+ # @return [Farday::Response] Faraday::Response instance
25
+ def perform(params)
26
+ adapter.send(*params.values_at(:verb, :endpoint, :body))
27
+ end
28
+
29
+ private
30
+ # Creates memoized Faraday::Connection instance
31
+ # @return [Faraday::Connection] Faraday::Connection instance
32
+ def adapter
33
+ @adapter ||= Faraday.new(server, {}, &middleware)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,64 @@
1
+ require 'minfraud/model/error'
2
+ require 'minfraud/model/factors'
3
+ require 'minfraud/model/insights'
4
+ require 'minfraud/model/score'
5
+
6
+ module Minfraud
7
+ module HTTPService
8
+ # Response class for HTTP requests
9
+ class Response
10
+ # @attribute status
11
+ # @return [Integer] HTTP response status
12
+ attr_reader :status
13
+
14
+ # @attribute body
15
+ # @return [Minfraud::Model::Score, Minfraud::Model::Insights,
16
+ # Minfraud::Model::Factors] HTTP response body
17
+ attr_reader :body
18
+
19
+ # @attribute headers
20
+ # @return [Hash] HTTP response headers
21
+ attr_reader :headers
22
+
23
+ # Creates Minfraud::HTTPService::Response instance
24
+ # @param [Hash] params hash of parameters
25
+ # @return [Minfraud::HTTPService::Response] Response instance
26
+ def initialize(params = {})
27
+ @status = params[:status]
28
+ @body = make_body(
29
+ params[:endpoint],
30
+ params[:body],
31
+ params[:locales]
32
+ )
33
+ @headers = params[:headers]
34
+ end
35
+
36
+ # Returns minFraud-specific response code
37
+ # @return [Symbol, nil] minFraud specific request code
38
+ def code
39
+ return nil if body.nil?
40
+
41
+ body.code.intern if body.respond_to?(:code) && body.code
42
+ end
43
+
44
+ private
45
+
46
+ def make_body(endpoint, body, locales)
47
+ if @status != 200
48
+ # Won't be a Hash when the body is not JSON.
49
+ return nil unless body.is_a?(Hash)
50
+
51
+ return Minfraud::Model::Error.new(body)
52
+ end
53
+
54
+ ENDPOINT_TO_CLASS[endpoint].new(body, locales)
55
+ end
56
+
57
+ ENDPOINT_TO_CLASS = {
58
+ factors: Minfraud::Model::Factors,
59
+ insights: Minfraud::Model::Insights,
60
+ score: Minfraud::Model::Score
61
+ }.freeze
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Minfraud
4
+ module Model
5
+ # @!visibility private
6
+ class Abstract
7
+ def initialize(record)
8
+ @record = record
9
+ end
10
+
11
+ protected
12
+
13
+ def get(key)
14
+ return nil if @record.nil? || !@record.key?(key)
15
+
16
+ @record[key]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Abstract model for a postal address.
8
+ class Address < Abstract
9
+ # The distance in kilometers from the address to the IP location.
10
+ #
11
+ # @return [Integer, nil]
12
+ attr_reader :distance_to_ip_location
13
+
14
+ # This property is true if the address is in the IP country. The property
15
+ # is false when the address is not in the IP country. If the address
16
+ # could not be parsed or was not provided or if the IP address could not
17
+ # be geolocated, the property will be nil.
18
+ #
19
+ # @return [Boolean, nil]
20
+ attr_reader :is_in_ip_country
21
+
22
+ # This property is true if the postal code provided with the address is
23
+ # in the city for the address. The property is false when the postal code
24
+ # is not in the city. If the address was not provided or could not be
25
+ # parsed, the property will be nil.
26
+ #
27
+ # @return [Boolean, nil]
28
+ attr_reader :is_postal_in_city
29
+
30
+ # The latitude associated with the address.
31
+ #
32
+ # @return [Float, nil]
33
+ attr_reader :latitude
34
+
35
+ # The longitude associated with the address.
36
+ #
37
+ # @return [Float, nil]
38
+ attr_reader :longitude
39
+
40
+ # @!visibility private
41
+ def initialize(record)
42
+ super(record)
43
+
44
+ @distance_to_ip_location = get('distance_to_ip_location')
45
+ @is_in_ip_country = get('is_in_ip_country')
46
+ @is_postal_in_city = get('is_postal_in_city')
47
+ @latitude = get('latitude')
48
+ @longitude = get('longitude')
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/address'
4
+
5
+ module Minfraud
6
+ module Model
7
+ # Model containing information about the billing address.
8
+ class BillingAddress < Address
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minfraud/model/abstract'
4
+ require 'minfraud/model/issuer'
5
+
6
+ module Minfraud
7
+ module Model
8
+ # Model with details about the credit card used.
9
+ class CreditCard < Abstract
10
+ # The card brand, such as "Visa", "Discover", "American Express", etc.
11
+ #
12
+ # @return [String, nil]
13
+ attr_reader :brand
14
+
15
+ # This property contains the two letter ISO 3166-1 alpha-2 country code
16
+ # (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) associated with the
17
+ # location of the majority of customers using this credit card as
18
+ # determined by their billing address. In cases where the location of
19
+ # customers is highly mixed, this defaults to the country of the bank
20
+ # issuing the card.
21
+ #
22
+ # @return [String, nil]
23
+ attr_reader :country
24
+
25
+ # This property is true if the card is a business card.
26
+ #
27
+ # @return [Boolean, nil]
28
+ attr_reader :is_business
29
+
30
+ # This property is true if the country of the billing address matches the
31
+ # country of the majority of customers using this credit card. In cases
32
+ # where the location of customers is highly mixed, the match is to the
33
+ # country of the bank issuing the card.
34
+ #
35
+ # @return [Boolean, nil]
36
+ attr_reader :is_issued_in_billing_address_country
37
+
38
+ # This property is true if the card is a prepaid card.
39
+ #
40
+ # @return [Boolean, nil]
41
+ attr_reader :is_prepaid
42
+
43
+ # This property is true if the card is a virtual card.
44
+ #
45
+ # @return [Boolean, nil]
46
+ attr_reader :is_virtual
47
+
48
+ # An object containing information about the credit card issuer.
49
+ #
50
+ # @return [Minfraud::Model::Issuer]
51
+ attr_reader :issuer
52
+
53
+ # The card's type. The valid values are: charge, credit, debit.
54
+ #
55
+ # @return [String, nil]
56
+ attr_reader :type
57
+
58
+ # @!visibility private
59
+ def initialize(record)
60
+ super(record)
61
+
62
+ @brand = get('brand')
63
+ @country = get('country')
64
+ @is_business = get('is_business')
65
+ @is_issued_in_billing_address_country = get(
66
+ 'is_issued_in_billing_address_country'
67
+ )
68
+ @is_prepaid = get('is_prepaid')
69
+ @is_virtual = get('is_virtual')
70
+ @issuer = Minfraud::Model::Issuer.new(get('issuer'))
71
+ @type = get('type')
72
+ end
73
+ end
74
+ end
75
+ end
@@ -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