securenative 0.1.16 → 0.1.22

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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +7 -15
  3. data/.github/workflows/publish.yml +1 -1
  4. data/.github/workflows/test.yml +5 -2
  5. data/.gitignore +3 -1
  6. data/Gemfile +6 -4
  7. data/Gemfile.lock +234 -23
  8. data/README.md +38 -33
  9. data/lib/api_manager.rb +39 -0
  10. data/lib/config/configuration_builder.rb +26 -0
  11. data/lib/config/configuration_manager.rb +55 -0
  12. data/lib/config/securenative_options.rb +22 -0
  13. data/lib/context/hanami_context.rb +42 -0
  14. data/lib/context/rails_context.rb +44 -0
  15. data/lib/context/securenative_context.rb +67 -0
  16. data/lib/context/sinatra_context.rb +42 -0
  17. data/lib/enums/api_route.rb +6 -0
  18. data/lib/enums/event_types.rb +23 -0
  19. data/lib/enums/failover_strategy.rb +6 -0
  20. data/lib/enums/risk_level.rb +7 -0
  21. data/lib/errors/securenative_config_error.rb +4 -0
  22. data/lib/errors/securenative_http_error.rb +4 -0
  23. data/lib/errors/securenative_invalid_options_error.rb +4 -0
  24. data/lib/errors/securenative_invalid_uri_error.rb +4 -0
  25. data/lib/errors/securenative_parse_error.rb +4 -0
  26. data/lib/errors/securenative_sdk_Illegal_state_error.rb +4 -0
  27. data/lib/errors/securenative_sdk_error.rb +4 -0
  28. data/lib/event_manager.rb +157 -0
  29. data/lib/http/secure_native_http_response.rb +12 -0
  30. data/lib/http/securenative_http_client.rb +50 -0
  31. data/lib/{securenative/models → models}/client_token.rb +2 -0
  32. data/lib/{securenative/models → models}/device.rb +3 -1
  33. data/lib/models/event_options.rb +37 -0
  34. data/lib/models/request_context.rb +18 -0
  35. data/lib/models/request_options.rb +12 -0
  36. data/lib/models/sdk_event.rb +49 -0
  37. data/lib/models/user_traits.rb +13 -0
  38. data/lib/models/verify_result.rb +16 -0
  39. data/lib/securenative.rb +83 -0
  40. data/lib/utils/date_utils.rb +9 -0
  41. data/lib/utils/encryption_utils.rb +49 -0
  42. data/lib/{securenative/utils → utils}/ip_utils.rb +7 -6
  43. data/lib/utils/request_utils.rb +54 -0
  44. data/lib/{securenative/logger.rb → utils/secure_native_logger.rb} +5 -3
  45. data/lib/{securenative/utils → utils}/signature_utils.rb +4 -2
  46. data/lib/utils/utils.rb +9 -0
  47. data/lib/utils/version_utils.rb +11 -0
  48. data/{lib/securenative → out/production/securenative-ruby}/api_manager.rb +6 -5
  49. data/{lib/securenative → out/production/securenative-ruby}/config/configuration_builder.rb +7 -3
  50. data/{lib/securenative → out/production/securenative-ruby}/config/configuration_manager.rb +5 -3
  51. data/{lib/securenative → out/production/securenative-ruby}/config/securenative_options.rb +3 -1
  52. data/out/production/securenative-ruby/context/securenative_context.rb +40 -0
  53. data/out/production/securenative-ruby/enums/api_route.rb +6 -0
  54. data/out/production/securenative-ruby/enums/event_types.rb +23 -0
  55. data/out/production/securenative-ruby/enums/failover_strategy.rb +6 -0
  56. data/out/production/securenative-ruby/enums/risk_level.rb +7 -0
  57. data/out/production/securenative-ruby/errors/securenative_config_error.rb +4 -0
  58. data/out/production/securenative-ruby/errors/securenative_http_error.rb +4 -0
  59. data/out/production/securenative-ruby/errors/securenative_invalid_options_error.rb +4 -0
  60. data/out/production/securenative-ruby/errors/securenative_invalid_uri_error.rb +4 -0
  61. data/out/production/securenative-ruby/errors/securenative_parse_error.rb +4 -0
  62. data/out/production/securenative-ruby/errors/securenative_sdk_Illegal_state_error.rb +4 -0
  63. data/out/production/securenative-ruby/errors/securenative_sdk_error.rb +4 -0
  64. data/out/production/securenative-ruby/event_manager.rb +156 -0
  65. data/out/production/securenative-ruby/event_options.rb +32 -0
  66. data/{lib/securenative → out/production/securenative-ruby}/http/http_response.rb +3 -1
  67. data/out/production/securenative-ruby/http/securenative_http_client.rb +32 -0
  68. data/out/production/securenative-ruby/models/client_token.rb +12 -0
  69. data/out/production/securenative-ruby/models/device.rb +10 -0
  70. data/{lib/securenative → out/production/securenative-ruby}/models/event_options.rb +3 -1
  71. data/{lib/securenative → out/production/securenative-ruby}/models/request_context.rb +5 -2
  72. data/out/production/securenative-ruby/models/request_options.rb +12 -0
  73. data/{lib/securenative → out/production/securenative-ruby}/models/sdk_event.rb +11 -3
  74. data/out/production/securenative-ruby/models/user_traits.rb +13 -0
  75. data/{lib/securenative → out/production/securenative-ruby}/models/verify_result.rb +3 -1
  76. data/{lib/securenative → out/production/securenative-ruby}/securenative.rb +24 -15
  77. data/out/production/securenative-ruby/utils/date_utils.rb +9 -0
  78. data/{lib/securenative → out/production/securenative-ruby}/utils/encryption_utils.rb +1 -4
  79. data/out/production/securenative-ruby/utils/ip_utils.rb +23 -0
  80. data/{lib/securenative → out/production/securenative-ruby}/utils/request_utils.rb +5 -3
  81. data/out/production/securenative-ruby/utils/secure_native_logger.rb +44 -0
  82. data/out/production/securenative-ruby/utils/signature_utils.rb +16 -0
  83. data/out/production/securenative-ruby/utils/utils.rb +9 -0
  84. data/{lib/securenative → out/production/securenative-ruby}/utils/version_utils.rb +3 -1
  85. data/out/test/securenative-ruby/spec_api_manager.rb +81 -0
  86. data/out/test/securenative-ruby/spec_context_builder.rb +69 -0
  87. data/out/test/securenative-ruby/spec_date_utils.rb +13 -0
  88. data/out/test/securenative-ruby/spec_encryption_utils.rb +26 -0
  89. data/out/test/securenative-ruby/spec_event_manager.rb +59 -0
  90. data/out/test/securenative-ruby/spec_helper.rb +20 -0
  91. data/out/test/securenative-ruby/spec_ip_utils.rb +41 -0
  92. data/out/test/securenative-ruby/spec_securenative.rb +65 -0
  93. data/out/test/securenative-ruby/spec_securenative_http_client.rb +23 -0
  94. data/out/test/securenative-ruby/spec_signature_utils.rb +18 -0
  95. data/securenative.gemspec +2 -2
  96. metadata +88 -43
  97. data/.travis.yml +0 -6
  98. data/VERSION +0 -1
  99. data/lib/securenative/context/context_builder.rb +0 -59
  100. data/lib/securenative/context/securenative_context.rb +0 -14
  101. data/lib/securenative/enums/api_route.rb +0 -4
  102. data/lib/securenative/enums/event_types.rb +0 -21
  103. data/lib/securenative/enums/failover_strategy.rb +0 -4
  104. data/lib/securenative/enums/risk_level.rb +0 -5
  105. data/lib/securenative/event_manager.rb +0 -149
  106. data/lib/securenative/event_options_builder.rb +0 -21
  107. data/lib/securenative/exceptions/securenative_config_exception.rb +0 -2
  108. data/lib/securenative/exceptions/securenative_http_exception.rb +0 -2
  109. data/lib/securenative/exceptions/securenative_invalid_options_exception.rb +0 -2
  110. data/lib/securenative/exceptions/securenative_invalid_uri_exception.rb +0 -2
  111. data/lib/securenative/exceptions/securenative_parse_exception.rb +0 -2
  112. data/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb +0 -2
  113. data/lib/securenative/exceptions/securenative_sdk_exception.rb +0 -2
  114. data/lib/securenative/http/securenative_http_client.rb +0 -30
  115. data/lib/securenative/models/request_options.rb +0 -10
  116. data/lib/securenative/models/user_traits.rb +0 -10
  117. data/lib/securenative/securenative.iml +0 -9
  118. data/lib/securenative/utils/date_utils.rb +0 -7
  119. data/lib/securenative/utils/utils.rb +0 -9
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class HttpResponse
2
4
  attr_reader :ok, :status_code, :body
