securenative 0.1.24 → 0.1.30

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/README.md +44 -30
  4. data/lib/securenative.rb +49 -0
  5. data/lib/securenative/api_manager.rb +10 -17
  6. data/lib/securenative/client.rb +75 -0
  7. data/lib/securenative/{models/client_token.rb → client_token.rb} +0 -0
  8. data/lib/securenative/config/configuration_builder.rb +22 -22
  9. data/lib/securenative/config/configuration_manager.rb +42 -43
  10. data/lib/securenative/context.rb +65 -0
  11. data/lib/securenative/{models/device.rb → device.rb} +0 -0
  12. data/lib/securenative/enums/api_route.rb +5 -3
  13. data/lib/securenative/enums/risk_level.rb +7 -5
  14. data/{out/production/securenative-ruby/errors/securenative_config_error.rb → lib/securenative/errors/config_error.rb} +0 -0
  15. data/{out/production/securenative-ruby/errors/securenative_http_error.rb → lib/securenative/errors/http_error.rb} +0 -0
  16. data/{out/production/securenative-ruby/errors/securenative_invalid_options_error.rb → lib/securenative/errors/invalid_options_error.rb} +0 -0
  17. data/lib/securenative/errors/{securenative_invalid_uri_error.rb → invalid_uri_error.rb} +0 -0
  18. data/lib/securenative/errors/{securenative_parse_error.rb → parse_error.rb} +0 -2
  19. data/{out/production/securenative-ruby/errors/securenative_sdk_Illegal_state_error.rb → lib/securenative/errors/sdk_Illegal_state_error.rb} +0 -0
  20. data/{out/production/securenative-ruby/errors/securenative_sdk_error.rb → lib/securenative/errors/sdk_error.rb} +0 -0
  21. data/lib/securenative/event_manager.rb +125 -128
  22. data/lib/securenative/{models/event_options.rb → event_options.rb} +3 -7
  23. data/lib/securenative/{enums/event_types.rb → event_types.rb} +0 -0
  24. data/lib/securenative/{enums/failover_strategy.rb → failover_strategy.rb} +0 -0
  25. data/lib/securenative/frameworks/hanami.rb +46 -0
  26. data/lib/securenative/frameworks/rails.rb +48 -0
  27. data/lib/securenative/frameworks/sinatra.rb +46 -0
  28. data/lib/securenative/{http/securenative_http_client.rb → http_client.rb} +7 -12
  29. data/lib/securenative/{http/secure_native_http_response.rb → http_response.rb} +1 -1
  30. data/lib/securenative/{config/securenative_options.rb → options.rb} +1 -3
  31. data/lib/securenative/{models/request_context.rb → request_context.rb} +0 -0
  32. data/lib/securenative/{models/request_options.rb → request_options.rb} +0 -0
  33. data/lib/securenative/{models/sdk_event.rb → sdk_event.rb} +4 -11
  34. data/lib/securenative/{models/user_traits.rb → user_traits.rb} +0 -0
  35. data/lib/securenative/utils/date_utils.rb +6 -4
  36. data/lib/securenative/utils/encryption_utils.rb +34 -37
  37. data/lib/securenative/utils/ip_utils.rb +15 -15
  38. data/lib/securenative/utils/{secure_native_logger.rb → log.rb} +1 -1
  39. data/lib/securenative/utils/request_utils.rb +55 -42
  40. data/lib/securenative/utils/signature_utils.rb +12 -12
  41. data/lib/securenative/utils/utils.rb +6 -4
  42. data/lib/securenative/utils/version_utils.rb +9 -7
  43. data/lib/securenative/{models/verify_result.rb → verify_result.rb} +0 -0
  44. data/lib/securenative/{errors/securenative_sdk_error.rb → version.rb} +1 -2
  45. data/securenative.gemspec +5 -2
  46. data/{out/test/securenative-ruby → spec}/spec_helper.rb +0 -0
  47. metadata +35 -83
  48. data/lib/securenative/context/hanami_context.rb +0 -44
  49. data/lib/securenative/context/rails_context.rb +0 -46
  50. data/lib/securenative/context/securenative_context.rb +0 -69
  51. data/lib/securenative/context/sinatra_context.rb +0 -44
  52. data/lib/securenative/errors/securenative_config_error.rb +0 -6
  53. data/lib/securenative/errors/securenative_http_error.rb +0 -6
  54. data/lib/securenative/errors/securenative_invalid_options_error.rb +0 -6
  55. data/lib/securenative/errors/securenative_sdk_Illegal_state_error.rb +0 -6
  56. data/lib/securenative/sdk.rb +0 -85
  57. data/out/production/securenative-ruby/api_manager.rb +0 -39
  58. data/out/production/securenative-ruby/config/configuration_builder.rb +0 -27
  59. data/out/production/securenative-ruby/config/configuration_manager.rb +0 -56
  60. data/out/production/securenative-ruby/config/securenative_options.rb +0 -23
  61. data/out/production/securenative-ruby/context/hanami_context.rb +0 -42
  62. data/out/production/securenative-ruby/context/rails_context.rb +0 -44
  63. data/out/production/securenative-ruby/context/securenative_context.rb +0 -67
  64. data/out/production/securenative-ruby/context/sinatra_context.rb +0 -42
  65. data/out/production/securenative-ruby/enums/api_route.rb +0 -6
  66. data/out/production/securenative-ruby/enums/event_types.rb +0 -23
  67. data/out/production/securenative-ruby/enums/failover_strategy.rb +0 -6
  68. data/out/production/securenative-ruby/enums/risk_level.rb +0 -7
  69. data/out/production/securenative-ruby/errors/securenative_invalid_uri_error.rb +0 -4
  70. data/out/production/securenative-ruby/errors/securenative_parse_error.rb +0 -4
  71. data/out/production/securenative-ruby/event_manager.rb +0 -157
  72. data/out/production/securenative-ruby/http/secure_native_http_response.rb +0 -12
  73. data/out/production/securenative-ruby/http/securenative_http_client.rb +0 -50
  74. data/out/production/securenative-ruby/models/client_token.rb +0 -12
  75. data/out/production/securenative-ruby/models/device.rb +0 -10
  76. data/out/production/securenative-ruby/models/event_options.rb +0 -37
  77. data/out/production/securenative-ruby/models/request_context.rb +0 -18
  78. data/out/production/securenative-ruby/models/request_options.rb +0 -12
  79. data/out/production/securenative-ruby/models/sdk_event.rb +0 -49
  80. data/out/production/securenative-ruby/models/user_traits.rb +0 -13
  81. data/out/production/securenative-ruby/models/verify_result.rb +0 -16
  82. data/out/production/securenative-ruby/securenative.rb +0 -83
  83. data/out/production/securenative-ruby/utils/date_utils.rb +0 -9
  84. data/out/production/securenative-ruby/utils/encryption_utils.rb +0 -49
  85. data/out/production/securenative-ruby/utils/ip_utils.rb +0 -23
  86. data/out/production/securenative-ruby/utils/request_utils.rb +0 -69
  87. data/out/production/securenative-ruby/utils/secure_native_logger.rb +0 -44
  88. data/out/production/securenative-ruby/utils/signature_utils.rb +0 -16
  89. data/out/production/securenative-ruby/utils/utils.rb +0 -9
  90. data/out/production/securenative-ruby/utils/version_utils.rb +0 -11
  91. data/out/test/securenative-ruby/spec_api_manager.rb +0 -87
  92. data/out/test/securenative-ruby/spec_context_builder.rb +0 -87
  93. data/out/test/securenative-ruby/spec_date_utils.rb +0 -13
  94. data/out/test/securenative-ruby/spec_encryption_utils.rb +0 -26
  95. data/out/test/securenative-ruby/spec_event_manager.rb +0 -93
  96. data/out/test/securenative-ruby/spec_ip_utils.rb +0 -41
  97. data/out/test/securenative-ruby/spec_request_utils.rb +0 -25
  98. data/out/test/securenative-ruby/spec_sdk_event.rb +0 -24
  99. data/out/test/securenative-ruby/spec_securenative.rb +0 -61
  100. data/out/test/securenative-ruby/spec_securenative_http_client.rb +0 -31
  101. data/out/test/securenative-ruby/spec_signature_utils.rb +0 -18
  102. data/out/test/securenative-ruby/spec_version_util.rb +0 -10
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SecureNative
4
+ class Context
5
+ attr_reader :client_token, :ip, :remote_ip, :headers, :url, :http_method, :body
6
+ attr_writer :client_token, :ip, :remote_ip, :headers, :url, :http_method, :body
7
+
8
+ SECURENATIVE_COOKIE = '_sn'
9
+
10
+ def initialize(client_token: '', ip: '', remote_ip: '', headers: nil, url: '', http_method: '', body: '')
11
+ @client_token = client_token
12
+ @ip = ip
13
+ @remote_ip = remote_ip
14
+ @headers = headers
15
+ @url = url
16
+ @http_method = http_method
17
+ @body = body
18
+ end
19
+
20
+ def self.default_context_builder
21
+ SecureNative::Context.new
22
+ end
23
+
24
+ def self.from_http_request(request)
25
+ client_token = SecureNative::Frameworks::Rails.get_client_token(request)
26
+ client_token = SecureNative::Frameworks::Sinatra.get_client_token(request) if client_token.nil?
27
+ client_token = SecureNative::Frameworks::Hanami.get_client_token(request) if client_token.nil?
28
+
29
+ begin
30
+ headers = SecureNative::Frameworks::Rails.get_headers(request)
31
+ headers = SecureNative::Frameworks::Sinatra.get_headers(request) if headers.nil?
32
+ headers = SecureNative::Frameworks::Hanami.get_headers(request) if headers.nil?
33
+
34
+ # Standard Ruby request
35
+ headers = request.header.to_hash if headers.nil?
36
+ rescue StandardError
37
+ headers = []
38
+ end
39
+
40
+ url = SecureNative::Frameworks::Rails.get_url(request)
41
+ url = SecureNative::Frameworks::Sinatra.get_url(request) if url.nil?
42
+ url = SecureNative::Frameworks::Hanami.get_url(request) if url.nil?
43
+ url = '' if url.nil?
44
+
45
+ method = SecureNative::Frameworks::Rails.get_method(request)
46
+ method = SecureNative::Frameworks::Sinatra.get_method(request) if method.nil?
47
+ method = SecureNative::Frameworks::Hanami.get_method(request) if method.nil?
48
+ method = '' if method.nil?
49
+
50
+ begin
51
+ body = request.body.to_s
52
+ rescue StandardError
53
+ body = ''
54
+ end
55
+
56
+ if SecureNative::Utils::Utils.null_or_empty?(client_token)
57
+ client_token = SecureNative::Utils::RequestUtils.get_secure_header_from_request(headers)
58
+ end
59
+
60
+ SecureNative::Context.new(client_token: client_token, ip: SecureNative::Utils::RequestUtils.get_client_ip_from_request(request),
61
+ remote_ip: SecureNative::Utils::RequestUtils.get_remote_ip_from_request(request),
62
+ headers: headers, url: url, http_method: method || '', body: body)
63
+ end
64
+ end
65
+ end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SecureNative
4
- module ApiRoute
5
- TRACK = 'track'
6
- VERIFY = 'verify'
4
+ module Enums
5
+ module ApiRoute
6
+ TRACK = 'track'
7
+ VERIFY = 'verify'
8
+ end
7
9
  end
