diff --git a/Gemfile b/Gemfile index b62edc1..b033448 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,6 @@ source "https://rubygems.org" gemspec gem "rspec" gem "rake" -gem "parseconfig" gem "simplecov", :require => false, :group => :test gem "codecov", :require => false, :group => :test gem "webmock", :require => false, :group => :test diff --git a/Gemfile.lock b/Gemfile.lock index ba2e409..3a767b9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -73,7 +73,7 @@ GEM crack (0.4.3) safe_yaml (~> 1.0.0) crass (1.0.6) - diff-lcs (1.3) + diff-lcs (1.4.4) docile (1.3.2) dry-configurable (0.11.6) concurrent-ruby (~> 1.0) @@ -174,7 +174,6 @@ GEM nio4r (2.5.2) nokogiri (1.10.10) mini_portile2 (~> 2.4.0) - parseconfig (1.0.8) public_suffix (4.0.5) rack (2.2.3) rack-protection (2.0.8.1) @@ -208,19 +207,19 @@ GEM rake (>= 0.8.7) thor (>= 0.20.3, < 2.0) rake (13.0.1) - rspec (3.8.0) - rspec-core (~> 3.8.0) - rspec-expectations (~> 3.8.0) - rspec-mocks (~> 3.8.0) - rspec-core (3.8.2) - rspec-support (~> 3.8.0) - rspec-expectations (3.8.4) + rspec (3.9.0) + rspec-core (~> 3.9.0) + rspec-expectations (~> 3.9.0) + rspec-mocks (~> 3.9.0) + rspec-core (3.9.2) + rspec-support (~> 3.9.3) + rspec-expectations (3.9.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-mocks (3.8.1) + rspec-support (~> 3.9.0) + rspec-mocks (3.9.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-support (3.8.2) + rspec-support (~> 3.9.0) + rspec-support (3.9.3) ruby2_keywords (0.0.2) safe_yaml (1.0.5) simplecov (0.19.0) @@ -263,7 +262,6 @@ DEPENDENCIES bundler (~> 2.0) codecov hanami - parseconfig rails rake rspec diff --git a/README.md b/README.md index 05f0c2b..97c1302 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Or install it yourself as: To get your *API KEY*, login to your SecureNative account and go to project settings page: ### Option 1: Initialize via Config file -SecureNative can automatically load your config from *securenative.cfg* file or from the file that is specified in your *SECURENATIVE_CONFIG_FILE* env variable: +SecureNative can automatically load your config from *securenative.yml* file or from the file that is specified in your *SECURENATIVE_CONFIG_FILE* env variable: ```ruby require 'securenative' @@ -69,7 +69,8 @@ securenative = SecureNative.init_with_api_key('YOUR_API_KEY') require 'securenative' -securenative = SecureNative.init_with_options(SecureNative.config_builder(api_key = 'API_KEY', max_event = 10, log_level = 'ERROR')) +options = ConfigurationBuilder.new(api_key: 'API_KEY', max_events: 10, log_level: 'ERROR') +SecureNative.init_with_options(options) ``` ## Getting SecureNative instance @@ -88,42 +89,46 @@ instance. Make sure you build event with the EventBuilder: ```ruby require 'securenative' -require 'securenative/enums/event_types' -require 'securenative/event_options_builder' -require 'securenative/models/user_traits' -require 'securenative/context/context_builder' +require 'models/event_options' +require 'enums/event_types' +require 'models/user_traits' -securenative = SecureNative.instance - -context = securenative.context_builder(ip = '127.0.0.1', client_token = 'SECURED_CLIENT_TOKEN', - headers = { 'user-agent' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405' }) - -event_options = EventOptions(event_type = EventTypes::LOG_IN, - user_id = '1234', user_traits = UserTraits('Your Name', 'name@gmail.com', '+1234567890'), - context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build - -securenative.track(event_options) +def track + securenative = SecureNative.instance + context = SecureNativeContext.new(client_token: '2a980d872b939c7e4f4378aa111a5eeffb22808b58b5372f658d34904ebd5b05fff0daab91921243ac08b72442a5b3992e402dc21df16aa7cc0e19f8bffa9d6cc59996d480d70aa22b857189403675d37fd144ebaf9dc697fed149b907678f2b1f964d73b332dc8ea7df63fcfc3c11f7bbb51ba2672652ca7d5d43f36a62e15db8b13dfd794a5eccfc5968ca514dd7cce59f2df2b9d8184d076eba808c81b311', ip: '127.0.0.1', + headers: { 'user-agent' => 'Mozilla: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.3 Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:42.0) Gecko/20100101 Firefox/43.4' }) + + event_options = EventOptions.new(event: EventTypes::LOG_IN, user_id: '1234', context: context, + user_traits: UserTraits.new(name: 'Your Name', email: 'name@gmail.com', phone: '+1234567890'), + properties: { custom_param1: 'CUSTOM_PARAM_VALUE', custom_param2: true, custom_param3: 3 }) + + securenative.track(event_options) + + @message = 'tracked' +end ``` You can also create request context from requests: ```ruby require 'securenative' -require 'securenative/enums/event_types' -require 'securenative/event_options_builder' -require 'securenative/models/user_traits' +require 'models/event_options' +require 'enums/event_types' +require 'models/user_traits' -def track(request) +def track securenative = SecureNative.instance - context = SecureNative.context_builder.from_http_request(request).build - - event_options = EventOptions(event_type = EventTypes::LOG_IN, - user_id = '1234', user_traits = UserTraits('Your Name', 'name@gmail.com', '+1234567890'), - context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build + context = SecureNativeContext.from_http_request(request) + + event_options = EventOptions.new(event: EventTypes::LOG_IN, user_id: '1234', context: context, + user_traits: UserTraits.new(name: 'Your Name', email: 'name@gmail.com', phone: '+1234567890'), + properties: { custom_param1: 'CUSTOM_PARAM_VALUE', custom_param2: true, custom_param3: 3 }) securenative.track(event_options) + + @message = 'tracked' end ``` @@ -133,18 +138,18 @@ end ```ruby require 'securenative' -require 'securenative/enums/event_types' -require 'securenative/event_options_builder' -require 'securenative/models/user_traits' +require 'models/event_options' +require 'enums/event_types' +require 'models/user_traits' def verify(request) securenative = SecureNative.instance - context = SecureNative.context_builder.from_http_request(request).build + context = SecureNativeContext.from_http_request(request) - event_options = EventOptions(event_type = EventTypes::LOG_IN, - user_id = '1234', user_traits = UserTraits('Your Name', 'name@gmail.com', '+1234567890'), - context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build + event_options = EventOptions.new(event: EventTypes::LOG_IN, user_id: '1234', context: context, + user_traits: UserTraits.new(name: 'Your Name', email: 'name@gmail.com', phone: '+1234567890'), + properties: { custom_param1: 'CUSTOM_PARAM_VALUE', custom_param2: true, custom_param3: 3 }) verify_result = securenative.verify(event_options) verify_result.risk_level # Low, Medium, High diff --git a/lib/api_manager.rb b/lib/api_manager.rb index c7ec1dd..f37893f 100644 --- a/lib/api_manager.rb +++ b/lib/api_manager.rb @@ -24,8 +24,9 @@ def verify(event_options) event = SDKEvent.new(event_options, @options) begin - res = @event_manager.send_sync(event, ApiRoute::VERIFY, false).to_json - return VerifyResult.new(risk_level: res['riskLevel'], score: res['score'], triggers: res['triggers']) + res = @event_manager.send_sync(event, ApiRoute::VERIFY, false) + ver_result = JSON.parse(res.body) + return VerifyResult.new(risk_level: ver_result['riskLevel'], score: ver_result['score'], triggers: ver_result['triggers']) rescue StandardError => e SecureNativeLogger.debug("Failed to call verify; #{e}") end diff --git a/lib/config/configuration_builder.rb b/lib/config/configuration_builder.rb index 8456ac0..749e429 100644 --- a/lib/config/configuration_builder.rb +++ b/lib/config/configuration_builder.rb @@ -20,10 +20,6 @@ def initialize(api_key: nil, api_url: 'https://api.securenative.com/collector/ap @fail_over_strategy = fail_over_strategy end - def self.default_config_builder - ConfigurationBuilder.new - end - def self.default_securenative_options SecureNativeOptions.new end diff --git a/lib/config/configuration_manager.rb b/lib/config/configuration_manager.rb index c3a9b86..1c99c56 100644 --- a/lib/config/configuration_manager.rb +++ b/lib/config/configuration_manager.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true -require 'parseconfig' +require 'yaml' +require 'config/configuration_builder' class ConfigurationManager - DEFAULT_CONFIG_FILE = 'securenative.cfg' + DEFAULT_CONFIG_FILE = 'securenative.yml' CUSTOM_CONFIG_FILE_ENV_NAME = 'SECURENATIVE_CONFIG_FILE' @config = nil def self.read_resource_file(resource_path) - @config = ParseConfig.new(resource_path) - properties = {} - @config.get_groups.each do |group| - group.each do |key, value| - properties[key.upcase] = value - end + begin + @config = YAML.load_file(resource_path) + properties = @config unless @config.nil? + rescue StandardError => e + SecureNativeLogger.error("Could not parse config file #{resource_path}; #{e}") end properties end @@ -24,32 +24,32 @@ def self._get_resource_path(env_name) end def self.config_builder - ConfigurationBuilder.default_config_builder + ConfigurationBuilder.new end def self._get_env_or_default(properties, key, default) - return Env[key] if Env[key] + return ENV[key] if ENV[key] return properties[key] if properties[key] default end def self.load_config - options = ConfigurationBuilder().default_securenative_options + options = ConfigurationBuilder.default_securenative_options resource_path = DEFAULT_CONFIG_FILE - resource_path = Env[CUSTOM_CONFIG_FILE_ENV_NAME] if Env[CUSTOM_CONFIG_FILE_ENV_NAME] + resource_path = ENV[CUSTOM_CONFIG_FILE_ENV_NAME] unless ENV[CUSTOM_CONFIG_FILE_ENV_NAME].nil? properties = read_resource_file(resource_path) - ConfigurationBuilder(_get_env_or_default(properties, 'SECURENATIVE_API_KEY', options.api_key), - _get_env_or_default(properties, 'SECURENATIVE_API_URL', options.api_url), - _get_env_or_default(properties, 'SECURENATIVE_INTERVAL', options.interval), - _get_env_or_default(properties, 'SECURENATIVE_MAX_EVENTS', options.max_events), - _get_env_or_default(properties, 'SECURENATIVE_TIMEOUT', options.timeout), - _get_env_or_default(properties, 'SECURENATIVE_AUTO_SEND', options.auto_send), - _get_env_or_default(properties, 'SECURENATIVE_DISABLE', options.disable), - _get_env_or_default(properties, 'SECURENATIVE_LOG_LEVEL', options.log_level), - _get_env_or_default(properties, 'SECURENATIVE_FAILOVER_STRATEGY', options.fail_over_strategy)) + ConfigurationBuilder.new(api_key: _get_env_or_default(properties, 'SECURENATIVE_API_KEY', options.api_key), + api_url: _get_env_or_default(properties, 'SECURENATIVE_API_URL', options.api_url), + interval: _get_env_or_default(properties, 'SECURENATIVE_INTERVAL', options.interval), + max_events: _get_env_or_default(properties, 'SECURENATIVE_MAX_EVENTS', options.max_events), + timeout: _get_env_or_default(properties, 'SECURENATIVE_TIMEOUT', options.timeout), + auto_send: _get_env_or_default(properties, 'SECURENATIVE_AUTO_SEND', options.auto_send), + disable: _get_env_or_default(properties, 'SECURENATIVE_DISABLE', options.disable), + log_level: _get_env_or_default(properties, 'SECURENATIVE_LOG_LEVEL', options.log_level), + fail_over_strategy: _get_env_or_default(properties, 'SECURENATIVE_FAILOVER_STRATEGY', options.fail_over_strategy)) end end diff --git a/lib/context/hanami_context.rb b/lib/context/hanami_context.rb index 5c48094..b4dfbec 100644 --- a/lib/context/hanami_context.rb +++ b/lib/context/hanami_context.rb @@ -1,11 +1,17 @@ # frozen_string_literal: true class HanamiContext + SECURENATIVE_COOKIE = '_sn' + def self.get_client_token(request) begin request.env[SECURENATIVE_COOKIE] rescue StandardError - nil + begin + request.cookies[SECURENATIVE_COOKIE] + rescue StandardError + nil + end end end @@ -27,7 +33,8 @@ def self.get_method(request) def self.get_headers(request) begin - request.headers.to_hash + # Note: At the moment we're filtering out everything but user-agent since ruby's payload is way too big + { 'user-agent' => request.env['HTTP_USER_AGENT'] } rescue StandardError nil end diff --git a/lib/context/rails_context.rb b/lib/context/rails_context.rb index bdda4d0..703ecdb 100644 --- a/lib/context/rails_context.rb +++ b/lib/context/rails_context.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class RailsContext + SECURENATIVE_COOKIE = '_sn' + def self.get_client_token(request) begin request.cookies[SECURENATIVE_COOKIE] @@ -33,7 +35,8 @@ def self.get_method(request) def self.get_headers(request) begin - request.headers.to_hash + # Note: At the moment we're filtering out everything but user-agent since ruby's payload is way too big + { 'user-agent' => request.env['HTTP_USER_AGENT'] } rescue StandardError nil end diff --git a/lib/context/sinatra_context.rb b/lib/context/sinatra_context.rb index 5303476..2315c83 100644 --- a/lib/context/sinatra_context.rb +++ b/lib/context/sinatra_context.rb @@ -1,17 +1,23 @@ # frozen_string_literal: true class SinatraContext + SECURENATIVE_COOKIE = '_sn' + def self.get_client_token(request) begin request.env[SECURENATIVE_COOKIE] rescue StandardError - nil + begin + request.cookies[SECURENATIVE_COOKIE] + rescue StandardError + nil + end end end def self.get_url(request) begin - request.url + request.env['REQUEST_URI'] rescue StandardError nil end @@ -19,7 +25,7 @@ def self.get_url(request) def self.get_method(request) begin - request.method + request.env['REQUEST_METHOD'] rescue StandardError nil end @@ -27,7 +33,8 @@ def self.get_method(request) def self.get_headers(request) begin - request.headers.to_hash + # Note: At the moment we're filtering out everything but user-agent since ruby's payload is way too big + { 'user-agent' => request.env['HTTP_USER_AGENT'] } rescue StandardError nil end diff --git a/lib/event_manager.rb b/lib/event_manager.rb index d6a5332..b80c3de 100644 --- a/lib/event_manager.rb +++ b/lib/event_manager.rb @@ -65,7 +65,7 @@ def send_sync(event, resource_path, retry_sending) SecureNativeLogger.debug("Attempting to send event #{event}") res = @http_client.post(resource_path, EventManager.serialize(event).to_json) - if res.nil? || res.code != 200 + if res.nil? || res.code != '200' SecureNativeLogger.info("SecureNative failed to call endpoint #{resource_path} with event #{event}. adding back to queue") item = QueueItem.new(resource_path, EventManager.serialize(event).to_json, retry_sending) @queue.append(item) diff --git a/lib/event_options.rb b/lib/event_options.rb deleted file mode 100644 index d68ca6f..0000000 --- a/lib/event_options.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -class EventOptions - MAX_PROPERTIES_SIZE = 10 - - def initialize(event_type, user_id, user_traits, user_name, email, phone, created_at, context, properties, timestamp) - traits = UserTraits(user_name) - if user_name && email && phone && created_at - traits = UserTraits(user_name, email, phone, created_at) - elsif user_name && email && phone - traits = UserTraits(user_name, email, phone) - elsif user_name && email - traits = UserTraits(user_name, email) - end - - @event_options = EventOptions(event_type) - @event_options.user_id = user_id - @event_options.user_traits = user_traits if user_traits - @event_options.user_traits = traits - @event_options.context = context - @event_options.properties = properties - @event_options.timestamp = timestamp - end - - def build - if !@event_options.properties.nil? && @event_options.properties.length > MAX_PROPERTIES_SIZE - raise SecureNativeInvalidOptionsError('You can have only up to {} custom properties', MAX_PROPERTIES_SIZE) - end - - @event_options - end -end diff --git a/lib/models/event_options.rb b/lib/models/event_options.rb index 8af623a..43c7db6 100644 --- a/lib/models/event_options.rb +++ b/lib/models/event_options.rb @@ -1,10 +1,32 @@ # frozen_string_literal: true +require 'models/event_options' +require 'models/user_traits' +require 'errors/securenative_invalid_options_error' + class EventOptions attr_reader :event, :user_id, :user_traits, :context, :properties, :timestamp attr_writer :event, :user_id, :user_traits, :context, :properties, :timestamp - def initialize(event: nil, user_id: nil, user_traits: nil, context: nil, properties: nil, timestamp: nil) + MAX_PROPERTIES_SIZE = 10 + + 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) + if !properties.nil? && properties.length > MAX_PROPERTIES_SIZE + raise SecureNativeInvalidOptionsError, "You can have only up to #{MAX_PROPERTIES_SIZE} custom properties" + end + + if user_traits.nil? + if user_name && email && phone && created_at + user_traits = UserTraits(user_name, email, phone, created_at) + elsif user_name && email && phone + user_traits = UserTraits(user_name, email, phone) + elsif user_name && email + user_traits = UserTraits(user_name, email) + else + user_traits = UserTraits.new + end + end + @event = event @user_id = user_id @user_traits = user_traits diff --git a/lib/models/sdk_event.rb b/lib/models/sdk_event.rb index 7dec4ec..8c09595 100644 --- a/lib/models/sdk_event.rb +++ b/lib/models/sdk_event.rb @@ -4,6 +4,7 @@ require 'utils/encryption_utils' require 'utils/date_utils' require 'models/request_context' +require 'securerandom' class SDKEvent attr_reader :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties diff --git a/lib/models/verify_result.rb b/lib/models/verify_result.rb index 734502b..b30a065 100644 --- a/lib/models/verify_result.rb +++ b/lib/models/verify_result.rb @@ -9,4 +9,8 @@ def initialize(risk_level: nil, score: nil, triggers: nil) @score = score @triggers = triggers end + + def to_s + "risk_level: #{@risk_level}, score: #{@score}, triggers: #{@triggers}" + end end diff --git a/lib/securenative.rb b/lib/securenative.rb index a0892d8..fa6612c 100644 --- a/lib/securenative.rb +++ b/lib/securenative.rb @@ -8,6 +8,7 @@ require 'errors/securenative_config_error' require 'enums/failover_strategy' require 'config/configuration_builder' +require 'config/configuration_manager' require 'event_manager' require 'api_manager' diff --git a/lib/utils/encryption_utils.rb b/lib/utils/encryption_utils.rb index 96c82c5..f031069 100644 --- a/lib/utils/encryption_utils.rb +++ b/lib/utils/encryption_utils.rb @@ -1,44 +1,49 @@ # frozen_string_literal: true require 'openssl' +require 'digest' +require 'base64' require 'models/client_token' class EncryptionUtils - BLOCK_SIZE = 16 - KEY_SIZE = 32 - - def self.encrypt(text, cipher_key) - begin - cipher = OpenSSL::Cipher::AES.new(KEY_SIZE, :CBC).encrypt - cipher.padding = 0 - - if text.size % BLOCK_SIZE != 0 - return nil + def self.padding_key(key, length) + if key.length == length + key + else + if key.length > length + key.slice(0, length) + else + (length - key.length).times { key << '0' } + key end + end + end - cipher_key = Digest::SHA1.hexdigest cipher_key - cipher.key = cipher_key.slice(0, BLOCK_SIZE) - s = cipher.update(text) + cipher.final - - s.unpack('H*')[0].upcase + def self.encrypt(plain_text, secret_key) + begin + cipher = OpenSSL::Cipher.new('aes-256-cbc') + cipher.encrypt + iv = cipher.random_iv + cipher.key = padding_key(secret_key, 32) + encrypted = cipher.update(plain_text) + cipher.final + (iv + encrypted).unpack1('H*') rescue StandardError '' end end - def self.decrypt(encrypted, cipher_key) + def self.decrypt(cipher_text, secret_key) begin - cipher = OpenSSL::Cipher::AES.new(KEY_SIZE, :CBC).decrypt - cipher.padding = 0 - - cipher_key = Digest::SHA1.hexdigest cipher_key - cipher.key = cipher_key.slice(0, BLOCK_SIZE) - s = [encrypted].pack('H*').unpack('C*').pack('c*') - - rv = cipher.update(s) + cipher.final - rv.strip + cipher = OpenSSL::Cipher.new('aes-256-cbc') + cipher.decrypt + raw_data = [cipher_text].pack('H*') + cipher.iv = raw_data.slice(0, 16) + cipher.key = padding_key(secret_key, 32) + decrypted = JSON.parse(cipher.update(raw_data.slice(16, raw_data.length)) + cipher.final) + + return ClientToken.new(decrypted['cid'], decrypted['vid'], decrypted['fp']) rescue StandardError - ClientToken.new('', '', '') + ClientToken.new('', '','') end end end diff --git a/lib/utils/version_utils.rb b/lib/utils/version_utils.rb index 3512577..326861c 100644 --- a/lib/utils/version_utils.rb +++ b/lib/utils/version_utils.rb @@ -3,11 +3,9 @@ class VersionUtils def self.version begin - spec = Gem::Specification.load('securenative.gemspec') - version = spec.version + Gem.loaded_specs['securenative'].version.to_s rescue StandardError - version = 'unknown' + 'unknown' end - version end end diff --git a/spec/spec_api_manager.rb b/spec/spec_api_manager.rb index 3f645d4..895ac36 100644 --- a/spec/spec_api_manager.rb +++ b/spec/spec_api_manager.rb @@ -16,15 +16,7 @@ it 'tracks an event' do options = ConfigurationBuilder.new(api_key: 'YOUR_API_KEY', auto_send: true, interval: 10, api_url: 'https://api.securenative-stg.com/collector/api/v1') - expected = '{"eventType":"sn.user.login","userId":"USER_ID","userTraits":{' \ - '"name":"USER_NAME","email":"USER_EMAIL","phone":"+1234567890","createdAt":null},"request":{' \ - '"cid":null,"vid":null,"fp":null,"ip":"127.0.0.1","remoteIp":null,"headers":{' \ - '"user-agent":"Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) ' \ - 'AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405"},"url":null,"method":null},' \ - '"properties":{"prop2":true,"prop1":"CUSTOM_PARAM_VALUE","prop3":3}}' - - stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track') - .with(body: JSON.parse(expected)).to_return(status: 200) + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track').to_return(status: 200) event_manager = EventManager.new(options) event_manager.start_event_persist api_manager = ApiManager.new(event_manager, options) @@ -33,10 +25,12 @@ properties: { prop1: 'CUSTOM_PARAM_VALUE', prop2: true, prop3: 3 }) begin - api_manager.track(event_options) + res = api_manager.track(event_options) ensure event_manager.stop_event_persist end + + expect(res).to_not be_nil end it 'uses invalid options' do @@ -63,8 +57,18 @@ it 'verifies an event' do options = ConfigurationBuilder.new(api_key: 'YOUR_API_KEY', api_url: 'https://api.securenative-stg.com/collector/api/v1') - stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track') - .with(body: { riskLevel: 'medium', score: 0.32, triggers: ['New IP', 'New City'] }).to_return(status: 200) + # stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track') + # .with(body: { riskLevel: 'medium', score: 0.32, triggers: ['New IP', 'New City'] }).to_return(status: 200) + + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/verify') + .with(headers: { + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Authorization' => 'YOUR_API_KEY', + 'Content-Type' => 'application/json', + 'Sn-Version' => '0.1.21', + 'User-Agent' => 'SecureNative-ruby' + }).to_return(status: 200, body: '', headers: {}) verify_result = VerifyResult.new(risk_level: RiskLevel::LOW, score: 0, triggers: nil) event_manager = EventManager.new(options) diff --git a/spec/spec_context_builder.rb b/spec/spec_context_builder.rb index 010bd08..f317ed9 100644 --- a/spec/spec_context_builder.rb +++ b/spec/spec_context_builder.rb @@ -10,8 +10,8 @@ RSpec.describe SecureNativeContext do it 'creates context from ruby default request' do stub_request(:any, 'www.example.com') - .to_return(status: 200, - headers: { '_sn': '71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a' }) + .to_return(status: 200, + headers: { '_sn': '71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a' }) request = Net::HTTP.get_response('www.example.com', '/') context = SecureNativeContext.from_http_request(request) diff --git a/spec/spec_encryption_utils.rb b/spec/spec_encryption_utils.rb index 2a86c39..cbfca79 100644 --- a/spec/spec_encryption_utils.rb +++ b/spec/spec_encryption_utils.rb @@ -5,7 +5,7 @@ RSpec.describe EncryptionUtils do it 'encrypts' do - secret_key = 'B00C42DAD33EAC6F6572DA756EA4915349C0A4F6' + secret_key = 'AFD16D89150FD7FB19EE9E936DC1AE3547CE119B' payload = '{"cid":"198a41ff-a10f-4cda-a2f3-a9ca80c0703b","vi":"148a42ff-b40f-4cda-a2f3-a8ca80c0703b","fp":"6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed"}' result = EncryptionUtils.encrypt(payload, secret_key) @@ -13,10 +13,10 @@ end it 'decrypts' do - secret_key = 'B00C42DAD33EAC6F6572DA756EA4915349C0A4F6' - encrypted_payload = '56463564485361554e70763250546e334954565667673d3d246949482f446b72352f6b31316a63466d4c515339703631754b6e54557854546e4a554433634b67744641712f44647356386569636f6a322b4c55354d0a4c6b72504d37464c6f5746632f614f644b542f38585346374566515954355859326a386e576a4439717a7a6a4269744363522f79386851522b7067640a2f67307a6e3264385a5130705a6d44356f4a50396e3236764133635144387379586d6835377475626452783165425976764b6b756952746b79544e350a58477552522f7051706c5a3838646b6a4f44753959626332697a723433564b6b72496943624d584f707770456355316d61662f7256706b3d' - cid = '198a41ff-a10f-4cda-a2f3-a9ca80c0703b' - fp = '6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed' + secret_key = 'AFD16D89150FD7FB19EE9E936DC1AE3547CE119B' + encrypted_payload = 'dfcc35bc71653771d4541f08937c35cbc98faea2c061ff7904f80abf7c072f0029157ed97a55b00efe09fb0d2f86f5693ecbba3f6339862ed3908f0d746533133c8c838be641dad76cf3f9cce67dc1b48cbc8574f24637be4aa90f802ec4b7e5d50b5f9cb3d64e6887ef99b8b941e69370ac7994ccafaf17ceff1d7a68ac30e4b0fe4eb1b844460d5f7687f16902cea61d0ccc085f7ea6087fae38482cd1ee1c7574dc4b0e996bc4e5946eeb8e8509fbdd9f1884eb3f02cbbaefe4566c999d50' + cid = '12946065-65af-4825-9893-fce901c8da49' + fp = '9a6e6a7d636ca772924bd2219853d73c.24700f9f1986800ab4fcc880530dd0ed' result = EncryptionUtils.decrypt(encrypted_payload, secret_key) diff --git a/spec/spec_event_manager.rb b/spec/spec_event_manager.rb index 3b842a9..c9f59bd 100644 --- a/spec/spec_event_manager.rb +++ b/spec/spec_event_manager.rb @@ -26,14 +26,13 @@ def initialize options = ConfigurationBuilder.new(api_key: 'YOUR_API_KEY', api_url: 'https://api.securenative-stg.com/collector/api/v1') event = SampleEvent.new - res_body = '{"data": true}' - stub_request(:any, 'http://api.securenative-stg.com:443/collector/api/v1/some-path/to-api') + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api') .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'YOUR_API_KEY', 'Content-Type' => 'application/json', - 'Sn-Version' => '0.1.19', + 'Sn-Version' => '0.1.21', 'User-Agent' => 'SecureNative-ruby' }).to_return(status: 200, body: '', headers: {}) event_manager = EventManager.new(options) @@ -49,13 +48,13 @@ def initialize options = ConfigurationBuilder.new(api_key: 'YOUR_API_KEY', api_url: 'https://api.securenative-stg.com/collector/api/v1') event = SampleEvent.new - stub_request(:any, 'http://api.securenative-stg.com:443/collector/api/v1/some-path/to-api') + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api') .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'YOUR_API_KEY', 'Content-Type' => 'application/json', - 'Sn-Version' => '0.1.19', + 'Sn-Version' => '0.1.21', 'User-Agent' => 'SecureNative-ruby' }).to_return(status: 401, body: '', headers: {}) @@ -69,13 +68,13 @@ def initialize options = ConfigurationBuilder.new(api_key: 'YOUR_API_KEY', api_url: 'https://api.securenative-stg.com/collector/api/v1') event = SampleEvent.new - stub_request(:post, 'http://api.securenative-stg.com:443/collector/api/v1/some-path/to-api') + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api') .with(headers: { 'Accept' => '*/*', 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Authorization' => 'YOUR_API_KEY', 'Content-Type' => 'application/json', - 'Sn-Version' => '0.1.19', + 'Sn-Version' => '0.1.21', 'User-Agent' => 'SecureNative-ruby' }).to_return(status: 500, body: '', headers: {}) event_manager = EventManager.new(options) diff --git a/spec/spec_securenative_http_client.rb b/spec/spec_securenative_http_client.rb index 0502d9f..1cf9535 100644 --- a/spec/spec_securenative_http_client.rb +++ b/spec/spec_securenative_http_client.rb @@ -9,17 +9,16 @@ it 'makes a simple post call' do options = ConfigurationBuilder.new(api_key: 'YOUR_API_KEY', api_url: 'https://api.securenative-stg.com/collector/api/v1') - stub_request(:post, 'http://api.securenative-stg.com:443/collector/api/v1/track') - .with(body: '"{\\"event\\": \\"SOME_EVENT_NAME\\"}"', + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track') + .with(body: '{"event": "SOME_EVENT_NAME"}', headers: { - 'Accept': '*/*', - 'Accept-Encoding': 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - 'Authorization': 'YOUR_API_KEY', - 'Content-Type': 'application/json', - 'Sn-Version': '0.1.19', - 'User-Agent': 'SecureNative-ruby' - }) - .to_return(status: 200, body: '', headers: {}) + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'Authorization' => 'YOUR_API_KEY', + 'Content-Type' => 'application/json', + 'Sn-Version' => '0.1.21', + 'User-Agent' => 'SecureNative-ruby' + }).to_return(status: 200, body: '', headers: {}) client = SecureNativeHttpClient.new(options) payload = '{"event": "SOME_EVENT_NAME"}' diff --git a/spec/spec_version_util.rb b/spec/spec_version_util.rb new file mode 100644 index 0000000..db4145a --- /dev/null +++ b/spec/spec_version_util.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'utils/version_utils' +require 'rspec' + +RSpec.describe VersionUtils do + it 'checks that parsing version is valid' do + expect(VersionUtils.version).not_to eq('unknown') + end +end