3
5
  attr_writer :ok, :status_code, :body
@@ -7,4 +9,4 @@ class HttpResponse
7
9
  @status_code = status_code
8
10
  @body = body
9
11
  end
10
- end
12
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httpclient'
4
+
5
+ class SecureNativeHttpClient
6
+ AUTHORIZATION_HEADER = 'Authorization'
7
+ VERSION_HEADER = 'SN-Version'
8
+ USER_AGENT_HEADER = 'User-Agent'
9
+ USER_AGENT_HEADER_VALUE = 'SecureNative-python'
10
+ CONTENT_TYPE_HEADER = 'Content-Type'
11
+ CONTENT_TYPE_HEADER_VALUE = 'application/json'
12
+
13
+ def initialize(securenative_options)
14
+ @options = securenative_options
15
+ @client = HTTPClient.new
16
+ end
17
+
18
+ def _headers
19
+ {
20
+ CONTENT_TYPE_HEADER => CONTENT_TYPE_HEADER_VALUE,
21
+ USER_AGENT_HEADER => USER_AGENT_HEADER_VALUE,
22
+ VERSION_HEADER => VersionUtils.version,
23
+ AUTHORIZATION_HEADER => @options.api_key
24
+ }
25
+ end
26
+
27
+ def post(path, body)
28
+ url = "#{@options.api_url}/#{path}"
29
+ headers = _headers
30
+ @client.post(url, body, headers)
31
+ end
32
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ClientToken
4
+ attr_reader :cid, :vid, :fp
5
+ attr_writer :cid, :vid, :fp
6
+
7
+ def initialize(cid, vid, fp)
8
+ @cid = cid
9
+ @vid = vid
10
+ @fp = fp
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Device
4
+ attr_reader :device_id
5
+ attr_writer :device_id
6
+
7
+ def initialize(device_id)
8
+ @device_id = device_id
9
+ end
10
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class EventOptions
2
4
  attr_reader :event, :user_id, :user_traits, :context, :properties, :timestamp
