securenative 0.1.20 → 0.1.21

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d6008fff3b5f2dea4e6d6680af895c51a18a14a80a495f1fbe3da99513d955b
4
- data.tar.gz: 6de47ae10eb46753aa40d1854ed35d42f961c39543bd12e931f80d191d033114
3
+ metadata.gz: 8aa7eb317d253da74f5b3f78ef8ca0739074e23c0c06396b4a4fb23d40e44320
4
+ data.tar.gz: '0975ccad317a881c689bc6b5d80d9c38b677d2d65907f275548471e4cc4c5f9d'
5
5
  SHA512:
6
- metadata.gz: 61c717b498a2a0464ad74fd32a1daca48f8ff115348f0b8a49710d54e3ce7f6d99f21c92560b8936c64548e08ba9ddd2cf105902d614f656925a15d9fa7094e4
7
- data.tar.gz: 7667f250f61f1629cdf36829e8f74ce74bcd66e862b183051616c3774090229426b8b38d96e873cc58496f64f8774616c4104799c50e26df8266acf95c60948f
6
+ metadata.gz: 5d032dcb9eead67fd2cda1e40e3d402853fc250134d3a325bfb37edf5545440307dd53def5ea79d40e737b2afc2a472110c6a7e9a5092f37d540f7a205637a1b
7
+ data.tar.gz: f8093a2e2c272d911f5a0ae9f6039e229f1598b1a428efdcdf6752f2f20b7b98acf5aa4553c820e8868b36d218937b7e26c85ab13ce4682ffa4054a729518cdd
data/Gemfile CHANGED
@@ -3,7 +3,6 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
  gem "rspec"
5
5
  gem "rake"
6
- gem "parseconfig"
7
6
  gem "simplecov", :require => false, :group => :test
8
7
  gem "codecov", :require => false, :group => :test
9
8
  gem "webmock", :require => false, :group => :test
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- securenative (0.1.20)
4
+ securenative (0.1.21)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -73,7 +73,7 @@ GEM
73
73
  crack (0.4.3)
74
74
  safe_yaml (~> 1.0.0)
75
75
  crass (1.0.6)
76
- diff-lcs (1.3)
76
+ diff-lcs (1.4.4)
77
77
  docile (1.3.2)
78
78
  dry-configurable (0.11.6)
79
79
  concurrent-ruby (~> 1.0)
@@ -174,7 +174,6 @@ GEM
174
174
  nio4r (2.5.2)
175
175
  nokogiri (1.10.10)
176
176
  mini_portile2 (~> 2.4.0)
177
- parseconfig (1.0.8)
178
177
  public_suffix (4.0.5)
179
178
  rack (2.2.3)
180
179
  rack-protection (2.0.8.1)
@@ -208,19 +207,19 @@ GEM
208
207
  rake (>= 0.8.7)
209
208
  thor (>= 0.20.3, < 2.0)
210
209
  rake (13.0.1)
211
- rspec (3.8.0)
212
- rspec-core (~> 3.8.0)
213
- rspec-expectations (~> 3.8.0)
214
- rspec-mocks (~> 3.8.0)
215
- rspec-core (3.8.2)
216
- rspec-support (~> 3.8.0)
217
- rspec-expectations (3.8.4)
210
+ rspec (3.9.0)
211
+ rspec-core (~> 3.9.0)
212
+ rspec-expectations (~> 3.9.0)
213
+ rspec-mocks (~> 3.9.0)
214
+ rspec-core (3.9.2)
215
+ rspec-support (~> 3.9.3)
216
+ rspec-expectations (3.9.2)
218
217
  diff-lcs (>= 1.2.0, < 2.0)
219
- rspec-support (~> 3.8.0)
220
- rspec-mocks (3.8.1)
218
+ rspec-support (~> 3.9.0)
219
+ rspec-mocks (3.9.1)
221
220
  diff-lcs (>= 1.2.0, < 2.0)
222
- rspec-support (~> 3.8.0)
223
- rspec-support (3.8.2)
221
+ rspec-support (~> 3.9.0)
222
+ rspec-support (3.9.3)
224
223
  ruby2_keywords (0.0.2)
225
224
  safe_yaml (1.0.5)
