securenative 0.1.23 → 0.1.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +3 -5
  3. data/README.md +36 -36
  4. data/lib/securenative/api_manager.rb +41 -0
  5. data/lib/securenative/config/configuration_builder.rb +29 -0
  6. data/lib/securenative/config/configuration_manager.rb +58 -0
  7. data/lib/securenative/config/securenative_options.rb +25 -0
  8. data/lib/securenative/context/hanami_context.rb +44 -0
  9. data/lib/securenative/context/rails_context.rb +46 -0
  10. data/lib/securenative/context/securenative_context.rb +69 -0
  11. data/lib/securenative/context/sinatra_context.rb +44 -0
  12. data/lib/securenative/enums/api_route.rb +8 -0
  13. data/lib/securenative/enums/event_types.rb +25 -0
  14. data/lib/securenative/enums/failover_strategy.rb +8 -0
  15. data/lib/securenative/enums/risk_level.rb +9 -0
  16. data/lib/securenative/errors/securenative_config_error.rb +6 -0
  17. data/lib/securenative/errors/securenative_http_error.rb +6 -0
  18. data/lib/securenative/errors/securenative_invalid_options_error.rb +6 -0
  19. data/lib/securenative/errors/securenative_invalid_uri_error.rb +6 -0
  20. data/lib/securenative/errors/securenative_parse_error.rb +6 -0
  21. data/lib/securenative/errors/securenative_sdk_Illegal_state_error.rb +6 -0
  22. data/lib/securenative/errors/securenative_sdk_error.rb +6 -0
  23. data/lib/securenative/event_manager.rb +159 -0
  24. data/lib/securenative/http/secure_native_http_response.rb +14 -0
  25. data/lib/securenative/http/securenative_http_client.rb +52 -0
  26. data/lib/securenative/models/client_token.rb +14 -0
  27. data/lib/securenative/models/device.rb +12 -0
  28. data/lib/securenative/models/event_options.rb +39 -0
  29. data/lib/securenative/models/request_context.rb +20 -0
  30. data/lib/securenative/models/request_options.rb +14 -0
  31. data/lib/securenative/models/sdk_event.rb +51 -0
  32. data/lib/securenative/models/user_traits.rb +15 -0
  33. data/lib/securenative/models/verify_result.rb +18 -0
  34. data/lib/securenative/sdk.rb +85 -0
  35. data/lib/securenative/utils/date_utils.rb +11 -0
  36. data/lib/securenative/utils/encryption_utils.rb +51 -0
  37. data/lib/securenative/utils/ip_utils.rb +25 -0
  38. data/lib/securenative/utils/request_utils.rb +71 -0
  39. data/lib/securenative/utils/secure_native_logger.rb +46 -0
  40. data/lib/securenative/utils/signature_utils.rb +18 -0
  41. data/lib/securenative/utils/utils.rb +11 -0
  42. data/lib/securenative/utils/version_utils.rb +13 -0
  43. data/securenative.gemspec +16 -14
  44. metadata +40 -40
  45. data/lib/api_manager.rb +0 -39
  46. data/lib/config/configuration_builder.rb +0 -27
  47. data/lib/config/configuration_manager.rb +0 -56
  48. data/lib/config/securenative_options.rb +0 -23
  49. data/lib/context/hanami_context.rb +0 -42
  50. data/lib/context/rails_context.rb +0 -44
  51. data/lib/context/securenative_context.rb +0 -67
  52. data/lib/context/sinatra_context.rb +0 -42
  53. data/lib/enums/api_route.rb +0 -6
  54. data/lib/enums/event_types.rb +0 -23
  55. data/lib/enums/failover_strategy.rb +0 -6
  56. data/lib/enums/risk_level.rb +0 -7
  57. data/lib/errors/securenative_config_error.rb +0 -4
  58. data/lib/errors/securenative_http_error.rb +0 -4
  59. data/lib/errors/securenative_invalid_options_error.rb +0 -4
  60. data/lib/errors/securenative_invalid_uri_error.rb +0 -4
  61. data/lib/errors/securenative_parse_error.rb +0 -4
  62. data/lib/errors/securenative_sdk_Illegal_state_error.rb +0 -4
  63. data/lib/errors/securenative_sdk_error.rb +0 -4
  64. data/lib/event_manager.rb +0 -157
  65. data/lib/http/secure_native_http_response.rb +0 -12
  66. data/lib/http/securenative_http_client.rb +0 -50
  67. data/lib/models/client_token.rb +0 -12
  68. data/lib/models/device.rb +0 -10
  69. data/lib/models/event_options.rb +0 -37
  70. data/lib/models/request_context.rb +0 -18
  71. data/lib/models/request_options.rb +0 -12
  72. data/lib/models/sdk_event.rb +0 -49
  73. data/lib/models/user_traits.rb +0 -13
  74. data/lib/models/verify_result.rb +0 -16
  75. data/lib/securenative.rb +0 -83
  76. data/lib/utils/date_utils.rb +0 -9
  77. data/lib/utils/encryption_utils.rb +0 -49
  78. data/lib/utils/ip_utils.rb +0 -23
  79. data/lib/utils/request_utils.rb +0 -69
  80. data/lib/utils/secure_native_logger.rb +0 -44
  81. data/lib/utils/signature_utils.rb +0 -16
  82. data/lib/utils/utils.rb +0 -9
  83. data/lib/utils/version_utils.rb +0 -11
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class DateUtils
4
- def self.to_timestamp(date)
5
- return Time.now.utc.iso8601 if date.nil?
6
-
7
- Time.parse(date).iso8601
8
- end
9
- end
@@ -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
@@ -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
@@ -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
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Utils
4
- def self.null_or_empty?(string)
5
- return true if !string || string.empty? || string.nil?
6
-
7
- false
8
- end
9
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class VersionUtils
4
- def self.version
5
- begin
6
- Gem.loaded_specs['securenative'].version.to_s
7
- rescue StandardError
8
- 'unknown'
9
- end
10
- end
11
- end