3
5
  attr_writer :event, :user_id, :user_traits, :context, :properties, :timestamp
@@ -10,4 +12,4 @@ class EventOptions
10
12
  @properties = properties
11
13
  @timestamp = timestamp
12
14
  end
13
- end
15
+ end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class RequestContext
2
- attr_reader :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method
3
- attr_writer :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method
4
+ attr_reader :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :http_method
5
+ attr_writer :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :http_method
4
6
 
5
7
  def initialize(cid = nil, vid = nil, fp = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil)
6
8
  @cid = cid
@@ -13,3 +15,4 @@ class RequestContext
13
15
  @method = method
14
16
  end
15
17
  end
18
+
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RequestOptions
4
+ attr_reader :url, :body, :retry_sending
5
+ attr_writer :url, :body, :retry_sending
6
+
7
+ def initialize(url, body, retry_sending)
8
+ @url = url
9
+ @body = body
10
+ @retry_sending = retry_sending
11
+ end
12
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class SDKEvent
2
4
  attr_reader :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties
3
5
  attr_writer :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties
@@ -16,10 +18,16 @@ class SDKEvent
16
18
  @user_id = event_options.user_id
17
19
  @user_traits = event_options.user_traits
18
20
  @request = RequestContext(cid = client_token ? client_token.cid : '', vid = client_token ? client_token.vid : '',
19
- fp = client_token ? client_token.fp : '', ip = @context.ip, remote_ip = @context.remote_ip,
20
- method = @context.method, url = @context.url, headers = @context.headers)
21
+ fp = client_token ? client_token.fp : '', ip = @context.ip,
22
+ remote_ip = @context.remote_ip, method = @context.http_method, url = @context.url,
23
+ headers = @context.headers)
21
24
 
22
25
  @timestamp = DateUtils.to_timestamp(event_options.timestamp)
23
26
  @properties = event_options.properties
24
27
  end