226
225
  simplecov (0.19.0)
@@ -263,7 +262,6 @@ DEPENDENCIES
263
262
  bundler (~> 2.0)
264
263
  codecov
265
264
  hanami
266
- parseconfig
267
265
  rails
268
266
  rake
269
267
  rspec
data/README.md CHANGED
@@ -47,7 +47,7 @@ Or install it yourself as:
47
47
  To get your *API KEY*, login to your SecureNative account and go to project settings page:
48
48
 
49
49
  ### Option 1: Initialize via Config file
50
- SecureNative can automatically load your config from *securenative.cfg* file or from the file that is specified in your *SECURENATIVE_CONFIG_FILE* env variable:
50
+ SecureNative can automatically load your config from *securenative.yml* file or from the file that is specified in your *SECURENATIVE_CONFIG_FILE* env variable:
51
51
 
52
52
  ```ruby
53
53
  require 'securenative'
@@ -69,7 +69,8 @@ securenative = SecureNative.init_with_api_key('YOUR_API_KEY')
69
69
  require 'securenative'
70
70
 
71
71
 
72
- securenative = SecureNative.init_with_options(SecureNative.config_builder(api_key = 'API_KEY', max_event = 10, log_level = 'ERROR'))
72
+ options = ConfigurationBuilder.new(api_key: 'API_KEY', max_events: 10, log_level: 'ERROR')
73
+ SecureNative.init_with_options(options)
73
74
  ```
74
75
 
75
76
  ## Getting SecureNative instance
@@ -88,42 +89,46 @@ instance. Make sure you build event with the EventBuilder:
88
89
 
89
90
  ```ruby
90
91
  require 'securenative'
91
- require 'securenative/enums/event_types'
92
- require 'securenative/event_options_builder'
93
- require 'securenative/models/user_traits'
94
- require 'securenative/context/context_builder'
92
+ require 'models/event_options'
93
+ require 'enums/event_types'
94
+ require 'models/user_traits'
95
95
 
96
96
 
97
- securenative = SecureNative.instance
98
-
99
- context = securenative.context_builder(ip = '127.0.0.1', client_token = 'SECURED_CLIENT_TOKEN',
100
- headers = { 'user-agent' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405' })
101
-
102
- event_options = EventOptions(event_type = EventTypes::LOG_IN,
103
- user_id = '1234', user_traits = UserTraits('Your Name', 'name@gmail.com', '+1234567890'),
104
- context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build
105
-
106
- securenative.track(event_options)
97
+ def track
98
+ securenative = SecureNative.instance
99
+ context = SecureNativeContext.new(client_token: '2a980d872b939c7e4f4378aa111a5eeffb22808b58b5372f658d34904ebd5b05fff0daab91921243ac08b72442a5b3992e402dc21df16aa7cc0e19f8bffa9d6cc59996d480d70aa22b857189403675d37fd144ebaf9dc697fed149b907678f2b1f964d73b332dc8ea7df63fcfc3c11f7bbb51ba2672652ca7d5d43f36a62e15db8b13dfd794a5eccfc5968ca514dd7cce59f2df2b9d8184d076eba808c81b311', ip: '127.0.0.1',
100
+ headers: { 'user-agent' => 'Mozilla: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.3 Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/43.4' })
101
+
102
+ event_options = EventOptions.new(event: EventTypes::LOG_IN, user_id: '1234', context: context,
103
+ user_traits: UserTraits.new(name: 'Your Name', email: 'name@gmail.com', phone: '+1234567890'),
104
+ properties: { custom_param1: 'CUSTOM_PARAM_VALUE', custom_param2: true, custom_param3: 3 })
105
+
106
+ securenative.track(event_options)
107
+
108
+ @message = 'tracked'
109
+ end
107
110
  ```
108
111
 
109
112
  You can also create request context from requests:
110
113
 