8
10
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SecureNative
4
- module RiskLevel
5
- LOW = 'low'
6
- MEDIUM = 'medium'
7
- HIGH = 'high'
4
+ module Enums
5
+ module RiskLevel
6
+ LOW = 'low'
7
+ MEDIUM = 'medium'
8
+ HIGH = 'high'
9
+ end
8
10
  end
9
- end
11
+ end
@@ -1,6 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module SecureNative
4
3
  class SecureNativeParseError < StandardError
5
4
  end
6
- end
@@ -1,159 +1,156 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securenative/utils/secure_native_logger'
4
- require 'securenative/config/securenative_options'
5
- require 'securenative/http/securenative_http_client'
6
- require 'securenative/errors/securenative_sdk_error'
7
- require 'securenative/errors/securenative_http_error'
8
-
9
- module SecureNative
10
- class QueueItem
11
- attr_reader :url, :body, :retry_sending
12
- attr_writer :url, :body, :retry_sending
13
-
14
- def initialize(url, body, retry_sending)
15
- @url = url
16
- @body = body
17
- @retry = retry_sending
18
- end
3
+ class QueueItem
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 = retry_sending
19
11
  end
12
+ end
20
13
 
21
- class EventManager
22
- def initialize(options = SecureNativeOptions.new, http_client = nil)
23
- if options.api_key.nil?
24
- raise SecureNativeSDKError, 'API key cannot be None, please get your API key from SecureNative console.'
25
- end
14
+ class EventManager
15
+ attr_reader :activated
26
16
 