25
- end
28
+
29
+ def to_s
30
+ "context: #{@context}, rid: #{@rid}, event_type: #{@event_type}, user_id: #{@user_id},
31
+ user_traits: #{@user_traits}, request: #{@request}, timestamp: #{@timestamp}, properties: #{@properties}"
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UserTraits
4
+ attr_reader :name, :email, :phone, :created_at
5
+ attr_writer :name, :email, :phone, :created_at
6
+
7
+ def initialize(name = nil, email = nil, phone = nil, created_at = nil)
8
+ @name = name
9
+ @email = email
10
+ @created_at = created_at
11
+ @phone = phone
12
+ end
13
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class VerifyResult
2
4
  attr_reader :risk_level, :score, :triggers
3
5
  attr_writer :risk_level, :score, :triggers
@@ -7,4 +9,4 @@ class VerifyResult
7
9
  @score = score
8
10
  @triggers = triggers
9
11
  end
10
- end
12
+ end
@@ -1,20 +1,29 @@
1
- require_relative 'logger'
2
- require_relative 'utils/signature_utils'
1
+ # frozen_string_literal: true
2
+
3
+ require 'utils/secure_native_logger'
4
+ require 'utils/signature_utils'
5
+ require 'utils/utils'
6
+ require 'errors/securenative_sdk_error'
7
+ require 'errors/securenative_sdk_Illegal_state_error'
8
+ require 'errors/securenative_config_error'
9
+ require 'enums/failover_strategy'
10
+ require 'config/configuration_builder'
11
+ require 'event_manager'
3
12
 
4
13
  class SecureNative
5
14
  attr_reader :options
6
15
 
7
16
  def initialize(options)
8
17
  @securenative = nil
9
- raise SecureNativeSDKException('You must pass your SecureNative api key') if Utils.null_or_empty?(options.api_key)
18
+ raise SecureNativeSDKError, 'You must pass your SecureNative api key' if Utils.null_or_empty?(options.api_key)
10
19
 
11
20
  @options = options
12
- @event_manager = EventManager(@options)
21
+ @event_manager = EventManager.new(@options)
13
22
 
14
23
  @event_manager.start_event_persist unless @options.api_url.nil?
15
24
 
16
25
  @api_manager = ApiManager.new(@event_manager, @options)
17
- Logger.init_logger(@options.log_level)
26
+ SecureNativeLogger.init_logger(@options.log_level)
18
27
  end
19
28
 
20
29
  def self.init_with_options(options)
@@ -22,21 +31,21 @@ class SecureNative
22
31
  @securenative = SecureNative.new(options)
23
32
  @securenative
24
33
  else
25
- Logger.debug('This SDK was already initialized.')
26
- raise SecureNativeSDKException('This SDK was already initialized.')
34
+ SecureNativeLogger.debug('This SDK was already initialized.')
35
+ raise SecureNativeSDKError, 'This SDK was already initialized.'
27
36
  end
28
37
  end
29
38
 
30
39
  def self.init_with_api_key(api_key)
31
- raise SecureNativeConfigException('You must pass your SecureNative api key') if Utils.null_or_empty?(api_key)
40
+ raise SecureNativeConfigError, 'You must pass your SecureNative api key' if Utils.null_or_empty?(api_key)
32
41
 
33
42
  if @securenative.nil?
34
- options = ConfigurationBuilder(api_key = api_key)
43
+ options = ConfigurationBuilder.new(api_key: api_key)
35
44
  @securenative = SecureNative.new(options)
36
45
  @securenative
37
46
  else
38
- Logger.debug('This SDK was already initialized.')
39
- raise SecureNativeSDKException(u('This SDK was already initialized.'))
47
+ SecureNativeLogger.debug('This SDK was already initialized.')
48
+ raise SecureNativeSDKError, 'This SDK was already initialized.'
40
49
  end
41
50
  end
42
51
 
@@ -46,7 +55,7 @@ class SecureNative
46
55
  end
47
56
 
48
57
  def self.instance
49
- raise SecureNativeSDKIllegalStateException() if @securenative.nil?
58
+ raise SecureNativeSDKIllegalStateError if @securenative.nil?
50
59
 
51
60
  @securenative
52
61
  end
@@ -54,11 +63,11 @@ class SecureNative
54
63
  def self.config_builder(api_key = nil, api_url = 'https://api.securenative.com/collector/api/v1', interval = 1000,
55
64
  max_events = 1000, timeout = 1500, auto_send = true, disable = false, log_level = 'FATAL',
56
65
  fail_over_strategy = FailOverStrategy::FAIL_OPEN)