111
114
  ```ruby
112
115
  require 'securenative'
113
- require 'securenative/enums/event_types'
114
- require 'securenative/event_options_builder'
115
- require 'securenative/models/user_traits'
116
+ require 'models/event_options'
117
+ require 'enums/event_types'
118
+ require 'models/user_traits'
116
119
 
117
120
 
118
- def track(request)
121
+ def track
119
122
  securenative = SecureNative.instance
120
- context = SecureNative.context_builder.from_http_request(request).build
121
-
122
- event_options = EventOptions(event_type = EventTypes::LOG_IN,
123
- user_id = '1234', user_traits = UserTraits('Your Name', 'name@gmail.com', '+1234567890'),
124
- context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build
123
+ context = SecureNativeContext.from_http_request(request)
124
+
125
+ event_options = EventOptions.new(event: EventTypes::LOG_IN, user_id: '1234', context: context,
126
+ user_traits: UserTraits.new(name: 'Your Name', email: 'name@gmail.com', phone: '+1234567890'),
127
+ properties: { custom_param1: 'CUSTOM_PARAM_VALUE', custom_param2: true, custom_param3: 3 })
125
128
 
126
129
  securenative.track(event_options)
130
+
131
+ @message = 'tracked'
127
132
  end
128
133
  ```
129
134
 
@@ -133,18 +138,18 @@ end
133
138
 