27
- @http_client = if http_client.nil?
28
- SecureNativeHttpClient.new(options)
29
- else
30
- http_client
31
- end
32
-
33
- @queue = []
34
- @semaphore = Mutex.new
35
- @interval = options.interval
36
- @options = options
37
- @send_enabled = false
38
- @attempt = 0
39
- @coefficients = [1, 1, 2, 3, 5, 8, 13]
40
-
41
- @thread = Thread.new { run }
17
+ def initialize(options = Options.new, http_client = nil)
18
+ if options.api_key.nil?
19
+ raise SecureNativeSDKError, 'API key cannot be None, please get your API key from SecureNative console.'
42
20
  end
43
21
 
44
- def send_async(event, resource_path)
45
- if @options.disable
46
- SecureNativeLogger.warning('SDK is disabled. no operation will be performed')
47
- return
48
- end
22
+ @http_client = if http_client.nil?
23
+ SecureNative::HttpClient.new(options)
24
+ else
25
+ http_client
26
+ end
27
+
28
+ @queue = []
29
+ @semaphore = Mutex.new
30
+ @options = options
31
+ @send_enabled = false
32
+ @attempt = 0
33
+ @coefficients = [1, 1, 2, 3, 5, 8, 13]
34
+ @thread = nil
35
+ end
49
36
 
