securenative 0.1.28 → 0.1.33

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/README.md +23 -32
  4. data/lib/securenative.rb +49 -0
  5. data/lib/securenative/api_manager.rb +10 -17
  6. data/lib/securenative/client.rb +79 -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 -127
  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 +66 -47
  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, options)
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(request.headers)
58
+ end
59
+
60
+ SecureNative::Context.new(client_token: client_token, ip: SecureNative::Utils::RequestUtils.get_client_ip_from_request(request, options),
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,158 +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
- if (item = !@queue.empty? && @send_enabled)
82
- begin
83
- item = @queue.shift
84
- res = @http_client.post(item.url, item.body)
85
- if res.code == '401'
86
- item.retry_sending = false
87
- elsif res.code != '200'
88
- @queue.append(item)
89
- raise SecureNativeHttpError, res.status_code
90
- end
91
- SecureNativeLogger.debug("Event successfully sent; #{item.body}")
92
- rescue Exception => e
93
- SecureNativeLogger.error("Failed to send event; #{e}")
94
- if item.retry_sending
95
- @attempt = 0 if @coefficients.length == @attempt + 1
96
-
97
- back_off = @coefficients[@attempt] * @options.interval
98
- SecureNativeLogger.debug("Automatic back-off of #{back_off}")
99
- @send_enabled = false
100
- sleep back_off
101
- @send_enabled = true
102
- 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
103
95
  end
104
96
  end
105
97
  end
106
- sleep @interval / 1000 if @queue.empty?
107
98
  end
99
+ sleep @options.interval / 1000 if @queue.empty?
108
100
  end
101
+ end
109
102
 
110
- def start_event_persist
111
- SecureNativeLogger.debug('Starting automatic event persistence')
112
- 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 }
113
108
  @send_enabled = true
114
- else
115
- 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
116
112
  end
113
+ else
114
+ SecureNative::Log.debug('Automatic event persistence is disabled, you should persist events manually')
117
115
  end
116
+ end
118
117
 
119
- def stop_event_persist
120
- if @send_enabled
121
- SecureNativeLogger.debug('Attempting to stop automatic event persistence')
122
- begin
123
- flush
124
- @thread&.stop?
125
- SecureNativeLogger.debug('Stopped event persistence')
126
- rescue StandardError => e
127
- SecureNativeLogger.error("Could not stop event scheduler; #{e}")
128
- 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}")
129
127
  end
130
128
  end
129
+ end
131
130
 
132
- def self.serialize(obj)
133
- {
134
- rid: obj.rid,
135
- eventType: obj.event_type,
136
- userId: obj.user_id,
137
- userTraits: {
138
- name: obj.user_traits.name,
139
- email: obj.user_traits.email,
140
- phone: obj.user_traits.phone,
141
- createdAt: obj.user_traits.created_at
142
- },
143
- request: {
144
- cid: obj.request.cid,
145
- vid: obj.request.vid,
146
- fp: obj.request.fp,
147
- ip: obj.request.ip,
148
- remoteIp: obj.request.remote_ip,
149
- method: obj.request.http_method || '',
150
- url: obj.request.url,
151
- headers: obj.request.headers
152
- },
153
- timestamp: obj.timestamp,
154
- properties: obj.properties
155
- }
156
- 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
+ }
157
155
  end
158
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