134
139
  ```ruby
135
140
  require 'securenative'
136
- require 'securenative/enums/event_types'
137
- require 'securenative/event_options_builder'
138
- require 'securenative/models/user_traits'
141
+ require 'models/event_options'
142
+ require 'enums/event_types'
143
+ require 'models/user_traits'
139
144
 
140
145
 
141
146
  def verify(request)
142
147
  securenative = SecureNative.instance
143
- context = SecureNative.context_builder.from_http_request(request).build
148
+ context = SecureNativeContext.from_http_request(request)
144
149
 
145
- event_options = EventOptions(event_type = EventTypes::LOG_IN,
146
- user_id = '1234', user_traits = UserTraits('Your Name', 'name@gmail.com', '+1234567890'),
147
- context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build
150
+ event_options = EventOptions.new(event: EventTypes::LOG_IN, user_id: '1234', context: context,
151
+ user_traits: UserTraits.new(name: 'Your Name', email: 'name@gmail.com', phone: '+1234567890'),
152
+ properties: { custom_param1: 'CUSTOM_PARAM_VALUE', custom_param2: true, custom_param3: 3 })
148
153
 
149
154
  verify_result = securenative.verify(event_options)
150
155
  verify_result.risk_level # Low, Medium, High
@@ -2,6 +2,9 @@
2
2
 
3
3
  require 'models/sdk_event'
4
4
  require 'enums/failover_strategy'
5
+ require 'enums/risk_level'
6
+ require 'enums/api_route'
7
+ require 'models/verify_result'
5
8
  require 'json'
6
9
 
7
10
  class ApiManager
@@ -21,8 +24,9 @@ class ApiManager
21
24
  event = SDKEvent.new(event_options, @options)
22
25
 
23
26
  begin
24
- res = JSON.parse(@event_manager.send_sync(event, ApiRoute::VERIFY, false))
25
- return VerifyResult.new(risk_level: res['riskLevel'], score: res['score'], triggers: res['triggers'])
27
+ res = @event_manager.send_sync(event, ApiRoute::VERIFY, false)
28
+ ver_result = JSON.parse(res.body)
29
+ return VerifyResult.new(risk_level: ver_result['riskLevel'], score: ver_result['score'], triggers: ver_result['triggers'])
26
30
  rescue StandardError => e
27
31
  SecureNativeLogger.debug("Failed to call verify; #{e}")
28
32
  end
@@ -20,10 +20,6 @@ class ConfigurationBuilder
20
20
  @fail_over_strategy = fail_over_strategy
21
21
  end
22
22
 
23
- def self.default_config_builder
24
- ConfigurationBuilder.new
25
- end
26
-
27
23
  def self.default_securenative_options
28
24
  SecureNativeOptions.new
29
25
  end
@@ -1,20 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'parseconfig'
3
+ require 'yaml'
4
+ require 'config/configuration_builder'
4
5
 
5
6
  class ConfigurationManager
6
- DEFAULT_CONFIG_FILE = 'securenative.cfg'
7
+ DEFAULT_CONFIG_FILE = 'securenative.yml'
7
8
  CUSTOM_CONFIG_FILE_ENV_NAME = 'SECURENATIVE_CONFIG_FILE'
8
9
  @config = nil
9
10
 
10
11
  def self.read_resource_file(resource_path)
11
- @config = ParseConfig.new(resource_path)
12
-
13
12
  properties = {}
14
- @config.get_groups.each do |group|
15
- group.each do |key, value|
16
- properties[key.upcase] = value
17
- end
13
+ begin
14
+ @config = YAML.load_file(resource_path)
15
+ properties = @config unless @config.nil?
16
+ rescue StandardError => e
17
+ SecureNativeLogger.error("Could not parse config file #{resource_path}; #{e}")
18
18
  end
19
19
  properties
20
20
  end
@@ -24,32 +24,32 @@ class ConfigurationManager
24
24
  end
25
25
 
26
26
  def self.config_builder
27
- ConfigurationBuilder.default_config_builder
27
+ ConfigurationBuilder.new
28
28
  end
29
29
 
30
30
  def self._get_env_or_default(properties, key, default)
31
- return Env[key] if Env[key]
31
+ return ENV[key] if ENV[key]
32
32
  return properties[key] if properties[key]
33
33
 
34
34
  default
35
35
  end
36
36
 
37
37
  def self.load_config
38
- options = ConfigurationBuilder().default_securenative_options
38
+ options = ConfigurationBuilder.default_securenative_options
39
39
 
40
40
  resource_path = DEFAULT_CONFIG_FILE
41
- resource_path = Env[CUSTOM_CONFIG_FILE_ENV_NAME] if Env[CUSTOM_CONFIG_FILE_ENV_NAME]
41
+ resource_path = ENV[CUSTOM_CONFIG_FILE_ENV_NAME] unless ENV[CUSTOM_CONFIG_FILE_ENV_NAME].nil?
42
42
 
43
43
  properties = read_resource_file(resource_path)
44
44
 
45
- ConfigurationBuilder(_get_env_or_default(properties, 'SECURENATIVE_API_KEY', options.api_key),
46
- _get_env_or_default(properties, 'SECURENATIVE_API_URL', options.api_url),
47
- _get_env_or_default(properties, 'SECURENATIVE_INTERVAL', options.interval),
48
- _get_env_or_default(properties, 'SECURENATIVE_MAX_EVENTS', options.max_events),
49
- _get_env_or_default(properties, 'SECURENATIVE_TIMEOUT', options.timeout),
50
- _get_env_or_default(properties, 'SECURENATIVE_AUTO_SEND', options.auto_send),
51
- _get_env_or_default(properties, 'SECURENATIVE_DISABLE', options.disable),
52
- _get_env_or_default(properties, 'SECURENATIVE_LOG_LEVEL', options.log_level),
53
- _get_env_or_default(properties, 'SECURENATIVE_FAILOVER_STRATEGY', options.fail_over_strategy))
45
+ ConfigurationBuilder.new(api_key: _get_env_or_default(properties, 'SECURENATIVE_API_KEY', options.api_key),
46
+ api_url: _get_env_or_default(properties, 'SECURENATIVE_API_URL', options.api_url),
47
+ interval: _get_env_or_default(properties, 'SECURENATIVE_INTERVAL', options.interval),
48
+ max_events: _get_env_or_default(properties, 'SECURENATIVE_MAX_EVENTS', options.max_events),
49
+ timeout: _get_env_or_default(properties, 'SECURENATIVE_TIMEOUT', options.timeout),
50
+ auto_send: _get_env_or_default(properties, 'SECURENATIVE_AUTO_SEND', options.auto_send),
51
+ disable: _get_env_or_default(properties, 'SECURENATIVE_DISABLE', options.disable),
52
+ log_level: _get_env_or_default(properties, 'SECURENATIVE_LOG_LEVEL', options.log_level),
53
+ fail_over_strategy: _get_env_or_default(properties, 'SECURENATIVE_FAILOVER_STRATEGY', options.fail_over_strategy))
54
54
  end
55
55
  end
@@ -1,11 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class HanamiContext
4
+ SECURENATIVE_COOKIE = '_sn'
5
+
4
6
  def self.get_client_token(request)
5
7
  begin
6
8
  request.env[SECURENATIVE_COOKIE]
7
9
  rescue StandardError
8
- nil
10
+ begin
11
+ request.cookies[SECURENATIVE_COOKIE]
12
+ rescue StandardError
13
+ nil
14
+ end
9
15
  end
10
16
  end
11
17
 
@@ -27,7 +33,8 @@ class HanamiContext
27
33
 
28
34
  def self.get_headers(request)
29
35
  begin
30
- request.headers.to_hash
36
+ # Note: At the moment we're filtering out everything but user-agent since ruby's payload is way too big
37
+ { 'user-agent' => request.env['HTTP_USER_AGENT'] }
31
38
  rescue StandardError
32
39
  nil
33
40
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class RailsContext
4
+ SECURENATIVE_COOKIE = '_sn'
5
+
4
6
  def self.get_client_token(request)
5
7
  begin
6
8
  request.cookies[SECURENATIVE_COOKIE]
@@ -33,7 +35,8 @@ class RailsContext
33
35
 
34
36
  def self.get_headers(request)
35
37
  begin
36
- request.headers.to_hash
38
+ # Note: At the moment we're filtering out everything but user-agent since ruby's payload is way too big
39
+ { 'user-agent' => request.env['HTTP_USER_AGENT'] }
37
40
  rescue StandardError
38
41
  nil
39
42
  end
@@ -12,7 +12,7 @@ class SecureNativeContext
12
12
 
13
13
  SECURENATIVE_COOKIE = '_sn'
14
14
 
15
- def initialize(client_token: nil, ip: nil, remote_ip: nil, headers: nil, url: nil, http_method: nil, body: nil)
15
+ def initialize(client_token: '', ip: '', remote_ip: '', headers: nil, url: '', http_method: '', body: '')
16
16
  @client_token = client_token
17
17
  @ip = ip
18
18
  @remote_ip = remote_ip
@@ -1,17 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class SinatraContext
4
+ SECURENATIVE_COOKIE = '_sn'
5
+
4
6
  def self.get_client_token(request)
5
7
  begin
6
8
  request.env[SECURENATIVE_COOKIE]
7
9
  rescue StandardError
8
- nil
10
+ begin
11
+ request.cookies[SECURENATIVE_COOKIE]
12
+ rescue StandardError
13
+ nil
14
+ end
9
15
  end
10
16
  end
11
17
 
12
18
  def self.get_url(request)
13
19
  begin
14
- request.url
20
+ request.env['REQUEST_URI']
15
21
  rescue StandardError
16
22
  nil
17
23
  end
@@ -19,7 +25,7 @@ class SinatraContext
19
25
 
20
26
  def self.get_method(request)
21
27
  begin
22
- request.method
28
+ request.env['REQUEST_METHOD']
23
29
  rescue StandardError
24
30
  nil
25
31
  end
@@ -27,7 +33,8 @@ class SinatraContext
27
33
 
28
34
  def self.get_headers(request)
29
35
  begin
30
- request.headers.to_hash
36
+ # Note: At the moment we're filtering out everything but user-agent since ruby's payload is way too big
37
+ { 'user-agent' => request.env['HTTP_USER_AGENT'] }
31
38
  rescue StandardError
32
39
  nil
33
40
  end
@@ -4,6 +4,7 @@ require 'utils/secure_native_logger'
4
4
  require 'config/securenative_options'
5
5
  require 'http/securenative_http_client'
6
6
  require 'errors/securenative_sdk_error'
7
+ require 'errors/securenative_http_error'
7
8
 
8
9
  class QueueItem
9
10
  attr_reader :url, :body, :retry_sending
@@ -64,7 +65,7 @@ class EventManager
64
65
  SecureNativeLogger.debug("Attempting to send event #{event}")
65
66
  res = @http_client.post(resource_path, EventManager.serialize(event).to_json)
66
67
 
67
- if res.code != 200
68
+ if res.nil? || res.code != '200'
68
69
  SecureNativeLogger.info("SecureNative failed to call endpoint #{resource_path} with event #{event}. adding back to queue")
69
70
  item = QueueItem.new(resource_path, EventManager.serialize(event).to_json, retry_sending)
70
71
  @queue.append(item)
@@ -81,9 +82,9 @@ class EventManager
81
82
  @queue.each do |item|
82
83
  begin
83
84
  res = @http_client.post(item.url, item.body)
84
- if res.status_code == 401
85
+ if res.code == '401'
85
86
  item.retry_sending = false
86
- elsif res.status_code != 200
87
+ elsif res.code != '200'
87
88
  raise SecureNativeHttpError, res.status_code
88
89
  end
89
90
  SecureNativeLogger.debug("Event successfully sent; #{item.body}")
@@ -145,7 +146,7 @@ class EventManager
145
146
  fp: obj.request.fp,
146
147
  ip: obj.request.ip,
147
148
  remoteIp: obj.request.remote_ip,
148
- http_method: obj.request.http_method,
149
+ method: obj.request.http_method || '',
149
150
  url: obj.request.url,
150
151
  headers: obj.request.headers
151
152
  },
@@ -3,6 +3,8 @@
3
3
  require 'net/http'
4
4
  require 'uri'
5
5
  require 'json'
6
+ require 'utils/version_utils'
7
+ require 'utils/secure_native_logger'
6
8
 
7
9
  class SecureNativeHttpClient
8
10
  AUTHORIZATION_HEADER = 'Authorization'
@@ -30,9 +32,19 @@ class SecureNativeHttpClient
30
32
  headers = _headers
31
33
 
32
34
  client = Net::HTTP.new(uri.host, uri.port)
35
+ client.use_ssl = true
36
+ client.verify_mode = OpenSSL::SSL::VERIFY_NONE
37
+
33
38
  request = Net::HTTP::Post.new(uri.request_uri, headers)
34
- request.body = body.to_json
39
+ request.body = body
35
40
 
36
- client.request(request)
41
+ res = nil
42
+ begin
43
+ res = client.request(request)
44
+ rescue StandardError => e
45
+ SecureNativeLogger.error("Failed to send request; #{e}")
46
+ return res
47
+ end
48
+ res
37
49
  end
38
50
  end
@@ -1,10 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'models/event_options'
4
+ require 'models/user_traits'
5
+ require 'errors/securenative_invalid_options_error'
6
+
3
7
  class EventOptions
4
8
  attr_reader :event, :user_id, :user_traits, :context, :properties, :timestamp
5
9
  attr_writer :event, :user_id, :user_traits, :context, :properties, :timestamp
6
10
 
7
- def initialize(event: nil, user_id: nil, user_traits: nil, context: nil, properties: nil, timestamp: nil)
11
+ MAX_PROPERTIES_SIZE = 10
12
+
13
+ def initialize(event: nil, user_id: nil, user_traits: nil, user_name: nil, email: nil, phone: nil, created_at: nil, context: nil, properties: nil, timestamp: nil)
14
+ if !properties.nil? && properties.length > MAX_PROPERTIES_SIZE
15
+ raise SecureNativeInvalidOptionsError, "You can have only up to #{MAX_PROPERTIES_SIZE} custom properties"
16
+ end
17
+
18
+ if user_traits.nil?
19
+ if user_name && email && phone && created_at
20
+ user_traits = UserTraits(user_name, email, phone, created_at)
21
+ elsif user_name && email && phone
22
+ user_traits = UserTraits(user_name, email, phone)
23
+ elsif user_name && email
24
+ user_traits = UserTraits(user_name, email)
25
+ else
26
+ user_traits = UserTraits.new
27
+ end
28
+ end
29
+
8
30
  @event = event
9
31
  @user_id = user_id
10
32
  @user_traits = user_traits
@@ -2,6 +2,9 @@
2
2
 
3
3
  require 'context/securenative_context'
4
4
  require 'utils/encryption_utils'
5
+ require 'utils/date_utils'
6
+ require 'models/request_context'
7
+ require 'securerandom'
5
8
 
6
9
  class SDKEvent
7
10
  attr_reader :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties
@@ -20,9 +23,11 @@ class SDKEvent
20
23
  @event_type = event_options.event
21
24
  @user_id = event_options.user_id
22
25
  @user_traits = event_options.user_traits
23
- @request = RequestContext(client_token ? client_token.cid : '', client_token ? client_token.vid : '',
24
- client_token ? client_token.fp : '', @context.ip,
25
- @context.remote_ip, @context.headers, @context.url, @context.http_method)
26
+ @request = RequestContext.new(cid: client_token ? client_token.cid : '', vid: client_token ? client_token.vid : '',
27
+ fp: client_token ? client_token.fp : '', ip: @context.ip,
28
+ remote_ip: @context.remote_ip, headers: @context.headers,
29
+ url: @context.url, http_method: @context.http_method)
30
+
26
31
 
27
32
  @timestamp = DateUtils.to_timestamp(event_options.timestamp)
28
33
  @properties = event_options.properties
@@ -9,4 +9,8 @@ class VerifyResult
9
9
  @score = score
10
10
  @triggers = triggers
11
11
  end
12
+
13
+ def to_s
14
+ "risk_level: #{@risk_level}, score: #{@score}, triggers: #{@triggers}"
15
+ end
12
16
  end
@@ -8,6 +8,7 @@ require 'errors/securenative_sdk_Illegal_state_error'
8
8
  require 'errors/securenative_config_error'
9
9
  require 'enums/failover_strategy'
10
10
  require 'config/configuration_builder'
11
+ require 'config/configuration_manager'
11
12
  require 'event_manager'
12
13
  require 'api_manager'
13
14
 
@@ -61,19 +62,6 @@ class SecureNative
61
62
  @securenative
62
63
  end
63
64
 
64
- def self.config_builder(api_key: nil, api_url: 'https://api.securenative.com/collector/api/v1', interval: 1000,
65
- max_events: 1000, timeout: 1500, auto_send: true, disable: false, log_level: 'FATAL',
66
- fail_over_strategy: FailOverStrategy::FAIL_OPEN)
67
- ConfigurationBuilder.new(api_key: api_key, api_url: api_url, interval: interval, max_events: max_events,
68
- timeout: timeout, auto_send: auto_send, disable: disable, log_level: log_level,
69
- fail_over_strategy: fail_over_strategy)
70
- end
71
-
72
- def self.context_builder(client_token: nil, ip: nil, remote_ip: nil, headers: nil, url: nil, http_method: nil, body: nil)
73
- SecureNativeContext.new(client_token: client_token, ip: ip, remote_ip: remote_ip, headers: headers,
74
- url: url, http_method: http_method, body: body)
75
- end
76
-
77
65
  def track(event_options)
78
66
  @api_manager.track(event_options)
79
67
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  class DateUtils
4
4
  def self.to_timestamp(date)
5
- return Time.now.strftime('%Y-%m-%dT%H:%M:%S%Z') if date.nil?
5
+ return Time.now.utc.iso8601 if date.nil?
6
6
 
7
7
  Time.parse(date).iso8601
8
8
  end
@@ -1,35 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'openssl'
4
+ require 'digest'
5
+ require 'base64'
6
+ require 'models/client_token'
4
7
 
5
8
  class EncryptionUtils
6
- BLOCK_SIZE = 16
7
- KEY_SIZE = 32
8
-
9
- def self.encrypt(text, cipher_key)
10
- cipher = OpenSSL::Cipher::AES.new(KEY_SIZE, :CBC).encrypt
11
- cipher.padding = 0
12
-
13
- if text.size % BLOCK_SIZE != 0
14
- return nil
9
+ def self.padding_key(key, length)
10
+ if key.length == length
11
+ key
12
+ else
13
+ if key.length > length
14
+ key.slice(0, length)
15
+ else
16
+ (length - key.length).times { key << '0' }
17
+ key
18
+ end
15
19
  end
16
-
17
- cipher_key = Digest::SHA1.hexdigest cipher_key
18
- cipher.key = cipher_key.slice(0, BLOCK_SIZE)
19
- s = cipher.update(text) + cipher.final
20
-
21
- s.unpack('H*')[0].upcase
22
20
  end
23
21
 
24
- def self.decrypt(encrypted, cipher_key)
25
- cipher = OpenSSL::Cipher::AES.new(KEY_SIZE, :CBC).decrypt
26
- cipher.padding = 0
27
-
28
- cipher_key = Digest::SHA1.hexdigest cipher_key
29
- cipher.key = cipher_key.slice(0, BLOCK_SIZE)
30
- s = [encrypted].pack('H*').unpack('C*').pack('c*')
22
+ def self.encrypt(plain_text, secret_key)
23
+ begin
24
+ cipher = OpenSSL::Cipher.new('aes-256-cbc')
25
+ cipher.encrypt
26
+ iv = cipher.random_iv
27
+ cipher.key = padding_key(secret_key, 32)
28
+ encrypted = cipher.update(plain_text) + cipher.final
29
+ (iv + encrypted).unpack1('H*')
30
+ rescue StandardError
31
+ ''
32
+ end
33
+ end
31
34
 
32
- rv = cipher.update(s) + cipher.final
33
- rv.strip
35
+ def self.decrypt(cipher_text, secret_key)
36
+ begin
37
+ cipher = OpenSSL::Cipher.new('aes-256-cbc')
38
+ cipher.decrypt
39
+ raw_data = [cipher_text].pack('H*')
40
+ cipher.iv = raw_data.slice(0, 16)
41
+ cipher.key = padding_key(secret_key, 32)
42
+ decrypted = JSON.parse(cipher.update(raw_data.slice(16, raw_data.length)) + cipher.final)
43
+
44
+ return ClientToken.new(decrypted['cid'], decrypted['vid'], decrypted['fp'])
45
+ rescue StandardError
46
+ ClientToken.new('', '','')
47
+ end
34
48
  end
35
49
  end
@@ -2,11 +2,10 @@
2
2
 
3
3
  class VersionUtils
4
4
  def self.version
5
- path = 'VERSION'
6
- file = File.open(path)
7
- version = file.read
8
- file.close
9
-
10
- version
5
+ begin
6
+ Gem.loaded_specs['securenative'].version.to_s
7
+ rescue StandardError
8
+ 'unknown'
9
+ end
11
10
  end
12
11
  end
@@ -4,7 +4,7 @@ require_relative "lib/utils/version_utils"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "securenative"
7
- spec.version = VersionUtils.version
7
+ spec.version = "0.1.21"
8
8
  spec.authors = ["SecureNative"]
9
9
  spec.email = ["support@securenative.com"]
10
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: securenative
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.20
4
+ version: 0.1.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - SecureNative
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-19 00:00:00.000000000 Z
11
+ date: 2020-08-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -56,7 +56,6 @@ files:
56
56
  - LICENSE
57
57
  - README.md
58
58
  - Rakefile
59
- - VERSION
60
59
  - bin/console
61
60
  - bin/setup
62
61
  - lib/api_manager.rb
@@ -79,7 +78,6 @@ files:
79
78
  - lib/errors/securenative_sdk_Illegal_state_error.rb
80
79
  - lib/errors/securenative_sdk_error.rb
81
80
  - lib/event_manager.rb
82
- - lib/event_options.rb
83
81
  - lib/http/secure_native_http_response.rb
84
82
  - lib/http/securenative_http_client.rb
85
83
  - lib/models/client_token.rb
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.1.20
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class EventOptions
4
- MAX_PROPERTIES_SIZE = 10
5
-
6
- def initialize(event_type, user_id, user_traits, user_name, email, phone, created_at, context, properties, timestamp)
7
- traits = UserTraits(user_name)
8
- if user_name && email && phone && created_at
9
- traits = UserTraits(user_name, email, phone, created_at)
10
- elsif user_name && email && phone
11
- traits = UserTraits(user_name, email, phone)
12
- elsif user_name && email
13
- traits = UserTraits(user_name, email)
14
- end
15
-
16
- @event_options = EventOptions(event_type)
17
- @event_options.user_id = user_id
18
- @event_options.user_traits = user_traits if user_traits
19
- @event_options.user_traits = traits
20
- @event_options.context = context
21
- @event_options.properties = properties
22
- @event_options.timestamp = timestamp
23
- end
24
-
25
- def build
26
- if !@event_options.properties.nil? && @event_options.properties.length > MAX_PROPERTIES_SIZE
27
- raise SecureNativeInvalidOptionsError('You can have only up to {} custom properties', MAX_PROPERTIES_SIZE)
28
- end
29
-
30
- @event_options
31
- end
32
- end