50
- item = QueueItem.new(resource_path, EventManager.serialize(event).to_json, false)
51
- @queue.append(item)
37
+ def send_async(event, resource_path)
38
+ if @options.disable
39
+ SecureNative::Log.warning('SDK is disabled. no operation will be performed')
40
+ return
52
41
  end
53
42
 
54
- def flush
55
- @queue.each do |item|
56
- @http_client.post(item.url, item.body)
57
- end
58
- end
43
+ start_event_persist unless @send_enabled
59
44
 
60
- def send_sync(event, resource_path, retry_sending)
61
- if @options.disable
62
- SecureNativeLogger.warning('SDK is disabled. no operation will be performed')
63
- return
64
- end
45
+ item = QueueItem.new(resource_path, EventManager.serialize(event).to_json, false)
46
+ @queue.append(item)
47
+ end
48
+
49
+ def flush
50
+ @queue.each do |item|
51
+ @http_client.post(item.url, item.body)
52
+ end
53
+ end
65
54
 
66
- SecureNativeLogger.debug("Attempting to send event #{event}")
67
- res = @http_client.post(resource_path, EventManager.serialize(event).to_json)
55
+ def send_sync(event, resource_path)
56
+ if @options.disable
57
+ SecureNative::Log.warning('SDK is disabled. no operation will be performed')
58
+ return
59
+ end
68
60
 
69
- if res.nil? || res.code != '200'
70
- SecureNativeLogger.info("SecureNative failed to call endpoint #{resource_path} with event #{event}. adding back to queue")
71
- item = QueueItem.new(resource_path, EventManager.serialize(event).to_json, retry_sending)
72
- @queue.append(item)
73
- end
61
+ SecureNative::Log.debug("Attempting to send event #{event}")
62
+ res = @http_client.post(resource_path, EventManager.serialize(event).to_json)
74
63
 
