securenative 0.1.21 → 0.1.27

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 (114) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +64 -68
  3. data/README.md +37 -37
  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 +82 -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/out/production/securenative-ruby/api_manager.rb +13 -5
  44. data/out/production/securenative-ruby/config/configuration_builder.rb +6 -9
  45. data/out/production/securenative-ruby/config/configuration_manager.rb +24 -23
  46. data/out/production/securenative-ruby/config/securenative_options.rb +8 -5
  47. data/{lib → out/production/securenative-ruby}/context/hanami_context.rb +0 -0
  48. data/{lib → out/production/securenative-ruby}/context/rails_context.rb +0 -0
  49. data/out/production/securenative-ruby/context/securenative_context.rb +35 -8
  50. data/{lib → out/production/securenative-ruby}/context/sinatra_context.rb +0 -0
  51. data/out/production/securenative-ruby/event_manager.rb +15 -14
  52. data/{lib → out/production/securenative-ruby}/http/secure_native_http_response.rb +0 -0
  53. data/out/production/securenative-ruby/http/securenative_http_client.rb +23 -5
  54. data/out/production/securenative-ruby/models/event_options.rb +23 -1
  55. data/out/production/securenative-ruby/models/request_context.rb +2 -2
  56. data/out/production/securenative-ruby/models/sdk_event.rb +22 -6
  57. data/out/production/securenative-ruby/models/user_traits.rb +1 -1
  58. data/out/production/securenative-ruby/models/verify_result.rb +5 -1
  59. data/out/production/securenative-ruby/securenative.rb +2 -10
  60. data/out/production/securenative-ruby/utils/date_utils.rb +1 -1
  61. data/out/production/securenative-ruby/utils/encryption_utils.rb +38 -24
  62. data/out/production/securenative-ruby/utils/request_utils.rb +53 -7
  63. data/out/production/securenative-ruby/utils/secure_native_logger.rb +6 -6
  64. data/out/production/securenative-ruby/utils/version_utils.rb +5 -6
  65. data/out/test/securenative-ruby/spec_api_manager.rb +37 -31
  66. data/out/test/securenative-ruby/spec_context_builder.rb +52 -34
  67. data/out/test/securenative-ruby/spec_encryption_utils.rb +13 -13
  68. data/out/test/securenative-ruby/spec_event_manager.rb +49 -15
  69. data/out/test/securenative-ruby/spec_helper.rb +8 -0
  70. data/out/test/securenative-ruby/spec_request_utils.rb +25 -0
  71. data/out/test/securenative-ruby/spec_sdk_event.rb +24 -0
  72. data/out/test/securenative-ruby/spec_securenative.rb +35 -39
  73. data/out/test/securenative-ruby/spec_securenative_http_client.rb +13 -5
  74. data/out/test/securenative-ruby/spec_signature_utils.rb +1 -1
  75. data/out/test/securenative-ruby/spec_version_util.rb +10 -0
  76. data/securenative.gemspec +16 -14
  77. metadata +48 -43
  78. data/lib/api_manager.rb +0 -39
  79. data/lib/config/configuration_builder.rb +0 -26
  80. data/lib/config/configuration_manager.rb +0 -55
  81. data/lib/config/securenative_options.rb +0 -22
  82. data/lib/context/securenative_context.rb +0 -67
  83. data/lib/enums/api_route.rb +0 -6
  84. data/lib/enums/event_types.rb +0 -23
  85. data/lib/enums/failover_strategy.rb +0 -6
  86. data/lib/enums/risk_level.rb +0 -7
  87. data/lib/errors/securenative_config_error.rb +0 -4
  88. data/lib/errors/securenative_http_error.rb +0 -4
  89. data/lib/errors/securenative_invalid_options_error.rb +0 -4
  90. data/lib/errors/securenative_invalid_uri_error.rb +0 -4
  91. data/lib/errors/securenative_parse_error.rb +0 -4
  92. data/lib/errors/securenative_sdk_Illegal_state_error.rb +0 -4
  93. data/lib/errors/securenative_sdk_error.rb +0 -4
  94. data/lib/event_manager.rb +0 -157
  95. data/lib/http/securenative_http_client.rb +0 -50
  96. data/lib/models/client_token.rb +0 -12
  97. data/lib/models/device.rb +0 -10
  98. data/lib/models/event_options.rb +0 -37
  99. data/lib/models/request_context.rb +0 -18
  100. data/lib/models/request_options.rb +0 -12
  101. data/lib/models/sdk_event.rb +0 -40
  102. data/lib/models/user_traits.rb +0 -13
  103. data/lib/models/verify_result.rb +0 -16
  104. data/lib/securenative.rb +0 -83
  105. data/lib/utils/date_utils.rb +0 -9
  106. data/lib/utils/encryption_utils.rb +0 -49
  107. data/lib/utils/ip_utils.rb +0 -23
  108. data/lib/utils/request_utils.rb +0 -54
  109. data/lib/utils/secure_native_logger.rb +0 -44
  110. data/lib/utils/signature_utils.rb +0 -16
  111. data/lib/utils/utils.rb +0 -9
  112. data/lib/utils/version_utils.rb +0 -11
  113. data/out/production/securenative-ruby/event_options.rb +0 -32
  114. data/out/production/securenative-ruby/http/http_response.rb +0 -12
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class SecureNativeHttpError < StandardError
4
- end
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class SecureNativeInvalidOptionsError < StandardError
4
- end
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class SecureNativeInvalidUriError < StandardError
4
- end
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class SecureNativeParseError < StandardError
4
- end
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class SecureNativeSDKIllegalStateError < StandardError
4
- end
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class SecureNativeSDKError < StandardError
4
- end
@@ -1,157 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'utils/secure_native_logger'
4
- require 'config/securenative_options'
5
- require 'http/securenative_http_client'
6
- require 'errors/securenative_sdk_error'
7
- require 'errors/securenative_http_error'
8
-
9
- class QueueItem
10
- attr_reader :url, :body, :retry_sending
11
- attr_writer :url, :body, :retry_sending
12
-
13
- def initialize(url, body, retry_sending)
14
- @url = url
15
- @body = body
16
- @retry = retry_sending
17
- end
18
- end
19
-
20
- class EventManager
21
- def initialize(options = SecureNativeOptions.new, http_client = nil)
22
- if options.api_key.nil?
23
- raise SecureNativeSDKError, 'API key cannot be None, please get your API key from SecureNative console.'
24
- end
25
-
26
- @http_client = if http_client.nil?
27
- SecureNativeHttpClient.new(options)
28
- else
29
- http_client
30
- end
31
-
32
- @queue = []
33
- @semaphore = Mutex.new
34
- @interval = options.interval
35
- @options = options
36
- @send_enabled = false
37
- @attempt = 0
38
- @coefficients = [1, 1, 2, 3, 5, 8, 13]
39
-
40
- @thread = Thread.new { run }
41
- end
42
-
43
- def send_async(event, resource_path)
44
- if @options.disable
45
- SecureNativeLogger.warning('SDK is disabled. no operation will be performed')
46
- return
47
- end
48
-
49
- item = QueueItem.new(resource_path, EventManager.serialize(event).to_json, false)
50
- @queue.append(item)
51
- end
52
-
53
- def flush
54
- @queue.each do |item|
55
- @http_client.post(item.url, item.body)
56
- end
57
- end
58
-
59
- def send_sync(event, resource_path, retry_sending)
60
- if @options.disable
61
- SecureNativeLogger.warning('SDK is disabled. no operation will be performed')
62
- return
63
- end
64
-
65
- SecureNativeLogger.debug("Attempting to send event #{event}")
66
- res = @http_client.post(resource_path, EventManager.serialize(event).to_json)
67
-
68
- if res.nil? || res.code != '200'
69
- SecureNativeLogger.info("SecureNative failed to call endpoint #{resource_path} with event #{event}. adding back to queue")
70
- item = QueueItem.new(resource_path, EventManager.serialize(event).to_json, retry_sending)
71
- @queue.append(item)
72
- end
73
-
74
- res
75
- end
76
-
77
- def run
78
- loop do
79
- @semaphore.synchronize do
80
- next unless !@queue.empty? && @send_enabled
81
-
82
- @queue.each do |item|
83
- begin
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
- raise SecureNativeHttpError, res.status_code
89
- end
90
- SecureNativeLogger.debug("Event successfully sent; #{item.body}")
91
- return res
92
- rescue StandardError => 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
103
- end
104
- end
105
- end
106
- sleep @interval / 1000
107
- end
108
- end
109
-
110
- def start_event_persist
111
- SecureNativeLogger.debug('Starting automatic event persistence')
112
- if @options.auto_send || @send_enabled
113
- @send_enabled = true
114
- else
115
- SecureNativeLogger.debug('Automatic event persistence is disabled, you should persist events manually')
116
- end
117
- end
118
-
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
129
- end
130
- end
131
-
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
157
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'net/http'
4
- require 'uri'
5
- require 'json'
6
- require 'utils/version_utils'
7
- require 'utils/secure_native_logger'
8
-
9
- class SecureNativeHttpClient
10
- AUTHORIZATION_HEADER = 'Authorization'
11
- VERSION_HEADER = 'SN-Version'
12
- USER_AGENT_HEADER = 'User-Agent'
13
- USER_AGENT_HEADER_VALUE = 'SecureNative-ruby'
14
- CONTENT_TYPE_HEADER = 'Content-Type'
15
- CONTENT_TYPE_HEADER_VALUE = 'application/json'
16
-
17
- def initialize(securenative_options)
18
- @options = securenative_options
19
- end
20
-
21
- def _headers
22
- {
23
- CONTENT_TYPE_HEADER => CONTENT_TYPE_HEADER_VALUE,
24
- USER_AGENT_HEADER => USER_AGENT_HEADER_VALUE,
25
- VERSION_HEADER => VersionUtils.version,
26
- AUTHORIZATION_HEADER => @options.api_key
27
- }
28
- end
29
-
30
- def post(path, body)
31
- uri = URI.parse("#{@options.api_url}/#{path}")
32
- headers = _headers
33
-
34
- client = Net::HTTP.new(uri.host, uri.port)
35
- client.use_ssl = true
36
- client.verify_mode = OpenSSL::SSL::VERIFY_NONE
37
-
38
- request = Net::HTTP::Post.new(uri.request_uri, headers)
39
- request.body = body
40
-
41
- res = nil
42
- begin
43
- res = client.request(request)
44
- rescue StandardError => e
45
- SecureNativeLogger.error("Failed to send request; #{e}")
46
- return res
47
- end
48
- res
49
- end
50
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class ClientToken
4
- attr_reader :cid, :vid, :fp
5
- attr_writer :cid, :vid, :fp
6
-
7
- def initialize(cid, vid, fp)
8
- @cid = cid
9
- @vid = vid
10
- @fp = fp
11
- end
12
- end
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Device
4
- attr_reader :device_id
5
- attr_writer :device_id
6
-
7
- def initialize(device_id)
8
- @device_id = device_id
9
- end
10
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'models/event_options'
4
- require 'models/user_traits'
5
- require 'errors/securenative_invalid_options_error'
6
-
7
- class EventOptions
8
- attr_reader :event, :user_id, :user_traits, :context, :properties, :timestamp
9
- attr_writer :event, :user_id, :user_traits, :context, :properties, :timestamp
10
-
11
- MAX_PROPERTIES_SIZE = 10
12
-
13
- def initialize(event: nil, user_id: nil, user_traits: nil, user_name: nil, email: nil, phone: nil, created_at: nil, context: nil, properties: nil, timestamp: nil)
14
- if !properties.nil? && properties.length > MAX_PROPERTIES_SIZE
15
- raise SecureNativeInvalidOptionsError, "You can have only up to #{MAX_PROPERTIES_SIZE} custom properties"
16
- end
17
-
18
- if user_traits.nil?
19
- if user_name && email && phone && created_at
20
- user_traits = UserTraits(user_name, email, phone, created_at)
21
- elsif user_name && email && phone
22
- user_traits = UserTraits(user_name, email, phone)
23
- elsif user_name && email
24
- user_traits = UserTraits(user_name, email)
25
- else
26
- user_traits = UserTraits.new
27
- end
28
- end
29
-
30
- @event = event
31
- @user_id = user_id
32
- @user_traits = user_traits
33
- @context = context
34
- @properties = properties
35
- @timestamp = timestamp
36
- end
37
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class RequestContext
4
- attr_reader :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :http_method
5
- attr_writer :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :http_method
6
-
7
- def initialize(cid: nil, vid: nil, fp: nil, ip: nil, remote_ip: nil, headers: nil, url: nil, http_method: nil)
8
- @cid = cid
9
- @vid = vid
10
- @fp = fp
11
- @ip = ip
12
- @remote_ip = remote_ip
13
- @headers = headers
14
- @url = url
15
- @method = http_method
16
- end
17
- end
18
-
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class RequestOptions
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_sending = retry_sending
11
- end
12
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'context/securenative_context'
4
- require 'utils/encryption_utils'
5
- require 'utils/date_utils'
6
- require 'models/request_context'
7
- require 'securerandom'
8
-
9
- class SDKEvent
10
- attr_reader :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties
11
- attr_writer :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties
12
-
13
- def initialize(event_options, securenative_options)
14
- @context = if !event_options.context.nil?
15
- event_options.context
16
- else
17
- SecureNativeContext.default_context_builder
18
- end
19
-
20
- client_token = EncryptionUtils.decrypt(@context.client_token, securenative_options.api_key)
21
-
22
- @rid = SecureRandom.uuid.to_str
23
- @event_type = event_options.event
24
- @user_id = event_options.user_id
25
- @user_traits = event_options.user_traits
26
- @request = RequestContext.new(cid: client_token ? client_token.cid : '', vid: client_token ? client_token.vid : '',
27
- fp: client_token ? client_token.fp : '', ip: @context.ip,
28
- remote_ip: @context.remote_ip, headers: @context.headers,
29
- url: @context.url, http_method: @context.http_method)
30
-
31
-
32
- @timestamp = DateUtils.to_timestamp(event_options.timestamp)
33
- @properties = event_options.properties
34
- end
35
-
36
- def to_s
37
- "context: #{@context}, rid: #{@rid}, event_type: #{@event_type}, user_id: #{@user_id},
38
- user_traits: #{@user_traits}, request: #{@request}, timestamp: #{@timestamp}, properties: #{@properties}"
39
- end
40
- 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