57
- ConfigurationBuilder(api_key, api_url, interval, max_events, timeout, auto_send, disable, log_level, fail_over_strategy)
66
+ ConfigurationBuilder.new(api_key, api_url, interval, max_events, timeout, auto_send, disable, log_level, fail_over_strategy)
58
67
  end
59
68
 
60
69
  def self.context_builder(client_token = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil, body = nil)
61
- ContextBuilder(client_token, ip, remote_ip, headers, url, method, body)
70
+ ContextBuilder.new(client_token, ip, remote_ip, headers, url, method, body)
62
71
  end
63
72
 
64
73
  def track(event_options)
@@ -79,4 +88,4 @@ class SecureNative
79
88
 
80
89
  SignatureUtils.valid_signature?(@options.api_key, body, request_signature)
81
90
  end
82
- end
91
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DateUtils
4
+ def self.to_timestamp(date)
5
+ return Time.now.strftime('%Y-%m-%dT%H:%M:%S%Z') if date.nil?
6
+
7
+ Time.parse(date).iso8601
8
+ end
9
+ end
@@ -11,9 +11,6 @@ class EncryptionUtils
11
11
  cipher.padding = 0
12
12
 
13
13
  if text.size % BLOCK_SIZE != 0
14
- logger = Logger.new(STDOUT)
15
- logger.level = Logger::WARN
16
- logger.fatal('data not multiple of block length')
17
14
  return nil
18
15
  end
19
16
 
@@ -35,4 +32,4 @@ class EncryptionUtils
35
32
  rv = cipher.update(s) + cipher.final
36
33
  rv.strip
37
34
  end
38
- end
35
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "resolv"
4
+
5
+ class IpUtils
6
+ def self.ip_address?(ip_address)
7
+ return true if ip_address =~ Resolv::IPv4::Regex
8
+ return true if ip_address =~ Resolv::IPv6::Regex
9
+
10
+ false
11
+ end
12
+
13
+ def self.valid_public_ip?(ip_address)
14
+ ip = IPAddr.new(ip_address)
15
+ return false if ip.loopback? || ip.private? || ip.link_local? || ip.untrusted? || ip.tainted?
16
+
17
+ true
18
+ end
19
+
20
+ def self.loop_back?(ip_address)
21
+ IPAddr.new(ip_address).loopback?
22
+ end
23
+ end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class RequestUtils
2
- SECURENATIVE_COOKIE = '_sn'.freeze
3
- SECURENATIVE_HEADER = 'x-securenative'.freeze
4
+ SECURENATIVE_COOKIE = '_sn'
5
+ SECURENATIVE_HEADER = 'x-securenative'
4
6
 
5
7
  def self.get_secure_header_from_request(headers)
6
8
  return headers[RequestUtils.SECURENATIVE_HEADER] unless headers.nil?
@@ -18,4 +20,4 @@ class RequestUtils
18
20
  def self.get_remote_ip_from_request(request)
19
21
  request.remote_ip
20
22
  end
21
- end
23
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ class SecureNativeLogger
6
+ @logger = Logger.new(STDOUT)
7
+
8
+ def self.init_logger(level = 'DEBUG')
9
+ @logger.level = case level
10
+ when 'WARN'
11
+ SecureNativeLogger::WARN
12
+ when 'DEBUG'
13
+ SecureNativeLogger::DEBUG
14
+ when 'ERROR'
15
+ SecureNativeLogger::ERROR
16
+ when 'FATAL'
17
+ SecureNativeLogger::FATAL
18
+ when 'INFO'
19
+ SecureNativeLogger::INFO
20
+ else
21
+ SecureNativeLogger::FATAL
22
+ end
23
+
24
+ @logger.formatter = proc do |severity, datetime, progname, msg|
25
+ "[#{datetime}] #{severity} (#{progname}): #{msg}\n"
26
+ end
27
+ end
28
+
29
+ def self.info(msg)
30
+ @logger.info(msg)
31
+ end
32
+
33
+ def self.debug(msg)
34
+ @logger.debug(msg)
35
+ end
36
+
37
+ def self.warning(msg)
38
+ @logger.warning(msg)
39
+ end
40
+
41
+ def self.error(msg)
42
+ @logger.error(msg)
43
+ end
44
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+
5
+ class SignatureUtils
6
+ SIGNATURE_HEADER = 'x-securenative'
7
+
8
+ def self.valid_signature?(api_key, payload, header_signature)
9
+ key = api_key.encode('utf-8')
10
+ body = payload.encode('utf-8')
11
+ calculated_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha512'), key, body)
12
+ calculated_signature.eql? header_signature
13
+ rescue StandardError
14
+ false
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Utils
4
+ def self.null_or_empty?(string)
5
+ return true if !string || string.empty? || string.nil?
6
+
7
+ false
8
+ end
9
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class VersionUtils
2
4
  def self.version