75
- res
64
+ if res.nil? || res.code != '200'
65
+ SecureNative::Log.info("SecureNative failed to call endpoint #{resource_path} with event #{event}. adding back to queue")
76
66
  end
77
67
 
78
- def run
79
- loop do
80
- @semaphore.synchronize do
81
- next unless !@queue.empty? && @send_enabled
82
-
83
- @queue.each do |item|
84
- begin
85
- res = @http_client.post(item.url, item.body)
86
- if res.code == '401'
87
- item.retry_sending = false
88
- elsif res.code != '200'
89
- raise SecureNativeHttpError, res.status_code
90
- end
91
- SecureNativeLogger.debug("Event successfully sent; #{item.body}")
92
- return res
93
- rescue StandardError => e
94
- SecureNativeLogger.error("Failed to send event; #{e}")
95
- if item.retry_sending
96
- @attempt = 0 if @coefficients.length == @attempt + 1
97
-
98
- back_off = @coefficients[@attempt] * @options.interval
99
- SecureNativeLogger.debug("Automatic back-off of #{back_off}")
100
- @send_enabled = false
101
- sleep back_off
102
- @send_enabled = true
103
- end
68
+ res
69
+ end
70
+
71
+ def run
72
+ loop do
73
+ @semaphore.synchronize do
74
+ if (item = !@queue.empty? && @send_enabled)
75
+ begin
76
+ item = @queue.shift
77
+ res = @http_client.post(item.url, item.body)
78
+ if res.code == '401'
79
+ item.retry_sending = false
80
+ elsif res.code != '200'
81
+ @queue.append(item)
82
+ raise SecureNativeHttpError, res.status_code
83
+ end
84
+ SecureNative::Log.debug("Event successfully sent; #{item.body}")
85
+ rescue Exception => e
86
+ SecureNative::Log.error("Failed to send event; #{e}")
87
+ if item.retry_sending
88
+ @attempt = 0 if @coefficients.length == @attempt + 1
89
+
90
+ back_off = @coefficients[@attempt] * @options.interval
91
+ SecureNative::Log.debug("Automatic back-off of #{back_off}")
92
+ @send_enabled = false
93
+ sleep back_off
94
+ @send_enabled = true
104
95
  end
105
96
  end
106
97
  end
107
- sleep @interval / 1000
108
98
  end
99
+ sleep @options.interval / 1000 if @queue.empty?
109
100
  end
101
+ end
110
102
 
111
- def start_event_persist
112
- SecureNativeLogger.debug('Starting automatic event persistence')
113
- if @options.auto_send || @send_enabled
103
+ def start_event_persist
104
+ SecureNative::Log.debug('Starting automatic event persistence')
105
+ if @options.auto_send
106
+ begin
107
+ @thread = Thread.new { run }
114
108
  @send_enabled = true
115
- else
116
- SecureNativeLogger.debug('Automatic event persistence is disabled, you should persist events manually')
109
+ rescue StandardError => e
110
+ SecureNative::Log.error("Could not start event scheduler; #{e}")
111
+ @send_enabled = false
117
112
  end
113
+ else
114
+ SecureNative::Log.debug('Automatic event persistence is disabled, you should persist events manually')
118
115
  end
116
+ end
119
117
 
120
- def stop_event_persist
121
- if @send_enabled
122
- SecureNativeLogger.debug('Attempting to stop automatic event persistence')
123
- begin
124
- flush
125
- @thread&.stop?
126
- SecureNativeLogger.debug('Stopped event persistence')
127
- rescue StandardError => e
128
- SecureNativeLogger.error("Could not stop event scheduler; #{e}")
129
- end
118
+ def stop_event_persist
119
+ if @send_enabled
120
+ SecureNative::Log.debug('Attempting to stop automatic event persistence')
121
+ begin
122
+ flush
123
+ @thread&.stop?
124
+ SecureNative::Log.debug('Stopped event persistence')
125
+ rescue StandardError => e
126
+ SecureNative::Log.error("Could not stop event scheduler; #{e}")
130
127
  end
