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.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +44 -30
- data/lib/securenative.rb +49 -0
- data/lib/securenative/api_manager.rb +10 -17
- data/lib/securenative/client.rb +75 -0
- data/lib/securenative/{models/client_token.rb → client_token.rb} +0 -0
- data/lib/securenative/config/configuration_builder.rb +22 -22
- data/lib/securenative/config/configuration_manager.rb +42 -43
- data/lib/securenative/context.rb +65 -0
- data/lib/securenative/{models/device.rb → device.rb} +0 -0
- data/lib/securenative/enums/api_route.rb +5 -3
- data/lib/securenative/enums/risk_level.rb +7 -5
- data/{out/production/securenative-ruby/errors/securenative_config_error.rb → lib/securenative/errors/config_error.rb} +0 -0
- data/{out/production/securenative-ruby/errors/securenative_http_error.rb → lib/securenative/errors/http_error.rb} +0 -0
- data/{out/production/securenative-ruby/errors/securenative_invalid_options_error.rb → lib/securenative/errors/invalid_options_error.rb} +0 -0
- data/lib/securenative/errors/{securenative_invalid_uri_error.rb → invalid_uri_error.rb} +0 -0
- data/lib/securenative/errors/{securenative_parse_error.rb → parse_error.rb} +0 -2
- data/{out/production/securenative-ruby/errors/securenative_sdk_Illegal_state_error.rb → lib/securenative/errors/sdk_Illegal_state_error.rb} +0 -0
- data/{out/production/securenative-ruby/errors/securenative_sdk_error.rb → lib/securenative/errors/sdk_error.rb} +0 -0
- data/lib/securenative/event_manager.rb +125 -128
- data/lib/securenative/{models/event_options.rb → event_options.rb} +3 -7
- data/lib/securenative/{enums/event_types.rb → event_types.rb} +0 -0
- data/lib/securenative/{enums/failover_strategy.rb → failover_strategy.rb} +0 -0
- data/lib/securenative/frameworks/hanami.rb +46 -0
- data/lib/securenative/frameworks/rails.rb +48 -0
- data/lib/securenative/frameworks/sinatra.rb +46 -0
- data/lib/securenative/{http/securenative_http_client.rb → http_client.rb} +7 -12
- data/lib/securenative/{http/secure_native_http_response.rb → http_response.rb} +1 -1
- data/lib/securenative/{config/securenative_options.rb → options.rb} +1 -3
- data/lib/securenative/{models/request_context.rb → request_context.rb} +0 -0
- data/lib/securenative/{models/request_options.rb → request_options.rb} +0 -0
- data/lib/securenative/{models/sdk_event.rb → sdk_event.rb} +4 -11
- data/lib/securenative/{models/user_traits.rb → user_traits.rb} +0 -0
- data/lib/securenative/utils/date_utils.rb +6 -4
- data/lib/securenative/utils/encryption_utils.rb +34 -37
- data/lib/securenative/utils/ip_utils.rb +15 -15
- data/lib/securenative/utils/{secure_native_logger.rb → log.rb} +1 -1
- data/lib/securenative/utils/request_utils.rb +55 -42
- data/lib/securenative/utils/signature_utils.rb +12 -12
- data/lib/securenative/utils/utils.rb +6 -4
- data/lib/securenative/utils/version_utils.rb +9 -7
- data/lib/securenative/{models/verify_result.rb → verify_result.rb} +0 -0
- data/lib/securenative/{errors/securenative_sdk_error.rb → version.rb} +1 -2
- data/securenative.gemspec +5 -2
- data/{out/test/securenative-ruby → spec}/spec_helper.rb +0 -0
- metadata +35 -83
- data/lib/securenative/context/hanami_context.rb +0 -44
- data/lib/securenative/context/rails_context.rb +0 -46
- data/lib/securenative/context/securenative_context.rb +0 -69
- data/lib/securenative/context/sinatra_context.rb +0 -44
- data/lib/securenative/errors/securenative_config_error.rb +0 -6
- data/lib/securenative/errors/securenative_http_error.rb +0 -6
- data/lib/securenative/errors/securenative_invalid_options_error.rb +0 -6
- data/lib/securenative/errors/securenative_sdk_Illegal_state_error.rb +0 -6
- data/lib/securenative/sdk.rb +0 -85
- data/out/production/securenative-ruby/api_manager.rb +0 -39
- data/out/production/securenative-ruby/config/configuration_builder.rb +0 -27
- data/out/production/securenative-ruby/config/configuration_manager.rb +0 -56
- data/out/production/securenative-ruby/config/securenative_options.rb +0 -23
- data/out/production/securenative-ruby/context/hanami_context.rb +0 -42
- data/out/production/securenative-ruby/context/rails_context.rb +0 -44
- data/out/production/securenative-ruby/context/securenative_context.rb +0 -67
- data/out/production/securenative-ruby/context/sinatra_context.rb +0 -42
- data/out/production/securenative-ruby/enums/api_route.rb +0 -6
- data/out/production/securenative-ruby/enums/event_types.rb +0 -23
- data/out/production/securenative-ruby/enums/failover_strategy.rb +0 -6
- data/out/production/securenative-ruby/enums/risk_level.rb +0 -7
- data/out/production/securenative-ruby/errors/securenative_invalid_uri_error.rb +0 -4
- data/out/production/securenative-ruby/errors/securenative_parse_error.rb +0 -4
- data/out/production/securenative-ruby/event_manager.rb +0 -157
- data/out/production/securenative-ruby/http/secure_native_http_response.rb +0 -12
- data/out/production/securenative-ruby/http/securenative_http_client.rb +0 -50
- data/out/production/securenative-ruby/models/client_token.rb +0 -12
- data/out/production/securenative-ruby/models/device.rb +0 -10
- data/out/production/securenative-ruby/models/event_options.rb +0 -37
- data/out/production/securenative-ruby/models/request_context.rb +0 -18
- data/out/production/securenative-ruby/models/request_options.rb +0 -12
- data/out/production/securenative-ruby/models/sdk_event.rb +0 -49
- data/out/production/securenative-ruby/models/user_traits.rb +0 -13
- data/out/production/securenative-ruby/models/verify_result.rb +0 -16
- data/out/production/securenative-ruby/securenative.rb +0 -83
- data/out/production/securenative-ruby/utils/date_utils.rb +0 -9
- data/out/production/securenative-ruby/utils/encryption_utils.rb +0 -49
- data/out/production/securenative-ruby/utils/ip_utils.rb +0 -23
- data/out/production/securenative-ruby/utils/request_utils.rb +0 -69
- data/out/production/securenative-ruby/utils/secure_native_logger.rb +0 -44
- data/out/production/securenative-ruby/utils/signature_utils.rb +0 -16
- data/out/production/securenative-ruby/utils/utils.rb +0 -9
- data/out/production/securenative-ruby/utils/version_utils.rb +0 -11
- data/out/test/securenative-ruby/spec_api_manager.rb +0 -87
- data/out/test/securenative-ruby/spec_context_builder.rb +0 -87
- data/out/test/securenative-ruby/spec_date_utils.rb +0 -13
- data/out/test/securenative-ruby/spec_encryption_utils.rb +0 -26
- data/out/test/securenative-ruby/spec_event_manager.rb +0 -93
- data/out/test/securenative-ruby/spec_ip_utils.rb +0 -41
- data/out/test/securenative-ruby/spec_request_utils.rb +0 -25
- data/out/test/securenative-ruby/spec_sdk_event.rb +0 -24
- data/out/test/securenative-ruby/spec_securenative.rb +0 -61
- data/out/test/securenative-ruby/spec_securenative_http_client.rb +0 -31
- data/out/test/securenative-ruby/spec_signature_utils.rb +0 -18
- 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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,159 +1,156 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
22
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
51
|
-
|
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
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
67
|
-
|
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
|
-
|
70
|
-
|
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
|
-
|
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
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
116
|
-
|
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
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
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
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
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
|
File without changes
|
File without changes
|
@@ -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
|