securenative 0.1.23 → 0.1.24
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 +3 -5
- data/README.md +36 -36
- data/lib/securenative/api_manager.rb +41 -0
- data/lib/securenative/config/configuration_builder.rb +29 -0
- data/lib/securenative/config/configuration_manager.rb +58 -0
- data/lib/securenative/config/securenative_options.rb +25 -0
- data/lib/securenative/context/hanami_context.rb +44 -0
- data/lib/securenative/context/rails_context.rb +46 -0
- data/lib/securenative/context/securenative_context.rb +69 -0
- data/lib/securenative/context/sinatra_context.rb +44 -0
- data/lib/securenative/enums/api_route.rb +8 -0
- data/lib/securenative/enums/event_types.rb +25 -0
- data/lib/securenative/enums/failover_strategy.rb +8 -0
- data/lib/securenative/enums/risk_level.rb +9 -0
- data/lib/securenative/errors/securenative_config_error.rb +6 -0
- data/lib/securenative/errors/securenative_http_error.rb +6 -0
- data/lib/securenative/errors/securenative_invalid_options_error.rb +6 -0
- data/lib/securenative/errors/securenative_invalid_uri_error.rb +6 -0
- data/lib/securenative/errors/securenative_parse_error.rb +6 -0
- data/lib/securenative/errors/securenative_sdk_Illegal_state_error.rb +6 -0
- data/lib/securenative/errors/securenative_sdk_error.rb +6 -0
- data/lib/securenative/event_manager.rb +159 -0
- data/lib/securenative/http/secure_native_http_response.rb +14 -0
- data/lib/securenative/http/securenative_http_client.rb +52 -0
- data/lib/securenative/models/client_token.rb +14 -0
- data/lib/securenative/models/device.rb +12 -0
- data/lib/securenative/models/event_options.rb +39 -0
- data/lib/securenative/models/request_context.rb +20 -0
- data/lib/securenative/models/request_options.rb +14 -0
- data/lib/securenative/models/sdk_event.rb +51 -0
- data/lib/securenative/models/user_traits.rb +15 -0
- data/lib/securenative/models/verify_result.rb +18 -0
- data/lib/securenative/sdk.rb +85 -0
- data/lib/securenative/utils/date_utils.rb +11 -0
- data/lib/securenative/utils/encryption_utils.rb +51 -0
- data/lib/securenative/utils/ip_utils.rb +25 -0
- data/lib/securenative/utils/request_utils.rb +71 -0
- data/lib/securenative/utils/secure_native_logger.rb +46 -0
- data/lib/securenative/utils/signature_utils.rb +18 -0
- data/lib/securenative/utils/utils.rb +11 -0
- data/lib/securenative/utils/version_utils.rb +13 -0
- data/securenative.gemspec +16 -14
- metadata +40 -40
- data/lib/api_manager.rb +0 -39
- data/lib/config/configuration_builder.rb +0 -27
- data/lib/config/configuration_manager.rb +0 -56
- data/lib/config/securenative_options.rb +0 -23
- data/lib/context/hanami_context.rb +0 -42
- data/lib/context/rails_context.rb +0 -44
- data/lib/context/securenative_context.rb +0 -67
- data/lib/context/sinatra_context.rb +0 -42
- data/lib/enums/api_route.rb +0 -6
- data/lib/enums/event_types.rb +0 -23
- data/lib/enums/failover_strategy.rb +0 -6
- data/lib/enums/risk_level.rb +0 -7
- data/lib/errors/securenative_config_error.rb +0 -4
- data/lib/errors/securenative_http_error.rb +0 -4
- data/lib/errors/securenative_invalid_options_error.rb +0 -4
- data/lib/errors/securenative_invalid_uri_error.rb +0 -4
- data/lib/errors/securenative_parse_error.rb +0 -4
- data/lib/errors/securenative_sdk_Illegal_state_error.rb +0 -4
- data/lib/errors/securenative_sdk_error.rb +0 -4
- data/lib/event_manager.rb +0 -157
- data/lib/http/secure_native_http_response.rb +0 -12
- data/lib/http/securenative_http_client.rb +0 -50
- data/lib/models/client_token.rb +0 -12
- data/lib/models/device.rb +0 -10
- data/lib/models/event_options.rb +0 -37
- data/lib/models/request_context.rb +0 -18
- data/lib/models/request_options.rb +0 -12
- data/lib/models/sdk_event.rb +0 -49
- data/lib/models/user_traits.rb +0 -13
- data/lib/models/verify_result.rb +0 -16
- data/lib/securenative.rb +0 -83
- data/lib/utils/date_utils.rb +0 -9
- data/lib/utils/encryption_utils.rb +0 -49
- data/lib/utils/ip_utils.rb +0 -23
- data/lib/utils/request_utils.rb +0 -69
- data/lib/utils/secure_native_logger.rb +0 -44
- data/lib/utils/signature_utils.rb +0 -16
- data/lib/utils/utils.rb +0 -9
- data/lib/utils/version_utils.rb +0 -11
data/lib/models/sdk_event.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'context/securenative_context'
|
4
|
-
require 'errors/securenative_invalid_options_error'
|
5
|
-
require 'utils/encryption_utils'
|
6
|
-
require 'utils/date_utils'
|
7
|
-
require 'models/request_context'
|
8
|
-
require 'securerandom'
|
9
|
-
|
10
|
-
class SDKEvent
|
11
|
-
attr_reader :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties
|
12
|
-
attr_writer :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties
|
13
|
-
|
14
|
-
def initialize(event_options, securenative_options)
|
15
|
-
if event_options.user_id.nil? || event_options.user_id.length <= 0 || event_options.user_id == ''
|
16
|
-
raise SecureNativeInvalidOptionsError.new, 'Invalid event structure; User Id is missing'
|
17
|
-
end
|
18
|
-
|
19
|
-
if event_options.event.nil? || event_options.event.length <= 0 || event_options.event == ''
|
20
|
-
raise SecureNativeInvalidOptionsError.new, 'Invalid event structure; Event Type is missing'
|
21
|
-
end
|
22
|
-
|
23
|
-
@context = if !event_options.context.nil?
|
24
|
-
event_options.context
|
25
|
-
else
|
26
|
-
SecureNativeContext.default_context_builder
|
27
|
-
end
|
28
|
-
|
29
|
-
client_token = EncryptionUtils.decrypt(@context.client_token, securenative_options.api_key)
|
30
|
-
|
31
|
-
@rid = SecureRandom.uuid.to_str
|
32
|
-
@event_type = event_options.event
|
33
|
-
@user_id = event_options.user_id
|
34
|
-
@user_traits = event_options.user_traits
|
35
|
-
@request = RequestContext.new(cid: client_token ? client_token.cid : '', vid: client_token ? client_token.vid : '',
|
36
|
-
fp: client_token ? client_token.fp : '', ip: @context.ip,
|
37
|
-
remote_ip: @context.remote_ip, headers: @context.headers,
|
38
|
-
url: @context.url, http_method: @context.http_method)
|
39
|
-
|
40
|
-
|
41
|
-
@timestamp = DateUtils.to_timestamp(event_options.timestamp)
|
42
|
-
@properties = event_options.properties
|
43
|
-
end
|
44
|
-
|
45
|
-
def to_s
|
46
|
-
"context: #{@context}, rid: #{@rid}, event_type: #{@event_type}, user_id: #{@user_id},
|
47
|
-
user_traits: #{@user_traits}, request: #{@request}, timestamp: #{@timestamp}, properties: #{@properties}"
|
48
|
-
end
|
49
|
-
end
|
data/lib/models/user_traits.rb
DELETED
@@ -1,13 +0,0 @@
|
|
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
|
data/lib/models/verify_result.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class VerifyResult
|
4
|
-
attr_reader :risk_level, :score, :triggers
|
5
|
-
attr_writer :risk_level, :score, :triggers
|
6
|
-
|
7
|
-
def initialize(risk_level: nil, score: nil, triggers: nil)
|
8
|
-
@risk_level = risk_level
|
9
|
-
@score = score
|
10
|
-
@triggers = triggers
|
11
|
-
end
|
12
|
-
|
13
|
-
def to_s
|
14
|
-
"risk_level: #{@risk_level}, score: #{@score}, triggers: #{@triggers}"
|
15
|
-
end
|
16
|
-
end
|
data/lib/securenative.rb
DELETED
@@ -1,83 +0,0 @@
|
|
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 'config/configuration_manager'
|
12
|
-
require 'event_manager'
|
13
|
-
require 'api_manager'
|
14
|
-
|
15
|
-
class SecureNative
|
16
|
-
attr_reader :options
|
17
|
-
|
18
|
-
def initialize(options)
|
19
|
-
@securenative = nil
|
20
|
-
raise SecureNativeSDKError, 'You must pass your SecureNative api key' if Utils.null_or_empty?(options.api_key)
|
21
|
-
|
22
|
-
@options = options
|
23
|
-
@event_manager = EventManager.new(@options)
|
24
|
-
|
25
|
-
@event_manager.start_event_persist unless @options.api_url.nil?
|
26
|
-
|
27
|
-
@api_manager = ApiManager.new(@event_manager, @options)
|
28
|
-
SecureNativeLogger.init_logger(@options.log_level)
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.init_with_options(options)
|
32
|
-
if @securenative.nil?
|
33
|
-
@securenative = SecureNative.new(options)
|
34
|
-
@securenative
|
35
|
-
else
|
36
|
-
SecureNativeLogger.debug('This SDK was already initialized.')
|
37
|
-
raise SecureNativeSDKError, 'This SDK was already initialized.'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.init_with_api_key(api_key)
|
42
|
-
raise SecureNativeConfigError, 'You must pass your SecureNative api key' if Utils.null_or_empty?(api_key)
|
43
|
-
|
44
|
-
if @securenative.nil?
|
45
|
-
options = ConfigurationBuilder.new(api_key: api_key)
|
46
|
-
@securenative = SecureNative.new(options)
|
47
|
-
@securenative
|
48
|
-
else
|
49
|
-
SecureNativeLogger.debug('This SDK was already initialized.')
|
50
|
-
raise SecureNativeSDKError, 'This SDK was already initialized.'
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.init
|
55
|
-
options = ConfigurationManager.load_config
|
56
|
-
init_with_options(options)
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.instance
|
60
|
-
raise SecureNativeSDKIllegalStateError if @securenative.nil?
|
61
|
-
|
62
|
-
@securenative
|
63
|
-
end
|
64
|
-
|
65
|
-
def track(event_options)
|
66
|
-
@api_manager.track(event_options)
|
67
|
-
end
|
68
|
-
|
69
|
-
def verify(event_options)
|
70
|
-
@api_manager.verify(event_options)
|
71
|
-
end
|
72
|
-
|
73
|
-
def self._flush
|
74
|
-
@securenative = nil
|
75
|
-
end
|
76
|
-
|
77
|
-
def verify_request_payload(request)
|
78
|
-
request_signature = request.header[SignatureUtils.SIGNATURE_HEADER]
|
79
|
-
body = request.body
|
80
|
-
|
81
|
-
SignatureUtils.valid_signature?(@options.api_key, body, request_signature)
|
82
|
-
end
|
83
|
-
end
|
data/lib/utils/date_utils.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'openssl'
|
4
|
-
require 'digest'
|
5
|
-
require 'base64'
|
6
|
-
require 'models/client_token'
|
7
|
-
|
8
|
-
class EncryptionUtils
|
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
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
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
|
34
|
-
|
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
|
48
|
-
end
|
49
|
-
end
|
data/lib/utils/ip_utils.rb
DELETED
@@ -1,23 +0,0 @@
|
|
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
|
data/lib/utils/request_utils.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class RequestUtils
|
4
|
-
SECURENATIVE_COOKIE = '_sn'
|
5
|
-
SECURENATIVE_HEADER = 'x-securenative'
|
6
|
-
|
7
|
-
def self.get_secure_header_from_request(headers)
|
8
|
-
begin
|
9
|
-
return headers[SECURENATIVE_HEADER] unless headers.nil?
|
10
|
-
rescue StandardError
|
11
|
-
[]
|
12
|
-
end
|
13
|
-
[]
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.get_client_ip_from_request(request, options = nil)
|
17
|
-
begin
|
18
|
-
return request.ip unless request.ip.nil?
|
19
|
-
rescue NoMethodError
|
20
|
-
end
|
21
|
-
|
22
|
-
begin
|
23
|
-
x_forwarded_for = request.env['HTTP_X_FORWARDED_FOR']
|
24
|
-
return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
|
25
|
-
rescue NoMethodError
|
26
|
-
begin
|
27
|
-
x_forwarded_for = request['HTTP_X_FORWARDED_FOR']
|
28
|
-
return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
|
29
|
-
rescue NoMethodError
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
begin
|
34
|
-
x_forwarded_for = request.env['REMOTE_ADDR']
|
35
|
-
return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
|
36
|
-
rescue NoMethodError
|
37
|
-
begin
|
38
|
-
x_forwarded_for = request['REMOTE_ADDR']
|
39
|
-
return x_forwarded_for.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless x_forwarded_for.nil?
|
40
|
-
rescue NoMethodError
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
unless options.nil?
|
45
|
-
for header in options.proxy_headers do
|
46
|
-
begin
|
47
|
-
h = request.env[header]
|
48
|
-
return h.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless h.nil?
|
49
|
-
rescue NoMethodError
|
50
|
-
begin
|
51
|
-
h = request[header]
|
52
|
-
return h.scan(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/)[0] unless h.nil?
|
53
|
-
rescue NoMethodError
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
''
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.get_remote_ip_from_request(request)
|
63
|
-
begin
|
64
|
-
request.remote_ip
|
65
|
-
rescue NoMethodError
|
66
|
-
''
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,44 +0,0 @@
|
|
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
|
-
Logger::WARN
|
12
|
-
when 'DEBUG'
|
13
|
-
Logger::DEBUG
|
14
|
-
when 'ERROR'
|
15
|
-
Logger::ERROR
|
16
|
-
when 'FATAL'
|
17
|
-
Logger::FATAL
|
18
|
-
when 'INFO'
|
19
|
-
Logger::INFO
|
20
|
-
else
|
21
|
-
Logger::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
|
@@ -1,16 +0,0 @@
|
|
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
|
data/lib/utils/utils.rb
DELETED