131
128
  end
129
+ end
132
130
 
133
- def self.serialize(obj)
134
- {
135
- rid: obj.rid,
136
- eventType: obj.event_type,
137
- userId: obj.user_id,
138
- userTraits: {
139
- name: obj.user_traits.name,
140
- email: obj.user_traits.email,
141
- phone: obj.user_traits.phone,
142
- createdAt: obj.user_traits.created_at
143
- },
144
- request: {
145
- cid: obj.request.cid,
146
- vid: obj.request.vid,
147
- fp: obj.request.fp,
148
- ip: obj.request.ip,
149
- remoteIp: obj.request.remote_ip,
150
- method: obj.request.http_method || '',
151
- url: obj.request.url,
152
- headers: obj.request.headers
153
- },
154
- timestamp: obj.timestamp,
155
- properties: obj.properties
156
- }
157
- end
131
+ def self.serialize(obj)
132
+ {
133
+ rid: obj.rid,
134
+ eventType: obj.event_type,
135
+ userId: obj.user_id,
136
+ userTraits: {
137
+ name: obj.user_traits.name,
138
+ email: obj.user_traits.email,
139
+ phone: obj.user_traits.phone,
140
+ createdAt: obj.user_traits.created_at
141
+ },
142
+ request: {
143
+ cid: obj.request.cid,
144
+ vid: obj.request.vid,
145
+ fp: obj.request.fp,
146
+ ip: obj.request.ip,
147
+ remoteIp: obj.request.remote_ip,
148
+ method: obj.request.http_method || '',
149
+ url: obj.request.url,
150
+ headers: obj.request.headers
151
+ },
152
+ timestamp: obj.timestamp,
153
+ properties: obj.properties
154
+ }
158
155
  end
159
156
  end
@@ -1,9 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'securenative/models/event_options'
4
- require 'securenative/models/user_traits'
5
- require 'securenative/errors/securenative_invalid_options_error'
6
-
7
3
  module SecureNative
8
4
  class EventOptions
9
5
  attr_reader :event, :user_id, :user_traits, :context, :properties, :timestamp
@@ -18,11 +14,11 @@ module SecureNative
18
14
 
19
15
  if user_traits.nil?
20
16
  if user_name && email && phone && created_at
21
- user_traits = UserTraits(user_name, email, phone, created_at)
17
+ user_traits = SecureNative::UserTraits(user_name, email, phone, created_at)
22
18
  elsif user_name && email && phone
23
- user_traits = UserTraits(user_name, email, phone)
19
+ user_traits = SecureNative::UserTraits(user_name, email, phone)
24
20
  elsif user_name && email
25
- user_traits = UserTraits(user_name, email)
21
+ user_traits = SecureNative::UserTraits(user_name, email)
26
22
  else
27
23
  user_traits = UserTraits.new
28
24
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SecureNative
4
+ module Frameworks
5
+ class Hanami
6
+ SECURENATIVE_COOKIE = '_sn'
7
+
8
+ def self.get_client_token(request)
9
+ begin
10
+ request.env[SECURENATIVE_COOKIE]
11
+ rescue StandardError
12
+ begin
13
+ request.cookies[SECURENATIVE_COOKIE]
14
+ rescue StandardError
15
+ nil
16
+ end
17
+ end
18
+ end
19
+
20
+ def self.get_url(request)
21
+ begin
22
+ request.env['REQUEST_PATH']
23
+ rescue StandardError
24
+ nil
25
+ end
26
+ end
27
+
28
+ def self.get_method(request)
29
+ begin
30
+ request.request_method
31
+ rescue StandardError
32
+ nil
33
+ end
34
+ end
35
+
36
+ def self.get_headers(request)
37
+ begin
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'] }
40
+ rescue StandardError
41
+ nil
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end