3
5
  path = 'VERSION'
@@ -7,4 +9,4 @@ class VersionUtils
7
9
 
8
10
  version
9
11
  end
10
- end
12
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'api_manager'
4
+ require 'webmock/rspec'
5
+ require 'rspec'
6
+
7
+ RSpec.describe ApiManager do
8
+ let(:context) do
9
+ ContextBuilder(ip: '127.0.0.1', client_token: 'SECURED_CLIENT_TOKEN',
10
+ headers: { 'user-agent' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us)
11
+ AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405' })
12
+ end
13
+ let(:event_options) do
14
+ EventOptions(event_type: EventTypes.LOG_IN, user_id: 'USER_ID',
15
+ user_traits: UserTraits('USER_NAME', 'USER_EMAIL', '+1234567890'),
16
+ properties: { prop1: 'CUSTOM_PARAM_VALUE', prop2: true, prop3: 3 }).build
17
+ end
18
+
19
+ it 'tracks an event' do
20
+ options = ConfigurationBuilder.new(api_key: 'YOUR_API_KEY', auto_send: true, interval: 10, api_url: 'https://api.securenative-stg.com/collector/api/v1')
21
+
22
+ expected = '{"eventType":"sn.user.login","userId":"USER_ID","userTraits":{' \
23
+ '"name":"USER_NAME","email":"USER_EMAIL","phone":"+1234567890","createdAt":null},"request":{' \
24
+ '"cid":null,"vid":null,"fp":null,"ip":"127.0.0.1","remoteIp":null,"headers":{' \
25
+ '"user-agent":"Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) ' \
26
+ 'AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405"},"url":null,"method":null},' \
27
+ '"properties":{"prop2":true,"prop1":"CUSTOM_PARAM_VALUE","prop3":3}}'
28
+
29
+ stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track')
30
+ .with(body: JSON.parse(expected)).to_return(status: 200)
31
+ event_manager = EventManager.new(options)
32
+ event_manager.start_event_persist
33
+ api_manager = ApiManager.new(event_manager, options)
34
+
35
+ begin
36
+ api_manager.track(:event_options)
37
+ ensure
38
+ event_manager.stop_event_persist
39
+ end
40
+ end
41
+
42
+ it 'uses invalid options' do
43
+ options = ConfigurationBuilder(api_key: 'YOUR_API_KEY', auto_send: true, interval: 10, api_url: 'https://api.securenative-stg.com/collector/api/v1')
44
+
45
+ properties = {}
46
+ (0..12).each do |i|
47
+ properties[i] = i
48
+ end
49
+
50
+ stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track').to_return(status: 200)
51
+ event_manager = EventManager.new(options)
52
+ event_manager.start_event_persist
53
+ api_manager = ApiManager.new(event_manager, options)
54
+
55
+ begin
56
+ expect { api_manager.track(EventOptions(event_type: EventTypes.LOG_IN, properties: properties).build) }
57
+ .to raise_error(SecureNativeInvalidOptionsError)
58
+ ensure
59
+ event_manager.stop_event_persist
60
+ end
61
+ end
62
+
63
+ it 'verifies an event' do
64
+ options = ConfigurationBuilder(api_key: 'YOUR_API_KEY', api_url: 'https://api.securenative-stg.com/collector/api/v1')
65
+
66
+ stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track')
67
+ .with(body: { riskLevel: 'medium', score: 0.32, triggers: ['New IP', 'New City'] }).to_return(status: 200)
68
+ verify_result = VerifyResult.new(RiskLevel.LOW, 0, nil)
69
+
70
+ event_manager = EventManager.new(options)
71
+ event_manager.start_event_persist
72
+ api_manager = ApiManager.new(event_manager, options)
73
+
74
+ result = api_manager.verify(:event_options)
75
+
76
+ expect(result).not_to be_nil
77
+ expect(result.risk_level).to eq(verify_result.risk_level)
78
+ expect(result.score).to eq(verify_result.score)
79
+ expect(result.triggers).to eq(verify_result.triggers)
80
+ end
81
+ end