From dec339d6a69419728aed0552fb881bcd51a1a021 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Tue, 16 Jun 2020 10:28:55 +0300 Subject: [PATCH 01/32] Restructure project, add config, context, enums and exceptions --- lib/securenative/config.rb | 11 --- .../config/configuration_builder.rb | 71 +++++++++++++++ .../config/configuration_manager.rb | 60 +++++++++++++ .../config/securenative_options.rb | 18 ++++ lib/securenative/context/context_builder.rb | 52 +++++++++++ .../context/securenative_context.rb | 14 +++ lib/securenative/enums/api_route.rb | 4 + .../{event_type.rb => enums/event_types.rb} | 8 +- lib/securenative/enums/failover_strategy.rb | 4 + lib/securenative/enums/risk_level.rb | 5 ++ lib/securenative/event_options.rb | 88 ------------------- .../securenative_config_exception.rb | 2 + .../exceptions/securenative_http_exception.rb | 2 + .../securenative_invalid_options_exception.rb | 2 + .../securenative_invalid_uri_exception.rb | 2 + .../securenative_parse_exception.rb | 2 + ...ecurenative_sdk_Illegal_state_exception.rb | 2 + .../exceptions/securenative_sdk_exception.rb | 2 + lib/securenative/http_client.rb | 20 ----- lib/securenative/secure_native_sdk.rb | 78 ---------------- lib/{ => securenative}/securenative.rb | 0 lib/securenative/securenative_options.rb | 19 ---- lib/securenative/sn_exception.rb | 5 -- lib/securenative/utils.rb | 74 ---------------- 24 files changed, 246 insertions(+), 299 deletions(-) delete mode 100644 lib/securenative/config.rb create mode 100644 lib/securenative/config/configuration_builder.rb create mode 100644 lib/securenative/config/configuration_manager.rb create mode 100644 lib/securenative/config/securenative_options.rb create mode 100644 lib/securenative/context/context_builder.rb create mode 100644 lib/securenative/context/securenative_context.rb create mode 100644 lib/securenative/enums/api_route.rb rename lib/securenative/{event_type.rb => enums/event_types.rb} (78%) create mode 100644 lib/securenative/enums/failover_strategy.rb create mode 100644 lib/securenative/enums/risk_level.rb delete mode 100644 lib/securenative/event_options.rb create mode 100644 lib/securenative/exceptions/securenative_config_exception.rb create mode 100644 lib/securenative/exceptions/securenative_http_exception.rb create mode 100644 lib/securenative/exceptions/securenative_invalid_options_exception.rb create mode 100644 lib/securenative/exceptions/securenative_invalid_uri_exception.rb create mode 100644 lib/securenative/exceptions/securenative_parse_exception.rb create mode 100644 lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb create mode 100644 lib/securenative/exceptions/securenative_sdk_exception.rb delete mode 100644 lib/securenative/http_client.rb delete mode 100644 lib/securenative/secure_native_sdk.rb rename lib/{ => securenative}/securenative.rb (100%) delete mode 100644 lib/securenative/securenative_options.rb delete mode 100644 lib/securenative/sn_exception.rb delete mode 100644 lib/securenative/utils.rb diff --git a/lib/securenative/config.rb b/lib/securenative/config.rb deleted file mode 100644 index 2a02d27..0000000 --- a/lib/securenative/config.rb +++ /dev/null @@ -1,11 +0,0 @@ -module Config - SDK_VERSION = '0.1.5' - MAX_ALLOWED_PARAMS = 6 - API_URL_PROD = "https://api.securenative.com/collector/api/v1" - API_URL_STG = "https://api.securenative-stg.com/collector/api/v1" - TRACK_EVENT = "/track" - VERIFY_EVENT = "/verify" - FLOW_EVENT = "/flow" - CIPHER_SIZE = 256 - AES_BLOCK_SIZE = 32 -end \ No newline at end of file diff --git a/lib/securenative/config/configuration_builder.rb b/lib/securenative/config/configuration_builder.rb new file mode 100644 index 0000000..f7a0486 --- /dev/null +++ b/lib/securenative/config/configuration_builder.rb @@ -0,0 +1,71 @@ +class ConfigurationBuilder + def initialize + @api_key = nil + @api_url = "https://api.securenative.com/collector/api/v1" + @interval = 1000 + @max_events = 1000 + @timeout = 1500 + @auto_send = true + @disable = false + @log_level = "CRITICAL" # TODO implement ruby logger + @fail_over_strategy = FailOverStrategy::FAIL_OPEN + end + + def self.default_config_builder + return ConfigurationBuilder() + end + + def with_api_key(api_key) + @api_key = api_key + self + end + + def with_api_url(api_url) + @api_url = api_url + self + end + + def with_interval(interval) + @interval = interval + self + end + + def with_max_events(max_events) + @max_events = max_events + self + end + + def with_timeout(timeout) + @timeout = timeout + self + end + + def with_auto_send(auto_send) + @auto_send = auto_send + self + end + + def with_disable(disable) + @disable = disable + self + end + + def with_log_level(log_level) + @log_level = log_level + self + end + + def with_fail_over_strategy(fail_over_strategy) + if fail_over_strategy != FailOverStrategy::FAIL_OPEN && fail_over_strategy != FailOverStrategy::FAIL_CLOSED + @fail_over_strategy = FailOverStrategy::FAIL_OPEN + self + else + @fail_over_strategy = fail_over_strategy + self + end + end + + def self.default_securenative_options + return SecureNativeOptions() + end +end \ No newline at end of file diff --git a/lib/securenative/config/configuration_manager.rb b/lib/securenative/config/configuration_manager.rb new file mode 100644 index 0000000..61fc2b2 --- /dev/null +++ b/lib/securenative/config/configuration_manager.rb @@ -0,0 +1,60 @@ +require "parseconfig" + +class ConfigurationManager + DEFAULT_CONFIG_FILE = "securenative.cfg" + CUSTOM_CONFIG_FILE_ENV_NAME = "SECURENATIVE_COMFIG_FILE" + @config = nil + + def self.read_resource_file(resource_path) + @config = ParseConfig.new(resource_path) + + properties = {} + @config.get_groups.each { |group| + group.each do |key, value| + properties[key.upcase] = value + end + } + return properties + end + + def self._get_resource_path(env_name) + return Env.fetch(env_name, ENV[DEFAULT_CONFIG_FILE]) + end + + def self.config_builder + return ConfigurationBuilder.default_config_builder + end + + def self._get_env_or_default(properties, key, default) + if Env[key] + return Env[key] + end + + if properties[key] + return properties[key] + end + return default + end + + def self.load_config + options = ConfigurationBuilder().default_securenative_options + + resource_path = DEFAULT_CONFIG_FILE + if Env[CUSTOM_CONFIG_FILE_ENV_NAME] + resource_path = Env[CUSTOM_CONFIG_FILE_ENV_NAME] + end + + properties = read_resource_file(resource_path) + + return ConfigurationBuilder() + .with_api_key(_get_env_or_default(properties, "SECURENATIVE_API_KEY", options.api_key)) + .with_api_url(_get_env_or_default(properties, "SECURENATIVE_API_URL", options.api_url)) + .with_interval(_get_env_or_default(properties, "SECURENATIVE_INTERVAL", options.interval)) + .with_max_events(_get_env_or_default(properties, "SECURENATIVE_MAX_EVENTS", options.max_events)) + .with_timeout(_get_env_or_default(properties, "SECURENATIVE_TIMEOUT", options.timeout)) + .with_auto_send(_get_env_or_default(properties, "SECURENATIVE_AUTO_SEND", options.auto_send)) + .with_disable(_get_env_or_default(properties, "SECURENATIVE_DISABLE", options.disable)) + .with_log_level(_get_env_or_default(properties, "SECURENATIVE_LOG_LEVEL", options.log_level)) + .with_fail_over_strategy(_get_env_or_default(properties, "SECURENATIVE_FAILOVER_STRATEGY", options.fail_over_strategy)) + end +end \ No newline at end of file diff --git a/lib/securenative/config/securenative_options.rb b/lib/securenative/config/securenative_options.rb new file mode 100644 index 0000000..9fe0730 --- /dev/null +++ b/lib/securenative/config/securenative_options.rb @@ -0,0 +1,18 @@ +class SecureNativeOptions + attr_reader :api_key, :api_url, :interval, :max_events, :timeout, :auto_send, :disable, :log_level, :fail_over_strategy + attr_writer :api_key, :api_url, :interval, :max_events, :timeout, :auto_send, :disable, :log_level, :fail_over_strategy + + def initialize(api_key = nil, api_url = "https://api.securenative.com/collector/api/v1", interval = 1000, + max_events = 1000, timeout = 1500, auto_send = true, disable = false, log_level = "CRITICAL", + fail_over_strategy = FailOverStrategy::FAIL_OPEN) + @api_key = api_key + @api_url = api_url + @interval = interval + @max_events = max_events + @timeout = timeout + @auto_send = auto_send + @disable = disable + @log_level = log_level + @fail_over_strategy = fail_over_strategy + end +end \ No newline at end of file diff --git a/lib/securenative/context/context_builder.rb b/lib/securenative/context/context_builder.rb new file mode 100644 index 0000000..59196a5 --- /dev/null +++ b/lib/securenative/context/context_builder.rb @@ -0,0 +1,52 @@ +class ContextBuilder + def initialize + @context = SecureNativeContext() + end + + def with_client_token(client_token) + @context.client_token = client_token + self + end + + def with_ip(ip) + @context.ip = ip + self + end + + def with_remote_ip(remote_ip) + @context.remote_ip = remote_ip + self + end + + def with_headers(headers) + @context.headers = headers + self + end + + def with_url(url) + @context.url = url + self + end + + def with_method(method) + @context.method = method + self + end + + def with_body(body) + @context.body = body + self + end + + def self.default_context_builder + return ContextBuilder() + end + + def self.from_http_request(request) + # TODO implement me + end + + def build + @context + end +end \ No newline at end of file diff --git a/lib/securenative/context/securenative_context.rb b/lib/securenative/context/securenative_context.rb new file mode 100644 index 0000000..efb2a46 --- /dev/null +++ b/lib/securenative/context/securenative_context.rb @@ -0,0 +1,14 @@ +class SecureNativeContext + attr_reader :client_token, :ip, :remote_ip, :headers, :url, :method, :body + attr_writer :client_token, :ip, :remote_ip, :headers, :url, :method, :body + + def initialize(client_token = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil, body = nil) + @client_token = client_token + @ip = ip + @remote_ip = remote_ip + @headers = headers + @url = url + @method = method + @body = body + end +end \ No newline at end of file diff --git a/lib/securenative/enums/api_route.rb b/lib/securenative/enums/api_route.rb new file mode 100644 index 0000000..a2c2278 --- /dev/null +++ b/lib/securenative/enums/api_route.rb @@ -0,0 +1,4 @@ +module ApiRoute + TRACK = "track" + VERIFY = "verify" +end \ No newline at end of file diff --git a/lib/securenative/event_type.rb b/lib/securenative/enums/event_types.rb similarity index 78% rename from lib/securenative/event_type.rb rename to lib/securenative/enums/event_types.rb index 8749bdf..f097e90 100644 --- a/lib/securenative/event_type.rb +++ b/lib/securenative/enums/event_types.rb @@ -1,4 +1,4 @@ -module EventType +module EventTypes LOG_IN = "sn.user.login" LOG_IN_CHALLENGE = "sn.user.login.challenge" LOG_IN_FAILURE = "sn.user.login.failure" @@ -9,10 +9,10 @@ module EventType AUTH_CHALLENGE_FAILURE = "sn.user.auth.challenge.failure" TWO_FACTOR_DISABLE = "sn.user.2fa.disable" EMAIL_UPDATE = "sn.user.email.update" - PASSWORD_RESET = "sn.user.password.reset" - PASSWORD_RESET_SUCCESS = "sn.user.password.reset.success" + PASSWORD_REST = "sn.user.password.reset" + PASSWORD_REST_SUCCESS = "sn.user.password.reset.success" PASSWORD_UPDATE = "sn.user.password.update" - PASSWORD_RESET_FAILURE = "sn.user.password.reset.failure" + PASSWORD_REST_FAILURE = "sn.user.password.reset.failure" USER_INVITE = "sn.user.invite" ROLE_UPDATE = "sn.user.role.update" PROFILE_UPDATE = "sn.user.profile.update" diff --git a/lib/securenative/enums/failover_strategy.rb b/lib/securenative/enums/failover_strategy.rb new file mode 100644 index 0000000..318cb19 --- /dev/null +++ b/lib/securenative/enums/failover_strategy.rb @@ -0,0 +1,4 @@ +module FailOverStrategy + FAIL_OPEN = "fail-open" + FAIL_CLOSED = "fail-closed" +end \ No newline at end of file diff --git a/lib/securenative/enums/risk_level.rb b/lib/securenative/enums/risk_level.rb new file mode 100644 index 0000000..8e2d30b --- /dev/null +++ b/lib/securenative/enums/risk_level.rb @@ -0,0 +1,5 @@ +module RiskLevel + LOW = "low" + MEDIUM = "medium" + HIGH = "high" +end \ No newline at end of file diff --git a/lib/securenative/event_options.rb b/lib/securenative/event_options.rb deleted file mode 100644 index 0896e8d..0000000 --- a/lib/securenative/event_options.rb +++ /dev/null @@ -1,88 +0,0 @@ -require 'securerandom' - -class User - def initialize(user_id: "", user_email: "", user_name: "") - @user_id = user_id - @user_email = user_email - @user_name = user_name - end - - attr_reader :user_id - attr_reader :user_email - attr_reader :user_name -end - -class Event - def initialize(event_type, user: User(), ip: "127.0.0.1", remote_ip: "127.0.0.1", user_agent: "unknown", sn_cookie: nil, params: nil) - @event_type = event_type - @user = user - @ip = ip - @remote_ip = remote_ip - @user_agent = user_agent - @cid = "" - @fp = "" - - if params != nil - if params.instance_of?(CustomParam) - raise ArgumentError.new("custom params should be a list of CustomParams") - else - @params = params - end - end - @params = params - - if sn_cookie - @cid, @cid = Utils.parse_cookie(sn_cookie) - end - @vid = SecureRandom.uuid - @ts = Time.now.getutc.to_i - end - - def to_hash - p = Array.new - if @params - @params.each do |param| - p << {:key => param.key, :value => param.value} - end - end - - { - :eventType => @event_type, - :user => { - :id => @user.user_id, - :email => @user.user_email, - :name => @user.user_name - }, - :remoteIP => @remote_ip, - :ip => @ip, - :cid => @cid, - :fp => @fp, - :ts => @ts, - :vid => @vid, - :userAgent => @user_agent, - :device => Hash.new, - :params => p - } - end - - attr_reader :cid - attr_reader :params - attr_reader :user_agent - attr_reader :user - attr_reader :remote_ip - attr_reader :event_type - attr_reader :fp - attr_reader :ip - attr_reader :ts - attr_reader :vid -end - -class CustomParam - def initialize(key, value) - @key = key - @value = value - end - - attr_reader :key - attr_reader :value -end diff --git a/lib/securenative/exceptions/securenative_config_exception.rb b/lib/securenative/exceptions/securenative_config_exception.rb new file mode 100644 index 0000000..1c6bb67 --- /dev/null +++ b/lib/securenative/exceptions/securenative_config_exception.rb @@ -0,0 +1,2 @@ +class SecureNativeConfigException < StandardError +end \ No newline at end of file diff --git a/lib/securenative/exceptions/securenative_http_exception.rb b/lib/securenative/exceptions/securenative_http_exception.rb new file mode 100644 index 0000000..85314aa --- /dev/null +++ b/lib/securenative/exceptions/securenative_http_exception.rb @@ -0,0 +1,2 @@ +class SecureNativeHttpException < StandardError +end \ No newline at end of file diff --git a/lib/securenative/exceptions/securenative_invalid_options_exception.rb b/lib/securenative/exceptions/securenative_invalid_options_exception.rb new file mode 100644 index 0000000..6b8be6d --- /dev/null +++ b/lib/securenative/exceptions/securenative_invalid_options_exception.rb @@ -0,0 +1,2 @@ +class SecureNativeInvalidOptionsException < StandardError +end \ No newline at end of file diff --git a/lib/securenative/exceptions/securenative_invalid_uri_exception.rb b/lib/securenative/exceptions/securenative_invalid_uri_exception.rb new file mode 100644 index 0000000..68b722b --- /dev/null +++ b/lib/securenative/exceptions/securenative_invalid_uri_exception.rb @@ -0,0 +1,2 @@ +class SecureNativeInvalidUriException < StandardError +end \ No newline at end of file diff --git a/lib/securenative/exceptions/securenative_parse_exception.rb b/lib/securenative/exceptions/securenative_parse_exception.rb new file mode 100644 index 0000000..ce65aee --- /dev/null +++ b/lib/securenative/exceptions/securenative_parse_exception.rb @@ -0,0 +1,2 @@ +class SecureNativeParseException < StandardError +end \ No newline at end of file diff --git a/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb b/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb new file mode 100644 index 0000000..536ef7e --- /dev/null +++ b/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb @@ -0,0 +1,2 @@ +class SecureNativeSDKIllegalStateException < StandardError +end \ No newline at end of file diff --git a/lib/securenative/exceptions/securenative_sdk_exception.rb b/lib/securenative/exceptions/securenative_sdk_exception.rb new file mode 100644 index 0000000..02412f5 --- /dev/null +++ b/lib/securenative/exceptions/securenative_sdk_exception.rb @@ -0,0 +1,2 @@ +class SecureNativeSDKException < StandardError +end \ No newline at end of file diff --git a/lib/securenative/http_client.rb b/lib/securenative/http_client.rb deleted file mode 100644 index bf28c92..0000000 --- a/lib/securenative/http_client.rb +++ /dev/null @@ -1,20 +0,0 @@ -require 'httpclient' - -class HttpClient - def initialize - @client = HTTPClient.new - end - - def headers(api_key) - { - "Content-Type" => 'application/json', - "User-Agent" => 'SecureNative-ruby', - "Sn-Version" => Config::SDK_VERSION, - "Authorization" => api_key - } - end - - def post(url, api_key, body) - @client.post(url, body, self.headers(api_key)) - end -end \ No newline at end of file diff --git a/lib/securenative/secure_native_sdk.rb b/lib/securenative/secure_native_sdk.rb deleted file mode 100644 index 48bb924..0000000 --- a/lib/securenative/secure_native_sdk.rb +++ /dev/null @@ -1,78 +0,0 @@ -require_relative 'event_manager' -require_relative 'config' -require_relative 'sn_exception' -require_relative 'utils' -require 'json' -require 'logger' - -class SecureNativeSDK - def initialize(api_key, options: SecureNativeOptions.new) - if api_key == nil - raise SecureNativeSDKException.new - end - - if options.debug - @logger = Logger.new(STDOUT) - @logger.level = Logger::INFO - @logger.info("sn logging was activated") - end - - @api_key = api_key - @options = options - @event_manager = EventManager.new(@api_key, options: @options) - end - - def api_key - @api_key - end - - def version - Config::SDK_VERSION - end - - def track(event) - if @options.debug - @logger.info("Track event was called") - end - validate_event(event) - @event_manager.send_async(event, Config::TRACK_EVENT) - end - - def verify(event) - if @options.debug - @logger.info("Verify event was called") - end - validate_event(event) - res = @event_manager.send_sync(event, Config::VERIFY_EVENT) - if res.status_code == 200 - return JSON.parse(res.body) - end - nil - end - - def flow(event) # Note: For future purposes - validate_event(event) - @event_manager.send_async(event, Config::FLOW_EVENT) - end - - def verify_webhook(hmac_header, body) - if @options.debug - @logger.info("Verify webhook was called") - end - Utils.verify_signature(@api_key, body, hmac_header) - end - - def flush - @event_manager.flush - end - - private - - def validate_event(event) - unless event.params.nil? - if event.params.length > Config::MAX_ALLOWED_PARAMS - event.params = event.params[0, Config::MAX_ALLOWED_PARAMS] - end - end - end -end \ No newline at end of file diff --git a/lib/securenative.rb b/lib/securenative/securenative.rb similarity index 100% rename from lib/securenative.rb rename to lib/securenative/securenative.rb diff --git a/lib/securenative/securenative_options.rb b/lib/securenative/securenative_options.rb deleted file mode 100644 index 7af850a..0000000 --- a/lib/securenative/securenative_options.rb +++ /dev/null @@ -1,19 +0,0 @@ -require_relative 'config' - -class SecureNativeOptions - def initialize(api_url: Config::API_URL_PROD, interval: 1000, max_events: 1000, timeout: 1500, auto_send: true, debug: false) - @timeout = timeout - @max_events = max_events - @api_url = api_url - @interval = interval - @auto_send = auto_send - @debug = debug - end - - attr_reader :timeout - attr_reader :max_events - attr_reader :api_url - attr_reader :interval - attr_reader :auto_send - attr_reader :debug -end \ No newline at end of file diff --git a/lib/securenative/sn_exception.rb b/lib/securenative/sn_exception.rb deleted file mode 100644 index bfa85e1..0000000 --- a/lib/securenative/sn_exception.rb +++ /dev/null @@ -1,5 +0,0 @@ -class SecureNativeSDKException < StandardError - def initialize(msg: "API key cannot be nil, please get your API key from SecureNative console") - super - end -end \ No newline at end of file diff --git a/lib/securenative/utils.rb b/lib/securenative/utils.rb deleted file mode 100644 index 229894b..0000000 --- a/lib/securenative/utils.rb +++ /dev/null @@ -1,74 +0,0 @@ -require_relative 'config' -require "logger" -require "base64" -require "json" -require 'openssl' - - -module Utils - def self.verify_signature(secret, text_body, header_signature) - begin - key = secret.encode('utf-8') - body = text_body.encode('utf-8') - calculated_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha512'), key, body) - calculated_signature.eql? header_signature - rescue Exception - return false - end - end - - def self.parse_cookie(cookie = nil) - fp = "" - cid = "" - unless cookie - return fp, cid - end - - begin - decoded_cookie = Base64.decode64(cookie) - unless decoded_cookie - decoded_cookie = "{}" - end - jsonified = JSON.generate(decoded_cookie) - if jsonified["fp"] - fp = jsonified["fp"] - end - if jsonified["cid"] - cid = jsonified["cid"] - end - rescue Exception - ensure - return fp, cid - end - end - - def self.encrypt(plain_text, key) - cipher = OpenSSL::Cipher::AES.new(Config::CIPHER_SIZE, :CBC).encrypt - cipher.padding = 0 - - if plain_text.size % Config::AES_BLOCK_SIZE != 0 - logger = Logger.new(STDOUT) - logger.level = Logger::WARN - logger.fatal("data not multiple of block length") - return nil - end - - key = Digest::SHA1.hexdigest key - cipher.key = key.slice(0, Config::AES_BLOCK_SIZE) - s = cipher.update(plain_text) + cipher.final - - s.unpack('H*')[0].upcase - end - - def self.decrypt(encrypted, key) - cipher = OpenSSL::Cipher::AES.new(Config::CIPHER_SIZE, :CBC).decrypt - cipher.padding = 0 - - key = Digest::SHA1.hexdigest key - cipher.key = key.slice(0, Config::AES_BLOCK_SIZE) - s = [encrypted].pack("H*").unpack("C*").pack("c*") - - rv = cipher.update(s) + cipher.final - return rv.strip - end -end \ No newline at end of file From 41154b19a2bb1f7cdb8cf2e35a7d212bb965d904 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Tue, 16 Jun 2020 12:04:35 +0300 Subject: [PATCH 02/32] Bump and clean versions --- Gemfile | 3 ++- Gemfile.lock | 4 +++- VERSION | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 VERSION diff --git a/Gemfile b/Gemfile index 5914d4b..bf81fcf 100644 --- a/Gemfile +++ b/Gemfile @@ -3,4 +3,5 @@ source "https://rubygems.org" gemspec gem "rspec" gem "rake" -gem "httpclient" \ No newline at end of file +gem "httpclient" +gem "parseconfig" \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 4ee5fa5..0acf5f8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,14 @@ PATH remote: . specs: - securenative (0.1.5) + securenative (0.1.16) GEM remote: https://rubygems.org/ specs: diff-lcs (1.3) httpclient (2.8.3) + parseconfig (1.0.8) rake (12.3.3) rspec (3.8.0) rspec-core (~> 3.8.0) @@ -29,6 +30,7 @@ PLATFORMS DEPENDENCIES bundler (~> 2.0) httpclient + parseconfig rake rspec securenative! diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..99a25fc --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.16 \ No newline at end of file From 8850ec561dc4bc5e31804770c0ae52ba29bb8b57 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Tue, 16 Jun 2020 12:04:57 +0300 Subject: [PATCH 03/32] Add http client, models and some utils --- lib/securenative/http/http_response.rb | 10 +++ .../http/securenative_http_client.rb | 30 ++++++++ lib/securenative/models/client_token.rb | 10 +++ lib/securenative/models/device.rb | 8 ++ lib/securenative/models/event_options.rb | 13 ++++ lib/securenative/models/request_context.rb | 75 +++++++++++++++++++ lib/securenative/models/request_options.rb | 10 +++ lib/securenative/models/sdk_event.rb | 32 ++++++++ lib/securenative/models/user_traits.rb | 10 +++ lib/securenative/models/verify_result.rb | 10 +++ lib/securenative/utils/date_utils.rb | 8 ++ lib/securenative/utils/encryption_utils.rb | 36 +++++++++ lib/securenative/utils/ip_utils.rb | 16 ++++ lib/securenative/utils/request_utils.rb | 16 ++++ lib/securenative/utils/signature_utils.rb | 14 ++++ lib/securenative/utils/utils.rb | 11 +++ lib/securenative/utils/version_utils.rb | 10 +++ 17 files changed, 319 insertions(+) create mode 100644 lib/securenative/http/http_response.rb create mode 100644 lib/securenative/http/securenative_http_client.rb create mode 100644 lib/securenative/models/client_token.rb create mode 100644 lib/securenative/models/device.rb create mode 100644 lib/securenative/models/event_options.rb create mode 100644 lib/securenative/models/request_context.rb create mode 100644 lib/securenative/models/request_options.rb create mode 100644 lib/securenative/models/sdk_event.rb create mode 100644 lib/securenative/models/user_traits.rb create mode 100644 lib/securenative/models/verify_result.rb create mode 100644 lib/securenative/utils/date_utils.rb create mode 100644 lib/securenative/utils/encryption_utils.rb create mode 100644 lib/securenative/utils/ip_utils.rb create mode 100644 lib/securenative/utils/request_utils.rb create mode 100644 lib/securenative/utils/signature_utils.rb create mode 100644 lib/securenative/utils/utils.rb create mode 100644 lib/securenative/utils/version_utils.rb diff --git a/lib/securenative/http/http_response.rb b/lib/securenative/http/http_response.rb new file mode 100644 index 0000000..27541aa --- /dev/null +++ b/lib/securenative/http/http_response.rb @@ -0,0 +1,10 @@ +class HttpResponse + attr_reader :ok, :status_code, :body + attr_writer :ok, :status_code, :body + + def initialize(ok, status_code, body) + @ok = ok + @status_code = status_code + @body = body + end +end \ No newline at end of file diff --git a/lib/securenative/http/securenative_http_client.rb b/lib/securenative/http/securenative_http_client.rb new file mode 100644 index 0000000..f1a787b --- /dev/null +++ b/lib/securenative/http/securenative_http_client.rb @@ -0,0 +1,30 @@ +require "httpclient" + +class SecureNativeHttpClient + AUTHORIZATION_HEADER = "Authorization" + VERSION_HEADER = "SN-Version" + USER_AGENT_HEADER = "User-Agent" + USER_AGENT_HEADER_VALUE = "SecureNative-python" + CONTENT_TYPE_HEADER = "Content-Type" + CONTENT_TYPE_HEADER_VALUE = "application/json" + + def __init__(securenative_options) + @options = securenative_options + @client = HTTPClient.new + end + + def _headers + { + CONTENT_TYPE_HEADER => CONTENT_TYPE_HEADER_VALUE, + USER_AGENT_HEADER => USER_AGENT_HEADER_VALUE, + VERSION_HEADER => VersionUtils.get_version, + AUTHORIZATION_HEADER => options.api_key + } + end + + def post(path, body) + url = "{}/{}".format(@options.api_url, path) + headers = _headers + @client.post(url, body, headers) + end +end \ No newline at end of file diff --git a/lib/securenative/models/client_token.rb b/lib/securenative/models/client_token.rb new file mode 100644 index 0000000..8f3c9dd --- /dev/null +++ b/lib/securenative/models/client_token.rb @@ -0,0 +1,10 @@ +class ClientToken + attr_reader :cid, :vid, :fp + attr_writer :cid, :vid, :fp + + def initialize(cid, vid, fp) + @cid = cid + @vid = vid + @fp = fp + end +end diff --git a/lib/securenative/models/device.rb b/lib/securenative/models/device.rb new file mode 100644 index 0000000..5ce321d --- /dev/null +++ b/lib/securenative/models/device.rb @@ -0,0 +1,8 @@ +class Device + attr_reader :device_id + attr_writer :device_id + + def initialize(device_id) + @device_id = device_id + end +end \ No newline at end of file diff --git a/lib/securenative/models/event_options.rb b/lib/securenative/models/event_options.rb new file mode 100644 index 0000000..fb8569b --- /dev/null +++ b/lib/securenative/models/event_options.rb @@ -0,0 +1,13 @@ +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, user_id = nil, user_traits = nil, context = nil, properties = nil, timestamp = nil) + @event = event + @user_id = user_id + @user_traits = user_traits + @context = context + @properties = properties + @timestamp = timestamp + end +end \ No newline at end of file diff --git a/lib/securenative/models/request_context.rb b/lib/securenative/models/request_context.rb new file mode 100644 index 0000000..0c3a421 --- /dev/null +++ b/lib/securenative/models/request_context.rb @@ -0,0 +1,75 @@ +class RequestContext + attr_reader :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method + attr_writer :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method + + def initialize(cid = nil, vid = nil, fp = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil) + @cid = cid + @vid = vid + @fp = fp + @ip = ip + @remote_ip = remote_ip + @headers = headers + @url = url + @method = method + end +end + +class RequestContextBuilder + attr_reader :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method + attr_writer :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method + + def initialize(cid = nil, vid = nil, fp = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil) + @cid = cid + @vid = vid + @fp = fp + @ip = ip + @remote_ip = remote_ip + @headers = headers + @url = url + @method = method + end + + def with_cid(cid) + @cid = cid + self + end + + def with_vid(vid) + @vid = vid + self + end + + def with_fp(fp) + @fp = fp + self + end + + def with_ip(ip) + @ip = ip + self + end + + def with_remote_ip(remote_ip) + @remote_ip = remote_ip + self + end + + def with_headers(headers) + @headers = headers + self + end + + def with_url(url) + @url = url + self + end + + def with_method(method) + @method = method + self + end + + def build + RequestContext(@cid, @vid, @fp, @ip, @remote_ip, @headers, @url, @method) + end +end diff --git a/lib/securenative/models/request_options.rb b/lib/securenative/models/request_options.rb new file mode 100644 index 0000000..fc1d47c --- /dev/null +++ b/lib/securenative/models/request_options.rb @@ -0,0 +1,10 @@ +class RequestOptions + attr_reader :url, :body, :retry + attr_writer :url, :body, :retry + + def initialize(url, body, _retry) + @url = url + @body = body + @retry = _retry + end +end \ No newline at end of file diff --git a/lib/securenative/models/sdk_event.rb b/lib/securenative/models/sdk_event.rb new file mode 100644 index 0000000..47f8447 --- /dev/null +++ b/lib/securenative/models/sdk_event.rb @@ -0,0 +1,32 @@ +class SdkEvent + attr_reader :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties + attr_writer :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties + + def initialize(event_options, securenative_options) + if !event_options.context.nil? + @context = event_options.context + else + @context = ContextBuilder.default_context_builder.build + end + + client_token = EncryptionUtils.decrypt(@context.client_token, securenative_options.api_key) + + @rid = SecureRandom.uuid.to_str + @event_type = event_options.event + @user_id = event_options.user_id + @user_traits = event_options.user_traits + @request = RequestContextBuilder() + .with_cid(client_token ? client_token.cid : "") + .with_vid(client_token ? client_token.vid : "") + .with_fp(client_token ? client_token.fp : "") + .with_ip(@context.ip) + .with_remote_ip(@context.remote_ip) + .with_method(@context.method) + .with_url(@context.url) + .with_headers(@context.headers) + .build + + @timestamp = DateUtils.to_timestamp(event_options.timestamp) + @properties = event_options.properties + end +end \ No newline at end of file diff --git a/lib/securenative/models/user_traits.rb b/lib/securenative/models/user_traits.rb new file mode 100644 index 0000000..7499e66 --- /dev/null +++ b/lib/securenative/models/user_traits.rb @@ -0,0 +1,10 @@ +class UserTraits + attr_reader :name, :email, :created_at + attr_writer :name, :email, :created_at + + def initialize(name = nil, email = nil, created_at = nil) + @name = name + @email = email + @created_at = created_at + end +end \ No newline at end of file diff --git a/lib/securenative/models/verify_result.rb b/lib/securenative/models/verify_result.rb new file mode 100644 index 0000000..c5e74b0 --- /dev/null +++ b/lib/securenative/models/verify_result.rb @@ -0,0 +1,10 @@ +class VerifyResult + attr_reader :risk_level, :score, :triggers + attr_writer :risk_level, :score, :triggers + + def initialize(risk_level = nil, score = nil, triggers = nil) + @risk_level = risk_level + @score = score + @triggers = triggers + end +end \ No newline at end of file diff --git a/lib/securenative/utils/date_utils.rb b/lib/securenative/utils/date_utils.rb new file mode 100644 index 0000000..c239a2b --- /dev/null +++ b/lib/securenative/utils/date_utils.rb @@ -0,0 +1,8 @@ +class DateUtils + def self.to_timestamp(date) + if date.nil? + return Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z") + end + return Time.strptime(date, "%Y-%m-%dT%H:%M:%S.%L%Z") + end +end \ No newline at end of file diff --git a/lib/securenative/utils/encryption_utils.rb b/lib/securenative/utils/encryption_utils.rb new file mode 100644 index 0000000..7a70279 --- /dev/null +++ b/lib/securenative/utils/encryption_utils.rb @@ -0,0 +1,36 @@ +require "openssl" + +class EncryptionUtils + BLOCK_SIZE = 16 + KEY_SIZE = 32 + + def self.encrypt(text, cipher_key) + cipher = OpenSSL::Cipher::AES.new(KEY_SIZE, :CBC).encrypt + cipher.padding = 0 + + if text.size % BLOCK_SIZE != 0 + logger = Logger.new(STDOUT) + logger.level = Logger::WARN + logger.fatal("data not multiple of block length") + return nil + 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 + end + + def self.decrypt(encrypted, cipher_key) + 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 + return rv.strip + end +end \ No newline at end of file diff --git a/lib/securenative/utils/ip_utils.rb b/lib/securenative/utils/ip_utils.rb new file mode 100644 index 0000000..109afce --- /dev/null +++ b/lib/securenative/utils/ip_utils.rb @@ -0,0 +1,16 @@ +class IpUtils # TODO implement me + VALID_IPV4_PATTERN = ("(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])") + VALID_IPV6_PATTERN = ("([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}") + + def self.is_ip_address(ip_address) + # code here + end + + def self.is_valid_public_ip(ip_address) + # code here + end + + def self.is_loop_back(ip_address) + # code here + end +end \ No newline at end of file diff --git a/lib/securenative/utils/request_utils.rb b/lib/securenative/utils/request_utils.rb new file mode 100644 index 0000000..854fe00 --- /dev/null +++ b/lib/securenative/utils/request_utils.rb @@ -0,0 +1,16 @@ +class RequestUtils # TODO implement me + SECURENATIVE_COOKIE = "_sn" + SECURENATIVE_HEADER = "x-securenative" + + def self.get_secure_header_from_request(headers) + # code here + end + + def self.get_client_ip_from_request(request) + # code here + end + + def self.get_remote_ip_from_request(request) + # code here + end +end \ No newline at end of file diff --git a/lib/securenative/utils/signature_utils.rb b/lib/securenative/utils/signature_utils.rb new file mode 100644 index 0000000..1c538f3 --- /dev/null +++ b/lib/securenative/utils/signature_utils.rb @@ -0,0 +1,14 @@ +require "openssl" + +class SignatureUtils + def self.is_valid_signature(api_key, payload, header_signature) + begin + key = api_key.encode('utf-8') + body = payload.encode('utf-8') + calculated_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha512'), key, body) + calculated_signature.eql? header_signature + rescue Exception + return false + end + end +end \ No newline at end of file diff --git a/lib/securenative/utils/utils.rb b/lib/securenative/utils/utils.rb new file mode 100644 index 0000000..7315da8 --- /dev/null +++ b/lib/securenative/utils/utils.rb @@ -0,0 +1,11 @@ +class Utils + def self.is_null_or_empty(string) + if !string.nil? && !string.empty? + return true + end + unless string.nil? + return true + end + return false + end +end \ No newline at end of file diff --git a/lib/securenative/utils/version_utils.rb b/lib/securenative/utils/version_utils.rb new file mode 100644 index 0000000..c0242ad --- /dev/null +++ b/lib/securenative/utils/version_utils.rb @@ -0,0 +1,10 @@ +class VersionUtils + def self.get_version + path = "VERSION" + file = File.open(path) + version = file.read + file.close + + return version + end +end \ No newline at end of file From 98cafc7c144d8110c0d78016cc490b74f89b7317 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Tue, 16 Jun 2020 13:03:25 +0300 Subject: [PATCH 04/32] Bump and clean versions --- securenative.gemspec | 8 +++--- test/test_event_manager.rb | 57 -------------------------------------- test/test_http_client.rb | 21 -------------- test/test_sdk.rb | 49 -------------------------------- test/test_utils.rb | 48 -------------------------------- 5 files changed, 4 insertions(+), 179 deletions(-) delete mode 100644 test/test_event_manager.rb delete mode 100644 test/test_http_client.rb delete mode 100644 test/test_sdk.rb delete mode 100644 test/test_utils.rb diff --git a/securenative.gemspec b/securenative.gemspec index 769e8ad..f919b70 100644 --- a/securenative.gemspec +++ b/securenative.gemspec @@ -1,14 +1,14 @@ lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require "securenative/config" +require_relative "lib/securenative/utils/version_utils" Gem::Specification.new do |spec| spec.name = "securenative" - spec.version = Config::SDK_VERSION + spec.version = VersionUtils.get_version spec.authors = ["SecureNative"] spec.email = ["support@securenative.com"] - spec.summary = %q{SecureNative SDK for ruby} + spec.summary = %q{SecureNative SDK for Ruby} spec.homepage = "https://www.securenative.com" spec.license = "MIT" @@ -24,5 +24,5 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.add_development_dependency "bundler", "~> 2.0" - spec.add_development_dependency "rake", "~> 10.0" + spec.add_development_dependency "rake", "~> 12.3.3" end diff --git a/test/test_event_manager.rb b/test/test_event_manager.rb deleted file mode 100644 index 7ac6fc7..0000000 --- a/test/test_event_manager.rb +++ /dev/null @@ -1,57 +0,0 @@ -require_relative '../lib/securenative/event_manager' -require_relative '../lib/securenative/securenative_options' -require_relative '../lib/securenative/event_type' -require_relative '../lib/securenative/event_options' -require 'rspec/autorun' -require 'securerandom' - -class MockHttpClient - def post(path, data, _) - { - :path => path, - :data => data, - :headers => { - "Content-Type" => 'application/json', - "User-Agent" => 'SecureNative-ruby', - "Sn-Version" => Config::SDK_VERSION, - "Authorization" => data - } - } - end -end - -def build_event(type = EventType::LOG_IN, id) - Event.new(event_type = type, - user: User.new(user_id: id, user_email: 'support@securenative.com', user_name: 'support'), - params: [CustomParam.new('key', 'val')] - ) -end - -describe EventManager do - let(:api_key) {ENV["SN_API_KEY"]} - let(:event_manager) {EventManager.new(api_key, options: SecureNativeOptions.new, http_client: MockHttpClient.new)} - - it "post a synced request" do - user_id = SecureRandom.uuid - url = "https://postman-echo.com/post" - event = build_event(EventType::LOG_IN, user_id) - item = event_manager.send_async(event, url) - event_manager.flush - - expect(item).to be_instance_of(Thread::Queue) - end - - it "post an a-synced request" do - user_id = SecureRandom.uuid - url = "https://postman-echo.com/post" - event = build_event(EventType::LOG_IN, user_id) - - res = event_manager.send_sync(event, url) - expect(res).not_to be_empty - expect(res[:data]).to eq(api_key) - expect(res[:headers]["Content-Type"]).to eq("application/json") - expect(res[:headers]["User-Agent"]).to eq("SecureNative-ruby") - expect(res[:headers]["Sn-Version"]).to eq(Config::SDK_VERSION) - expect(res[:headers]["Authorization"]).to eq(api_key) - end -end diff --git a/test/test_http_client.rb b/test/test_http_client.rb deleted file mode 100644 index 3529468..0000000 --- a/test/test_http_client.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'rspec/autorun' -require 'json' -require_relative '../lib/securenative/http_client' -require_relative '../lib/securenative/config' - -describe HttpClient do - let(:client) {HttpClient.new} - - it "post a request to postman-echo" do - api_key = "some api key" - url = "https://postman-echo.com/post" - res = client.post(url, api_key, "") - - expect(res.status).to eq(200) - res_body = JSON.parse(res.body) - expect(res_body["headers"]['content-type']).to eq("application/json") - expect(res_body["headers"]['user-agent']).to eq("SecureNative-ruby") - expect(res_body["headers"]['sn-version']).to eq(Config::SDK_VERSION) - expect(res_body["headers"]['authorization']).to eq(api_key) - end -end \ No newline at end of file diff --git a/test/test_sdk.rb b/test/test_sdk.rb deleted file mode 100644 index cf2b88b..0000000 --- a/test/test_sdk.rb +++ /dev/null @@ -1,49 +0,0 @@ -require_relative '../lib/securenative' -require_relative '../lib/securenative/securenative_options' -require_relative '../lib/securenative/event_type' -require_relative '../lib/securenative/event_options' -require 'rspec/autorun' -require 'securerandom' -require 'json' - -def build_event(type = EventType::LOG_IN, id) - Event.new(event_type = type, - user: User.new(user_id: id, user_email: 'support@securenative.com', user_name: 'support'), - params: [CustomParam.new('key', 'val')] - ) -end - -describe SecureNativeSDK do - let(:sn_options) {SecureNativeOptions.new} - let(:sn) {nil} - - it "use sdk without api key" do - api_key = nil - expect {SecureNative.init(api_key, options: sn_options)}.to raise_error(SecureNativeSDKException) - end - - it "check for singleton use" do - sn = SecureNative.init(ENV["SN_API_KEY"], options: sn_options) - expect {sn.init(ENV["SN_API_KEY"], options: sn_options)}.to raise_error(StandardError) - end - - it "track an event" do - sn = SecureNative._get_or_throw - user_id = SecureRandom.uuid - event = build_event(EventType::LOG_IN, user_id) - sn.track(event) - expect(sn.flush).not_to be_empty - end - - it "verify an event" do - sn = SecureNative._get_or_throw - user_id = SecureRandom.uuid - event = build_event(EventType::LOG_OUT, user_id) - res = sn.verify(event) - - expect(res).not_to be_empty - expect(res['triggers']).not_to be_empty - expect(res['riskLevel']).to eq('high') - expect(res['score']).to eq(0.64) - end -end \ No newline at end of file diff --git a/test/test_utils.rb b/test/test_utils.rb deleted file mode 100644 index 0ca29a5..0000000 --- a/test/test_utils.rb +++ /dev/null @@ -1,48 +0,0 @@ -require 'rspec/autorun' -require "base64" -require_relative '../lib/securenative/utils' - -describe Utils do - it "verifies a signature" do - secret = "super secretive secret" - body = "random body" - true_signature = "acfd06a839604c12d21649508c1b3fa25d84e043d2b1e26b5967b9f9883184227c80c249decd9229205c7d072d2c7dc0f5c525cf4c14209d34f72306de97d50c" - false_signature = "c80c249decd9229205c7d072d2c7dc0f5c525cf4c14209d34f72306de97d50cacfd06a839604c12d21649508c1b3fa25d84e043d2b1e26b5967b9f9883184227" - expect(Utils.verify_signature(secret, body, true_signature)).to eq(true) - expect(Utils.verify_signature(secret, body, false_signature)).to eq(false) - end - - it "successfully parse a cookie" do - cookie = Utils.parse_cookie(Base64.encode64('{"fp": fp, "cid": cid}')) - expect(cookie).to_not be_empty - expect(cookie[0]).to eq("fp") - expect(cookie[1]).to eq("cid") - end - - it "fails at parsing a cookie" do - cookie = Utils.parse_cookie - expect(cookie).to_not be_empty - expect(cookie[0]).to be_empty - expect(cookie[1]).to be_empty - end - - it "encrypt text" do - plain_text = "Some random plain text for test" - key = "6EA4915349C0AAC6F6572DA4F6B00C42DAD33E75" - encrypted = "B8D770D0F7388EC3DF62B0097C36C05CAB03E934F2E2760536004F87FE11644C" - - res = Utils.encrypt(plain_text, key) - expect(res).to_not be_empty - expect(res).to eq(encrypted) - end - - it "decrypt text" do - encrypted_text = "B8D770D0F7388EC3DF62B0097C36C05CAB03E934F2E2760536004F87FE11644C" - decrypted = "Some random plain text for test" - key = "6EA4915349C0AAC6F6572DA4F6B00C42DAD33E75" - - res = Utils.decrypt(encrypted_text, key) - expect(res).to_not be_empty - expect(res).to eq(decrypted) - end -end \ No newline at end of file From cb20692e8db7bd759b2053ca927ff6f70ac28133 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Tue, 16 Jun 2020 18:30:08 +0300 Subject: [PATCH 05/32] Add event manager, utils and context builder --- .../config/configuration_builder.rb | 2 +- .../config/configuration_manager.rb | 2 +- .../config/securenative_options.rb | 2 +- lib/securenative/event_manager.rb | 194 ++++++++++++------ .../http/securenative_http_client.rb | 2 +- lib/securenative/models/sdk_event.rb | 2 +- lib/securenative/utils/encryption_utils.rb | 2 +- lib/securenative/utils/ip_utils.rb | 18 +- lib/securenative/utils/request_utils.rb | 15 +- lib/securenative/utils/signature_utils.rb | 2 +- 10 files changed, 166 insertions(+), 75 deletions(-) diff --git a/lib/securenative/config/configuration_builder.rb b/lib/securenative/config/configuration_builder.rb index f7a0486..1ddd7a6 100644 --- a/lib/securenative/config/configuration_builder.rb +++ b/lib/securenative/config/configuration_builder.rb @@ -7,7 +7,7 @@ def initialize @timeout = 1500 @auto_send = true @disable = false - @log_level = "CRITICAL" # TODO implement ruby logger + @log_level = "FATAL" @fail_over_strategy = FailOverStrategy::FAIL_OPEN end diff --git a/lib/securenative/config/configuration_manager.rb b/lib/securenative/config/configuration_manager.rb index 61fc2b2..5f087bc 100644 --- a/lib/securenative/config/configuration_manager.rb +++ b/lib/securenative/config/configuration_manager.rb @@ -1,4 +1,4 @@ -require "parseconfig" +require 'parseconfig' class ConfigurationManager DEFAULT_CONFIG_FILE = "securenative.cfg" diff --git a/lib/securenative/config/securenative_options.rb b/lib/securenative/config/securenative_options.rb index 9fe0730..b801cb8 100644 --- a/lib/securenative/config/securenative_options.rb +++ b/lib/securenative/config/securenative_options.rb @@ -3,7 +3,7 @@ class SecureNativeOptions attr_writer :api_key, :api_url, :interval, :max_events, :timeout, :auto_send, :disable, :log_level, :fail_over_strategy def initialize(api_key = nil, api_url = "https://api.securenative.com/collector/api/v1", interval = 1000, - max_events = 1000, timeout = 1500, auto_send = true, disable = false, log_level = "CRITICAL", + max_events = 1000, timeout = 1500, auto_send = true, disable = false, log_level = "FATAL", fail_over_strategy = FailOverStrategy::FAIL_OPEN) @api_key = api_key @api_url = api_url diff --git a/lib/securenative/event_manager.rb b/lib/securenative/event_manager.rb index fb7f4c8..84878c6 100644 --- a/lib/securenative/event_manager.rb +++ b/lib/securenative/event_manager.rb @@ -1,88 +1,162 @@ -require_relative 'securenative_options' -require_relative 'http_client' -require_relative 'sn_exception' -require 'json' -require 'thread' +require_relative 'logger' class QueueItem - def initialize(url, body) + attr_reader :url, :body, :retry + attr_writer :url, :body, :retry + + def initialize(url, body, _retry) @url = url @body = body + @retry = _retry end - - attr_reader :url - attr_reader :body end class EventManager - def initialize(api_key, options: SecureNativeOptions.new, http_client: HttpClient.new) - if api_key == nil - raise SecureNativeSDKException.new + def initialize(options = SecureNativeOptions(), http_client = nil) + if options.api_key.nil? + raise SecureNativeSDKException('API key cannot be None, please get your API key from SecureNative console.') end - @api_key = api_key - @options = options - @http_client = http_client - @queue = Queue.new - - if @options.auto_send - interval_seconds = [(@options.interval / 1000).floor, 1].max - Thread.new do - loop do - flush - sleep(interval_seconds) - end - end + if http_client.nil? + @http_client = SecureNativeHttpClient(options) + else + @http_client = http_client end - end - def send_async(event, path) - q_item = QueueItem.new(build_url(path), event) - @queue.push(q_item) + @queue = [] + @thread = Thread.new(run) + @thread.start + + @options = options + @send_enabled = false + @attempt = 0 + @coefficients = [1, 1, 2, 3, 5, 8, 13] + @thread = nil + @interval = options.interval end - def send_sync(event, path) - @http_client.post( - build_url(path), - @api_key, - event.to_hash.to_json + def send_async(event, resource_path) + if @options.disable + Logger.warning("SDK is disabled. no operation will be performed") + return + end + + item = QueueItem( + resource_path, + JSON.parse(EventManager.serialize(event)), + false ) + + @queue.append(item) end def flush - if is_queue_full - i = @options.max_events - 1 - while i >= 0 - item = @queue.pop - @http_client.post( - build_url(item.url), - @api_key, - item.body.to_hash.to_json - ) - end - else - q = Array.new(@queue.size) {@queue.pop} - q.each do |item| - @http_client.post( - build_url(item.url), - @api_key, - item.body - ) - @queue = Queue.new - end + @queue.each do |item| + @http_client.post(item.url, item.body) + end + end + + def send_sync(event, resource_path, _retry) + if @options.disable + Logger.warning("SDK is disabled. no operation will be performed") + return + end + + Logger.debug("Attempting to send event {}".format(event)) + res = @http_client.post(resource_path, JSON.parse(EventManager.serialize(event))) + + if res.status_code != 200 + Logger.info("SecureNative failed to call endpoint {} with event {}. adding back to queue".format(resource_path, event)) + item = QueueItem( + resource_path, + JSON.parse(EventManager.serialize(event)), + _retry + ) + @queue.append(item) end + + res end - private + def run + while true : + if @queue.length > 0 and @send_enabled + @queue.each do |item| + begin + res = @http_client.post(item.url, item.body) + if res.status_code == 401 + item.retry = false + elsif res.status_code != 200 + raise SecureNativeHttpException(res.status_code) + end + Logger.debug("Event successfully sent; {}".format(item.body)) + return res + rescue StandardError => e + Logger.error("Failed to send event; {}".format(e)) + if item.retry + if @coefficients.length == @attempt + 1 + @attempt = 0 + end - def build_url(path) - @options.api_url + path + back_off = @coefficients[@attempt] * @options.interval + Logger.debug("Automatic back-off of {}".format(back_off)) + @send_enabled = false + time.sleep(back_off) # TODO add time sleep + @send_enabled = true + end + end + end + time.sleep(self.interval / 1000) # TODO add time sleep + end + end end - private + def start_event_persist + Logger.debug("Starting automatic event persistence") + if @options.auto_send || @send_enabled + @send_enabled = true + else + Logger.debug("Automatic event persistence is disabled, you should persist events manually") + end + end - def is_queue_full - @queue.length > @options.max_events + def stop_event_persist + if @send_enabled + Logger.debug("Attempting to stop automatic event persistence") + begin + flush + unless @thread.nil? + @thread.stop + end + Logger.debug("Stopped event persistence") + rescue StandardError => e + Logger.error("Could not stop event scheduler; {}".format(e)) + end + end end + def self.serialize(obj) + return { + :rid => obj.rid, + :eventType => obj.event_type, + :userId => obj.user_id, + :userTraits => { + :name => obj.user_traits.name, + :email => obj.user_traits.email, + :createdAt => obj.user_traits.created_at, + }, + :request => { + :cid => obj.request.cid, + :vid => obj.request.vid, + :fp => obj.request.fp, + :ip => obj.request.ip, + :remoteIp => bj.request.remote_ip, + :method => obj.request.method, + :url => obj.request.url, + :headers => obj.request.headers + }, + :timestamp => obj.timestamp, + :properties => obj.properties, + } + end end \ No newline at end of file diff --git a/lib/securenative/http/securenative_http_client.rb b/lib/securenative/http/securenative_http_client.rb index f1a787b..38212d5 100644 --- a/lib/securenative/http/securenative_http_client.rb +++ b/lib/securenative/http/securenative_http_client.rb @@ -1,4 +1,4 @@ -require "httpclient" +require 'httpclient' class SecureNativeHttpClient AUTHORIZATION_HEADER = "Authorization" diff --git a/lib/securenative/models/sdk_event.rb b/lib/securenative/models/sdk_event.rb index 47f8447..391f177 100644 --- a/lib/securenative/models/sdk_event.rb +++ b/lib/securenative/models/sdk_event.rb @@ -1,4 +1,4 @@ -class SdkEvent +class SDKEvent attr_reader :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties attr_writer :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties diff --git a/lib/securenative/utils/encryption_utils.rb b/lib/securenative/utils/encryption_utils.rb index 7a70279..add2c62 100644 --- a/lib/securenative/utils/encryption_utils.rb +++ b/lib/securenative/utils/encryption_utils.rb @@ -1,4 +1,4 @@ -require "openssl" +require 'openssl' class EncryptionUtils BLOCK_SIZE = 16 diff --git a/lib/securenative/utils/ip_utils.rb b/lib/securenative/utils/ip_utils.rb index 109afce..d8d1120 100644 --- a/lib/securenative/utils/ip_utils.rb +++ b/lib/securenative/utils/ip_utils.rb @@ -1,16 +1,26 @@ -class IpUtils # TODO implement me +class IpUtils VALID_IPV4_PATTERN = ("(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])") VALID_IPV6_PATTERN = ("([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}") def self.is_ip_address(ip_address) - # code here + if IpUtils.VALID_IPV4_PATTERN.match(ip_address) + return true + end + if IpUtils.VALID_IPV6_PATTERN.match(ip_address) + return true + end + return false end def self.is_valid_public_ip(ip_address) - # code here + ip = IPAddr.new(ip_address) + if ip.loopback? || ip.private? || ip.link_local? || ip.untrusted? || ip.tainted? + return false + end + return true end def self.is_loop_back(ip_address) - # code here + IPAddr.new(ip_address).loopback? end end \ No newline at end of file diff --git a/lib/securenative/utils/request_utils.rb b/lib/securenative/utils/request_utils.rb index 854fe00..15e2faf 100644 --- a/lib/securenative/utils/request_utils.rb +++ b/lib/securenative/utils/request_utils.rb @@ -1,16 +1,23 @@ -class RequestUtils # TODO implement me +class RequestUtils SECURENATIVE_COOKIE = "_sn" SECURENATIVE_HEADER = "x-securenative" def self.get_secure_header_from_request(headers) - # code here + unless headers.nil? + return headers[RequestUtils.SECURENATIVE_HEADER] + end + return [] end def self.get_client_ip_from_request(request) - # code here + x_forwarded_for = request.env["HTTP_X_FORWARDED_FOR"] + unless x_forwarded_for.nil? + return x_forwarded_for + end + return request.env["REMOTE_ADDR"] end def self.get_remote_ip_from_request(request) - # code here + return request.remote_ip end end \ No newline at end of file diff --git a/lib/securenative/utils/signature_utils.rb b/lib/securenative/utils/signature_utils.rb index 1c538f3..3c759f3 100644 --- a/lib/securenative/utils/signature_utils.rb +++ b/lib/securenative/utils/signature_utils.rb @@ -1,4 +1,4 @@ -require "openssl" +require 'openssl' class SignatureUtils def self.is_valid_signature(api_key, payload, header_signature) From f5c7d66261351f0bcc986275301ab84d4e317cde Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Tue, 16 Jun 2020 18:47:17 +0300 Subject: [PATCH 06/32] Add api manager, logger and event builder --- lib/securenative/api_manager.rb | 31 ++++++ lib/securenative/context/context_builder.rb | 25 ++++- lib/securenative/event_options_builder.rb | 44 +++++++++ lib/securenative/logger.rb | 42 ++++++++ lib/securenative/securenative.rb | 100 ++++++++++++++------ 5 files changed, 210 insertions(+), 32 deletions(-) create mode 100644 lib/securenative/api_manager.rb create mode 100644 lib/securenative/event_options_builder.rb create mode 100644 lib/securenative/logger.rb diff --git a/lib/securenative/api_manager.rb b/lib/securenative/api_manager.rb new file mode 100644 index 0000000..34c3460 --- /dev/null +++ b/lib/securenative/api_manager.rb @@ -0,0 +1,31 @@ +require 'json' +require_relative 'logger' + +class ApiManager + def initialize(event_manager, securenative_options) + @event_manager = event_manager + @options = securenative_options + end + + def track(event_options) + Logger.debug("Track event call") + event = SDKEvent.new(event_options, @options) + @event_manager.send_async(event, ApiRoute::TRACK) + end + + def verify(event_options) + Logger.debug("Verify event call") + event = SDKEvent.new(event_options, @options) + + begin + res = JSON.parse(@event_manager.send_sync(event, ApiRoute::VERIFY, false)) + return VerifyResult.new(res["riskLevel"], res["score"], res["triggers"]) + rescue StandardError => e + Logger.debug("Failed to call verify; {}".format(e)) + end + if @options.fail_over_strategy == FailOverStrategy::FAIL_OPEN + return VerifyResult.new(RiskLevel::LOW, 0, nil) + end + VerifyResult.new(RiskLevel::HIGH, 1, nil) + end +end \ No newline at end of file diff --git a/lib/securenative/context/context_builder.rb b/lib/securenative/context/context_builder.rb index 59196a5..f46c980 100644 --- a/lib/securenative/context/context_builder.rb +++ b/lib/securenative/context/context_builder.rb @@ -43,7 +43,30 @@ def self.default_context_builder end def self.from_http_request(request) - # TODO implement me + begin + client_token = request.cookies[RequestUtils.SECURENATIVE_COOKIE] + rescue StandardError + client_token = nil + end + + begin + headers = request.headers + rescue StandardError + headers = nil + end + + if Utils.is_null_or_empty(client_token) + client_token = RequestUtils.get_secure_header_from_request(headers) + end + + return ContextBuilder() + .with_url(request.url) + .with_method(request.method) + .with_headers(headers) + .with_client_token(client_token) + .with_ip(RequestUtils.get_client_ip_from_request(request)) + .with_remote_ip(RequestUtils.get_remote_ip_from_request(request)) + .with_body(nil) end def build diff --git a/lib/securenative/event_options_builder.rb b/lib/securenative/event_options_builder.rb new file mode 100644 index 0000000..59e1c7e --- /dev/null +++ b/lib/securenative/event_options_builder.rb @@ -0,0 +1,44 @@ +class EventOptionsBuilder + MAX_PROPERTIES_SIZE = 10 + + def initialize(event_type) + @event_options = EventOptions(event_type) + end + + def with_user_id(user_id) + @event_options.user_id = user_id + self + end + + def with_user_traits(user_traits) + @event_options.user_traits = user_traits + self + end + + def with_user(name, email, created_at = nil) + @event_options.user_traits = UserTraits(name, email, created_at) + self + end + + def with_context(context) + @event_options.context = context + self + end + + def with_properties(properties) + @event_options.properties = properties + self + end + + def with_timestamp(timestamp) + @event_options.timestamp = timestamp + self + end + + def build + if !@event_options.properties.nil? && @event_options.properties.length > MAX_PROPERTIES_SIZE + raise SecureNativeInvalidOptionsException("You can have only up to {} custom properties", MAX_PROPERTIES_SIZE) + end + @event_options + end +end \ No newline at end of file diff --git a/lib/securenative/logger.rb b/lib/securenative/logger.rb new file mode 100644 index 0000000..e6b122e --- /dev/null +++ b/lib/securenative/logger.rb @@ -0,0 +1,42 @@ +require 'logger' + +class Logger + @logger = Logger.new(STDOUT) + + def self.init_logger(level) + case level + when "WARN" + @logger.level = Logger::WARN + when "DEBUG" + @logger.level = Logger::DEBUG + when "ERROR" + @logger.level = Logger::ERROR + when "FATAL" + @logger.level = Logger::FATAL + when "INFO" + @logger.level = Logger::INFO + else + @logger.level = Logger::FATAL + end + + @logger.formatter = proc do |severity, datetime, progname, msg| + "[#{datetime}] #{severity} (#{progname}): #{msg}\n" + end + end + + def self.info(msg) + @logger.info(msg) + end + + def self.debug(msg) + @logger.debug(msg) + end + + def self.warning(msg) + @logger.warning(msg) + end + + def self.error(msg) + @logger.error(msg) + end +end \ No newline at end of file diff --git a/lib/securenative/securenative.rb b/lib/securenative/securenative.rb index ee6f2d3..ed04b6a 100644 --- a/lib/securenative/securenative.rb +++ b/lib/securenative/securenative.rb @@ -1,45 +1,83 @@ -require_relative 'securenative/sn_exception' -require_relative 'securenative/secure_native_sdk' -require 'logger' - -$securenative = nil -$logger = Logger.new(STDOUT) -$logger.level = Logger::INFO - -module SecureNative - def self.init(api_key, options: SecureNativeOptions.new) - if $securenative == nil - $securenative = SecureNativeSDK.new(api_key, options: options) +require_relative 'logger' + +class SecureNative + def initialize(options) + @securenative = nil + if Utils.is_null_or_empty(options.api_key) + raise SecureNativeSDKException("You must pass your SecureNative api key") + end + + @options = options + @event_manager = EventManager(@options) + + unless @options.api_url.nil? + @event_manager.start_event_persist + end + + @api_manager = ApiManager.new(@event_manager, @options) + Logger.init_logger(@options.log_level) + end + + def self.init_with_options(options) + if @securenative.nil? + @securenative = SecureNative.new(options) + return @securenative else - $logger.info("This SDK was already initialized") - raise StandardError.new("This SDK was already initialized") + Logger.debug('This SDK was already initialized.') + raise SecureNativeSDKException(u 'This SDK was already initialized.') end end - def self.track(event) - sdk = _get_or_throw - sdk.track(event) + def self.init_with_api_key(api_key) + if Utils.is_null_or_empty(api_key) + raise SecureNativeConfigException("You must pass your SecureNative api key") + end + + if @securenative.nil? + builder = ConfigurationBuilder().default_config_builder + options = builder.with_api_key(api_key) + @securenative = SecureNative.new(options) + return @securenative + else + Logger.debug('This SDK was already initialized.') + raise SecureNativeSDKException(u 'This SDK was already initialized.') + end end - def self.verify(event) - sdk = _get_or_throw - sdk.verify(event) + def self.init + options = ConfigurationManager.load_config + init_with_options(options) end - def self.verify_webhook(hmac_header, body) - sdk = _get_or_throw - sdk.verify_webhook(hmac_header = hmac_header, body = body) + def self.get_instance + if @securenative.nil? + raise SecureNativeSDKIllegalStateException() + end + return @securenative end - def self.flush - sdk = _get_or_throw - sdk.flush + def get_options + @options end - def self._get_or_throw - if $securenative == nil - raise SecureNativeSDKException.new - end - $securenative + + def self.config_builder + return ConfigurationBuilder.default_config_builder + end + + def self.context_builder + return ContextBuilder.default_context_builder + end + + def track(event_options) + @api_manager.track(event_options) + end + + def verify(event_options) + @api_manager.verify(event_options) + end + + def self._flush + @securenative = nil end end \ No newline at end of file From a3e42fe8761128f5dcbf76c2679779e422c55ecf Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Wed, 17 Jun 2020 13:11:16 +0300 Subject: [PATCH 07/32] Update readme and add unit test structure --- README.md | 214 ++++++++++++++++++-------- lib/securenative/securenative.rb | 5 + test/test_api_manager.rb | 3 + test/test_configuration_manager.rb | 3 + test/test_context_builder.rb | 3 + test/test_date_utils.rb | 3 + test/test_encryption_utils.rb | 3 + test/test_event_manager.rb | 3 + test/test_ip_utils.rb | 3 + test/test_securenative.rb | 3 + test/test_securenative_http_client.rb | 3 + test/test_signature_utils.rb | 3 + 12 files changed, 183 insertions(+), 66 deletions(-) create mode 100644 test/test_api_manager.rb create mode 100644 test/test_configuration_manager.rb create mode 100644 test/test_context_builder.rb create mode 100644 test/test_date_utils.rb create mode 100644 test/test_encryption_utils.rb create mode 100644 test/test_event_manager.rb create mode 100644 test/test_ip_utils.rb create mode 100644 test/test_securenative.rb create mode 100644 test/test_securenative_http_client.rb create mode 100644 test/test_signature_utils.rb diff --git a/README.md b/README.md index 909e2c1..63abf50 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,31 @@ -# SecureNative -**[SecureNative](https://www.securenative.com/) is rethinking-security-as-a-service, disrupting the cyber security space and the way enterprises consume and implement security solutions.** - -## Installation +

+ SecureNative Logo +

+ +

+ A Cloud-Native Security Monitoring and Protection for Modern Applications +

+

+ + Github Actions + + + + +

+

+ Documentation | + Quick Start | + Blog | + Chat with us on Slack! +

+
+ + +[SecureNative](https://www.securenative.com/) performs user monitoring by analyzing user interactions with your application and various factors such as network, devices, locations and access patterns to stop and prevent account takeover attacks. + + +## Install the SDK Add this line to your application's Gemfile: @@ -9,7 +33,7 @@ Add this line to your application's Gemfile: gem 'securenative' ``` -And then execute: +Then execute: $ bundle @@ -18,85 +42,143 @@ Or install it yourself as: $ gem install securenative ## Initialize the SDK -Retrieve your API key from settings page of your SecureNative account and use the following in your code to initialize and use the sdk. + +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: + ```ruby require 'securenative' -# Do some cool stuff here -# ... -# ... - -begin - SecureNative.init('YOUR_API_KEY') # Should be called before any other call to securenative -rescue SecureNativeSDKException => e - # Do some error handling -end + +secureative = SecureNative.init +``` +### Option 2: Initialize via API Key + +```ruby +require 'securenative' + + +securenative = SecureNative.init_with_api_key("YOUR_API_KEY") +``` + +### Option 3: Initialize via ConfigurationBuilder +```ruby +require 'securenative' + + +securenative = SecureNative.init_with_options(SecureNative.config_builder + .with_api_key("API_KEY") + .with_max_events(10) + .with_log_level("ERROR") + .build) +``` + +## Getting SecureNative instance +Once initialized, sdk will create a singleton instance which you can get: +```ruby +require 'securenative' + + +secureNative = SecureNative.get_instance ``` ## Tracking events -Once the SDK has been initialized, you can start sending new events with the `track` function: + +Once the SDK has been initialized, tracking requests sent through the SDK +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' + + +securenative = SecureNative.get_instance + +context = SecureNative.context_builder + .with_ip("127.0.0.1") + .with_client_token("SECURED_CLIENT_TOKEN") + .with_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"}) + .build + +event_options = EventOptionsBuilder(EventTypes::LOG_IN) + .with_user_id("USER_ID") + .with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")) + .with_context(context) + .with_properties({"prop1" => "CUSTOM_PARAM_VALUE", "prop2" => true, "prop3" => 3}) + .build + +securenative.track(event_options) + ``` + +You can also create request context from requests: + ```ruby require 'securenative' -require 'securenative/event_type' - - -def login - # Do some cool stuff here - # ... - # ... - - SecureNative.track(Event.new( - event_type = EventTypes::LOG_IN, - user: User.new("1", "Jon Snow", "jon@snow.com"), - ip: "1.2.3.4", - remote_ip: "5.6.7.8", - user_agent: "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-URL-Manager Mobile Safari/537.36", - sn_cookie: "cookie")) +require 'securenative/enums/event_types' +require 'securenative/event_options_builder' +require 'securenative/models/user_traits' + + +def track(request) + securenative = SecureNative.get_instance + context = SecureNative.context_builder.from_http_request(request).build + + event_options = EventOptionsBuilder(EventTypes::LOG_IN) + .with_user_id("USER_ID") + .with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")) + .with_context(context) + .with_properties({"prop1" => "CUSTOM_PARAM_VALUE", "prop2" => true, "prop3" => 3}) + .build + + securenative.track(event_options) end ``` -## Verification events -Once the SDK has been initialized, you can start sending new events with the `verify` function: +## Verify events + +**Example** + ```ruby require 'securenative' -require 'securenative/event_type' - - -def reset_password - res = SecureNative.verify(Event.new( - event_type = EventTypes::PASSWORD_RESET, - user: User.new("1", "Jon Snow", "jon@snow.com"), - ip: "1.2.3.4", - remote_ip: "5.6.7.8", - user_agent: "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-URL-Manager Mobile Safari/537.36", - sn_cookie: "cookie")) - - if res['riskLevel'] == 'high' - return 'Cannot change password' - else res['riskLevel'] == 'medium' - return 'MFA' - end +require 'securenative/enums/event_types' +require 'securenative/event_options_builder' +require 'securenative/models/user_traits' + + +def track(request) + securenative = SecureNative.get_instance + context = SecureNative.context_builder.from_http_request(request).build + + event_options = EventOptionsBuilder(EventTypes::LOG_IN) + .with_user_id("USER_ID") + .with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")) + .with_context(context) + .with_properties({"prop1" => "CUSTOM_PARAM_VALUE", "prop2" => true, "prop3" => 3}) + .build + + verify_result = securenative.verify(event_options) + verify_result.risk_level # Low, Medium, High + verify_result.score # Risk score: 0 -1 (0 - Very Low, 1 - Very High) + verify_result.triggers # ["TOR", "New IP", "New City"] end ``` -## Using webhooks -You can use the SDK to verify incoming webhooks from SecureNative, just call the `veriy_webhook` function which return a boolean which indicates if the webhook came from Secure Native servers. +## Webhook signature verification + +Apply our filter to verify the request is from us, for example: + ```ruby require 'securenative' -begin - SecureNative.init('YOUR_API_KEY') # Should be called before any other call to securenative -rescue SecureNativeSDKException => e - # Do some error handling -end -def handle_some_code(headers, body) - sig_header = headers["X-SecureNative"] - if SecureNative.verify_webhook(sig_header, body) - # Handle the webhook - level = body['riskLevel'] - else - # This request wasn't sent from Secure Native servers, you can dismiss/investigate it - end +def webhook_endpoint(request) + securenative = SecureNative.get_instance + + # Checks if request is verified + is_verified = securenative.verify_request_payload(request) end -``` + ``` \ No newline at end of file diff --git a/lib/securenative/securenative.rb b/lib/securenative/securenative.rb index ed04b6a..ca2ff18 100644 --- a/lib/securenative/securenative.rb +++ b/lib/securenative/securenative.rb @@ -80,4 +80,9 @@ def verify(event_options) def self._flush @securenative = nil end + + # TODO! + def verify_request_payload(request) + # code here + end end \ No newline at end of file diff --git a/test/test_api_manager.rb b/test/test_api_manager.rb new file mode 100644 index 0000000..109fa61 --- /dev/null +++ b/test/test_api_manager.rb @@ -0,0 +1,3 @@ +describe ApiManager do + +end \ No newline at end of file diff --git a/test/test_configuration_manager.rb b/test/test_configuration_manager.rb new file mode 100644 index 0000000..aa72ad3 --- /dev/null +++ b/test/test_configuration_manager.rb @@ -0,0 +1,3 @@ +describe ConfigurationManager do + +end \ No newline at end of file diff --git a/test/test_context_builder.rb b/test/test_context_builder.rb new file mode 100644 index 0000000..dbf1a01 --- /dev/null +++ b/test/test_context_builder.rb @@ -0,0 +1,3 @@ +describe ContextBuilder do + +end \ No newline at end of file diff --git a/test/test_date_utils.rb b/test/test_date_utils.rb new file mode 100644 index 0000000..f4c816c --- /dev/null +++ b/test/test_date_utils.rb @@ -0,0 +1,3 @@ +describe DateUtils do + +end \ No newline at end of file diff --git a/test/test_encryption_utils.rb b/test/test_encryption_utils.rb new file mode 100644 index 0000000..f5cd606 --- /dev/null +++ b/test/test_encryption_utils.rb @@ -0,0 +1,3 @@ +describe EncryptionUtils do + +end \ No newline at end of file diff --git a/test/test_event_manager.rb b/test/test_event_manager.rb new file mode 100644 index 0000000..623a180 --- /dev/null +++ b/test/test_event_manager.rb @@ -0,0 +1,3 @@ +describe EventManager do + +end \ No newline at end of file diff --git a/test/test_ip_utils.rb b/test/test_ip_utils.rb new file mode 100644 index 0000000..7c586f3 --- /dev/null +++ b/test/test_ip_utils.rb @@ -0,0 +1,3 @@ +describe IpUtils do + +end \ No newline at end of file diff --git a/test/test_securenative.rb b/test/test_securenative.rb new file mode 100644 index 0000000..2e280eb --- /dev/null +++ b/test/test_securenative.rb @@ -0,0 +1,3 @@ +describe SecureNative do + +end \ No newline at end of file diff --git a/test/test_securenative_http_client.rb b/test/test_securenative_http_client.rb new file mode 100644 index 0000000..443abe2 --- /dev/null +++ b/test/test_securenative_http_client.rb @@ -0,0 +1,3 @@ +describe SecureNativeHttpClient do + +end \ No newline at end of file diff --git a/test/test_signature_utils.rb b/test/test_signature_utils.rb new file mode 100644 index 0000000..4e74263 --- /dev/null +++ b/test/test_signature_utils.rb @@ -0,0 +1,3 @@ +describe SignatureUtils do + +end \ No newline at end of file From b49e5d3f5654a47305257c245d8bca9ba20ebcf3 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 11:07:32 +0300 Subject: [PATCH 08/32] Add unit tests --- .github/workflows/ci.yml | 63 ++++++++++++++++++++++++++ .github/workflows/publish.yml | 59 ++++++++++++++++++++++++ .github/workflows/test.yml | 47 ++++++++++++++++++++ test/test_api_manager.rb | 64 +++++++++++++++++++++++++++ test/test_configuration_manager.rb | 26 +++++++++++ test/test_context_builder.rb | 30 +++++++++++++ test/test_date_utils.rb | 5 +++ test/test_encryption_utils.rb | 18 ++++++++ test/test_event_manager.rb | 48 ++++++++++++++++++++ test/test_ip_utils.rb | 33 ++++++++++++++ test/test_securenative.rb | 49 ++++++++++++++++++++ test/test_securenative_http_client.rb | 13 ++++++ test/test_signature_utils.rb | 10 +++++ 13 files changed, 465 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/publish.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4f39663 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,63 @@ +name: CI + +on: + pull_request: + branches: + - master + - dev + - dev-* + +jobs: + ci: + runs-on: ubuntu-latest + steps: + - name: Notify slack success + if: success() + id: slack # IMPORTANT: reference this step ID value in future Slack steps + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + channel: github-actions + status: STARTING + color: warning + + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.6' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pytest pytest-cov responses codecov requests-mock + - name: Test with pytest + run: | + pytest --cov=./ --cov-report=xml + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + + - name: Notify slack success + if: success() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: SUCCESS + color: good + + - name: Notify slack fail + if: failure() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: FAILED + color: danger diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..7a2ee3a --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,59 @@ +name: Upload Python Package + +on: + release: + types: [created] + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Notify slack success + if: success() + id: slack # IMPORTANT: reference this step ID value in future Slack steps + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + channel: github-actions + status: STARTING + color: warning + + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.6' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel twine + - name: Build and publish + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + python setup.py sdist bdist_wheel + twine upload dist/* + + - name: Notify slack success + if: success() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: SUCCESS + color: good + + - name: Notify slack fail + if: failure() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: FAILED + color: danger \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..85f5530 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,47 @@ +name: Testing + +on: + push: + branches: + - '*' + - '!master' + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.6' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install pytest responses requests-mock + - name: Test with pytest + run: | + pytest -vv + + - name: Notify slack success + if: success() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: SUCCESS + color: good + + - name: Notify slack fail + if: failure() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: FAILED + color: danger \ No newline at end of file diff --git a/test/test_api_manager.rb b/test/test_api_manager.rb index 109fa61..525e55b 100644 --- a/test/test_api_manager.rb +++ b/test/test_api_manager.rb @@ -1,3 +1,67 @@ describe ApiManager do + let(:context) { ContextBuilder().with_ip("127.0.0.1").with_client_token("SECURED_CLIENT_TOKEN").with_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"}).build } + let(:event_options) { EventOptionsBuilder(EventTypes.LOG_IN).with_user_id("USER_ID").with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")).with_context(context).with_properties({:prop1 => "CUSTOM_PARAM_VALUE", :prop2 => true, :prop3 => 3}).build } + it "tracks an event" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_auto_send(true).with_interval(10).with_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\",\"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}}" + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json = json.loads(expected), status = 200) + event_manager = EventManager.new(options) + event_manager.start_event_persist + api_manager = ApiManager.new(event_manager, options) + + begin + api_manager.track(event_options) + ensure + event_manager.stop_event_persist + end + end + + it "uses invalid options" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_auto_send(true).with_interval(10).with_api_url("https://api.securenative-stg.com/collector/api/v1") + + properties = {} + (0..12).each { |i| + properties[i] = i + } + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json = {}, status = 200) + event_manager = EventManager.new(options) + event_manager.start_event_persist + api_manager = ApiManager.new(event_manager, options) + + begin + expect { api_manager.track(EventOptionsBuilder(EventTypes.LOG_IN).with_properties(properties).build) }.to raise_error(Errors::SecureNativeInvalidOptionsException) + ensure + event_manager.stop_event_persist + end + end + + it "verifies an event" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/verify", json = {:riskLevel => "medium", :score => 0.32, :triggers => ["New IP", "New City"]}, status = 200) + verify_result = VerifyResult.new(RiskLevel.LOW, 0, nil) + + event_manager = EventManager.new(options) + event_manager.start_event_persist + api_manager = ApiManager.new(event_manager, options) + + result = api_manager.verify(event_options) + + expect(result).not_to be_empty + expect(result.risk_level).to eq(verify_result.risk_level) + expect(result.score).to eq(verify_result.score) + expect(result.triggers).to eq(verify_result.triggers) + end end \ No newline at end of file diff --git a/test/test_configuration_manager.rb b/test/test_configuration_manager.rb index aa72ad3..5626869 100644 --- a/test/test_configuration_manager.rb +++ b/test/test_configuration_manager.rb @@ -1,3 +1,29 @@ describe ConfigurationManager do + it "parses a config file correctly" do + # code here + end + it "ignores unknown config in properties file" do + # code here + end + + it "handles invalid config file" do + # code here + end + + it "ignores invalid config file entries" do + # code here + end + + it "loads default config" do + # code here + end + + it "gets config from env variables" do + # code here + end + + it "uses default values for invalid enum config props" do + # code here + end end \ No newline at end of file diff --git a/test/test_context_builder.rb b/test/test_context_builder.rb index dbf1a01..3128e13 100644 --- a/test/test_context_builder.rb +++ b/test/test_context_builder.rb @@ -1,3 +1,33 @@ describe ContextBuilder do + it "creates context from request" do + # TODO code here + end + it "creates context from request with cookie" do + # TODO code here + end + + it "creates default context builder" do + context = ContextBuilder.default_context_builder.build + + expect(context.client_token).not_to be_empty + expect(context.ip).not_to be_empty + expect(context.method).not_to be_empty + expect(context.url).not_to be_empty + expect(context.remote_ip).not_to be_empty + expect(context.headers).not_to be_empty + expect(context.body).not_to be_empty + end + + it "creates custom context with context builder" do + context = ContextBuilder.default_context_builder.with_url("/some-url").with_client_token("SECRET_TOKEN").with_ip("10.0.0.0").with_body("{ \"name\": \"YOUR_NAME\" }").with_method("Get").with_remote_ip("10.0.0.1").with_headers({:header1 => "value1"}).build + + expect(context.url).to eq("/some-url") + expect(context.client_token).to eq("SECRET_TOKEN") + expect(context.ip).to eq("10.0.0.0") + expect(context.body).to eq("{ \"name\": \"YOUR_NAME\" }") + expect(context.method).to eq("Get") + expect(context.remote_ip).to eq("10.0.0.0") + expect(context.headers).to eq({:header1 => "value1"}) + end end \ No newline at end of file diff --git a/test/test_date_utils.rb b/test/test_date_utils.rb index f4c816c..35204bd 100644 --- a/test/test_date_utils.rb +++ b/test/test_date_utils.rb @@ -1,3 +1,8 @@ describe DateUtils do + it "converts to timestamp" do + iso_8601_date = "2020-05-20T15:07:13Z" + result = DateUtils.to_timestamp(iso_8601_date) + expect(result).to eq(Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z")) + end end \ No newline at end of file diff --git a/test/test_encryption_utils.rb b/test/test_encryption_utils.rb index f5cd606..d7d6132 100644 --- a/test/test_encryption_utils.rb +++ b/test/test_encryption_utils.rb @@ -1,3 +1,21 @@ describe EncryptionUtils do + let(:SECRET_KEY) { "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6" } + let(:PAYLOAD) { "{\"cid\":\"198a41ff-a10f-4cda-a2f3-a9ca80c0703b\",\"vi\":\"148a42ff-b40f-4cda-a2f3-a8ca80c0703b\",\"fp\":\"6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed\"}" } + let(:CID) { "198a41ff-a10f-4cda-a2f3-a9ca80c0703b" } + let(:FP) { "6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed" } + it "decrypts" do + result = EncryptionUtils.encrypt(PAYLOAD, SECRET_KEY) + + expect(result).not_to be_empty + expect(result.length).to eq(PAYLOAD.length) + end + + it "encrypts" do + encrypted_payload = "5208ae703cc2fa0851347f55d3b76d3fd6035ee081d71a401e8bc92ebdc25d42440f62310bda60628537744ac03f200d78da9e61f1019ce02087b7ce6c976e7b2d8ad6aa978c532cea8f3e744cc6a5cafedc4ae6cd1b08a4ef75d6e37aa3c0c76954d16d57750be2980c2c91ac7ef0bbd0722abd59bf6be22493ea9b9759c3ff4d17f17ab670b0b6fc320e6de982313f1c4e74c0897f9f5a32d58e3e53050ae8fdbebba9009d0d1250fe34dcde1ebb42acbc22834a02f53889076140f0eb8db1" + result = EncryptionUtils.decrypt(encrypted_payload, SECRET_KEY) + + expect(result.cid).to eq(CID) + expect(result.fp).to eq(FP) + end end \ No newline at end of file diff --git a/test/test_event_manager.rb b/test/test_event_manager.rb index 623a180..6c95931 100644 --- a/test/test_event_manager.rb +++ b/test/test_event_manager.rb @@ -1,3 +1,51 @@ +class SampleEvent + attr_reader :event_type, :timestamp, :rid, :user_id, :user_traits, :request, :properties + + def initialize + @event_type = "custom-event" + @timestamp = Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z") + @rid = "432532" + @user_id = "1" + @user_traits = UserTraits("some user", "email@securenative.com") + @request = RequestContext() + @properties = [] + end +end + describe EventManager do + let(:event) { SampleEvent() } + + it "successfully sends sync event with status code 200" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + + res_body = "{\"data\": true}" + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = json.loads(res_body), status = 200) + event_manager = EventManager.new(options) + data = event_manager.send_sync(self.event, "some-path/to-api", false) + + expect(res_body).to eq(data.text) + end + + it "fails when send sync event status code is 401" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = {}, status = 401) + event_manager = EventManager.new(options) + res = event_manager.send_sync(self.event, "some-path/to-api", false) + + expect(res.status_code).to eq(401) + end + + it "fails when send sync event status code is 500" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = {}, status = 500) + event_manager = EventManager.new(options) + res = event_manager.send_sync(self.event, "some-path/to-api", false) + expect(res.status_code).to eq(500) + end end \ No newline at end of file diff --git a/test/test_ip_utils.rb b/test/test_ip_utils.rb index 7c586f3..16e9401 100644 --- a/test/test_ip_utils.rb +++ b/test/test_ip_utils.rb @@ -1,3 +1,36 @@ describe IpUtils do + it "checks if ip address valid ipv4" do + valid_ipv4 = "172.16.254.1" + expect(IpUtils.is_ip_address(valid_ipv4)).to be_truthy + end + it "checks if ip address valid ipv6" do + valid_ipv6 = "2001:db8:1234:0000:0000:0000:0000:0000" + expect(IpUtils.is_ip_address(valid_ipv6)).to be_truthy + end + + it "checks if ip address invalid ipv4" do + invalid_ipv4 = "172.16.2541" + expect(IpUtils.is_ip_address(invalid_ipv4)).to be_falsey + end + + it "checks if ip address invalid ipv6" do + invalid_ipv6 = "2001:db8:1234:0000" + expect(IpUtils.is_ip_address(invalid_ipv6)).to be_falsey + end + + it "checks if valid public ip" do + ip = "64.71.222.37" + expect(IpUtils.is_valid_public_ip(ip)).to be_truthy + end + + it "checks if not valid public ip" do + ip = "10.0.0.0" + expect(IpUtils.is_valid_public_ip(ip)).to be_falsey + end + + it "checks if valid loopback ip" do + ip = "127.0.0.1" + expect(IpUtils.is_loop_back(ip)).to be_truthy + end end \ No newline at end of file diff --git a/test/test_securenative.rb b/test/test_securenative.rb index 2e280eb..e9cfd7b 100644 --- a/test/test_securenative.rb +++ b/test/test_securenative.rb @@ -1,3 +1,52 @@ describe SecureNative do + it "gets sdk instance without init throws" do + expect { SecureNative.get_instance }.to raise_error(Errors::SecureNativeSDKIllegalStateException) + end + it "inits sdk without api key and throws" do + expect { SecureNative.init_with_options(ConfigurationManager.config_builder) }.to raise_error(Errors::SecureNativeSDKException) + end + + it "inits sdk with empty api key and throws" do + expect { SecureNative.init_with_api_key("") }.to raise_error(Errors::SecureNativeSDKException) + end + + it "inits sdk with api key and defaults" do + SecureNative._flush + api_key = "API_KEY" + securenative = SecureNative.init_with_api_key(api_key) + options = securenative.get_options + + expect(options.api_key).to eq(api_key) + expect(options.api_url).to eq("https://api.securenative.com/collector/api/v1") + expect(options.interval).to eq(1000) + expect(options.timeout).to eq(1500) + expect(options.max_events).to eq(100) + expect(options.auto_send).to eq(true) + expect(options.disable).to eq(false) + expect(options.log_level).to eq("FATAL") + expect(options.fail_over_strategy).to eq(FailOverStrategy::FAIL_OPEN) + end + + it "inits sdk twice and throws" do + expect { SecureNative.init_with_api_key("API_KEY") }.to raise_error(Errors::SecureNativeSDKException) + end + + it "inits sdk with api key and gets instance" do + SecureNative._flush + api_key = "API_KEY" + securenative = SecureNative.init_with_api_key(api_key) + + expect(securenative).to eq(SecureNative.get_instance) + end + + it "inits sdk with builder" do + SecureNative._flush + securenative = SecureNative.init_with_options(SecureNative.config_builder.with_api_key("API_KEY").with_max_events(10).with_log_level("ERROR")) + options = securenative.get_options + + expect(options.api_key).to eq("API_KEY") + expect(options.max_events).to eq(10) + expect(options.log_level).to eq("ERROR") + end end \ No newline at end of file diff --git a/test/test_securenative_http_client.rb b/test/test_securenative_http_client.rb index 443abe2..43892b1 100644 --- a/test/test_securenative_http_client.rb +++ b/test/test_securenative_http_client.rb @@ -1,3 +1,16 @@ describe SecureNativeHttpClient do + it "makes a simple post call" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json={"event" => "SOME_EVENT_NAME"}, status=200) + client = SecureNativeHttpClient(options) + payload = "{\"event\": \"SOME_EVENT_NAME\"}" + + res = client.post("track", payload) + + expect(res.ok).to eq(true) + expect(res.status_code).to eq(200) + expect(res.text).to eq(payload) + end end \ No newline at end of file diff --git a/test/test_signature_utils.rb b/test/test_signature_utils.rb index 4e74263..fde96ca 100644 --- a/test/test_signature_utils.rb +++ b/test/test_signature_utils.rb @@ -1,3 +1,13 @@ describe SignatureUtils do + it "verifies request payload" do + signature = "c4574c1748064735513697750c6223ff36b03ae3b85b160ce8788557d01e1d9d1c9cd942074323ee0061d3dcc8c94359c5acfa6eee8e2da095b3967b1a88ab73" + payload = "{\"id\":\"4a9157ffbd18cfbd73a57298\",\"type\":\"security-action\",\"flow\":{\"id\":\"62298c73a9bb433fbd1f75984a9157fd\",\"name\":\"Block user that violates geo velocity\"},\"userId\":\"73a9bb433fbd1f75984a9157\",\"userTraits\":{\"name\":\"John Doe\",\"email\":\"john.doe@gmail.com\"},\"request\":{\"ip\":\"10.0.0.0\",\"fp\":\"9bb433fb984a9157d1f7598\"},\"action\":\"block\",\"properties\":{\"type\":\"customer\"},\"timestamp\":\"2020-02-23T22:28:55.387Z\"}" + secret_key = "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6" + expect(SignatureUtils.is_valid_signature(secret_key, payload, signature)).to be_truthy + end + + it "verifies request empty signature" do + expect(SignatureUtils.is_valid_signature("", "", "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6")).to be_falsey + end end \ No newline at end of file From 5a0e807424fbf48395a71b202328a5995b8837a4 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 11:25:00 +0300 Subject: [PATCH 09/32] Add testing action --- .github/workflows/test.yml | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 85f5530..f04fda8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,21 +8,19 @@ on: jobs: test: - runs-on: ubuntu-latest + name: RSpec + runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.6' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install pytest responses requests-mock - - name: Test with pytest - run: | - pytest -vv + - uses: actions/checkout@v1 + - uses: actions/setup-ruby@v1 + with: + ruby-version: [ '2.5', '2.6' ] + - name: Install dependencies + run: | + gem install bundler + bundler install + - name: Run tests + run: bundler exec rake - name: Notify slack success if: success() From 8dda9c70c0365f51456354a049bb537b2d45696b Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 11:26:28 +0300 Subject: [PATCH 10/32] Add testing action --- .github/workflows/test.yml | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f04fda8..32e1750 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,24 +22,24 @@ jobs: - name: Run tests run: bundler exec rake - - name: Notify slack success - if: success() - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - uses: voxmedia/github-action-slack-notify-build@v1.1.1 - with: - message_id: ${{ steps.slack.outputs.message_id }} - channel: github-actions - status: SUCCESS - color: good + - name: Notify slack success + if: success() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: SUCCESS + color: good - - name: Notify slack fail - if: failure() - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - uses: voxmedia/github-action-slack-notify-build@v1.1.1 - with: - message_id: ${{ steps.slack.outputs.message_id }} - channel: github-actions - status: FAILED - color: danger \ No newline at end of file + - name: Notify slack fail + if: failure() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: FAILED + color: danger \ No newline at end of file From 99befffa31ae98e51c0dbfa48ff6297ea053bfbc Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 11:27:50 +0300 Subject: [PATCH 11/32] Add testing action --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 32e1750..9a1b8c2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-ruby@v1 with: - ruby-version: [ '2.5', '2.6' ] + ruby-version: "2.6" - name: Install dependencies run: | gem install bundler From c83bed27bc56cde5e0722081a019330347bd213e Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 11:30:29 +0300 Subject: [PATCH 12/32] Add testing action --- .github/workflows/test.yml | 2 +- Rakefile | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9a1b8c2..84fb56e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ on: jobs: test: - name: RSpec + name: Testing runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v1 diff --git a/Rakefile b/Rakefile index 6a164d1..f912feb 100644 --- a/Rakefile +++ b/Rakefile @@ -1,2 +1,6 @@ require "bundler/gem_tasks" -task :default => :spec \ No newline at end of file +task :default => :spec + +require 'rspec/core/rake_task' +task :default => :spec +RSpec::Core::RakeTask.new \ No newline at end of file From 9fdc34ee87c5c61c532c3966d45a6e038ee68c76 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 11:49:06 +0300 Subject: [PATCH 13/32] Add ci and publish actions --- .github/workflows/ci.yml | 91 +++++++++++++++++----------------- .github/workflows/publish.yml | 92 +++++++++++++++++------------------ .github/workflows/test.yml | 2 +- Gemfile | 3 +- test/helper.rb | 5 ++ 5 files changed, 98 insertions(+), 95 deletions(-) create mode 100644 test/helper.rb diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f39663..4b3aed1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,53 +11,50 @@ jobs: ci: runs-on: ubuntu-latest steps: - - name: Notify slack success - if: success() - id: slack # IMPORTANT: reference this step ID value in future Slack steps - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - uses: voxmedia/github-action-slack-notify-build@v1.1.1 - with: - channel: github-actions - status: STARTING - color: warning + - name: Notify slack success + if: success() + id: slack # IMPORTANT: reference this step ID value in future Slack steps + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + channel: github-actions + status: STARTING + color: warning - - uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.6' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install pytest pytest-cov responses codecov requests-mock - - name: Test with pytest - run: | - pytest --cov=./ --cov-report=xml - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} + - uses: actions/checkout@v1 + - uses: actions/setup-ruby@v1 + with: + ruby-version: 2.6.x + - name: Install dependencies + run: | + gem install bundler + bundler install + - name: Run tests + run: bundler exec rake + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} - - name: Notify slack success - if: success() - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - uses: voxmedia/github-action-slack-notify-build@v1.1.1 - with: - message_id: ${{ steps.slack.outputs.message_id }} - channel: github-actions - status: SUCCESS - color: good + - name: Notify slack success + if: success() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: SUCCESS + color: good - - name: Notify slack fail - if: failure() - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - uses: voxmedia/github-action-slack-notify-build@v1.1.1 - with: - message_id: ${{ steps.slack.outputs.message_id }} - channel: github-actions - status: FAILED - color: danger + - name: Notify slack fail + if: failure() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: FAILED + color: danger diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7a2ee3a..613ac2c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,52 +8,52 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - name: Notify slack success - if: success() - id: slack # IMPORTANT: reference this step ID value in future Slack steps - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - uses: voxmedia/github-action-slack-notify-build@v1.1.1 - with: - channel: github-actions - status: STARTING - color: warning + - name: Notify slack success + if: success() + id: slack # IMPORTANT: reference this step ID value in future Slack steps + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + channel: github-actions + status: STARTING + color: warning - - uses: actions/checkout@v2 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: '3.6' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install setuptools wheel twine - - name: Build and publish - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - run: | - python setup.py sdist bdist_wheel - twine upload dist/* + - uses: actions/checkout@v2 + - name: Set up Ruby 2.6 + uses: actions/setup-ruby@v1 + with: + version: 2.6.x - - name: Notify slack success - if: success() - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - uses: voxmedia/github-action-slack-notify-build@v1.1.1 - with: - message_id: ${{ steps.slack.outputs.message_id }} - channel: github-actions - status: SUCCESS - color: good + - name: Publish to RubyGems + run: | + mkdir -p $HOME/.gem + touch $HOME/.gem/credentials + chmod 0600 $HOME/.gem/credentials + printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials + gem build *.gemspec + gem push *.gem + env: + GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}} - - name: Notify slack fail - if: failure() - env: - SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} - uses: voxmedia/github-action-slack-notify-build@v1.1.1 - with: - message_id: ${{ steps.slack.outputs.message_id }} - channel: github-actions - status: FAILED - color: danger \ No newline at end of file + - name: Notify slack success + if: success() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: SUCCESS + color: good + + - name: Notify slack fail + if: failure() + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + uses: voxmedia/github-action-slack-notify-build@v1.1.1 + with: + message_id: ${{ steps.slack.outputs.message_id }} + channel: github-actions + status: FAILED + color: danger \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 84fb56e..6ee04b9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v1 - uses: actions/setup-ruby@v1 with: - ruby-version: "2.6" + ruby-version: 2.6.x - name: Install dependencies run: | gem install bundler diff --git a/Gemfile b/Gemfile index bf81fcf..3619989 100644 --- a/Gemfile +++ b/Gemfile @@ -4,4 +4,5 @@ gemspec gem "rspec" gem "rake" gem "httpclient" -gem "parseconfig" \ No newline at end of file +gem "parseconfig" +gem "codecov", :require => false, :group => :test \ No newline at end of file diff --git a/test/helper.rb b/test/helper.rb new file mode 100644 index 0000000..878be66 --- /dev/null +++ b/test/helper.rb @@ -0,0 +1,5 @@ +require 'simplecov' +SimpleCov.start + +require 'codecov' +SimpleCov.formatter = SimpleCov::Formatter::Codecov \ No newline at end of file From 4850ed4ad5282ab6135966d230448528f4d58d43 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 11:50:06 +0300 Subject: [PATCH 14/32] Add ci and publish actions --- .github/workflows/publish.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 613ac2c..afc1d25 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,15 +26,15 @@ jobs: version: 2.6.x - name: Publish to RubyGems - run: | - mkdir -p $HOME/.gem - touch $HOME/.gem/credentials - chmod 0600 $HOME/.gem/credentials - printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials - gem build *.gemspec - gem push *.gem - env: - GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}} + run: | + mkdir -p $HOME/.gem + touch $HOME/.gem/credentials + chmod 0600 $HOME/.gem/credentials + printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials + gem build *.gemspec + gem push *.gem + env: + GEM_HOST_API_KEY: ${{secrets.RUBYGEMS_AUTH_TOKEN}} - name: Notify slack success if: success() From eccbcc357381c9fc091ffba55c4baa35bb5c242b Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 11:53:53 +0300 Subject: [PATCH 15/32] Add ci and publish actions --- .github/workflows/ci.yml | 1 + .github/workflows/publish.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b3aed1..abfcafc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,7 @@ on: jobs: ci: runs-on: ubuntu-latest + name: CI steps: - name: Notify slack success if: success() diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index afc1d25..2bec702 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,6 +6,7 @@ on: jobs: deploy: + name: Publish runs-on: ubuntu-latest steps: - name: Notify slack success From e9bbc8e16819c35428c4a3219217f848054a3361 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 14:44:05 +0300 Subject: [PATCH 16/32] Fix project structure --- .../.github}/workflows/ci.yml | 0 .../.github}/workflows/publish.yml | 0 .../.github}/workflows/test.yml | 0 securenative/.rakeTasks | 7 ++ Gemfile => securenative/Gemfile | 0 Gemfile.lock => securenative/Gemfile.lock | 12 ++++ Rakefile => securenative/Rakefile | 0 VERSION => securenative/VERSION | 0 {bin => securenative/bin}/console | 0 {bin => securenative/bin}/setup | 0 .../bin/test/securenative}/helper.rb | 0 .../test/securenative}/test_api_manager.rb | 0 .../test_configuration_manager.rb | 0 .../securenative}/test_context_builder.rb | 0 .../bin/test/securenative}/test_date_utils.rb | 0 .../securenative}/test_encryption_utils.rb | 0 .../test/securenative}/test_event_manager.rb | 0 .../bin/test/securenative}/test_ip_utils.rb | 0 .../test/securenative}/test_securenative.rb | 0 .../test_securenative_http_client.rb | 0 .../securenative}/test_signature_utils.rb | 0 securenative/coverage/.last_run.json | 5 ++ securenative/coverage/.resultset.json.lock | 0 .../lib}/securenative/api_manager.rb | 0 .../config/configuration_builder.rb | 0 .../config/configuration_manager.rb | 0 .../config/securenative_options.rb | 0 .../securenative/context/context_builder.rb | 0 .../context/securenative_context.rb | 0 .../lib}/securenative/enums/api_route.rb | 0 .../lib}/securenative/enums/event_types.rb | 0 .../securenative/enums/failover_strategy.rb | 0 .../lib}/securenative/enums/risk_level.rb | 0 .../lib}/securenative/event_manager.rb | 0 .../securenative/event_options_builder.rb | 0 .../securenative_config_exception.rb | 0 .../exceptions/securenative_http_exception.rb | 0 .../securenative_invalid_options_exception.rb | 0 .../securenative_invalid_uri_exception.rb | 0 .../securenative_parse_exception.rb | 0 ...ecurenative_sdk_Illegal_state_exception.rb | 0 .../exceptions/securenative_sdk_exception.rb | 0 .../lib}/securenative/http/http_response.rb | 0 .../http/securenative_http_client.rb | 0 .../lib}/securenative/logger.rb | 0 .../lib}/securenative/models/client_token.rb | 0 .../lib}/securenative/models/device.rb | 0 .../lib}/securenative/models/event_options.rb | 0 .../securenative/models/request_context.rb | 0 .../securenative/models/request_options.rb | 0 .../lib}/securenative/models/sdk_event.rb | 0 .../lib}/securenative/models/user_traits.rb | 0 .../lib}/securenative/models/verify_result.rb | 0 .../lib}/securenative/securenative.rb | 0 .../lib}/securenative/utils/date_utils.rb | 0 .../securenative/utils/encryption_utils.rb | 0 .../lib}/securenative/utils/ip_utils.rb | 0 .../lib}/securenative/utils/request_utils.rb | 0 .../securenative/utils/signature_utils.rb | 0 .../lib}/securenative/utils/utils.rb | 0 .../lib}/securenative/utils/version_utils.rb | 0 .../securenative.gemspec | 0 securenative/securenative.iml | 16 +++++ securenative/test/helper.rb | 5 ++ securenative/test/test_api_manager.rb | 67 +++++++++++++++++++ .../test/test_configuration_manager.rb | 29 ++++++++ securenative/test/test_context_builder.rb | 33 +++++++++ securenative/test/test_date_utils.rb | 8 +++ securenative/test/test_encryption_utils.rb | 21 ++++++ securenative/test/test_event_manager.rb | 51 ++++++++++++++ securenative/test/test_ip_utils.rb | 36 ++++++++++ securenative/test/test_securenative.rb | 52 ++++++++++++++ .../test/test_securenative_http_client.rb | 16 +++++ securenative/test/test_signature_utils.rb | 13 ++++ 74 files changed, 371 insertions(+) rename {.github => securenative/.github}/workflows/ci.yml (100%) rename {.github => securenative/.github}/workflows/publish.yml (100%) rename {.github => securenative/.github}/workflows/test.yml (100%) create mode 100644 securenative/.rakeTasks rename Gemfile => securenative/Gemfile (100%) rename Gemfile.lock => securenative/Gemfile.lock (75%) rename Rakefile => securenative/Rakefile (100%) rename VERSION => securenative/VERSION (100%) rename {bin => securenative/bin}/console (100%) rename {bin => securenative/bin}/setup (100%) rename {test => securenative/bin/test/securenative}/helper.rb (100%) rename {test => securenative/bin/test/securenative}/test_api_manager.rb (100%) rename {test => securenative/bin/test/securenative}/test_configuration_manager.rb (100%) rename {test => securenative/bin/test/securenative}/test_context_builder.rb (100%) rename {test => securenative/bin/test/securenative}/test_date_utils.rb (100%) rename {test => securenative/bin/test/securenative}/test_encryption_utils.rb (100%) rename {test => securenative/bin/test/securenative}/test_event_manager.rb (100%) rename {test => securenative/bin/test/securenative}/test_ip_utils.rb (100%) rename {test => securenative/bin/test/securenative}/test_securenative.rb (100%) rename {test => securenative/bin/test/securenative}/test_securenative_http_client.rb (100%) rename {test => securenative/bin/test/securenative}/test_signature_utils.rb (100%) create mode 100644 securenative/coverage/.last_run.json create mode 100644 securenative/coverage/.resultset.json.lock rename {lib => securenative/lib}/securenative/api_manager.rb (100%) rename {lib => securenative/lib}/securenative/config/configuration_builder.rb (100%) rename {lib => securenative/lib}/securenative/config/configuration_manager.rb (100%) rename {lib => securenative/lib}/securenative/config/securenative_options.rb (100%) rename {lib => securenative/lib}/securenative/context/context_builder.rb (100%) rename {lib => securenative/lib}/securenative/context/securenative_context.rb (100%) rename {lib => securenative/lib}/securenative/enums/api_route.rb (100%) rename {lib => securenative/lib}/securenative/enums/event_types.rb (100%) rename {lib => securenative/lib}/securenative/enums/failover_strategy.rb (100%) rename {lib => securenative/lib}/securenative/enums/risk_level.rb (100%) rename {lib => securenative/lib}/securenative/event_manager.rb (100%) rename {lib => securenative/lib}/securenative/event_options_builder.rb (100%) rename {lib => securenative/lib}/securenative/exceptions/securenative_config_exception.rb (100%) rename {lib => securenative/lib}/securenative/exceptions/securenative_http_exception.rb (100%) rename {lib => securenative/lib}/securenative/exceptions/securenative_invalid_options_exception.rb (100%) rename {lib => securenative/lib}/securenative/exceptions/securenative_invalid_uri_exception.rb (100%) rename {lib => securenative/lib}/securenative/exceptions/securenative_parse_exception.rb (100%) rename {lib => securenative/lib}/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb (100%) rename {lib => securenative/lib}/securenative/exceptions/securenative_sdk_exception.rb (100%) rename {lib => securenative/lib}/securenative/http/http_response.rb (100%) rename {lib => securenative/lib}/securenative/http/securenative_http_client.rb (100%) rename {lib => securenative/lib}/securenative/logger.rb (100%) rename {lib => securenative/lib}/securenative/models/client_token.rb (100%) rename {lib => securenative/lib}/securenative/models/device.rb (100%) rename {lib => securenative/lib}/securenative/models/event_options.rb (100%) rename {lib => securenative/lib}/securenative/models/request_context.rb (100%) rename {lib => securenative/lib}/securenative/models/request_options.rb (100%) rename {lib => securenative/lib}/securenative/models/sdk_event.rb (100%) rename {lib => securenative/lib}/securenative/models/user_traits.rb (100%) rename {lib => securenative/lib}/securenative/models/verify_result.rb (100%) rename {lib => securenative/lib}/securenative/securenative.rb (100%) rename {lib => securenative/lib}/securenative/utils/date_utils.rb (100%) rename {lib => securenative/lib}/securenative/utils/encryption_utils.rb (100%) rename {lib => securenative/lib}/securenative/utils/ip_utils.rb (100%) rename {lib => securenative/lib}/securenative/utils/request_utils.rb (100%) rename {lib => securenative/lib}/securenative/utils/signature_utils.rb (100%) rename {lib => securenative/lib}/securenative/utils/utils.rb (100%) rename {lib => securenative/lib}/securenative/utils/version_utils.rb (100%) rename securenative.gemspec => securenative/securenative.gemspec (100%) create mode 100644 securenative/securenative.iml create mode 100644 securenative/test/helper.rb create mode 100644 securenative/test/test_api_manager.rb create mode 100644 securenative/test/test_configuration_manager.rb create mode 100644 securenative/test/test_context_builder.rb create mode 100644 securenative/test/test_date_utils.rb create mode 100644 securenative/test/test_encryption_utils.rb create mode 100644 securenative/test/test_event_manager.rb create mode 100644 securenative/test/test_ip_utils.rb create mode 100644 securenative/test/test_securenative.rb create mode 100644 securenative/test/test_securenative_http_client.rb create mode 100644 securenative/test/test_signature_utils.rb diff --git a/.github/workflows/ci.yml b/securenative/.github/workflows/ci.yml similarity index 100% rename from .github/workflows/ci.yml rename to securenative/.github/workflows/ci.yml diff --git a/.github/workflows/publish.yml b/securenative/.github/workflows/publish.yml similarity index 100% rename from .github/workflows/publish.yml rename to securenative/.github/workflows/publish.yml diff --git a/.github/workflows/test.yml b/securenative/.github/workflows/test.yml similarity index 100% rename from .github/workflows/test.yml rename to securenative/.github/workflows/test.yml diff --git a/securenative/.rakeTasks b/securenative/.rakeTasks new file mode 100644 index 0000000..c6865d9 --- /dev/null +++ b/securenative/.rakeTasks @@ -0,0 +1,7 @@ + + diff --git a/Gemfile b/securenative/Gemfile similarity index 100% rename from Gemfile rename to securenative/Gemfile diff --git a/Gemfile.lock b/securenative/Gemfile.lock similarity index 75% rename from Gemfile.lock rename to securenative/Gemfile.lock index 0acf5f8..6204c67 100644 --- a/Gemfile.lock +++ b/securenative/Gemfile.lock @@ -6,8 +6,14 @@ PATH GEM remote: https://rubygems.org/ specs: + codecov (0.1.17) + json + simplecov + url diff-lcs (1.3) + docile (1.3.2) httpclient (2.8.3) + json (2.3.0) parseconfig (1.0.8) rake (12.3.3) rspec (3.8.0) @@ -23,12 +29,18 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-support (3.8.2) + simplecov (0.18.5) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov-html (0.12.2) + url (0.3.2) PLATFORMS ruby DEPENDENCIES bundler (~> 2.0) + codecov httpclient parseconfig rake diff --git a/Rakefile b/securenative/Rakefile similarity index 100% rename from Rakefile rename to securenative/Rakefile diff --git a/VERSION b/securenative/VERSION similarity index 100% rename from VERSION rename to securenative/VERSION diff --git a/bin/console b/securenative/bin/console similarity index 100% rename from bin/console rename to securenative/bin/console diff --git a/bin/setup b/securenative/bin/setup similarity index 100% rename from bin/setup rename to securenative/bin/setup diff --git a/test/helper.rb b/securenative/bin/test/securenative/helper.rb similarity index 100% rename from test/helper.rb rename to securenative/bin/test/securenative/helper.rb diff --git a/test/test_api_manager.rb b/securenative/bin/test/securenative/test_api_manager.rb similarity index 100% rename from test/test_api_manager.rb rename to securenative/bin/test/securenative/test_api_manager.rb diff --git a/test/test_configuration_manager.rb b/securenative/bin/test/securenative/test_configuration_manager.rb similarity index 100% rename from test/test_configuration_manager.rb rename to securenative/bin/test/securenative/test_configuration_manager.rb diff --git a/test/test_context_builder.rb b/securenative/bin/test/securenative/test_context_builder.rb similarity index 100% rename from test/test_context_builder.rb rename to securenative/bin/test/securenative/test_context_builder.rb diff --git a/test/test_date_utils.rb b/securenative/bin/test/securenative/test_date_utils.rb similarity index 100% rename from test/test_date_utils.rb rename to securenative/bin/test/securenative/test_date_utils.rb diff --git a/test/test_encryption_utils.rb b/securenative/bin/test/securenative/test_encryption_utils.rb similarity index 100% rename from test/test_encryption_utils.rb rename to securenative/bin/test/securenative/test_encryption_utils.rb diff --git a/test/test_event_manager.rb b/securenative/bin/test/securenative/test_event_manager.rb similarity index 100% rename from test/test_event_manager.rb rename to securenative/bin/test/securenative/test_event_manager.rb diff --git a/test/test_ip_utils.rb b/securenative/bin/test/securenative/test_ip_utils.rb similarity index 100% rename from test/test_ip_utils.rb rename to securenative/bin/test/securenative/test_ip_utils.rb diff --git a/test/test_securenative.rb b/securenative/bin/test/securenative/test_securenative.rb similarity index 100% rename from test/test_securenative.rb rename to securenative/bin/test/securenative/test_securenative.rb diff --git a/test/test_securenative_http_client.rb b/securenative/bin/test/securenative/test_securenative_http_client.rb similarity index 100% rename from test/test_securenative_http_client.rb rename to securenative/bin/test/securenative/test_securenative_http_client.rb diff --git a/test/test_signature_utils.rb b/securenative/bin/test/securenative/test_signature_utils.rb similarity index 100% rename from test/test_signature_utils.rb rename to securenative/bin/test/securenative/test_signature_utils.rb diff --git a/securenative/coverage/.last_run.json b/securenative/coverage/.last_run.json new file mode 100644 index 0000000..a69eb39 --- /dev/null +++ b/securenative/coverage/.last_run.json @@ -0,0 +1,5 @@ +{ + "result": { + "covered_percent": 0.0 + } +} diff --git a/securenative/coverage/.resultset.json.lock b/securenative/coverage/.resultset.json.lock new file mode 100644 index 0000000..e69de29 diff --git a/lib/securenative/api_manager.rb b/securenative/lib/securenative/api_manager.rb similarity index 100% rename from lib/securenative/api_manager.rb rename to securenative/lib/securenative/api_manager.rb diff --git a/lib/securenative/config/configuration_builder.rb b/securenative/lib/securenative/config/configuration_builder.rb similarity index 100% rename from lib/securenative/config/configuration_builder.rb rename to securenative/lib/securenative/config/configuration_builder.rb diff --git a/lib/securenative/config/configuration_manager.rb b/securenative/lib/securenative/config/configuration_manager.rb similarity index 100% rename from lib/securenative/config/configuration_manager.rb rename to securenative/lib/securenative/config/configuration_manager.rb diff --git a/lib/securenative/config/securenative_options.rb b/securenative/lib/securenative/config/securenative_options.rb similarity index 100% rename from lib/securenative/config/securenative_options.rb rename to securenative/lib/securenative/config/securenative_options.rb diff --git a/lib/securenative/context/context_builder.rb b/securenative/lib/securenative/context/context_builder.rb similarity index 100% rename from lib/securenative/context/context_builder.rb rename to securenative/lib/securenative/context/context_builder.rb diff --git a/lib/securenative/context/securenative_context.rb b/securenative/lib/securenative/context/securenative_context.rb similarity index 100% rename from lib/securenative/context/securenative_context.rb rename to securenative/lib/securenative/context/securenative_context.rb diff --git a/lib/securenative/enums/api_route.rb b/securenative/lib/securenative/enums/api_route.rb similarity index 100% rename from lib/securenative/enums/api_route.rb rename to securenative/lib/securenative/enums/api_route.rb diff --git a/lib/securenative/enums/event_types.rb b/securenative/lib/securenative/enums/event_types.rb similarity index 100% rename from lib/securenative/enums/event_types.rb rename to securenative/lib/securenative/enums/event_types.rb diff --git a/lib/securenative/enums/failover_strategy.rb b/securenative/lib/securenative/enums/failover_strategy.rb similarity index 100% rename from lib/securenative/enums/failover_strategy.rb rename to securenative/lib/securenative/enums/failover_strategy.rb diff --git a/lib/securenative/enums/risk_level.rb b/securenative/lib/securenative/enums/risk_level.rb similarity index 100% rename from lib/securenative/enums/risk_level.rb rename to securenative/lib/securenative/enums/risk_level.rb diff --git a/lib/securenative/event_manager.rb b/securenative/lib/securenative/event_manager.rb similarity index 100% rename from lib/securenative/event_manager.rb rename to securenative/lib/securenative/event_manager.rb diff --git a/lib/securenative/event_options_builder.rb b/securenative/lib/securenative/event_options_builder.rb similarity index 100% rename from lib/securenative/event_options_builder.rb rename to securenative/lib/securenative/event_options_builder.rb diff --git a/lib/securenative/exceptions/securenative_config_exception.rb b/securenative/lib/securenative/exceptions/securenative_config_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_config_exception.rb rename to securenative/lib/securenative/exceptions/securenative_config_exception.rb diff --git a/lib/securenative/exceptions/securenative_http_exception.rb b/securenative/lib/securenative/exceptions/securenative_http_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_http_exception.rb rename to securenative/lib/securenative/exceptions/securenative_http_exception.rb diff --git a/lib/securenative/exceptions/securenative_invalid_options_exception.rb b/securenative/lib/securenative/exceptions/securenative_invalid_options_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_invalid_options_exception.rb rename to securenative/lib/securenative/exceptions/securenative_invalid_options_exception.rb diff --git a/lib/securenative/exceptions/securenative_invalid_uri_exception.rb b/securenative/lib/securenative/exceptions/securenative_invalid_uri_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_invalid_uri_exception.rb rename to securenative/lib/securenative/exceptions/securenative_invalid_uri_exception.rb diff --git a/lib/securenative/exceptions/securenative_parse_exception.rb b/securenative/lib/securenative/exceptions/securenative_parse_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_parse_exception.rb rename to securenative/lib/securenative/exceptions/securenative_parse_exception.rb diff --git a/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb b/securenative/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb rename to securenative/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb diff --git a/lib/securenative/exceptions/securenative_sdk_exception.rb b/securenative/lib/securenative/exceptions/securenative_sdk_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_sdk_exception.rb rename to securenative/lib/securenative/exceptions/securenative_sdk_exception.rb diff --git a/lib/securenative/http/http_response.rb b/securenative/lib/securenative/http/http_response.rb similarity index 100% rename from lib/securenative/http/http_response.rb rename to securenative/lib/securenative/http/http_response.rb diff --git a/lib/securenative/http/securenative_http_client.rb b/securenative/lib/securenative/http/securenative_http_client.rb similarity index 100% rename from lib/securenative/http/securenative_http_client.rb rename to securenative/lib/securenative/http/securenative_http_client.rb diff --git a/lib/securenative/logger.rb b/securenative/lib/securenative/logger.rb similarity index 100% rename from lib/securenative/logger.rb rename to securenative/lib/securenative/logger.rb diff --git a/lib/securenative/models/client_token.rb b/securenative/lib/securenative/models/client_token.rb similarity index 100% rename from lib/securenative/models/client_token.rb rename to securenative/lib/securenative/models/client_token.rb diff --git a/lib/securenative/models/device.rb b/securenative/lib/securenative/models/device.rb similarity index 100% rename from lib/securenative/models/device.rb rename to securenative/lib/securenative/models/device.rb diff --git a/lib/securenative/models/event_options.rb b/securenative/lib/securenative/models/event_options.rb similarity index 100% rename from lib/securenative/models/event_options.rb rename to securenative/lib/securenative/models/event_options.rb diff --git a/lib/securenative/models/request_context.rb b/securenative/lib/securenative/models/request_context.rb similarity index 100% rename from lib/securenative/models/request_context.rb rename to securenative/lib/securenative/models/request_context.rb diff --git a/lib/securenative/models/request_options.rb b/securenative/lib/securenative/models/request_options.rb similarity index 100% rename from lib/securenative/models/request_options.rb rename to securenative/lib/securenative/models/request_options.rb diff --git a/lib/securenative/models/sdk_event.rb b/securenative/lib/securenative/models/sdk_event.rb similarity index 100% rename from lib/securenative/models/sdk_event.rb rename to securenative/lib/securenative/models/sdk_event.rb diff --git a/lib/securenative/models/user_traits.rb b/securenative/lib/securenative/models/user_traits.rb similarity index 100% rename from lib/securenative/models/user_traits.rb rename to securenative/lib/securenative/models/user_traits.rb diff --git a/lib/securenative/models/verify_result.rb b/securenative/lib/securenative/models/verify_result.rb similarity index 100% rename from lib/securenative/models/verify_result.rb rename to securenative/lib/securenative/models/verify_result.rb diff --git a/lib/securenative/securenative.rb b/securenative/lib/securenative/securenative.rb similarity index 100% rename from lib/securenative/securenative.rb rename to securenative/lib/securenative/securenative.rb diff --git a/lib/securenative/utils/date_utils.rb b/securenative/lib/securenative/utils/date_utils.rb similarity index 100% rename from lib/securenative/utils/date_utils.rb rename to securenative/lib/securenative/utils/date_utils.rb diff --git a/lib/securenative/utils/encryption_utils.rb b/securenative/lib/securenative/utils/encryption_utils.rb similarity index 100% rename from lib/securenative/utils/encryption_utils.rb rename to securenative/lib/securenative/utils/encryption_utils.rb diff --git a/lib/securenative/utils/ip_utils.rb b/securenative/lib/securenative/utils/ip_utils.rb similarity index 100% rename from lib/securenative/utils/ip_utils.rb rename to securenative/lib/securenative/utils/ip_utils.rb diff --git a/lib/securenative/utils/request_utils.rb b/securenative/lib/securenative/utils/request_utils.rb similarity index 100% rename from lib/securenative/utils/request_utils.rb rename to securenative/lib/securenative/utils/request_utils.rb diff --git a/lib/securenative/utils/signature_utils.rb b/securenative/lib/securenative/utils/signature_utils.rb similarity index 100% rename from lib/securenative/utils/signature_utils.rb rename to securenative/lib/securenative/utils/signature_utils.rb diff --git a/lib/securenative/utils/utils.rb b/securenative/lib/securenative/utils/utils.rb similarity index 100% rename from lib/securenative/utils/utils.rb rename to securenative/lib/securenative/utils/utils.rb diff --git a/lib/securenative/utils/version_utils.rb b/securenative/lib/securenative/utils/version_utils.rb similarity index 100% rename from lib/securenative/utils/version_utils.rb rename to securenative/lib/securenative/utils/version_utils.rb diff --git a/securenative.gemspec b/securenative/securenative.gemspec similarity index 100% rename from securenative.gemspec rename to securenative/securenative.gemspec diff --git a/securenative/securenative.iml b/securenative/securenative.iml new file mode 100644 index 0000000..10434d1 --- /dev/null +++ b/securenative/securenative.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/securenative/test/helper.rb b/securenative/test/helper.rb new file mode 100644 index 0000000..878be66 --- /dev/null +++ b/securenative/test/helper.rb @@ -0,0 +1,5 @@ +require 'simplecov' +SimpleCov.start + +require 'codecov' +SimpleCov.formatter = SimpleCov::Formatter::Codecov \ No newline at end of file diff --git a/securenative/test/test_api_manager.rb b/securenative/test/test_api_manager.rb new file mode 100644 index 0000000..525e55b --- /dev/null +++ b/securenative/test/test_api_manager.rb @@ -0,0 +1,67 @@ +describe ApiManager do + let(:context) { ContextBuilder().with_ip("127.0.0.1").with_client_token("SECURED_CLIENT_TOKEN").with_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"}).build } + let(:event_options) { EventOptionsBuilder(EventTypes.LOG_IN).with_user_id("USER_ID").with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")).with_context(context).with_properties({:prop1 => "CUSTOM_PARAM_VALUE", :prop2 => true, :prop3 => 3}).build } + + it "tracks an event" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_auto_send(true).with_interval(10).with_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\",\"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}}" + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json = json.loads(expected), status = 200) + event_manager = EventManager.new(options) + event_manager.start_event_persist + api_manager = ApiManager.new(event_manager, options) + + begin + api_manager.track(event_options) + ensure + event_manager.stop_event_persist + end + end + + it "uses invalid options" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_auto_send(true).with_interval(10).with_api_url("https://api.securenative-stg.com/collector/api/v1") + + properties = {} + (0..12).each { |i| + properties[i] = i + } + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json = {}, status = 200) + event_manager = EventManager.new(options) + event_manager.start_event_persist + api_manager = ApiManager.new(event_manager, options) + + begin + expect { api_manager.track(EventOptionsBuilder(EventTypes.LOG_IN).with_properties(properties).build) }.to raise_error(Errors::SecureNativeInvalidOptionsException) + ensure + event_manager.stop_event_persist + end + end + + it "verifies an event" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/verify", json = {:riskLevel => "medium", :score => 0.32, :triggers => ["New IP", "New City"]}, status = 200) + verify_result = VerifyResult.new(RiskLevel.LOW, 0, nil) + + event_manager = EventManager.new(options) + event_manager.start_event_persist + api_manager = ApiManager.new(event_manager, options) + + result = api_manager.verify(event_options) + + expect(result).not_to be_empty + expect(result.risk_level).to eq(verify_result.risk_level) + expect(result.score).to eq(verify_result.score) + expect(result.triggers).to eq(verify_result.triggers) + end +end \ No newline at end of file diff --git a/securenative/test/test_configuration_manager.rb b/securenative/test/test_configuration_manager.rb new file mode 100644 index 0000000..5626869 --- /dev/null +++ b/securenative/test/test_configuration_manager.rb @@ -0,0 +1,29 @@ +describe ConfigurationManager do + it "parses a config file correctly" do + # code here + end + + it "ignores unknown config in properties file" do + # code here + end + + it "handles invalid config file" do + # code here + end + + it "ignores invalid config file entries" do + # code here + end + + it "loads default config" do + # code here + end + + it "gets config from env variables" do + # code here + end + + it "uses default values for invalid enum config props" do + # code here + end +end \ No newline at end of file diff --git a/securenative/test/test_context_builder.rb b/securenative/test/test_context_builder.rb new file mode 100644 index 0000000..3128e13 --- /dev/null +++ b/securenative/test/test_context_builder.rb @@ -0,0 +1,33 @@ +describe ContextBuilder do + it "creates context from request" do + # TODO code here + end + + it "creates context from request with cookie" do + # TODO code here + end + + it "creates default context builder" do + context = ContextBuilder.default_context_builder.build + + expect(context.client_token).not_to be_empty + expect(context.ip).not_to be_empty + expect(context.method).not_to be_empty + expect(context.url).not_to be_empty + expect(context.remote_ip).not_to be_empty + expect(context.headers).not_to be_empty + expect(context.body).not_to be_empty + end + + it "creates custom context with context builder" do + context = ContextBuilder.default_context_builder.with_url("/some-url").with_client_token("SECRET_TOKEN").with_ip("10.0.0.0").with_body("{ \"name\": \"YOUR_NAME\" }").with_method("Get").with_remote_ip("10.0.0.1").with_headers({:header1 => "value1"}).build + + expect(context.url).to eq("/some-url") + expect(context.client_token).to eq("SECRET_TOKEN") + expect(context.ip).to eq("10.0.0.0") + expect(context.body).to eq("{ \"name\": \"YOUR_NAME\" }") + expect(context.method).to eq("Get") + expect(context.remote_ip).to eq("10.0.0.0") + expect(context.headers).to eq({:header1 => "value1"}) + end +end \ No newline at end of file diff --git a/securenative/test/test_date_utils.rb b/securenative/test/test_date_utils.rb new file mode 100644 index 0000000..35204bd --- /dev/null +++ b/securenative/test/test_date_utils.rb @@ -0,0 +1,8 @@ +describe DateUtils do + it "converts to timestamp" do + iso_8601_date = "2020-05-20T15:07:13Z" + result = DateUtils.to_timestamp(iso_8601_date) + + expect(result).to eq(Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z")) + end +end \ No newline at end of file diff --git a/securenative/test/test_encryption_utils.rb b/securenative/test/test_encryption_utils.rb new file mode 100644 index 0000000..d7d6132 --- /dev/null +++ b/securenative/test/test_encryption_utils.rb @@ -0,0 +1,21 @@ +describe EncryptionUtils do + let(:SECRET_KEY) { "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6" } + let(:PAYLOAD) { "{\"cid\":\"198a41ff-a10f-4cda-a2f3-a9ca80c0703b\",\"vi\":\"148a42ff-b40f-4cda-a2f3-a8ca80c0703b\",\"fp\":\"6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed\"}" } + let(:CID) { "198a41ff-a10f-4cda-a2f3-a9ca80c0703b" } + let(:FP) { "6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed" } + + it "decrypts" do + result = EncryptionUtils.encrypt(PAYLOAD, SECRET_KEY) + + expect(result).not_to be_empty + expect(result.length).to eq(PAYLOAD.length) + end + + it "encrypts" do + encrypted_payload = "5208ae703cc2fa0851347f55d3b76d3fd6035ee081d71a401e8bc92ebdc25d42440f62310bda60628537744ac03f200d78da9e61f1019ce02087b7ce6c976e7b2d8ad6aa978c532cea8f3e744cc6a5cafedc4ae6cd1b08a4ef75d6e37aa3c0c76954d16d57750be2980c2c91ac7ef0bbd0722abd59bf6be22493ea9b9759c3ff4d17f17ab670b0b6fc320e6de982313f1c4e74c0897f9f5a32d58e3e53050ae8fdbebba9009d0d1250fe34dcde1ebb42acbc22834a02f53889076140f0eb8db1" + result = EncryptionUtils.decrypt(encrypted_payload, SECRET_KEY) + + expect(result.cid).to eq(CID) + expect(result.fp).to eq(FP) + end +end \ No newline at end of file diff --git a/securenative/test/test_event_manager.rb b/securenative/test/test_event_manager.rb new file mode 100644 index 0000000..6c95931 --- /dev/null +++ b/securenative/test/test_event_manager.rb @@ -0,0 +1,51 @@ +class SampleEvent + attr_reader :event_type, :timestamp, :rid, :user_id, :user_traits, :request, :properties + + def initialize + @event_type = "custom-event" + @timestamp = Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z") + @rid = "432532" + @user_id = "1" + @user_traits = UserTraits("some user", "email@securenative.com") + @request = RequestContext() + @properties = [] + end +end + +describe EventManager do + let(:event) { SampleEvent() } + + it "successfully sends sync event with status code 200" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + + res_body = "{\"data\": true}" + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = json.loads(res_body), status = 200) + event_manager = EventManager.new(options) + data = event_manager.send_sync(self.event, "some-path/to-api", false) + + expect(res_body).to eq(data.text) + end + + it "fails when send sync event status code is 401" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = {}, status = 401) + event_manager = EventManager.new(options) + res = event_manager.send_sync(self.event, "some-path/to-api", false) + + expect(res.status_code).to eq(401) + end + + it "fails when send sync event status code is 500" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = {}, status = 500) + event_manager = EventManager.new(options) + res = event_manager.send_sync(self.event, "some-path/to-api", false) + + expect(res.status_code).to eq(500) + end +end \ No newline at end of file diff --git a/securenative/test/test_ip_utils.rb b/securenative/test/test_ip_utils.rb new file mode 100644 index 0000000..16e9401 --- /dev/null +++ b/securenative/test/test_ip_utils.rb @@ -0,0 +1,36 @@ +describe IpUtils do + it "checks if ip address valid ipv4" do + valid_ipv4 = "172.16.254.1" + expect(IpUtils.is_ip_address(valid_ipv4)).to be_truthy + end + + it "checks if ip address valid ipv6" do + valid_ipv6 = "2001:db8:1234:0000:0000:0000:0000:0000" + expect(IpUtils.is_ip_address(valid_ipv6)).to be_truthy + end + + it "checks if ip address invalid ipv4" do + invalid_ipv4 = "172.16.2541" + expect(IpUtils.is_ip_address(invalid_ipv4)).to be_falsey + end + + it "checks if ip address invalid ipv6" do + invalid_ipv6 = "2001:db8:1234:0000" + expect(IpUtils.is_ip_address(invalid_ipv6)).to be_falsey + end + + it "checks if valid public ip" do + ip = "64.71.222.37" + expect(IpUtils.is_valid_public_ip(ip)).to be_truthy + end + + it "checks if not valid public ip" do + ip = "10.0.0.0" + expect(IpUtils.is_valid_public_ip(ip)).to be_falsey + end + + it "checks if valid loopback ip" do + ip = "127.0.0.1" + expect(IpUtils.is_loop_back(ip)).to be_truthy + end +end \ No newline at end of file diff --git a/securenative/test/test_securenative.rb b/securenative/test/test_securenative.rb new file mode 100644 index 0000000..e9cfd7b --- /dev/null +++ b/securenative/test/test_securenative.rb @@ -0,0 +1,52 @@ +describe SecureNative do + it "gets sdk instance without init throws" do + expect { SecureNative.get_instance }.to raise_error(Errors::SecureNativeSDKIllegalStateException) + end + + it "inits sdk without api key and throws" do + expect { SecureNative.init_with_options(ConfigurationManager.config_builder) }.to raise_error(Errors::SecureNativeSDKException) + end + + it "inits sdk with empty api key and throws" do + expect { SecureNative.init_with_api_key("") }.to raise_error(Errors::SecureNativeSDKException) + end + + it "inits sdk with api key and defaults" do + SecureNative._flush + api_key = "API_KEY" + securenative = SecureNative.init_with_api_key(api_key) + options = securenative.get_options + + expect(options.api_key).to eq(api_key) + expect(options.api_url).to eq("https://api.securenative.com/collector/api/v1") + expect(options.interval).to eq(1000) + expect(options.timeout).to eq(1500) + expect(options.max_events).to eq(100) + expect(options.auto_send).to eq(true) + expect(options.disable).to eq(false) + expect(options.log_level).to eq("FATAL") + expect(options.fail_over_strategy).to eq(FailOverStrategy::FAIL_OPEN) + end + + it "inits sdk twice and throws" do + expect { SecureNative.init_with_api_key("API_KEY") }.to raise_error(Errors::SecureNativeSDKException) + end + + it "inits sdk with api key and gets instance" do + SecureNative._flush + api_key = "API_KEY" + securenative = SecureNative.init_with_api_key(api_key) + + expect(securenative).to eq(SecureNative.get_instance) + end + + it "inits sdk with builder" do + SecureNative._flush + securenative = SecureNative.init_with_options(SecureNative.config_builder.with_api_key("API_KEY").with_max_events(10).with_log_level("ERROR")) + options = securenative.get_options + + expect(options.api_key).to eq("API_KEY") + expect(options.max_events).to eq(10) + expect(options.log_level).to eq("ERROR") + end +end \ No newline at end of file diff --git a/securenative/test/test_securenative_http_client.rb b/securenative/test/test_securenative_http_client.rb new file mode 100644 index 0000000..43892b1 --- /dev/null +++ b/securenative/test/test_securenative_http_client.rb @@ -0,0 +1,16 @@ +describe SecureNativeHttpClient do + it "makes a simple post call" do + options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + + # TODO + responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json={"event" => "SOME_EVENT_NAME"}, status=200) + client = SecureNativeHttpClient(options) + payload = "{\"event\": \"SOME_EVENT_NAME\"}" + + res = client.post("track", payload) + + expect(res.ok).to eq(true) + expect(res.status_code).to eq(200) + expect(res.text).to eq(payload) + end +end \ No newline at end of file diff --git a/securenative/test/test_signature_utils.rb b/securenative/test/test_signature_utils.rb new file mode 100644 index 0000000..fde96ca --- /dev/null +++ b/securenative/test/test_signature_utils.rb @@ -0,0 +1,13 @@ +describe SignatureUtils do + it "verifies request payload" do + signature = "c4574c1748064735513697750c6223ff36b03ae3b85b160ce8788557d01e1d9d1c9cd942074323ee0061d3dcc8c94359c5acfa6eee8e2da095b3967b1a88ab73" + payload = "{\"id\":\"4a9157ffbd18cfbd73a57298\",\"type\":\"security-action\",\"flow\":{\"id\":\"62298c73a9bb433fbd1f75984a9157fd\",\"name\":\"Block user that violates geo velocity\"},\"userId\":\"73a9bb433fbd1f75984a9157\",\"userTraits\":{\"name\":\"John Doe\",\"email\":\"john.doe@gmail.com\"},\"request\":{\"ip\":\"10.0.0.0\",\"fp\":\"9bb433fb984a9157d1f7598\"},\"action\":\"block\",\"properties\":{\"type\":\"customer\"},\"timestamp\":\"2020-02-23T22:28:55.387Z\"}" + secret_key = "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6" + + expect(SignatureUtils.is_valid_signature(secret_key, payload, signature)).to be_truthy + end + + it "verifies request empty signature" do + expect(SignatureUtils.is_valid_signature("", "", "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6")).to be_falsey + end +end \ No newline at end of file From 77a315b0d0dd72164c38670260b801d5e2da788b Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 14:45:38 +0300 Subject: [PATCH 17/32] Fix project structure --- {securenative/.github => .github}/workflows/ci.yml | 0 {securenative/.github => .github}/workflows/publish.yml | 0 {securenative/.github => .github}/workflows/test.yml | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {securenative/.github => .github}/workflows/ci.yml (100%) rename {securenative/.github => .github}/workflows/publish.yml (100%) rename {securenative/.github => .github}/workflows/test.yml (100%) diff --git a/securenative/.github/workflows/ci.yml b/.github/workflows/ci.yml similarity index 100% rename from securenative/.github/workflows/ci.yml rename to .github/workflows/ci.yml diff --git a/securenative/.github/workflows/publish.yml b/.github/workflows/publish.yml similarity index 100% rename from securenative/.github/workflows/publish.yml rename to .github/workflows/publish.yml diff --git a/securenative/.github/workflows/test.yml b/.github/workflows/test.yml similarity index 100% rename from securenative/.github/workflows/test.yml rename to .github/workflows/test.yml From 8c91ac5a4f67b3400f7413a901ef52671dfe342f Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 14:49:54 +0300 Subject: [PATCH 18/32] Fix project structure --- securenative/.rakeTasks => .rakeTasks | 0 securenative/Gemfile => Gemfile | 0 securenative/Gemfile.lock => Gemfile.lock | 0 securenative/Rakefile => Rakefile | 0 securenative/VERSION => VERSION | 0 securenative/securenative.gemspec => securenative.gemspec | 0 securenative/securenative.iml | 2 +- 7 files changed, 1 insertion(+), 1 deletion(-) rename securenative/.rakeTasks => .rakeTasks (100%) rename securenative/Gemfile => Gemfile (100%) rename securenative/Gemfile.lock => Gemfile.lock (100%) rename securenative/Rakefile => Rakefile (100%) rename securenative/VERSION => VERSION (100%) rename securenative/securenative.gemspec => securenative.gemspec (100%) diff --git a/securenative/.rakeTasks b/.rakeTasks similarity index 100% rename from securenative/.rakeTasks rename to .rakeTasks diff --git a/securenative/Gemfile b/Gemfile similarity index 100% rename from securenative/Gemfile rename to Gemfile diff --git a/securenative/Gemfile.lock b/Gemfile.lock similarity index 100% rename from securenative/Gemfile.lock rename to Gemfile.lock diff --git a/securenative/Rakefile b/Rakefile similarity index 100% rename from securenative/Rakefile rename to Rakefile diff --git a/securenative/VERSION b/VERSION similarity index 100% rename from securenative/VERSION rename to VERSION diff --git a/securenative/securenative.gemspec b/securenative.gemspec similarity index 100% rename from securenative/securenative.gemspec rename to securenative.gemspec diff --git a/securenative/securenative.iml b/securenative/securenative.iml index 10434d1..7ee1a88 100644 --- a/securenative/securenative.iml +++ b/securenative/securenative.iml @@ -5,11 +5,11 @@ + - From 4a9f94f0129f2c863d4fe9ea8e33774753248f09 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 15:10:32 +0300 Subject: [PATCH 19/32] Fix project structure --- .rspec | 3 + .travis.yml | 6 ++ {securenative/bin => bin}/console | 0 {securenative/bin => bin}/setup | 0 .../lib => lib}/securenative/api_manager.rb | 0 .../config/configuration_builder.rb | 0 .../config/configuration_manager.rb | 0 .../config/securenative_options.rb | 0 .../securenative/context/context_builder.rb | 0 .../context/securenative_context.rb | 0 .../securenative/enums/api_route.rb | 0 .../securenative/enums/event_types.rb | 0 .../securenative/enums/failover_strategy.rb | 0 .../securenative/enums/risk_level.rb | 0 .../lib => lib}/securenative/event_manager.rb | 0 .../securenative/event_options_builder.rb | 0 .../securenative_config_exception.rb | 0 .../exceptions/securenative_http_exception.rb | 0 .../securenative_invalid_options_exception.rb | 0 .../securenative_invalid_uri_exception.rb | 0 .../securenative_parse_exception.rb | 0 ...ecurenative_sdk_Illegal_state_exception.rb | 0 .../exceptions/securenative_sdk_exception.rb | 0 .../securenative/http/http_response.rb | 0 .../http/securenative_http_client.rb | 0 .../lib => lib}/securenative/logger.rb | 0 .../securenative/models/client_token.rb | 0 .../lib => lib}/securenative/models/device.rb | 0 .../securenative/models/event_options.rb | 0 .../securenative/models/request_context.rb | 0 .../securenative/models/request_options.rb | 0 .../securenative/models/sdk_event.rb | 0 .../securenative/models/user_traits.rb | 0 .../securenative/models/verify_result.rb | 0 .../lib => lib}/securenative/securenative.rb | 0 .../securenative/utils/date_utils.rb | 0 .../securenative/utils/encryption_utils.rb | 0 .../securenative/utils/ip_utils.rb | 0 .../securenative/utils/request_utils.rb | 0 .../securenative/utils/signature_utils.rb | 0 .../lib => lib}/securenative/utils/utils.rb | 0 .../securenative/utils/version_utils.rb | 0 .../securenative.iml => securenative.iml | 3 +- securenative/bin/test/securenative/helper.rb | 5 -- securenative/coverage/.last_run.json | 5 -- securenative/coverage/.resultset.json.lock | 0 securenative/test/helper.rb | 5 -- securenative/test/test_api_manager.rb | 67 ------------------- .../test/test_configuration_manager.rb | 29 -------- securenative/test/test_context_builder.rb | 33 --------- securenative/test/test_date_utils.rb | 8 --- securenative/test/test_encryption_utils.rb | 21 ------ securenative/test/test_event_manager.rb | 51 -------------- securenative/test/test_ip_utils.rb | 36 ---------- securenative/test/test_securenative.rb | 52 -------------- .../test/test_securenative_http_client.rb | 16 ----- securenative/test/test_signature_utils.rb | 13 ---- spec/securanative_spec.rb | 9 +++ spec/spec_helper.rb | 20 ++++++ .../securenative => spec}/test_api_manager.rb | 0 .../test_configuration_manager.rb | 0 .../test_context_builder.rb | 0 .../securenative => spec}/test_date_utils.rb | 0 .../test_encryption_utils.rb | 0 .../test_event_manager.rb | 0 .../securenative => spec}/test_ip_utils.rb | 0 .../test_securenative.rb | 0 .../test_securenative_http_client.rb | 0 .../test_signature_utils.rb | 0 69 files changed, 39 insertions(+), 343 deletions(-) create mode 100644 .rspec create mode 100644 .travis.yml rename {securenative/bin => bin}/console (100%) rename {securenative/bin => bin}/setup (100%) rename {securenative/lib => lib}/securenative/api_manager.rb (100%) rename {securenative/lib => lib}/securenative/config/configuration_builder.rb (100%) rename {securenative/lib => lib}/securenative/config/configuration_manager.rb (100%) rename {securenative/lib => lib}/securenative/config/securenative_options.rb (100%) rename {securenative/lib => lib}/securenative/context/context_builder.rb (100%) rename {securenative/lib => lib}/securenative/context/securenative_context.rb (100%) rename {securenative/lib => lib}/securenative/enums/api_route.rb (100%) rename {securenative/lib => lib}/securenative/enums/event_types.rb (100%) rename {securenative/lib => lib}/securenative/enums/failover_strategy.rb (100%) rename {securenative/lib => lib}/securenative/enums/risk_level.rb (100%) rename {securenative/lib => lib}/securenative/event_manager.rb (100%) rename {securenative/lib => lib}/securenative/event_options_builder.rb (100%) rename {securenative/lib => lib}/securenative/exceptions/securenative_config_exception.rb (100%) rename {securenative/lib => lib}/securenative/exceptions/securenative_http_exception.rb (100%) rename {securenative/lib => lib}/securenative/exceptions/securenative_invalid_options_exception.rb (100%) rename {securenative/lib => lib}/securenative/exceptions/securenative_invalid_uri_exception.rb (100%) rename {securenative/lib => lib}/securenative/exceptions/securenative_parse_exception.rb (100%) rename {securenative/lib => lib}/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb (100%) rename {securenative/lib => lib}/securenative/exceptions/securenative_sdk_exception.rb (100%) rename {securenative/lib => lib}/securenative/http/http_response.rb (100%) rename {securenative/lib => lib}/securenative/http/securenative_http_client.rb (100%) rename {securenative/lib => lib}/securenative/logger.rb (100%) rename {securenative/lib => lib}/securenative/models/client_token.rb (100%) rename {securenative/lib => lib}/securenative/models/device.rb (100%) rename {securenative/lib => lib}/securenative/models/event_options.rb (100%) rename {securenative/lib => lib}/securenative/models/request_context.rb (100%) rename {securenative/lib => lib}/securenative/models/request_options.rb (100%) rename {securenative/lib => lib}/securenative/models/sdk_event.rb (100%) rename {securenative/lib => lib}/securenative/models/user_traits.rb (100%) rename {securenative/lib => lib}/securenative/models/verify_result.rb (100%) rename {securenative/lib => lib}/securenative/securenative.rb (100%) rename {securenative/lib => lib}/securenative/utils/date_utils.rb (100%) rename {securenative/lib => lib}/securenative/utils/encryption_utils.rb (100%) rename {securenative/lib => lib}/securenative/utils/ip_utils.rb (100%) rename {securenative/lib => lib}/securenative/utils/request_utils.rb (100%) rename {securenative/lib => lib}/securenative/utils/signature_utils.rb (100%) rename {securenative/lib => lib}/securenative/utils/utils.rb (100%) rename {securenative/lib => lib}/securenative/utils/version_utils.rb (100%) rename securenative/securenative.iml => securenative.iml (84%) delete mode 100644 securenative/bin/test/securenative/helper.rb delete mode 100644 securenative/coverage/.last_run.json delete mode 100644 securenative/coverage/.resultset.json.lock delete mode 100644 securenative/test/helper.rb delete mode 100644 securenative/test/test_api_manager.rb delete mode 100644 securenative/test/test_configuration_manager.rb delete mode 100644 securenative/test/test_context_builder.rb delete mode 100644 securenative/test/test_date_utils.rb delete mode 100644 securenative/test/test_encryption_utils.rb delete mode 100644 securenative/test/test_event_manager.rb delete mode 100644 securenative/test/test_ip_utils.rb delete mode 100644 securenative/test/test_securenative.rb delete mode 100644 securenative/test/test_securenative_http_client.rb delete mode 100644 securenative/test/test_signature_utils.rb create mode 100644 spec/securanative_spec.rb create mode 100644 spec/spec_helper.rb rename {securenative/bin/test/securenative => spec}/test_api_manager.rb (100%) rename {securenative/bin/test/securenative => spec}/test_configuration_manager.rb (100%) rename {securenative/bin/test/securenative => spec}/test_context_builder.rb (100%) rename {securenative/bin/test/securenative => spec}/test_date_utils.rb (100%) rename {securenative/bin/test/securenative => spec}/test_encryption_utils.rb (100%) rename {securenative/bin/test/securenative => spec}/test_event_manager.rb (100%) rename {securenative/bin/test/securenative => spec}/test_ip_utils.rb (100%) rename {securenative/bin/test/securenative => spec}/test_securenative.rb (100%) rename {securenative/bin/test/securenative => spec}/test_securenative_http_client.rb (100%) rename {securenative/bin/test/securenative => spec}/test_signature_utils.rb (100%) diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..34c5164 --- /dev/null +++ b/.rspec @@ -0,0 +1,3 @@ +--format documentation +--color +--require spec_helper diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..8dd84f7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +--- +language: ruby +cache: bundler +rvm: + - 2.7.1 +before_install: gem install bundler -v 2.1.2 diff --git a/securenative/bin/console b/bin/console similarity index 100% rename from securenative/bin/console rename to bin/console diff --git a/securenative/bin/setup b/bin/setup similarity index 100% rename from securenative/bin/setup rename to bin/setup diff --git a/securenative/lib/securenative/api_manager.rb b/lib/securenative/api_manager.rb similarity index 100% rename from securenative/lib/securenative/api_manager.rb rename to lib/securenative/api_manager.rb diff --git a/securenative/lib/securenative/config/configuration_builder.rb b/lib/securenative/config/configuration_builder.rb similarity index 100% rename from securenative/lib/securenative/config/configuration_builder.rb rename to lib/securenative/config/configuration_builder.rb diff --git a/securenative/lib/securenative/config/configuration_manager.rb b/lib/securenative/config/configuration_manager.rb similarity index 100% rename from securenative/lib/securenative/config/configuration_manager.rb rename to lib/securenative/config/configuration_manager.rb diff --git a/securenative/lib/securenative/config/securenative_options.rb b/lib/securenative/config/securenative_options.rb similarity index 100% rename from securenative/lib/securenative/config/securenative_options.rb rename to lib/securenative/config/securenative_options.rb diff --git a/securenative/lib/securenative/context/context_builder.rb b/lib/securenative/context/context_builder.rb similarity index 100% rename from securenative/lib/securenative/context/context_builder.rb rename to lib/securenative/context/context_builder.rb diff --git a/securenative/lib/securenative/context/securenative_context.rb b/lib/securenative/context/securenative_context.rb similarity index 100% rename from securenative/lib/securenative/context/securenative_context.rb rename to lib/securenative/context/securenative_context.rb diff --git a/securenative/lib/securenative/enums/api_route.rb b/lib/securenative/enums/api_route.rb similarity index 100% rename from securenative/lib/securenative/enums/api_route.rb rename to lib/securenative/enums/api_route.rb diff --git a/securenative/lib/securenative/enums/event_types.rb b/lib/securenative/enums/event_types.rb similarity index 100% rename from securenative/lib/securenative/enums/event_types.rb rename to lib/securenative/enums/event_types.rb diff --git a/securenative/lib/securenative/enums/failover_strategy.rb b/lib/securenative/enums/failover_strategy.rb similarity index 100% rename from securenative/lib/securenative/enums/failover_strategy.rb rename to lib/securenative/enums/failover_strategy.rb diff --git a/securenative/lib/securenative/enums/risk_level.rb b/lib/securenative/enums/risk_level.rb similarity index 100% rename from securenative/lib/securenative/enums/risk_level.rb rename to lib/securenative/enums/risk_level.rb diff --git a/securenative/lib/securenative/event_manager.rb b/lib/securenative/event_manager.rb similarity index 100% rename from securenative/lib/securenative/event_manager.rb rename to lib/securenative/event_manager.rb diff --git a/securenative/lib/securenative/event_options_builder.rb b/lib/securenative/event_options_builder.rb similarity index 100% rename from securenative/lib/securenative/event_options_builder.rb rename to lib/securenative/event_options_builder.rb diff --git a/securenative/lib/securenative/exceptions/securenative_config_exception.rb b/lib/securenative/exceptions/securenative_config_exception.rb similarity index 100% rename from securenative/lib/securenative/exceptions/securenative_config_exception.rb rename to lib/securenative/exceptions/securenative_config_exception.rb diff --git a/securenative/lib/securenative/exceptions/securenative_http_exception.rb b/lib/securenative/exceptions/securenative_http_exception.rb similarity index 100% rename from securenative/lib/securenative/exceptions/securenative_http_exception.rb rename to lib/securenative/exceptions/securenative_http_exception.rb diff --git a/securenative/lib/securenative/exceptions/securenative_invalid_options_exception.rb b/lib/securenative/exceptions/securenative_invalid_options_exception.rb similarity index 100% rename from securenative/lib/securenative/exceptions/securenative_invalid_options_exception.rb rename to lib/securenative/exceptions/securenative_invalid_options_exception.rb diff --git a/securenative/lib/securenative/exceptions/securenative_invalid_uri_exception.rb b/lib/securenative/exceptions/securenative_invalid_uri_exception.rb similarity index 100% rename from securenative/lib/securenative/exceptions/securenative_invalid_uri_exception.rb rename to lib/securenative/exceptions/securenative_invalid_uri_exception.rb diff --git a/securenative/lib/securenative/exceptions/securenative_parse_exception.rb b/lib/securenative/exceptions/securenative_parse_exception.rb similarity index 100% rename from securenative/lib/securenative/exceptions/securenative_parse_exception.rb rename to lib/securenative/exceptions/securenative_parse_exception.rb diff --git a/securenative/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb b/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb similarity index 100% rename from securenative/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb rename to lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb diff --git a/securenative/lib/securenative/exceptions/securenative_sdk_exception.rb b/lib/securenative/exceptions/securenative_sdk_exception.rb similarity index 100% rename from securenative/lib/securenative/exceptions/securenative_sdk_exception.rb rename to lib/securenative/exceptions/securenative_sdk_exception.rb diff --git a/securenative/lib/securenative/http/http_response.rb b/lib/securenative/http/http_response.rb similarity index 100% rename from securenative/lib/securenative/http/http_response.rb rename to lib/securenative/http/http_response.rb diff --git a/securenative/lib/securenative/http/securenative_http_client.rb b/lib/securenative/http/securenative_http_client.rb similarity index 100% rename from securenative/lib/securenative/http/securenative_http_client.rb rename to lib/securenative/http/securenative_http_client.rb diff --git a/securenative/lib/securenative/logger.rb b/lib/securenative/logger.rb similarity index 100% rename from securenative/lib/securenative/logger.rb rename to lib/securenative/logger.rb diff --git a/securenative/lib/securenative/models/client_token.rb b/lib/securenative/models/client_token.rb similarity index 100% rename from securenative/lib/securenative/models/client_token.rb rename to lib/securenative/models/client_token.rb diff --git a/securenative/lib/securenative/models/device.rb b/lib/securenative/models/device.rb similarity index 100% rename from securenative/lib/securenative/models/device.rb rename to lib/securenative/models/device.rb diff --git a/securenative/lib/securenative/models/event_options.rb b/lib/securenative/models/event_options.rb similarity index 100% rename from securenative/lib/securenative/models/event_options.rb rename to lib/securenative/models/event_options.rb diff --git a/securenative/lib/securenative/models/request_context.rb b/lib/securenative/models/request_context.rb similarity index 100% rename from securenative/lib/securenative/models/request_context.rb rename to lib/securenative/models/request_context.rb diff --git a/securenative/lib/securenative/models/request_options.rb b/lib/securenative/models/request_options.rb similarity index 100% rename from securenative/lib/securenative/models/request_options.rb rename to lib/securenative/models/request_options.rb diff --git a/securenative/lib/securenative/models/sdk_event.rb b/lib/securenative/models/sdk_event.rb similarity index 100% rename from securenative/lib/securenative/models/sdk_event.rb rename to lib/securenative/models/sdk_event.rb diff --git a/securenative/lib/securenative/models/user_traits.rb b/lib/securenative/models/user_traits.rb similarity index 100% rename from securenative/lib/securenative/models/user_traits.rb rename to lib/securenative/models/user_traits.rb diff --git a/securenative/lib/securenative/models/verify_result.rb b/lib/securenative/models/verify_result.rb similarity index 100% rename from securenative/lib/securenative/models/verify_result.rb rename to lib/securenative/models/verify_result.rb diff --git a/securenative/lib/securenative/securenative.rb b/lib/securenative/securenative.rb similarity index 100% rename from securenative/lib/securenative/securenative.rb rename to lib/securenative/securenative.rb diff --git a/securenative/lib/securenative/utils/date_utils.rb b/lib/securenative/utils/date_utils.rb similarity index 100% rename from securenative/lib/securenative/utils/date_utils.rb rename to lib/securenative/utils/date_utils.rb diff --git a/securenative/lib/securenative/utils/encryption_utils.rb b/lib/securenative/utils/encryption_utils.rb similarity index 100% rename from securenative/lib/securenative/utils/encryption_utils.rb rename to lib/securenative/utils/encryption_utils.rb diff --git a/securenative/lib/securenative/utils/ip_utils.rb b/lib/securenative/utils/ip_utils.rb similarity index 100% rename from securenative/lib/securenative/utils/ip_utils.rb rename to lib/securenative/utils/ip_utils.rb diff --git a/securenative/lib/securenative/utils/request_utils.rb b/lib/securenative/utils/request_utils.rb similarity index 100% rename from securenative/lib/securenative/utils/request_utils.rb rename to lib/securenative/utils/request_utils.rb diff --git a/securenative/lib/securenative/utils/signature_utils.rb b/lib/securenative/utils/signature_utils.rb similarity index 100% rename from securenative/lib/securenative/utils/signature_utils.rb rename to lib/securenative/utils/signature_utils.rb diff --git a/securenative/lib/securenative/utils/utils.rb b/lib/securenative/utils/utils.rb similarity index 100% rename from securenative/lib/securenative/utils/utils.rb rename to lib/securenative/utils/utils.rb diff --git a/securenative/lib/securenative/utils/version_utils.rb b/lib/securenative/utils/version_utils.rb similarity index 100% rename from securenative/lib/securenative/utils/version_utils.rb rename to lib/securenative/utils/version_utils.rb diff --git a/securenative/securenative.iml b/securenative.iml similarity index 84% rename from securenative/securenative.iml rename to securenative.iml index 7ee1a88..a314dbe 100644 --- a/securenative/securenative.iml +++ b/securenative.iml @@ -3,13 +3,12 @@ - - + diff --git a/securenative/bin/test/securenative/helper.rb b/securenative/bin/test/securenative/helper.rb deleted file mode 100644 index 878be66..0000000 --- a/securenative/bin/test/securenative/helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'simplecov' -SimpleCov.start - -require 'codecov' -SimpleCov.formatter = SimpleCov::Formatter::Codecov \ No newline at end of file diff --git a/securenative/coverage/.last_run.json b/securenative/coverage/.last_run.json deleted file mode 100644 index a69eb39..0000000 --- a/securenative/coverage/.last_run.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "result": { - "covered_percent": 0.0 - } -} diff --git a/securenative/coverage/.resultset.json.lock b/securenative/coverage/.resultset.json.lock deleted file mode 100644 index e69de29..0000000 diff --git a/securenative/test/helper.rb b/securenative/test/helper.rb deleted file mode 100644 index 878be66..0000000 --- a/securenative/test/helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'simplecov' -SimpleCov.start - -require 'codecov' -SimpleCov.formatter = SimpleCov::Formatter::Codecov \ No newline at end of file diff --git a/securenative/test/test_api_manager.rb b/securenative/test/test_api_manager.rb deleted file mode 100644 index 525e55b..0000000 --- a/securenative/test/test_api_manager.rb +++ /dev/null @@ -1,67 +0,0 @@ -describe ApiManager do - let(:context) { ContextBuilder().with_ip("127.0.0.1").with_client_token("SECURED_CLIENT_TOKEN").with_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"}).build } - let(:event_options) { EventOptionsBuilder(EventTypes.LOG_IN).with_user_id("USER_ID").with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")).with_context(context).with_properties({:prop1 => "CUSTOM_PARAM_VALUE", :prop2 => true, :prop3 => 3}).build } - - it "tracks an event" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_auto_send(true).with_interval(10).with_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\",\"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}}" - - # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json = json.loads(expected), status = 200) - event_manager = EventManager.new(options) - event_manager.start_event_persist - api_manager = ApiManager.new(event_manager, options) - - begin - api_manager.track(event_options) - ensure - event_manager.stop_event_persist - end - end - - it "uses invalid options" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_auto_send(true).with_interval(10).with_api_url("https://api.securenative-stg.com/collector/api/v1") - - properties = {} - (0..12).each { |i| - properties[i] = i - } - - # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json = {}, status = 200) - event_manager = EventManager.new(options) - event_manager.start_event_persist - api_manager = ApiManager.new(event_manager, options) - - begin - expect { api_manager.track(EventOptionsBuilder(EventTypes.LOG_IN).with_properties(properties).build) }.to raise_error(Errors::SecureNativeInvalidOptionsException) - ensure - event_manager.stop_event_persist - end - end - - it "verifies an event" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") - - # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/verify", json = {:riskLevel => "medium", :score => 0.32, :triggers => ["New IP", "New City"]}, status = 200) - verify_result = VerifyResult.new(RiskLevel.LOW, 0, nil) - - event_manager = EventManager.new(options) - event_manager.start_event_persist - api_manager = ApiManager.new(event_manager, options) - - result = api_manager.verify(event_options) - - expect(result).not_to be_empty - expect(result.risk_level).to eq(verify_result.risk_level) - expect(result.score).to eq(verify_result.score) - expect(result.triggers).to eq(verify_result.triggers) - end -end \ No newline at end of file diff --git a/securenative/test/test_configuration_manager.rb b/securenative/test/test_configuration_manager.rb deleted file mode 100644 index 5626869..0000000 --- a/securenative/test/test_configuration_manager.rb +++ /dev/null @@ -1,29 +0,0 @@ -describe ConfigurationManager do - it "parses a config file correctly" do - # code here - end - - it "ignores unknown config in properties file" do - # code here - end - - it "handles invalid config file" do - # code here - end - - it "ignores invalid config file entries" do - # code here - end - - it "loads default config" do - # code here - end - - it "gets config from env variables" do - # code here - end - - it "uses default values for invalid enum config props" do - # code here - end -end \ No newline at end of file diff --git a/securenative/test/test_context_builder.rb b/securenative/test/test_context_builder.rb deleted file mode 100644 index 3128e13..0000000 --- a/securenative/test/test_context_builder.rb +++ /dev/null @@ -1,33 +0,0 @@ -describe ContextBuilder do - it "creates context from request" do - # TODO code here - end - - it "creates context from request with cookie" do - # TODO code here - end - - it "creates default context builder" do - context = ContextBuilder.default_context_builder.build - - expect(context.client_token).not_to be_empty - expect(context.ip).not_to be_empty - expect(context.method).not_to be_empty - expect(context.url).not_to be_empty - expect(context.remote_ip).not_to be_empty - expect(context.headers).not_to be_empty - expect(context.body).not_to be_empty - end - - it "creates custom context with context builder" do - context = ContextBuilder.default_context_builder.with_url("/some-url").with_client_token("SECRET_TOKEN").with_ip("10.0.0.0").with_body("{ \"name\": \"YOUR_NAME\" }").with_method("Get").with_remote_ip("10.0.0.1").with_headers({:header1 => "value1"}).build - - expect(context.url).to eq("/some-url") - expect(context.client_token).to eq("SECRET_TOKEN") - expect(context.ip).to eq("10.0.0.0") - expect(context.body).to eq("{ \"name\": \"YOUR_NAME\" }") - expect(context.method).to eq("Get") - expect(context.remote_ip).to eq("10.0.0.0") - expect(context.headers).to eq({:header1 => "value1"}) - end -end \ No newline at end of file diff --git a/securenative/test/test_date_utils.rb b/securenative/test/test_date_utils.rb deleted file mode 100644 index 35204bd..0000000 --- a/securenative/test/test_date_utils.rb +++ /dev/null @@ -1,8 +0,0 @@ -describe DateUtils do - it "converts to timestamp" do - iso_8601_date = "2020-05-20T15:07:13Z" - result = DateUtils.to_timestamp(iso_8601_date) - - expect(result).to eq(Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z")) - end -end \ No newline at end of file diff --git a/securenative/test/test_encryption_utils.rb b/securenative/test/test_encryption_utils.rb deleted file mode 100644 index d7d6132..0000000 --- a/securenative/test/test_encryption_utils.rb +++ /dev/null @@ -1,21 +0,0 @@ -describe EncryptionUtils do - let(:SECRET_KEY) { "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6" } - let(:PAYLOAD) { "{\"cid\":\"198a41ff-a10f-4cda-a2f3-a9ca80c0703b\",\"vi\":\"148a42ff-b40f-4cda-a2f3-a8ca80c0703b\",\"fp\":\"6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed\"}" } - let(:CID) { "198a41ff-a10f-4cda-a2f3-a9ca80c0703b" } - let(:FP) { "6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed" } - - it "decrypts" do - result = EncryptionUtils.encrypt(PAYLOAD, SECRET_KEY) - - expect(result).not_to be_empty - expect(result.length).to eq(PAYLOAD.length) - end - - it "encrypts" do - encrypted_payload = "5208ae703cc2fa0851347f55d3b76d3fd6035ee081d71a401e8bc92ebdc25d42440f62310bda60628537744ac03f200d78da9e61f1019ce02087b7ce6c976e7b2d8ad6aa978c532cea8f3e744cc6a5cafedc4ae6cd1b08a4ef75d6e37aa3c0c76954d16d57750be2980c2c91ac7ef0bbd0722abd59bf6be22493ea9b9759c3ff4d17f17ab670b0b6fc320e6de982313f1c4e74c0897f9f5a32d58e3e53050ae8fdbebba9009d0d1250fe34dcde1ebb42acbc22834a02f53889076140f0eb8db1" - result = EncryptionUtils.decrypt(encrypted_payload, SECRET_KEY) - - expect(result.cid).to eq(CID) - expect(result.fp).to eq(FP) - end -end \ No newline at end of file diff --git a/securenative/test/test_event_manager.rb b/securenative/test/test_event_manager.rb deleted file mode 100644 index 6c95931..0000000 --- a/securenative/test/test_event_manager.rb +++ /dev/null @@ -1,51 +0,0 @@ -class SampleEvent - attr_reader :event_type, :timestamp, :rid, :user_id, :user_traits, :request, :properties - - def initialize - @event_type = "custom-event" - @timestamp = Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z") - @rid = "432532" - @user_id = "1" - @user_traits = UserTraits("some user", "email@securenative.com") - @request = RequestContext() - @properties = [] - end -end - -describe EventManager do - let(:event) { SampleEvent() } - - it "successfully sends sync event with status code 200" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") - - res_body = "{\"data\": true}" - # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = json.loads(res_body), status = 200) - event_manager = EventManager.new(options) - data = event_manager.send_sync(self.event, "some-path/to-api", false) - - expect(res_body).to eq(data.text) - end - - it "fails when send sync event status code is 401" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") - - # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = {}, status = 401) - event_manager = EventManager.new(options) - res = event_manager.send_sync(self.event, "some-path/to-api", false) - - expect(res.status_code).to eq(401) - end - - it "fails when send sync event status code is 500" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") - - # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = {}, status = 500) - event_manager = EventManager.new(options) - res = event_manager.send_sync(self.event, "some-path/to-api", false) - - expect(res.status_code).to eq(500) - end -end \ No newline at end of file diff --git a/securenative/test/test_ip_utils.rb b/securenative/test/test_ip_utils.rb deleted file mode 100644 index 16e9401..0000000 --- a/securenative/test/test_ip_utils.rb +++ /dev/null @@ -1,36 +0,0 @@ -describe IpUtils do - it "checks if ip address valid ipv4" do - valid_ipv4 = "172.16.254.1" - expect(IpUtils.is_ip_address(valid_ipv4)).to be_truthy - end - - it "checks if ip address valid ipv6" do - valid_ipv6 = "2001:db8:1234:0000:0000:0000:0000:0000" - expect(IpUtils.is_ip_address(valid_ipv6)).to be_truthy - end - - it "checks if ip address invalid ipv4" do - invalid_ipv4 = "172.16.2541" - expect(IpUtils.is_ip_address(invalid_ipv4)).to be_falsey - end - - it "checks if ip address invalid ipv6" do - invalid_ipv6 = "2001:db8:1234:0000" - expect(IpUtils.is_ip_address(invalid_ipv6)).to be_falsey - end - - it "checks if valid public ip" do - ip = "64.71.222.37" - expect(IpUtils.is_valid_public_ip(ip)).to be_truthy - end - - it "checks if not valid public ip" do - ip = "10.0.0.0" - expect(IpUtils.is_valid_public_ip(ip)).to be_falsey - end - - it "checks if valid loopback ip" do - ip = "127.0.0.1" - expect(IpUtils.is_loop_back(ip)).to be_truthy - end -end \ No newline at end of file diff --git a/securenative/test/test_securenative.rb b/securenative/test/test_securenative.rb deleted file mode 100644 index e9cfd7b..0000000 --- a/securenative/test/test_securenative.rb +++ /dev/null @@ -1,52 +0,0 @@ -describe SecureNative do - it "gets sdk instance without init throws" do - expect { SecureNative.get_instance }.to raise_error(Errors::SecureNativeSDKIllegalStateException) - end - - it "inits sdk without api key and throws" do - expect { SecureNative.init_with_options(ConfigurationManager.config_builder) }.to raise_error(Errors::SecureNativeSDKException) - end - - it "inits sdk with empty api key and throws" do - expect { SecureNative.init_with_api_key("") }.to raise_error(Errors::SecureNativeSDKException) - end - - it "inits sdk with api key and defaults" do - SecureNative._flush - api_key = "API_KEY" - securenative = SecureNative.init_with_api_key(api_key) - options = securenative.get_options - - expect(options.api_key).to eq(api_key) - expect(options.api_url).to eq("https://api.securenative.com/collector/api/v1") - expect(options.interval).to eq(1000) - expect(options.timeout).to eq(1500) - expect(options.max_events).to eq(100) - expect(options.auto_send).to eq(true) - expect(options.disable).to eq(false) - expect(options.log_level).to eq("FATAL") - expect(options.fail_over_strategy).to eq(FailOverStrategy::FAIL_OPEN) - end - - it "inits sdk twice and throws" do - expect { SecureNative.init_with_api_key("API_KEY") }.to raise_error(Errors::SecureNativeSDKException) - end - - it "inits sdk with api key and gets instance" do - SecureNative._flush - api_key = "API_KEY" - securenative = SecureNative.init_with_api_key(api_key) - - expect(securenative).to eq(SecureNative.get_instance) - end - - it "inits sdk with builder" do - SecureNative._flush - securenative = SecureNative.init_with_options(SecureNative.config_builder.with_api_key("API_KEY").with_max_events(10).with_log_level("ERROR")) - options = securenative.get_options - - expect(options.api_key).to eq("API_KEY") - expect(options.max_events).to eq(10) - expect(options.log_level).to eq("ERROR") - end -end \ No newline at end of file diff --git a/securenative/test/test_securenative_http_client.rb b/securenative/test/test_securenative_http_client.rb deleted file mode 100644 index 43892b1..0000000 --- a/securenative/test/test_securenative_http_client.rb +++ /dev/null @@ -1,16 +0,0 @@ -describe SecureNativeHttpClient do - it "makes a simple post call" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") - - # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json={"event" => "SOME_EVENT_NAME"}, status=200) - client = SecureNativeHttpClient(options) - payload = "{\"event\": \"SOME_EVENT_NAME\"}" - - res = client.post("track", payload) - - expect(res.ok).to eq(true) - expect(res.status_code).to eq(200) - expect(res.text).to eq(payload) - end -end \ No newline at end of file diff --git a/securenative/test/test_signature_utils.rb b/securenative/test/test_signature_utils.rb deleted file mode 100644 index fde96ca..0000000 --- a/securenative/test/test_signature_utils.rb +++ /dev/null @@ -1,13 +0,0 @@ -describe SignatureUtils do - it "verifies request payload" do - signature = "c4574c1748064735513697750c6223ff36b03ae3b85b160ce8788557d01e1d9d1c9cd942074323ee0061d3dcc8c94359c5acfa6eee8e2da095b3967b1a88ab73" - payload = "{\"id\":\"4a9157ffbd18cfbd73a57298\",\"type\":\"security-action\",\"flow\":{\"id\":\"62298c73a9bb433fbd1f75984a9157fd\",\"name\":\"Block user that violates geo velocity\"},\"userId\":\"73a9bb433fbd1f75984a9157\",\"userTraits\":{\"name\":\"John Doe\",\"email\":\"john.doe@gmail.com\"},\"request\":{\"ip\":\"10.0.0.0\",\"fp\":\"9bb433fb984a9157d1f7598\"},\"action\":\"block\",\"properties\":{\"type\":\"customer\"},\"timestamp\":\"2020-02-23T22:28:55.387Z\"}" - secret_key = "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6" - - expect(SignatureUtils.is_valid_signature(secret_key, payload, signature)).to be_truthy - end - - it "verifies request empty signature" do - expect(SignatureUtils.is_valid_signature("", "", "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6")).to be_falsey - end -end \ No newline at end of file diff --git a/spec/securanative_spec.rb b/spec/securanative_spec.rb new file mode 100644 index 0000000..87a526f --- /dev/null +++ b/spec/securanative_spec.rb @@ -0,0 +1,9 @@ +RSpec.describe Securanative do + it "has a version number" do + expect(Securanative::VERSION).not_to be nil + end + + it "does something useful" do + expect(false).to eq(true) + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..7bb8e23 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,20 @@ +require "bundler/setup" +require "securenative/lib/securenative/securenative" + +require 'simplecov' +SimpleCov.start + +require 'codecov' +SimpleCov.formatter = SimpleCov::Formatter::Codecov + +RSpec.configure do |config| + # Enable flags like --only-failures and --next-failure + config.example_status_persistence_file_path = ".rspec_status" + + # Disable RSpec exposing methods globally on `Module` and `main` + config.disable_monkey_patching! + + config.expect_with :rspec do |c| + c.syntax = :expect + end +end \ No newline at end of file diff --git a/securenative/bin/test/securenative/test_api_manager.rb b/spec/test_api_manager.rb similarity index 100% rename from securenative/bin/test/securenative/test_api_manager.rb rename to spec/test_api_manager.rb diff --git a/securenative/bin/test/securenative/test_configuration_manager.rb b/spec/test_configuration_manager.rb similarity index 100% rename from securenative/bin/test/securenative/test_configuration_manager.rb rename to spec/test_configuration_manager.rb diff --git a/securenative/bin/test/securenative/test_context_builder.rb b/spec/test_context_builder.rb similarity index 100% rename from securenative/bin/test/securenative/test_context_builder.rb rename to spec/test_context_builder.rb diff --git a/securenative/bin/test/securenative/test_date_utils.rb b/spec/test_date_utils.rb similarity index 100% rename from securenative/bin/test/securenative/test_date_utils.rb rename to spec/test_date_utils.rb diff --git a/securenative/bin/test/securenative/test_encryption_utils.rb b/spec/test_encryption_utils.rb similarity index 100% rename from securenative/bin/test/securenative/test_encryption_utils.rb rename to spec/test_encryption_utils.rb diff --git a/securenative/bin/test/securenative/test_event_manager.rb b/spec/test_event_manager.rb similarity index 100% rename from securenative/bin/test/securenative/test_event_manager.rb rename to spec/test_event_manager.rb diff --git a/securenative/bin/test/securenative/test_ip_utils.rb b/spec/test_ip_utils.rb similarity index 100% rename from securenative/bin/test/securenative/test_ip_utils.rb rename to spec/test_ip_utils.rb diff --git a/securenative/bin/test/securenative/test_securenative.rb b/spec/test_securenative.rb similarity index 100% rename from securenative/bin/test/securenative/test_securenative.rb rename to spec/test_securenative.rb diff --git a/securenative/bin/test/securenative/test_securenative_http_client.rb b/spec/test_securenative_http_client.rb similarity index 100% rename from securenative/bin/test/securenative/test_securenative_http_client.rb rename to spec/test_securenative_http_client.rb diff --git a/securenative/bin/test/securenative/test_signature_utils.rb b/spec/test_signature_utils.rb similarity index 100% rename from securenative/bin/test/securenative/test_signature_utils.rb rename to spec/test_signature_utils.rb From 151aff02660fb24e660d218d3a44f26689d3ddcf Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 15:12:07 +0300 Subject: [PATCH 20/32] Fix project structure --- spec/securanative_spec.rb | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 spec/securanative_spec.rb diff --git a/spec/securanative_spec.rb b/spec/securanative_spec.rb deleted file mode 100644 index 87a526f..0000000 --- a/spec/securanative_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -RSpec.describe Securanative do - it "has a version number" do - expect(Securanative::VERSION).not_to be nil - end - - it "does something useful" do - expect(false).to eq(true) - end -end From 31bb2f5f457a80089b88cc98092a2c3d824fae42 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 15:13:42 +0300 Subject: [PATCH 21/32] Fix project structure --- spec/spec_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7bb8e23..8637652 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,5 @@ require "bundler/setup" -require "securenative/lib/securenative/securenative" +require "securenative" require 'simplecov' SimpleCov.start From a37d6fb8c6cadee87ee5d6a340bc8c2b72dc950a Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 15:14:50 +0300 Subject: [PATCH 22/32] Fix project structure --- spec/spec_helper.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8637652..63c2c04 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,4 @@ require "bundler/setup" -require "securenative" require 'simplecov' SimpleCov.start From ad971deb18a222ac233b48253ba5391a4e755e0e Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 15:28:46 +0300 Subject: [PATCH 23/32] Fix project structure --- lib/{securenative => }/api_manager.rb | 0 .../config/configuration_builder.rb | 0 .../config/configuration_manager.rb | 0 .../config/securenative_options.rb | 0 .../context/context_builder.rb | 0 .../context/securenative_context.rb | 0 lib/{securenative => }/enums/api_route.rb | 0 lib/{securenative => }/enums/event_types.rb | 0 .../enums/failover_strategy.rb | 0 lib/{securenative => }/enums/risk_level.rb | 0 lib/{securenative => }/event_manager.rb | 0 .../event_options_builder.rb | 0 .../securenative_config_exception.rb | 0 .../exceptions/securenative_http_exception.rb | 0 .../securenative_invalid_options_exception.rb | 0 .../securenative_invalid_uri_exception.rb | 0 .../securenative_parse_exception.rb | 0 ...ecurenative_sdk_Illegal_state_exception.rb | 0 .../exceptions/securenative_sdk_exception.rb | 0 lib/{securenative => }/http/http_response.rb | 0 .../http/securenative_http_client.rb | 0 lib/{securenative => }/logger.rb | 0 lib/{securenative => }/models/client_token.rb | 0 lib/{securenative => }/models/device.rb | 0 .../models/event_options.rb | 0 .../models/request_context.rb | 0 .../models/request_options.rb | 0 lib/{securenative => }/models/sdk_event.rb | 0 lib/{securenative => }/models/user_traits.rb | 0 .../models/verify_result.rb | 0 lib/{securenative => }/securenative.rb | 0 lib/{securenative => }/utils/date_utils.rb | 0 .../utils/encryption_utils.rb | 0 lib/{securenative => }/utils/ip_utils.rb | 0 lib/{securenative => }/utils/request_utils.rb | 0 .../utils/signature_utils.rb | 0 lib/{securenative => }/utils/utils.rb | 0 lib/{securenative => }/utils/version_utils.rb | 0 securenative.gemspec | 2 +- securenative.iml | 24 ++++++++++++++----- 40 files changed, 19 insertions(+), 7 deletions(-) rename lib/{securenative => }/api_manager.rb (100%) rename lib/{securenative => }/config/configuration_builder.rb (100%) rename lib/{securenative => }/config/configuration_manager.rb (100%) rename lib/{securenative => }/config/securenative_options.rb (100%) rename lib/{securenative => }/context/context_builder.rb (100%) rename lib/{securenative => }/context/securenative_context.rb (100%) rename lib/{securenative => }/enums/api_route.rb (100%) rename lib/{securenative => }/enums/event_types.rb (100%) rename lib/{securenative => }/enums/failover_strategy.rb (100%) rename lib/{securenative => }/enums/risk_level.rb (100%) rename lib/{securenative => }/event_manager.rb (100%) rename lib/{securenative => }/event_options_builder.rb (100%) rename lib/{securenative => }/exceptions/securenative_config_exception.rb (100%) rename lib/{securenative => }/exceptions/securenative_http_exception.rb (100%) rename lib/{securenative => }/exceptions/securenative_invalid_options_exception.rb (100%) rename lib/{securenative => }/exceptions/securenative_invalid_uri_exception.rb (100%) rename lib/{securenative => }/exceptions/securenative_parse_exception.rb (100%) rename lib/{securenative => }/exceptions/securenative_sdk_Illegal_state_exception.rb (100%) rename lib/{securenative => }/exceptions/securenative_sdk_exception.rb (100%) rename lib/{securenative => }/http/http_response.rb (100%) rename lib/{securenative => }/http/securenative_http_client.rb (100%) rename lib/{securenative => }/logger.rb (100%) rename lib/{securenative => }/models/client_token.rb (100%) rename lib/{securenative => }/models/device.rb (100%) rename lib/{securenative => }/models/event_options.rb (100%) rename lib/{securenative => }/models/request_context.rb (100%) rename lib/{securenative => }/models/request_options.rb (100%) rename lib/{securenative => }/models/sdk_event.rb (100%) rename lib/{securenative => }/models/user_traits.rb (100%) rename lib/{securenative => }/models/verify_result.rb (100%) rename lib/{securenative => }/securenative.rb (100%) rename lib/{securenative => }/utils/date_utils.rb (100%) rename lib/{securenative => }/utils/encryption_utils.rb (100%) rename lib/{securenative => }/utils/ip_utils.rb (100%) rename lib/{securenative => }/utils/request_utils.rb (100%) rename lib/{securenative => }/utils/signature_utils.rb (100%) rename lib/{securenative => }/utils/utils.rb (100%) rename lib/{securenative => }/utils/version_utils.rb (100%) diff --git a/lib/securenative/api_manager.rb b/lib/api_manager.rb similarity index 100% rename from lib/securenative/api_manager.rb rename to lib/api_manager.rb diff --git a/lib/securenative/config/configuration_builder.rb b/lib/config/configuration_builder.rb similarity index 100% rename from lib/securenative/config/configuration_builder.rb rename to lib/config/configuration_builder.rb diff --git a/lib/securenative/config/configuration_manager.rb b/lib/config/configuration_manager.rb similarity index 100% rename from lib/securenative/config/configuration_manager.rb rename to lib/config/configuration_manager.rb diff --git a/lib/securenative/config/securenative_options.rb b/lib/config/securenative_options.rb similarity index 100% rename from lib/securenative/config/securenative_options.rb rename to lib/config/securenative_options.rb diff --git a/lib/securenative/context/context_builder.rb b/lib/context/context_builder.rb similarity index 100% rename from lib/securenative/context/context_builder.rb rename to lib/context/context_builder.rb diff --git a/lib/securenative/context/securenative_context.rb b/lib/context/securenative_context.rb similarity index 100% rename from lib/securenative/context/securenative_context.rb rename to lib/context/securenative_context.rb diff --git a/lib/securenative/enums/api_route.rb b/lib/enums/api_route.rb similarity index 100% rename from lib/securenative/enums/api_route.rb rename to lib/enums/api_route.rb diff --git a/lib/securenative/enums/event_types.rb b/lib/enums/event_types.rb similarity index 100% rename from lib/securenative/enums/event_types.rb rename to lib/enums/event_types.rb diff --git a/lib/securenative/enums/failover_strategy.rb b/lib/enums/failover_strategy.rb similarity index 100% rename from lib/securenative/enums/failover_strategy.rb rename to lib/enums/failover_strategy.rb diff --git a/lib/securenative/enums/risk_level.rb b/lib/enums/risk_level.rb similarity index 100% rename from lib/securenative/enums/risk_level.rb rename to lib/enums/risk_level.rb diff --git a/lib/securenative/event_manager.rb b/lib/event_manager.rb similarity index 100% rename from lib/securenative/event_manager.rb rename to lib/event_manager.rb diff --git a/lib/securenative/event_options_builder.rb b/lib/event_options_builder.rb similarity index 100% rename from lib/securenative/event_options_builder.rb rename to lib/event_options_builder.rb diff --git a/lib/securenative/exceptions/securenative_config_exception.rb b/lib/exceptions/securenative_config_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_config_exception.rb rename to lib/exceptions/securenative_config_exception.rb diff --git a/lib/securenative/exceptions/securenative_http_exception.rb b/lib/exceptions/securenative_http_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_http_exception.rb rename to lib/exceptions/securenative_http_exception.rb diff --git a/lib/securenative/exceptions/securenative_invalid_options_exception.rb b/lib/exceptions/securenative_invalid_options_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_invalid_options_exception.rb rename to lib/exceptions/securenative_invalid_options_exception.rb diff --git a/lib/securenative/exceptions/securenative_invalid_uri_exception.rb b/lib/exceptions/securenative_invalid_uri_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_invalid_uri_exception.rb rename to lib/exceptions/securenative_invalid_uri_exception.rb diff --git a/lib/securenative/exceptions/securenative_parse_exception.rb b/lib/exceptions/securenative_parse_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_parse_exception.rb rename to lib/exceptions/securenative_parse_exception.rb diff --git a/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb b/lib/exceptions/securenative_sdk_Illegal_state_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb rename to lib/exceptions/securenative_sdk_Illegal_state_exception.rb diff --git a/lib/securenative/exceptions/securenative_sdk_exception.rb b/lib/exceptions/securenative_sdk_exception.rb similarity index 100% rename from lib/securenative/exceptions/securenative_sdk_exception.rb rename to lib/exceptions/securenative_sdk_exception.rb diff --git a/lib/securenative/http/http_response.rb b/lib/http/http_response.rb similarity index 100% rename from lib/securenative/http/http_response.rb rename to lib/http/http_response.rb diff --git a/lib/securenative/http/securenative_http_client.rb b/lib/http/securenative_http_client.rb similarity index 100% rename from lib/securenative/http/securenative_http_client.rb rename to lib/http/securenative_http_client.rb diff --git a/lib/securenative/logger.rb b/lib/logger.rb similarity index 100% rename from lib/securenative/logger.rb rename to lib/logger.rb diff --git a/lib/securenative/models/client_token.rb b/lib/models/client_token.rb similarity index 100% rename from lib/securenative/models/client_token.rb rename to lib/models/client_token.rb diff --git a/lib/securenative/models/device.rb b/lib/models/device.rb similarity index 100% rename from lib/securenative/models/device.rb rename to lib/models/device.rb diff --git a/lib/securenative/models/event_options.rb b/lib/models/event_options.rb similarity index 100% rename from lib/securenative/models/event_options.rb rename to lib/models/event_options.rb diff --git a/lib/securenative/models/request_context.rb b/lib/models/request_context.rb similarity index 100% rename from lib/securenative/models/request_context.rb rename to lib/models/request_context.rb diff --git a/lib/securenative/models/request_options.rb b/lib/models/request_options.rb similarity index 100% rename from lib/securenative/models/request_options.rb rename to lib/models/request_options.rb diff --git a/lib/securenative/models/sdk_event.rb b/lib/models/sdk_event.rb similarity index 100% rename from lib/securenative/models/sdk_event.rb rename to lib/models/sdk_event.rb diff --git a/lib/securenative/models/user_traits.rb b/lib/models/user_traits.rb similarity index 100% rename from lib/securenative/models/user_traits.rb rename to lib/models/user_traits.rb diff --git a/lib/securenative/models/verify_result.rb b/lib/models/verify_result.rb similarity index 100% rename from lib/securenative/models/verify_result.rb rename to lib/models/verify_result.rb diff --git a/lib/securenative/securenative.rb b/lib/securenative.rb similarity index 100% rename from lib/securenative/securenative.rb rename to lib/securenative.rb diff --git a/lib/securenative/utils/date_utils.rb b/lib/utils/date_utils.rb similarity index 100% rename from lib/securenative/utils/date_utils.rb rename to lib/utils/date_utils.rb diff --git a/lib/securenative/utils/encryption_utils.rb b/lib/utils/encryption_utils.rb similarity index 100% rename from lib/securenative/utils/encryption_utils.rb rename to lib/utils/encryption_utils.rb diff --git a/lib/securenative/utils/ip_utils.rb b/lib/utils/ip_utils.rb similarity index 100% rename from lib/securenative/utils/ip_utils.rb rename to lib/utils/ip_utils.rb diff --git a/lib/securenative/utils/request_utils.rb b/lib/utils/request_utils.rb similarity index 100% rename from lib/securenative/utils/request_utils.rb rename to lib/utils/request_utils.rb diff --git a/lib/securenative/utils/signature_utils.rb b/lib/utils/signature_utils.rb similarity index 100% rename from lib/securenative/utils/signature_utils.rb rename to lib/utils/signature_utils.rb diff --git a/lib/securenative/utils/utils.rb b/lib/utils/utils.rb similarity index 100% rename from lib/securenative/utils/utils.rb rename to lib/utils/utils.rb diff --git a/lib/securenative/utils/version_utils.rb b/lib/utils/version_utils.rb similarity index 100% rename from lib/securenative/utils/version_utils.rb rename to lib/utils/version_utils.rb diff --git a/securenative.gemspec b/securenative.gemspec index f919b70..7f9740b 100644 --- a/securenative.gemspec +++ b/securenative.gemspec @@ -1,6 +1,6 @@ lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require_relative "lib/securenative/utils/version_utils" +require_relative "lib/utils/version_utils" Gem::Specification.new do |spec| spec.name = "securenative" diff --git a/securenative.iml b/securenative.iml index a314dbe..1460564 100644 --- a/securenative.iml +++ b/securenative.iml @@ -3,13 +3,25 @@ - + + - + - - - - + + + + + + + + + + + + + + + \ No newline at end of file From d217b2d24c5e476c72fed14722918bbc7d3b5344 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 16:05:10 +0300 Subject: [PATCH 24/32] Add robocop --- README.md | 10 +- lib/api_manager.rb | 13 ++- lib/config/configuration_builder.rb | 10 +- lib/config/configuration_manager.rb | 46 ++++----- lib/context/context_builder.rb | 22 ++--- lib/enums/api_route.rb | 4 +- lib/enums/event_types.rb | 38 ++++---- lib/enums/failover_strategy.rb | 4 +- lib/enums/risk_level.rb | 6 +- lib/event_manager.rb | 133 ++++++++++++-------------- lib/event_options_builder.rb | 3 +- lib/http/securenative_http_client.rb | 16 ++-- lib/logger.rb | 28 +++--- lib/models/request_context.rb | 2 +- lib/models/sdk_event.rb | 28 +++--- lib/securenative.rb | 38 +++----- lib/utils/date_utils.rb | 7 +- lib/utils/encryption_utils.rb | 8 +- lib/utils/ip_utils.rb | 28 +++--- lib/utils/request_utils.rb | 22 ++--- lib/utils/signature_utils.rb | 16 ++-- lib/utils/utils.rb | 14 ++- lib/utils/version_utils.rb | 6 +- securenative.gemspec | 2 +- spec/test_api_manager.rb | 46 ++++----- spec/test_configuration_manager.rb | 16 ++-- spec/test_context_builder.rb | 28 +++--- spec/test_date_utils.rb | 8 +- spec/test_encryption_utils.rb | 26 ++--- spec/test_event_manager.rb | 38 ++++---- spec/test_ip_utils.rb | 44 +++++---- spec/test_securenative.rb | 44 +++++---- spec/test_securenative_http_client.rb | 12 ++- spec/test_signature_utils.rb | 16 ++-- 34 files changed, 379 insertions(+), 403 deletions(-) diff --git a/README.md b/README.md index 63abf50..1e9ccfb 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ Once initialized, sdk will create a singleton instance which you can get: require 'securenative' -secureNative = SecureNative.get_instance +secureNative = SecureNative.instance ``` ## Tracking events @@ -96,7 +96,7 @@ require 'securenative/event_options_builder' require 'securenative/models/user_traits' -securenative = SecureNative.get_instance +securenative = SecureNative.instance context = SecureNative.context_builder .with_ip("127.0.0.1") @@ -124,7 +124,7 @@ require 'securenative/models/user_traits' def track(request) - securenative = SecureNative.get_instance + securenative = SecureNative.instance context = SecureNative.context_builder.from_http_request(request).build event_options = EventOptionsBuilder(EventTypes::LOG_IN) @@ -150,7 +150,7 @@ require 'securenative/models/user_traits' def track(request) - securenative = SecureNative.get_instance + securenative = SecureNative.instance context = SecureNative.context_builder.from_http_request(request).build event_options = EventOptionsBuilder(EventTypes::LOG_IN) @@ -176,7 +176,7 @@ require 'securenative' def webhook_endpoint(request) - securenative = SecureNative.get_instance + securenative = SecureNative.instance # Checks if request is verified is_verified = securenative.verify_request_payload(request) diff --git a/lib/api_manager.rb b/lib/api_manager.rb index 34c3460..0d6e641 100644 --- a/lib/api_manager.rb +++ b/lib/api_manager.rb @@ -8,24 +8,23 @@ def initialize(event_manager, securenative_options) end def track(event_options) - Logger.debug("Track event call") + Logger.debug('Track event call') event = SDKEvent.new(event_options, @options) @event_manager.send_async(event, ApiRoute::TRACK) end def verify(event_options) - Logger.debug("Verify event call") + Logger.debug('Verify event call') event = SDKEvent.new(event_options, @options) begin res = JSON.parse(@event_manager.send_sync(event, ApiRoute::VERIFY, false)) - return VerifyResult.new(res["riskLevel"], res["score"], res["triggers"]) + return VerifyResult.new(res['riskLevel'], res['score'], res['triggers']) rescue StandardError => e - Logger.debug("Failed to call verify; {}".format(e)) - end - if @options.fail_over_strategy == FailOverStrategy::FAIL_OPEN - return VerifyResult.new(RiskLevel::LOW, 0, nil) + Logger.debug('Failed to call verify; {}'.format(e)) end + return VerifyResult.new(RiskLevel::LOW, 0, nil) if @options.fail_over_strategy == FailOverStrategy::FAIL_OPEN + VerifyResult.new(RiskLevel::HIGH, 1, nil) end end \ No newline at end of file diff --git a/lib/config/configuration_builder.rb b/lib/config/configuration_builder.rb index 1ddd7a6..a7b7ecd 100644 --- a/lib/config/configuration_builder.rb +++ b/lib/config/configuration_builder.rb @@ -1,18 +1,18 @@ class ConfigurationBuilder def initialize @api_key = nil - @api_url = "https://api.securenative.com/collector/api/v1" + @api_url = 'https://api.securenative.com/collector/api/v1' @interval = 1000 @max_events = 1000 @timeout = 1500 @auto_send = true @disable = false - @log_level = "FATAL" + @log_level = 'FATAL' @fail_over_strategy = FailOverStrategy::FAIL_OPEN end def self.default_config_builder - return ConfigurationBuilder() + ConfigurationBuilder() end def with_api_key(api_key) @@ -58,14 +58,12 @@ def with_log_level(log_level) def with_fail_over_strategy(fail_over_strategy) if fail_over_strategy != FailOverStrategy::FAIL_OPEN && fail_over_strategy != FailOverStrategy::FAIL_CLOSED @fail_over_strategy = FailOverStrategy::FAIL_OPEN - self else @fail_over_strategy = fail_over_strategy - self end end def self.default_securenative_options - return SecureNativeOptions() + SecureNativeOptions() end end \ No newline at end of file diff --git a/lib/config/configuration_manager.rb b/lib/config/configuration_manager.rb index 5f087bc..c52c8b8 100644 --- a/lib/config/configuration_manager.rb +++ b/lib/config/configuration_manager.rb @@ -1,8 +1,8 @@ require 'parseconfig' class ConfigurationManager - DEFAULT_CONFIG_FILE = "securenative.cfg" - CUSTOM_CONFIG_FILE_ENV_NAME = "SECURENATIVE_COMFIG_FILE" + DEFAULT_CONFIG_FILE = 'securenative.cfg'.freeze + CUSTOM_CONFIG_FILE_ENV_NAME = 'SECURENATIVE_COMFIG_FILE'.freeze @config = nil def self.read_resource_file(resource_path) @@ -14,47 +14,41 @@ def self.read_resource_file(resource_path) properties[key.upcase] = value end } - return properties + properties end def self._get_resource_path(env_name) - return Env.fetch(env_name, ENV[DEFAULT_CONFIG_FILE]) + Env.fetch(env_name, ENV[DEFAULT_CONFIG_FILE]) end def self.config_builder - return ConfigurationBuilder.default_config_builder + ConfigurationBuilder.default_config_builder end def self._get_env_or_default(properties, key, default) - if Env[key] - return Env[key] - end - - if properties[key] - return properties[key] - end - return default + return Env[key] if Env[key] + return properties[key] if properties[key] + + default end def self.load_config options = ConfigurationBuilder().default_securenative_options resource_path = DEFAULT_CONFIG_FILE - if Env[CUSTOM_CONFIG_FILE_ENV_NAME] - resource_path = Env[CUSTOM_CONFIG_FILE_ENV_NAME] - end + resource_path = Env[CUSTOM_CONFIG_FILE_ENV_NAME] if Env[CUSTOM_CONFIG_FILE_ENV_NAME] properties = read_resource_file(resource_path) - return ConfigurationBuilder() - .with_api_key(_get_env_or_default(properties, "SECURENATIVE_API_KEY", options.api_key)) - .with_api_url(_get_env_or_default(properties, "SECURENATIVE_API_URL", options.api_url)) - .with_interval(_get_env_or_default(properties, "SECURENATIVE_INTERVAL", options.interval)) - .with_max_events(_get_env_or_default(properties, "SECURENATIVE_MAX_EVENTS", options.max_events)) - .with_timeout(_get_env_or_default(properties, "SECURENATIVE_TIMEOUT", options.timeout)) - .with_auto_send(_get_env_or_default(properties, "SECURENATIVE_AUTO_SEND", options.auto_send)) - .with_disable(_get_env_or_default(properties, "SECURENATIVE_DISABLE", options.disable)) - .with_log_level(_get_env_or_default(properties, "SECURENATIVE_LOG_LEVEL", options.log_level)) - .with_fail_over_strategy(_get_env_or_default(properties, "SECURENATIVE_FAILOVER_STRATEGY", options.fail_over_strategy)) + ConfigurationBuilder() + .with_api_key(_get_env_or_default(properties, 'SECURENATIVE_API_KEY', options.api_key)) + .with_api_url(_get_env_or_default(properties, 'SECURENATIVE_API_URL', options.api_url)) + .with_interval(_get_env_or_default(properties, 'SECURENATIVE_INTERVAL', options.interval)) + .with_max_events(_get_env_or_default(properties, 'SECURENATIVE_MAX_EVENTS', options.max_events)) + .with_timeout(_get_env_or_default(properties, 'SECURENATIVE_TIMEOUT', options.timeout)) + .with_auto_send(_get_env_or_default(properties, 'SECURENATIVE_AUTO_SEND', options.auto_send)) + .with_disable(_get_env_or_default(properties, 'SECURENATIVE_DISABLE', options.disable)) + .with_log_level(_get_env_or_default(properties, 'SECURENATIVE_LOG_LEVEL', options.log_level)) + .with_fail_over_strategy(_get_env_or_default(properties, 'SECURENATIVE_FAILOVER_STRATEGY', options.fail_over_strategy)) end end \ No newline at end of file diff --git a/lib/context/context_builder.rb b/lib/context/context_builder.rb index f46c980..5f1f68a 100644 --- a/lib/context/context_builder.rb +++ b/lib/context/context_builder.rb @@ -39,7 +39,7 @@ def with_body(body) end def self.default_context_builder - return ContextBuilder() + ContextBuilder() end def self.from_http_request(request) @@ -55,18 +55,16 @@ def self.from_http_request(request) headers = nil end - if Utils.is_null_or_empty(client_token) - client_token = RequestUtils.get_secure_header_from_request(headers) - end + client_token = RequestUtils.get_secure_header_from_request(headers) if Utils.null_or_empty?(client_token) - return ContextBuilder() - .with_url(request.url) - .with_method(request.method) - .with_headers(headers) - .with_client_token(client_token) - .with_ip(RequestUtils.get_client_ip_from_request(request)) - .with_remote_ip(RequestUtils.get_remote_ip_from_request(request)) - .with_body(nil) + ContextBuilder() + .with_url(request.url) + .with_method(request.method) + .with_headers(headers) + .with_client_token(client_token) + .with_ip(RequestUtils.get_client_ip_from_request(request)) + .with_remote_ip(RequestUtils.get_remote_ip_from_request(request)) + .with_body(nil) end def build diff --git a/lib/enums/api_route.rb b/lib/enums/api_route.rb index a2c2278..84c4a00 100644 --- a/lib/enums/api_route.rb +++ b/lib/enums/api_route.rb @@ -1,4 +1,4 @@ module ApiRoute - TRACK = "track" - VERIFY = "verify" + TRACK = 'track'.freeze + VERIFY = 'verify'.freeze end \ No newline at end of file diff --git a/lib/enums/event_types.rb b/lib/enums/event_types.rb index f097e90..76be140 100644 --- a/lib/enums/event_types.rb +++ b/lib/enums/event_types.rb @@ -1,21 +1,21 @@ module EventTypes - LOG_IN = "sn.user.login" - LOG_IN_CHALLENGE = "sn.user.login.challenge" - LOG_IN_FAILURE = "sn.user.login.failure" - LOG_OUT = "sn.user.logout" - SIGN_UP = "sn.user.signup" - AUTH_CHALLENGE = "sn.user.auth.challenge" - AUTH_CHALLENGE_SUCCESS = "sn.user.auth.challenge.success" - AUTH_CHALLENGE_FAILURE = "sn.user.auth.challenge.failure" - TWO_FACTOR_DISABLE = "sn.user.2fa.disable" - EMAIL_UPDATE = "sn.user.email.update" - PASSWORD_REST = "sn.user.password.reset" - PASSWORD_REST_SUCCESS = "sn.user.password.reset.success" - PASSWORD_UPDATE = "sn.user.password.update" - PASSWORD_REST_FAILURE = "sn.user.password.reset.failure" - USER_INVITE = "sn.user.invite" - ROLE_UPDATE = "sn.user.role.update" - PROFILE_UPDATE = "sn.user.profile.update" - PAGE_VIEW = "sn.user.page.view" - VERIFY = "sn.verify" + LOG_IN = 'sn.user.login'.freeze + LOG_IN_CHALLENGE = 'sn.user.login.challenge'.freeze + LOG_IN_FAILURE = 'sn.user.login.failure'.freeze + LOG_OUT = 'sn.user.logout'.freeze + SIGN_UP = 'sn.user.signup'.freeze + AUTH_CHALLENGE = 'sn.user.auth.challenge'.freeze + AUTH_CHALLENGE_SUCCESS = 'sn.user.auth.challenge.success'.freeze + AUTH_CHALLENGE_FAILURE = 'sn.user.auth.challenge.failure'.freeze + TWO_FACTOR_DISABLE = 'sn.user.2fa.disable'.freeze + EMAIL_UPDATE = 'sn.user.email.update'.freeze + PASSWORD_REST = 'sn.user.password.reset'.freeze + PASSWORD_REST_SUCCESS = 'sn.user.password.reset.success'.freeze + PASSWORD_UPDATE = 'sn.user.password.update'.freeze + PASSWORD_REST_FAILURE = 'sn.user.password.reset.failure'.freeze + USER_INVITE = 'sn.user.invite'.freeze + ROLE_UPDATE = 'sn.user.role.update'.freeze + PROFILE_UPDATE = 'sn.user.profile.update'.freeze + PAGE_VIEW = 'sn.user.page.view'.freeze + VERIFY = 'sn.verify'.freeze end \ No newline at end of file diff --git a/lib/enums/failover_strategy.rb b/lib/enums/failover_strategy.rb index 318cb19..3ba4df6 100644 --- a/lib/enums/failover_strategy.rb +++ b/lib/enums/failover_strategy.rb @@ -1,4 +1,4 @@ module FailOverStrategy - FAIL_OPEN = "fail-open" - FAIL_CLOSED = "fail-closed" + FAIL_OPEN = 'fail-open'.freeze + FAIL_CLOSED = 'fail-closed'.freeze end \ No newline at end of file diff --git a/lib/enums/risk_level.rb b/lib/enums/risk_level.rb index 8e2d30b..01343c4 100644 --- a/lib/enums/risk_level.rb +++ b/lib/enums/risk_level.rb @@ -1,5 +1,5 @@ module RiskLevel - LOW = "low" - MEDIUM = "medium" - HIGH = "high" + LOW = 'low'.freeze + MEDIUM = 'medium'.freeze + HIGH = 'high'.freeze end \ No newline at end of file diff --git a/lib/event_manager.rb b/lib/event_manager.rb index 84878c6..4f8d865 100644 --- a/lib/event_manager.rb +++ b/lib/event_manager.rb @@ -17,11 +17,11 @@ def initialize(options = SecureNativeOptions(), http_client = nil) raise SecureNativeSDKException('API key cannot be None, please get your API key from SecureNative console.') end - if http_client.nil? - @http_client = SecureNativeHttpClient(options) - else - @http_client = http_client - end + @http_client = if http_client.nil? + SecureNativeHttpClient(options) + else + http_client + end @queue = [] @thread = Thread.new(run) @@ -37,16 +37,11 @@ def initialize(options = SecureNativeOptions(), http_client = nil) def send_async(event, resource_path) if @options.disable - Logger.warning("SDK is disabled. no operation will be performed") + Logger.warning('SDK is disabled. no operation will be performed') return end - item = QueueItem( - resource_path, - JSON.parse(EventManager.serialize(event)), - false - ) - + item = QueueItem(resource_path, JSON.parse(EventManager.serialize(event)), false) @queue.append(item) end @@ -58,20 +53,16 @@ def flush def send_sync(event, resource_path, _retry) if @options.disable - Logger.warning("SDK is disabled. no operation will be performed") + Logger.warning('SDK is disabled. no operation will be performed') return end - Logger.debug("Attempting to send event {}".format(event)) + Logger.debug('Attempting to send event {}'.format(event)) res = @http_client.post(resource_path, JSON.parse(EventManager.serialize(event))) if res.status_code != 200 - Logger.info("SecureNative failed to call endpoint {} with event {}. adding back to queue".format(resource_path, event)) - item = QueueItem( - resource_path, - JSON.parse(EventManager.serialize(event)), - _retry - ) + Logger.info('SecureNative failed to call endpoint {} with event {}. adding back to queue'.format(resource_path, event)) + item = QueueItem(resource_path, JSON.parse(EventManager.serialize(event)), _retry) @queue.append(item) end @@ -79,84 +70,80 @@ def send_sync(event, resource_path, _retry) end def run - while true : - if @queue.length > 0 and @send_enabled - @queue.each do |item| - begin - res = @http_client.post(item.url, item.body) - if res.status_code == 401 - item.retry = false - elsif res.status_code != 200 - raise SecureNativeHttpException(res.status_code) - end - Logger.debug("Event successfully sent; {}".format(item.body)) - return res - rescue StandardError => e - Logger.error("Failed to send event; {}".format(e)) - if item.retry - if @coefficients.length == @attempt + 1 - @attempt = 0 - end - - back_off = @coefficients[@attempt] * @options.interval - Logger.debug("Automatic back-off of {}".format(back_off)) - @send_enabled = false - time.sleep(back_off) # TODO add time sleep - @send_enabled = true - end + loop do + next unless !@queue.empty? && @send_enabled + + @queue.each do |item| + begin + res = @http_client.post(item.url, item.body) + if res.status_code == 401 + item.retry = false + elsif res.status_code != 200 + raise SecureNativeHttpException(res.status_code) + end + Logger.debug('Event successfully sent; {}'.format(item.body)) + return res + rescue StandardError => e + Logger.error('Failed to send event; {}'.format(e)) + if item.retry + @attempt = 0 if @coefficients.length == @attempt + 1 + + back_off = @coefficients[@attempt] * @options.interval + Logger.debug('Automatic back-off of {}'.format(back_off)) + @send_enabled = false + time.sleep(back_off) # TODO: add time sleep + @send_enabled = true end end - time.sleep(self.interval / 1000) # TODO add time sleep end + time.sleep(@interval / 1000) # TODO: add time sleep end end def start_event_persist - Logger.debug("Starting automatic event persistence") + Logger.debug('Starting automatic event persistence') if @options.auto_send || @send_enabled @send_enabled = true else - Logger.debug("Automatic event persistence is disabled, you should persist events manually") + Logger.debug('Automatic event persistence is disabled, you should persist events manually') end end def stop_event_persist if @send_enabled - Logger.debug("Attempting to stop automatic event persistence") + Logger.debug('Attempting to stop automatic event persistence') begin flush - unless @thread.nil? - @thread.stop - end - Logger.debug("Stopped event persistence") + @thread&.stop + Logger.debug('Stopped event persistence') rescue StandardError => e - Logger.error("Could not stop event scheduler; {}".format(e)) + Logger.error('Could not stop event scheduler; {}'.format(e)) end end end def self.serialize(obj) - return { - :rid => obj.rid, - :eventType => obj.event_type, - :userId => obj.user_id, - :userTraits => { - :name => obj.user_traits.name, - :email => obj.user_traits.email, - :createdAt => obj.user_traits.created_at, + { + rid: obj.rid, + eventType: obj.event_type, + userId: obj.user_id, + userTraits: { + name: obj.user_traits.name, + email: obj.user_traits.email, + createdAt: obj.user_traits.created_at }, - :request => { - :cid => obj.request.cid, - :vid => obj.request.vid, - :fp => obj.request.fp, - :ip => obj.request.ip, - :remoteIp => bj.request.remote_ip, - :method => obj.request.method, - :url => obj.request.url, - :headers => obj.request.headers + request: { + cid: obj.request.cid, + vid: obj.request.vid, + fp: obj.request.fp, + ip: obj.request.ip, + remoteIp: obj.request.remote_ip, + method: obj.request.method, + url: obj.request.url, + headers: obj.request.headers }, - :timestamp => obj.timestamp, - :properties => obj.properties, + timestamp: obj.timestamp, + properties: obj.properties } end end \ No newline at end of file diff --git a/lib/event_options_builder.rb b/lib/event_options_builder.rb index 59e1c7e..e8ba3d8 100644 --- a/lib/event_options_builder.rb +++ b/lib/event_options_builder.rb @@ -37,8 +37,9 @@ def with_timestamp(timestamp) def build if !@event_options.properties.nil? && @event_options.properties.length > MAX_PROPERTIES_SIZE - raise SecureNativeInvalidOptionsException("You can have only up to {} custom properties", MAX_PROPERTIES_SIZE) + raise SecureNativeInvalidOptionsException('You can have only up to {} custom properties', MAX_PROPERTIES_SIZE) end + @event_options end end \ No newline at end of file diff --git a/lib/http/securenative_http_client.rb b/lib/http/securenative_http_client.rb index 38212d5..a764b62 100644 --- a/lib/http/securenative_http_client.rb +++ b/lib/http/securenative_http_client.rb @@ -1,12 +1,12 @@ require 'httpclient' class SecureNativeHttpClient - AUTHORIZATION_HEADER = "Authorization" - VERSION_HEADER = "SN-Version" - USER_AGENT_HEADER = "User-Agent" - USER_AGENT_HEADER_VALUE = "SecureNative-python" - CONTENT_TYPE_HEADER = "Content-Type" - CONTENT_TYPE_HEADER_VALUE = "application/json" + AUTHORIZATION_HEADER = 'Authorization'.freeze + VERSION_HEADER = 'SN-Version'.freeze + USER_AGENT_HEADER = 'User-Agent'.freeze + USER_AGENT_HEADER_VALUE = 'SecureNative-python'.freeze + CONTENT_TYPE_HEADER = 'Content-Type'.freeze + CONTENT_TYPE_HEADER_VALUE = 'application/json'.freeze def __init__(securenative_options) @options = securenative_options @@ -17,13 +17,13 @@ def _headers { CONTENT_TYPE_HEADER => CONTENT_TYPE_HEADER_VALUE, USER_AGENT_HEADER => USER_AGENT_HEADER_VALUE, - VERSION_HEADER => VersionUtils.get_version, + VERSION_HEADER => VersionUtils.version, AUTHORIZATION_HEADER => options.api_key } end def post(path, body) - url = "{}/{}".format(@options.api_url, path) + url = '{}/{}'.format(@options.api_url, path) headers = _headers @client.post(url, body, headers) end diff --git a/lib/logger.rb b/lib/logger.rb index e6b122e..96bc718 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -4,20 +4,20 @@ class Logger @logger = Logger.new(STDOUT) def self.init_logger(level) - case level - when "WARN" - @logger.level = Logger::WARN - when "DEBUG" - @logger.level = Logger::DEBUG - when "ERROR" - @logger.level = Logger::ERROR - when "FATAL" - @logger.level = Logger::FATAL - when "INFO" - @logger.level = Logger::INFO - else - @logger.level = Logger::FATAL - end + @logger.level = case level + when 'WARN' + Logger::WARN + when 'DEBUG' + Logger::DEBUG + when 'ERROR' + Logger::ERROR + when 'FATAL' + Logger::FATAL + when 'INFO' + Logger::INFO + else + Logger::FATAL + end @logger.formatter = proc do |severity, datetime, progname, msg| "[#{datetime}] #{severity} (#{progname}): #{msg}\n" diff --git a/lib/models/request_context.rb b/lib/models/request_context.rb index 0c3a421..6eacd21 100644 --- a/lib/models/request_context.rb +++ b/lib/models/request_context.rb @@ -72,4 +72,4 @@ def with_method(method) def build RequestContext(@cid, @vid, @fp, @ip, @remote_ip, @headers, @url, @method) end -end +end diff --git a/lib/models/sdk_event.rb b/lib/models/sdk_event.rb index 391f177..3265014 100644 --- a/lib/models/sdk_event.rb +++ b/lib/models/sdk_event.rb @@ -3,11 +3,11 @@ class SDKEvent attr_writer :context, :rid, :event_type, :user_id, :user_traits, :request, :timestamp, :properties def initialize(event_options, securenative_options) - if !event_options.context.nil? - @context = event_options.context - else - @context = ContextBuilder.default_context_builder.build - end + @context = if !event_options.context.nil? + event_options.context + else + ContextBuilder.default_context_builder.build + end client_token = EncryptionUtils.decrypt(@context.client_token, securenative_options.api_key) @@ -16,15 +16,15 @@ def initialize(event_options, securenative_options) @user_id = event_options.user_id @user_traits = event_options.user_traits @request = RequestContextBuilder() - .with_cid(client_token ? client_token.cid : "") - .with_vid(client_token ? client_token.vid : "") - .with_fp(client_token ? client_token.fp : "") - .with_ip(@context.ip) - .with_remote_ip(@context.remote_ip) - .with_method(@context.method) - .with_url(@context.url) - .with_headers(@context.headers) - .build + .with_cid(client_token ? client_token.cid : '') + .with_vid(client_token ? client_token.vid : '') + .with_fp(client_token ? client_token.fp : '') + .with_ip(@context.ip) + .with_remote_ip(@context.remote_ip) + .with_method(@context.method) + .with_url(@context.url) + .with_headers(@context.headers) + .build @timestamp = DateUtils.to_timestamp(event_options.timestamp) @properties = event_options.properties diff --git a/lib/securenative.rb b/lib/securenative.rb index ca2ff18..fa09280 100644 --- a/lib/securenative.rb +++ b/lib/securenative.rb @@ -1,18 +1,16 @@ require_relative 'logger' class SecureNative + attr_reader :options + def initialize(options) @securenative = nil - if Utils.is_null_or_empty(options.api_key) - raise SecureNativeSDKException("You must pass your SecureNative api key") - end + raise SecureNativeSDKException('You must pass your SecureNative api key') if Utils.null_or_empty?(options.api_key) @options = options @event_manager = EventManager(@options) - unless @options.api_url.nil? - @event_manager.start_event_persist - end + @event_manager.start_event_persist unless @options.api_url.nil? @api_manager = ApiManager.new(@event_manager, @options) Logger.init_logger(@options.log_level) @@ -21,26 +19,24 @@ def initialize(options) def self.init_with_options(options) if @securenative.nil? @securenative = SecureNative.new(options) - return @securenative + @securenative else Logger.debug('This SDK was already initialized.') - raise SecureNativeSDKException(u 'This SDK was already initialized.') + raise SecureNativeSDKException('This SDK was already initialized.') end end def self.init_with_api_key(api_key) - if Utils.is_null_or_empty(api_key) - raise SecureNativeConfigException("You must pass your SecureNative api key") - end + raise SecureNativeConfigException('You must pass your SecureNative api key') if Utils.null_or_empty?(api_key) if @securenative.nil? builder = ConfigurationBuilder().default_config_builder options = builder.with_api_key(api_key) @securenative = SecureNative.new(options) - return @securenative + @securenative else Logger.debug('This SDK was already initialized.') - raise SecureNativeSDKException(u 'This SDK was already initialized.') + raise SecureNativeSDKException(u('This SDK was already initialized.')) end end @@ -49,24 +45,18 @@ def self.init init_with_options(options) end - def self.get_instance - if @securenative.nil? - raise SecureNativeSDKIllegalStateException() - end - return @securenative - end + def self.instance + raise SecureNativeSDKIllegalStateException() if @securenative.nil? - def get_options - @options + @securenative end - def self.config_builder - return ConfigurationBuilder.default_config_builder + ConfigurationBuilder.default_config_builder end def self.context_builder - return ContextBuilder.default_context_builder + ContextBuilder.default_context_builder end def track(event_options) diff --git a/lib/utils/date_utils.rb b/lib/utils/date_utils.rb index c239a2b..cd9ac5a 100644 --- a/lib/utils/date_utils.rb +++ b/lib/utils/date_utils.rb @@ -1,8 +1,7 @@ class DateUtils def self.to_timestamp(date) - if date.nil? - return Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z") - end - return Time.strptime(date, "%Y-%m-%dT%H:%M:%S.%L%Z") + return Time.now.strftime('%Y-%m-%dT%H:%M:%S.%L%Z') if date.nil? + + Time.strptime(date, '%Y-%m-%dT%H:%M:%S.%L%Z') end end \ No newline at end of file diff --git a/lib/utils/encryption_utils.rb b/lib/utils/encryption_utils.rb index add2c62..67c8ef9 100644 --- a/lib/utils/encryption_utils.rb +++ b/lib/utils/encryption_utils.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'openssl' class EncryptionUtils @@ -11,7 +13,7 @@ def self.encrypt(text, cipher_key) if text.size % BLOCK_SIZE != 0 logger = Logger.new(STDOUT) logger.level = Logger::WARN - logger.fatal("data not multiple of block length") + logger.fatal('data not multiple of block length') return nil end @@ -28,9 +30,9 @@ def self.decrypt(encrypted, cipher_key) cipher_key = Digest::SHA1.hexdigest cipher_key cipher.key = cipher_key.slice(0, BLOCK_SIZE) - s = [encrypted].pack("H*").unpack("C*").pack("c*") + s = [encrypted].pack('H*').unpack('C*').pack('c*') rv = cipher.update(s) + cipher.final - return rv.strip + rv.strip end end \ No newline at end of file diff --git a/lib/utils/ip_utils.rb b/lib/utils/ip_utils.rb index d8d1120..91b892c 100644 --- a/lib/utils/ip_utils.rb +++ b/lib/utils/ip_utils.rb @@ -1,26 +1,22 @@ class IpUtils - VALID_IPV4_PATTERN = ("(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])") - VALID_IPV6_PATTERN = ("([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}") + VALID_IPV4_PATTERN = '(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])'.freeze + VALID_IPV6_PATTERN = '([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}'.freeze - def self.is_ip_address(ip_address) - if IpUtils.VALID_IPV4_PATTERN.match(ip_address) - return true - end - if IpUtils.VALID_IPV6_PATTERN.match(ip_address) - return true - end - return false + def self.ip_address?(ip_address) + return true if IpUtils.VALID_IPV4_PATTERN.match(ip_address) + return true if IpUtils.VALID_IPV6_PATTERN.match(ip_address) + + false end - def self.is_valid_public_ip(ip_address) + def self.valid_public_ip?(ip_address) ip = IPAddr.new(ip_address) - if ip.loopback? || ip.private? || ip.link_local? || ip.untrusted? || ip.tainted? - return false - end - return true + return false if ip.loopback? || ip.private? || ip.link_local? || ip.untrusted? || ip.tainted? + + true end - def self.is_loop_back(ip_address) + def self.loop_back?(ip_address) IPAddr.new(ip_address).loopback? end end \ No newline at end of file diff --git a/lib/utils/request_utils.rb b/lib/utils/request_utils.rb index 15e2faf..fc9b0ac 100644 --- a/lib/utils/request_utils.rb +++ b/lib/utils/request_utils.rb @@ -1,23 +1,21 @@ class RequestUtils - SECURENATIVE_COOKIE = "_sn" - SECURENATIVE_HEADER = "x-securenative" + SECURENATIVE_COOKIE = '_sn'.freeze + SECURENATIVE_HEADER = 'x-securenative'.freeze def self.get_secure_header_from_request(headers) - unless headers.nil? - return headers[RequestUtils.SECURENATIVE_HEADER] - end - return [] + return headers[RequestUtils.SECURENATIVE_HEADER] unless headers.nil? + + [] end def self.get_client_ip_from_request(request) - x_forwarded_for = request.env["HTTP_X_FORWARDED_FOR"] - unless x_forwarded_for.nil? - return x_forwarded_for - end - return request.env["REMOTE_ADDR"] + x_forwarded_for = request.env['HTTP_X_FORWARDED_FOR'] + return x_forwarded_for unless x_forwarded_for.nil? + + request.env['REMOTE_ADDR'] end def self.get_remote_ip_from_request(request) - return request.remote_ip + request.remote_ip end end \ No newline at end of file diff --git a/lib/utils/signature_utils.rb b/lib/utils/signature_utils.rb index 3c759f3..a465ced 100644 --- a/lib/utils/signature_utils.rb +++ b/lib/utils/signature_utils.rb @@ -1,14 +1,12 @@ require 'openssl' class SignatureUtils - def self.is_valid_signature(api_key, payload, header_signature) - begin - key = api_key.encode('utf-8') - body = payload.encode('utf-8') - calculated_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha512'), key, body) - calculated_signature.eql? header_signature - rescue Exception - return false - end + def self.valid_signature?(api_key, payload, header_signature) + key = api_key.encode('utf-8') + body = payload.encode('utf-8') + calculated_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha512'), key, body) + calculated_signature.eql? header_signature + rescue StandardError + false end end \ No newline at end of file diff --git a/lib/utils/utils.rb b/lib/utils/utils.rb index 7315da8..57641ad 100644 --- a/lib/utils/utils.rb +++ b/lib/utils/utils.rb @@ -1,11 +1,9 @@ class Utils - def self.is_null_or_empty(string) - if !string.nil? && !string.empty? - return true - end - unless string.nil? - return true - end - return false + def self.null_or_empty?(string) + return true if !string.nil? && !string.empty? + + return true unless string.nil? + + false end end \ No newline at end of file diff --git a/lib/utils/version_utils.rb b/lib/utils/version_utils.rb index c0242ad..d46e495 100644 --- a/lib/utils/version_utils.rb +++ b/lib/utils/version_utils.rb @@ -1,10 +1,10 @@ class VersionUtils - def self.get_version - path = "VERSION" + def self.version + path = 'VERSION' file = File.open(path) version = file.read file.close - return version + version end end \ No newline at end of file diff --git a/securenative.gemspec b/securenative.gemspec index 7f9740b..221c990 100644 --- a/securenative.gemspec +++ b/securenative.gemspec @@ -4,7 +4,7 @@ require_relative "lib/utils/version_utils" Gem::Specification.new do |spec| spec.name = "securenative" - spec.version = VersionUtils.get_version + spec.version = VersionUtils.version spec.authors = ["SecureNative"] spec.email = ["support@securenative.com"] diff --git a/spec/test_api_manager.rb b/spec/test_api_manager.rb index 525e55b..d47a2d1 100644 --- a/spec/test_api_manager.rb +++ b/spec/test_api_manager.rb @@ -1,63 +1,65 @@ +# frozen_string_literal: true + describe ApiManager do - let(:context) { ContextBuilder().with_ip("127.0.0.1").with_client_token("SECURED_CLIENT_TOKEN").with_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"}).build } - let(:event_options) { EventOptionsBuilder(EventTypes.LOG_IN).with_user_id("USER_ID").with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")).with_context(context).with_properties({:prop1 => "CUSTOM_PARAM_VALUE", :prop2 => true, :prop3 => 3}).build } + let(:context) { ContextBuilder().with_ip('127.0.0.1').with_client_token('SECURED_CLIENT_TOKEN').with_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'}).build } + let(:event_options) { EventOptionsBuilder(EventTypes.LOG_IN).with_user_id('USER_ID').with_user_traits(UserTraits('USER_NAME', 'USER_EMAIL')).with_context(:context).with_properties({prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build } - it "tracks an event" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_auto_send(true).with_interval(10).with_api_url("https://api.securenative-stg.com/collector/api/v1") + it 'tracks an event' do + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_auto_send(true).with_interval(10).with_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\",\"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}}" + expected = '{"eventType":"sn.user.login","userId":"USER_ID","userTraits":{' \ + '"name":"USER_NAME","email":"USER_EMAIL","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}}' # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json = json.loads(expected), status = 200) + responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/track', json = json.loads(expected), status = 200) event_manager = EventManager.new(options) event_manager.start_event_persist api_manager = ApiManager.new(event_manager, options) begin - api_manager.track(event_options) + api_manager.track(:event_options) ensure event_manager.stop_event_persist end end - it "uses invalid options" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_auto_send(true).with_interval(10).with_api_url("https://api.securenative-stg.com/collector/api/v1") + it 'uses invalid options' do + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_auto_send(true).with_interval(10).with_api_url('https://api.securenative-stg.com/collector/api/v1') properties = {} - (0..12).each { |i| + (0..12).each do |i| properties[i] = i - } + end # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json = {}, status = 200) + responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/track', json = {}, status = 200) event_manager = EventManager.new(options) event_manager.start_event_persist api_manager = ApiManager.new(event_manager, options) begin - expect { api_manager.track(EventOptionsBuilder(EventTypes.LOG_IN).with_properties(properties).build) }.to raise_error(Errors::SecureNativeInvalidOptionsException) + expect { api_manager.track(EventOptionsBuilder(EventTypes.LOG_IN).with_properties(properties).build) }.to raise_error(SecureNativeInvalidOptionsException) ensure event_manager.stop_event_persist end end - it "verifies an event" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + it 'verifies an event' do + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/verify", json = {:riskLevel => "medium", :score => 0.32, :triggers => ["New IP", "New City"]}, status = 200) + responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/verify', json = {:riskLevel => 'medium', :score => 0.32, :triggers => ['New IP', 'New City']}, status = 200) verify_result = VerifyResult.new(RiskLevel.LOW, 0, nil) event_manager = EventManager.new(options) event_manager.start_event_persist api_manager = ApiManager.new(event_manager, options) - result = api_manager.verify(event_options) + result = api_manager.verify(:event_options) expect(result).not_to be_empty expect(result.risk_level).to eq(verify_result.risk_level) diff --git a/spec/test_configuration_manager.rb b/spec/test_configuration_manager.rb index 5626869..915c886 100644 --- a/spec/test_configuration_manager.rb +++ b/spec/test_configuration_manager.rb @@ -1,29 +1,31 @@ +# frozen_string_literal: true + describe ConfigurationManager do - it "parses a config file correctly" do + it 'parses a config file correctly' do # code here end - it "ignores unknown config in properties file" do + it 'ignores unknown config in properties file' do # code here end - it "handles invalid config file" do + it 'handles invalid config file' do # code here end - it "ignores invalid config file entries" do + it 'ignores invalid config file entries' do # code here end - it "loads default config" do + it 'loads default config' do # code here end - it "gets config from env variables" do + it 'gets config from env variables' do # code here end - it "uses default values for invalid enum config props" do + it 'uses default values for invalid enum config props' do # code here end end \ No newline at end of file diff --git a/spec/test_context_builder.rb b/spec/test_context_builder.rb index 3128e13..faffc16 100644 --- a/spec/test_context_builder.rb +++ b/spec/test_context_builder.rb @@ -1,13 +1,13 @@ describe ContextBuilder do - it "creates context from request" do - # TODO code here + it 'creates context from request' do + # TODO: code here end - it "creates context from request with cookie" do - # TODO code here + it 'creates context from request with cookie' do + # TODO: code here end - it "creates default context builder" do + it 'creates default context builder' do context = ContextBuilder.default_context_builder.build expect(context.client_token).not_to be_empty @@ -19,15 +19,15 @@ expect(context.body).not_to be_empty end - it "creates custom context with context builder" do - context = ContextBuilder.default_context_builder.with_url("/some-url").with_client_token("SECRET_TOKEN").with_ip("10.0.0.0").with_body("{ \"name\": \"YOUR_NAME\" }").with_method("Get").with_remote_ip("10.0.0.1").with_headers({:header1 => "value1"}).build + it 'creates custom context with context builder' do + context = ContextBuilder.default_context_builder.with_url('/some-url').with_client_token('SECRET_TOKEN').with_ip('10.0.0.0').with_body('{ "name": "YOUR_NAME" }').with_method('Get').with_remote_ip('10.0.0.1').with_headers({ header1: 'value1' }).build - expect(context.url).to eq("/some-url") - expect(context.client_token).to eq("SECRET_TOKEN") - expect(context.ip).to eq("10.0.0.0") - expect(context.body).to eq("{ \"name\": \"YOUR_NAME\" }") - expect(context.method).to eq("Get") - expect(context.remote_ip).to eq("10.0.0.0") - expect(context.headers).to eq({:header1 => "value1"}) + expect(context.url).to eq('/some-url') + expect(context.client_token).to eq('SECRET_TOKEN') + expect(context.ip).to eq('10.0.0.0') + expect(context.body).to eq('{ "name": "YOUR_NAME" }') + expect(context.method).to eq('Get') + expect(context.remote_ip).to eq('10.0.0.0') + expect(context.headers).to eq({ header1: 'value1' }) end end \ No newline at end of file diff --git a/spec/test_date_utils.rb b/spec/test_date_utils.rb index 35204bd..5765b09 100644 --- a/spec/test_date_utils.rb +++ b/spec/test_date_utils.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + describe DateUtils do - it "converts to timestamp" do - iso_8601_date = "2020-05-20T15:07:13Z" + it 'converts to timestamp' do + iso_8601_date = '2020-05-20T15:07:13Z' result = DateUtils.to_timestamp(iso_8601_date) - expect(result).to eq(Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z")) + expect(result).to eq(Time.now.strftime('%Y-%m-%dT%H:%M:%S.%L%Z')) end end \ No newline at end of file diff --git a/spec/test_encryption_utils.rb b/spec/test_encryption_utils.rb index d7d6132..5d08cb2 100644 --- a/spec/test_encryption_utils.rb +++ b/spec/test_encryption_utils.rb @@ -1,21 +1,23 @@ +# frozen_string_literal: true + describe EncryptionUtils do - let(:SECRET_KEY) { "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6" } - let(:PAYLOAD) { "{\"cid\":\"198a41ff-a10f-4cda-a2f3-a9ca80c0703b\",\"vi\":\"148a42ff-b40f-4cda-a2f3-a8ca80c0703b\",\"fp\":\"6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed\"}" } - let(:CID) { "198a41ff-a10f-4cda-a2f3-a9ca80c0703b" } - let(:FP) { "6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed" } + let(:SECRET_KEY) { 'B00C42DAD33EAC6F6572DA756EA4915349C0A4F6' } + let(:PAYLOAD) { '{"cid":"198a41ff-a10f-4cda-a2f3-a9ca80c0703b","vi":"148a42ff-b40f-4cda-a2f3-a8ca80c0703b","fp":"6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed"}' } + let(:CID) { '198a41ff-a10f-4cda-a2f3-a9ca80c0703b' } + let(:FP) { '6d8cabd95987f8318b1fe01593d5c2a5.24700f9f1986800ab4fcc880530dd0ed' } - it "decrypts" do - result = EncryptionUtils.encrypt(PAYLOAD, SECRET_KEY) + it 'decrypts' do + result = EncryptionUtils.encrypt(:PAYLOAD, :SECRET_KEY) expect(result).not_to be_empty - expect(result.length).to eq(PAYLOAD.length) + expect(result.length).to eq(:PAYLOAD.length) end - it "encrypts" do - encrypted_payload = "5208ae703cc2fa0851347f55d3b76d3fd6035ee081d71a401e8bc92ebdc25d42440f62310bda60628537744ac03f200d78da9e61f1019ce02087b7ce6c976e7b2d8ad6aa978c532cea8f3e744cc6a5cafedc4ae6cd1b08a4ef75d6e37aa3c0c76954d16d57750be2980c2c91ac7ef0bbd0722abd59bf6be22493ea9b9759c3ff4d17f17ab670b0b6fc320e6de982313f1c4e74c0897f9f5a32d58e3e53050ae8fdbebba9009d0d1250fe34dcde1ebb42acbc22834a02f53889076140f0eb8db1" - result = EncryptionUtils.decrypt(encrypted_payload, SECRET_KEY) + it 'encrypts' do + encrypted_payload = '5208ae703cc2fa0851347f55d3b76d3fd6035ee081d71a401e8bc92ebdc25d42440f62310bda60628537744ac03f200d78da9e61f1019ce02087b7ce6c976e7b2d8ad6aa978c532cea8f3e744cc6a5cafedc4ae6cd1b08a4ef75d6e37aa3c0c76954d16d57750be2980c2c91ac7ef0bbd0722abd59bf6be22493ea9b9759c3ff4d17f17ab670b0b6fc320e6de982313f1c4e74c0897f9f5a32d58e3e53050ae8fdbebba9009d0d1250fe34dcde1ebb42acbc22834a02f53889076140f0eb8db1' + result = EncryptionUtils.decrypt(encrypted_payload, :SECRET_KEY) - expect(result.cid).to eq(CID) - expect(result.fp).to eq(FP) + expect(result.cid).to eq(:CID) + expect(result.fp).to eq(:FP) end end \ No newline at end of file diff --git a/spec/test_event_manager.rb b/spec/test_event_manager.rb index 6c95931..92c262d 100644 --- a/spec/test_event_manager.rb +++ b/spec/test_event_manager.rb @@ -1,12 +1,14 @@ +# frozen_string_literal: true + class SampleEvent attr_reader :event_type, :timestamp, :rid, :user_id, :user_traits, :request, :properties def initialize - @event_type = "custom-event" - @timestamp = Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L%Z") - @rid = "432532" - @user_id = "1" - @user_traits = UserTraits("some user", "email@securenative.com") + @event_type = 'custom-event' + @timestamp = Time.now.strftime('%Y-%m-%dT%H:%M:%S.%L%Z') + @rid = '432532' + @user_id = '1' + @user_traits = UserTraits('some user', 'email@securenative.com') @request = RequestContext() @properties = [] end @@ -15,36 +17,36 @@ def initialize describe EventManager do let(:event) { SampleEvent() } - it "successfully sends sync event with status code 200" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + it 'successfully sends sync event with status code 200' do + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') - res_body = "{\"data\": true}" + res_body = '{"data": true}' # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = json.loads(res_body), status = 200) + responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api', json = json.loads(res_body), status = 200) event_manager = EventManager.new(options) - data = event_manager.send_sync(self.event, "some-path/to-api", false) + data = event_manager.send_sync(:event, 'some-path/to-api', false) expect(res_body).to eq(data.text) end - it "fails when send sync event status code is 401" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + it 'fails when send sync event status code is 401' do + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = {}, status = 401) + responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api', json = {}, status = 401) event_manager = EventManager.new(options) - res = event_manager.send_sync(self.event, "some-path/to-api", false) + res = event_manager.send_sync(:event, 'some-path/to-api', false) expect(res.status_code).to eq(401) end - it "fails when send sync event status code is 500" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + it 'fails when send sync event status code is 500' do + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/some-path/to-api", json = {}, status = 500) + responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api', json = {}, status = 500) event_manager = EventManager.new(options) - res = event_manager.send_sync(self.event, "some-path/to-api", false) + res = event_manager.send_sync(:event, 'some-path/to-api', false) expect(res.status_code).to eq(500) end diff --git a/spec/test_ip_utils.rb b/spec/test_ip_utils.rb index 16e9401..100d83b 100644 --- a/spec/test_ip_utils.rb +++ b/spec/test_ip_utils.rb @@ -1,36 +1,38 @@ +# frozen_string_literal: true + describe IpUtils do - it "checks if ip address valid ipv4" do - valid_ipv4 = "172.16.254.1" - expect(IpUtils.is_ip_address(valid_ipv4)).to be_truthy + it 'checks if ip address valid ipv4' do + valid_ipv4 = '172.16.254.1' + expect(IpUtils.ip_address?(valid_ipv4)).to be_truthy end - it "checks if ip address valid ipv6" do - valid_ipv6 = "2001:db8:1234:0000:0000:0000:0000:0000" - expect(IpUtils.is_ip_address(valid_ipv6)).to be_truthy + it 'checks if ip address valid ipv6' do + valid_ipv6 = '2001:db8:1234:0000:0000:0000:0000:0000' + expect(IpUtils.ip_address?(valid_ipv6)).to be_truthy end - it "checks if ip address invalid ipv4" do - invalid_ipv4 = "172.16.2541" - expect(IpUtils.is_ip_address(invalid_ipv4)).to be_falsey + it 'checks if ip address invalid ipv4' do + invalid_ipv4 = '172.16.2541' + expect(IpUtils.ip_address?(invalid_ipv4)).to be_falsey end - it "checks if ip address invalid ipv6" do - invalid_ipv6 = "2001:db8:1234:0000" - expect(IpUtils.is_ip_address(invalid_ipv6)).to be_falsey + it 'checks if ip address invalid ipv6' do + invalid_ipv6 = '2001:db8:1234:0000' + expect(IpUtils.ip_address?(invalid_ipv6)).to be_falsey end - it "checks if valid public ip" do - ip = "64.71.222.37" - expect(IpUtils.is_valid_public_ip(ip)).to be_truthy + it 'checks if valid public ip' do + ip = '64.71.222.37' + expect(IpUtils.valid_public_ip?(ip)).to be_truthy end - it "checks if not valid public ip" do - ip = "10.0.0.0" - expect(IpUtils.is_valid_public_ip(ip)).to be_falsey + it 'checks if not valid public ip' do + ip = '10.0.0.0' + expect(IpUtils.valid_public_ip?(ip)).to be_falsey end - it "checks if valid loopback ip" do - ip = "127.0.0.1" - expect(IpUtils.is_loop_back(ip)).to be_truthy + it 'checks if valid loopback ip' do + ip = '127.0.0.1' + expect(IpUtils.loop_back?(ip)).to be_truthy end end \ No newline at end of file diff --git a/spec/test_securenative.rb b/spec/test_securenative.rb index e9cfd7b..eca56b3 100644 --- a/spec/test_securenative.rb +++ b/spec/test_securenative.rb @@ -1,52 +1,54 @@ +# frozen_string_literal: true + describe SecureNative do - it "gets sdk instance without init throws" do - expect { SecureNative.get_instance }.to raise_error(Errors::SecureNativeSDKIllegalStateException) + it 'gets sdk instance without init throws' do + expect { SecureNative.instance }.to raise_error(SecureNativeSDKIllegalStateException) end - it "inits sdk without api key and throws" do - expect { SecureNative.init_with_options(ConfigurationManager.config_builder) }.to raise_error(Errors::SecureNativeSDKException) + it 'inits sdk without api key and throws' do + expect { SecureNative.init_with_options(ConfigurationManager.config_builder) }.to raise_error(SecureNativeSDKException) end - it "inits sdk with empty api key and throws" do - expect { SecureNative.init_with_api_key("") }.to raise_error(Errors::SecureNativeSDKException) + it 'inits sdk with empty api key and throws' do + expect { SecureNative.init_with_api_key('') }.to raise_error(SecureNativeSDKException) end - it "inits sdk with api key and defaults" do + it 'inits sdk with api key and defaults' do SecureNative._flush - api_key = "API_KEY" + api_key = 'API_KEY' securenative = SecureNative.init_with_api_key(api_key) - options = securenative.get_options + options = securenative.options expect(options.api_key).to eq(api_key) - expect(options.api_url).to eq("https://api.securenative.com/collector/api/v1") + expect(options.api_url).to eq('https://api.securenative.com/collector/api/v1') expect(options.interval).to eq(1000) expect(options.timeout).to eq(1500) expect(options.max_events).to eq(100) expect(options.auto_send).to eq(true) expect(options.disable).to eq(false) - expect(options.log_level).to eq("FATAL") + expect(options.log_level).to eq('FATAL') expect(options.fail_over_strategy).to eq(FailOverStrategy::FAIL_OPEN) end - it "inits sdk twice and throws" do - expect { SecureNative.init_with_api_key("API_KEY") }.to raise_error(Errors::SecureNativeSDKException) + it 'inits sdk twice and throws' do + expect { SecureNative.init_with_api_key('API_KEY') }.to raise_error(SecureNativeSDKException) end - it "inits sdk with api key and gets instance" do + it 'inits sdk with api key and gets instance' do SecureNative._flush - api_key = "API_KEY" + api_key = 'API_KEY' securenative = SecureNative.init_with_api_key(api_key) - expect(securenative).to eq(SecureNative.get_instance) + expect(securenative).to eq(SecureNative.instance) end - it "inits sdk with builder" do + it 'inits sdk with builder' do SecureNative._flush - securenative = SecureNative.init_with_options(SecureNative.config_builder.with_api_key("API_KEY").with_max_events(10).with_log_level("ERROR")) - options = securenative.get_options + securenative = SecureNative.init_with_options(SecureNative.config_builder.with_api_key('API_KEY').with_max_events(10).with_log_level('ERROR')) + options = securenative.options - expect(options.api_key).to eq("API_KEY") + expect(options.api_key).to eq('API_KEY') expect(options.max_events).to eq(10) - expect(options.log_level).to eq("ERROR") + expect(options.log_level).to eq('ERROR') end end \ No newline at end of file diff --git a/spec/test_securenative_http_client.rb b/spec/test_securenative_http_client.rb index 43892b1..b491f62 100644 --- a/spec/test_securenative_http_client.rb +++ b/spec/test_securenative_http_client.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + describe SecureNativeHttpClient do - it "makes a simple post call" do - options = ConfigurationManager.config_builder.with_api_key("YOUR_API_KEY").with_api_url("https://api.securenative-stg.com/collector/api/v1") + it 'makes a simple post call' do + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') # TODO - responses.add(responses.POST, "https://api.securenative-stg.com/collector/api/v1/track", json={"event" => "SOME_EVENT_NAME"}, status=200) + responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/track', json={'event' => 'SOME_EVENT_NAME'}, status=200) client = SecureNativeHttpClient(options) - payload = "{\"event\": \"SOME_EVENT_NAME\"}" + payload = '{"event": "SOME_EVENT_NAME"}' - res = client.post("track", payload) + res = client.post('track', payload) expect(res.ok).to eq(true) expect(res.status_code).to eq(200) diff --git a/spec/test_signature_utils.rb b/spec/test_signature_utils.rb index fde96ca..9d54d6d 100644 --- a/spec/test_signature_utils.rb +++ b/spec/test_signature_utils.rb @@ -1,13 +1,15 @@ +# frozen_string_literal: true + describe SignatureUtils do - it "verifies request payload" do - signature = "c4574c1748064735513697750c6223ff36b03ae3b85b160ce8788557d01e1d9d1c9cd942074323ee0061d3dcc8c94359c5acfa6eee8e2da095b3967b1a88ab73" - payload = "{\"id\":\"4a9157ffbd18cfbd73a57298\",\"type\":\"security-action\",\"flow\":{\"id\":\"62298c73a9bb433fbd1f75984a9157fd\",\"name\":\"Block user that violates geo velocity\"},\"userId\":\"73a9bb433fbd1f75984a9157\",\"userTraits\":{\"name\":\"John Doe\",\"email\":\"john.doe@gmail.com\"},\"request\":{\"ip\":\"10.0.0.0\",\"fp\":\"9bb433fb984a9157d1f7598\"},\"action\":\"block\",\"properties\":{\"type\":\"customer\"},\"timestamp\":\"2020-02-23T22:28:55.387Z\"}" - secret_key = "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6" + it 'verifies request payload' do + signature = 'c4574c1748064735513697750c6223ff36b03ae3b85b160ce8788557d01e1d9d1c9cd942074323ee0061d3dcc8c94359c5acfa6eee8e2da095b3967b1a88ab73' + payload = '{"id":"4a9157ffbd18cfbd73a57298","type":"security-action","flow":{"id":"62298c73a9bb433fbd1f75984a9157fd","name":"Block user that violates geo velocity"},"userId":"73a9bb433fbd1f75984a9157","userTraits":{"name":"John Doe","email":"john.doe@gmail.com"},"request":{"ip":"10.0.0.0","fp":"9bb433fb984a9157d1f7598"},"action":"block","properties":{"type":"customer"},"timestamp":"2020-02-23T22:28:55.387Z"}' + secret_key = 'B00C42DAD33EAC6F6572DA756EA4915349C0A4F6' - expect(SignatureUtils.is_valid_signature(secret_key, payload, signature)).to be_truthy + expect(SignatureUtils.valid_signature?(secret_key, payload, signature)).to be_truthy end - it "verifies request empty signature" do - expect(SignatureUtils.is_valid_signature("", "", "B00C42DAD33EAC6F6572DA756EA4915349C0A4F6")).to be_falsey + it 'verifies request empty signature' do + expect(SignatureUtils.valid_signature?('', '', 'B00C42DAD33EAC6F6572DA756EA4915349C0A4F6')).to be_falsey end end \ No newline at end of file From a876e6f426fbef23146c835e5b4ffb62eff575ae Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 16:08:28 +0300 Subject: [PATCH 25/32] Add spec framework --- spec/{test_api_manager.rb => spec_api_manager.rb} | 0 ...est_configuration_manager.rb => spec_configuration_manager.rb} | 0 spec/{test_context_builder.rb => spec_context_builder.rb} | 0 spec/{test_date_utils.rb => spec_date_utils.rb} | 0 spec/{test_encryption_utils.rb => spec_encryption_utils.rb} | 0 spec/{test_event_manager.rb => spec_event_manager.rb} | 0 spec/{test_ip_utils.rb => spec_ip_utils.rb} | 0 spec/{test_securenative.rb => spec_securenative.rb} | 0 ...curenative_http_client.rb => spec_securenative_http_client.rb} | 0 spec/{test_signature_utils.rb => spec_signature_utils.rb} | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename spec/{test_api_manager.rb => spec_api_manager.rb} (100%) rename spec/{test_configuration_manager.rb => spec_configuration_manager.rb} (100%) rename spec/{test_context_builder.rb => spec_context_builder.rb} (100%) rename spec/{test_date_utils.rb => spec_date_utils.rb} (100%) rename spec/{test_encryption_utils.rb => spec_encryption_utils.rb} (100%) rename spec/{test_event_manager.rb => spec_event_manager.rb} (100%) rename spec/{test_ip_utils.rb => spec_ip_utils.rb} (100%) rename spec/{test_securenative.rb => spec_securenative.rb} (100%) rename spec/{test_securenative_http_client.rb => spec_securenative_http_client.rb} (100%) rename spec/{test_signature_utils.rb => spec_signature_utils.rb} (100%) diff --git a/spec/test_api_manager.rb b/spec/spec_api_manager.rb similarity index 100% rename from spec/test_api_manager.rb rename to spec/spec_api_manager.rb diff --git a/spec/test_configuration_manager.rb b/spec/spec_configuration_manager.rb similarity index 100% rename from spec/test_configuration_manager.rb rename to spec/spec_configuration_manager.rb diff --git a/spec/test_context_builder.rb b/spec/spec_context_builder.rb similarity index 100% rename from spec/test_context_builder.rb rename to spec/spec_context_builder.rb diff --git a/spec/test_date_utils.rb b/spec/spec_date_utils.rb similarity index 100% rename from spec/test_date_utils.rb rename to spec/spec_date_utils.rb diff --git a/spec/test_encryption_utils.rb b/spec/spec_encryption_utils.rb similarity index 100% rename from spec/test_encryption_utils.rb rename to spec/spec_encryption_utils.rb diff --git a/spec/test_event_manager.rb b/spec/spec_event_manager.rb similarity index 100% rename from spec/test_event_manager.rb rename to spec/spec_event_manager.rb diff --git a/spec/test_ip_utils.rb b/spec/spec_ip_utils.rb similarity index 100% rename from spec/test_ip_utils.rb rename to spec/spec_ip_utils.rb diff --git a/spec/test_securenative.rb b/spec/spec_securenative.rb similarity index 100% rename from spec/test_securenative.rb rename to spec/spec_securenative.rb diff --git a/spec/test_securenative_http_client.rb b/spec/spec_securenative_http_client.rb similarity index 100% rename from spec/test_securenative_http_client.rb rename to spec/spec_securenative_http_client.rb diff --git a/spec/test_signature_utils.rb b/spec/spec_signature_utils.rb similarity index 100% rename from spec/test_signature_utils.rb rename to spec/spec_signature_utils.rb From fc7ef4ebdb8dd8a02b1909801f24c48971a8e0b1 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 16:10:35 +0300 Subject: [PATCH 26/32] Add spec framework --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6ee04b9..27f96b8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: gem install bundler bundler install - name: Run tests - run: bundler exec rake + run: bundler exec rspec -t :repository-token - name: Notify slack success if: success() From d1178467954abde57aa5462d81e921d43d001ff8 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 16:11:38 +0300 Subject: [PATCH 27/32] Add spec framework --- .github/workflows/ci.yml | 2 +- .github/workflows/test.yml | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index abfcafc..b7cc183 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: gem install bundler bundler install - name: Run tests - run: bundler exec rake + run: bundler exec rspec - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 27f96b8..30d596d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,11 @@ jobs: gem install bundler bundler install - name: Run tests - run: bundler exec rspec -t :repository-token + run: bundler exec rspec + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} - name: Notify slack success if: success() From d084b7ce515d84245d870989cad9d4df050ad97d Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 16:12:25 +0300 Subject: [PATCH 28/32] Add spec framework --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 30d596d..0952bbb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,9 +22,9 @@ jobs: - name: Run tests run: bundler exec rspec - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} - name: Notify slack success if: success() From 703055bab0f86e325c2bea09b3b7d1135426c22e Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Sun, 21 Jun 2020 18:39:09 +0300 Subject: [PATCH 29/32] Use http mock server for testing --- .github/workflows/ci.yml | 4 --- .github/workflows/test.yml | 4 --- Gemfile | 1 + Gemfile.lock | 14 ++++++++- lib/event_manager.rb | 4 +-- securenative.iml | 7 +++++ spec/spec_api_manager.rb | 41 ++++++++++++++++++--------- spec/spec_configuration_manager.rb | 14 ++++----- spec/spec_context_builder.rb | 33 ++++++++++++++++----- spec/spec_encryption_utils.rb | 2 +- spec/spec_event_manager.rb | 12 ++++---- spec/spec_helper.rb | 9 +++--- spec/spec_securenative_http_client.rb | 4 +-- 13 files changed, 98 insertions(+), 51 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7cc183..009ea3d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,10 +33,6 @@ jobs: bundler install - name: Run tests run: bundler exec rspec - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: Notify slack success if: success() diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0952bbb..31475ca 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,10 +21,6 @@ jobs: bundler install - name: Run tests run: bundler exec rspec - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - name: Notify slack success if: success() diff --git a/Gemfile b/Gemfile index 3619989..7b08844 100644 --- a/Gemfile +++ b/Gemfile @@ -5,4 +5,5 @@ gem "rspec" gem "rake" gem "httpclient" gem "parseconfig" +gem "webmock" gem "codecov", :require => false, :group => :test \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 6204c67..1d3e55a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,15 +6,21 @@ PATH GEM remote: https://rubygems.org/ specs: + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) codecov (0.1.17) json simplecov url + crack (0.4.3) + safe_yaml (~> 1.0.0) diff-lcs (1.3) docile (1.3.2) + hashdiff (1.0.1) httpclient (2.8.3) json (2.3.0) parseconfig (1.0.8) + public_suffix (4.0.5) rake (12.3.3) rspec (3.8.0) rspec-core (~> 3.8.0) @@ -29,11 +35,16 @@ GEM diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-support (3.8.2) + safe_yaml (1.0.5) simplecov (0.18.5) docile (~> 1.1) simplecov-html (~> 0.11) simplecov-html (0.12.2) url (0.3.2) + webmock (3.8.3) + addressable (>= 2.3.6) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) PLATFORMS ruby @@ -46,6 +57,7 @@ DEPENDENCIES rake rspec securenative! + webmock BUNDLED WITH - 2.1.0.pre.1 + 2.1.4 diff --git a/lib/event_manager.rb b/lib/event_manager.rb index 4f8d865..cc6525b 100644 --- a/lib/event_manager.rb +++ b/lib/event_manager.rb @@ -91,12 +91,12 @@ def run back_off = @coefficients[@attempt] * @options.interval Logger.debug('Automatic back-off of {}'.format(back_off)) @send_enabled = false - time.sleep(back_off) # TODO: add time sleep + sleep back_off @send_enabled = true end end end - time.sleep(@interval / 1000) # TODO: add time sleep + sleep @interval / 1000 end end diff --git a/securenative.iml b/securenative.iml index 1460564..4d969e7 100644 --- a/securenative.iml +++ b/securenative.iml @@ -8,20 +8,27 @@ + + + + + + + \ No newline at end of file diff --git a/spec/spec_api_manager.rb b/spec/spec_api_manager.rb index d47a2d1..4cb8a49 100644 --- a/spec/spec_api_manager.rb +++ b/spec/spec_api_manager.rb @@ -1,11 +1,24 @@ # frozen_string_literal: true +require 'webmock/rspec' + describe ApiManager do - let(:context) { ContextBuilder().with_ip('127.0.0.1').with_client_token('SECURED_CLIENT_TOKEN').with_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'}).build } - let(:event_options) { EventOptionsBuilder(EventTypes.LOG_IN).with_user_id('USER_ID').with_user_traits(UserTraits('USER_NAME', 'USER_EMAIL')).with_context(:context).with_properties({prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build } + let(:context) do + ContextBuilder().with_ip('127.0.0.1').with_client_token('SECURED_CLIENT_TOKEN') + .with_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' }) + .build + end + let(:event_options) do + EventOptionsBuilder(EventTypes.LOG_IN) + .with_user_id('USER_ID') + .with_user_traits(UserTraits('USER_NAME', 'USER_EMAIL')).with_context(:context) + .with_properties({ prop1: 'CUSTOM_PARAM_VALUE', prop2: true, prop3: 3 }).build + end it 'tracks an event' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_auto_send(true).with_interval(10).with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_auto_send(true).with_interval(10) + .with_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","createdAt":null},"request":{' \ @@ -14,8 +27,8 @@ 'AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405"},"url":null,"method":null},' \ '"properties":{"prop2":true,"prop1":"CUSTOM_PARAM_VALUE","prop3":3}}' - # TODO - responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/track', json = json.loads(expected), status = 200) + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track') + .with(body: JSON.parse(expected)).to_return(status: 200) event_manager = EventManager.new(options) event_manager.start_event_persist api_manager = ApiManager.new(event_manager, options) @@ -28,31 +41,33 @@ end it 'uses invalid options' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_auto_send(true).with_interval(10).with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_auto_send(true).with_interval(10) + .with_api_url('https://api.securenative-stg.com/collector/api/v1') properties = {} (0..12).each do |i| properties[i] = i end - # TODO - responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/track', json = {}, 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) begin - expect { api_manager.track(EventOptionsBuilder(EventTypes.LOG_IN).with_properties(properties).build) }.to raise_error(SecureNativeInvalidOptionsException) + expect { api_manager.track(EventOptionsBuilder(EventTypes.LOG_IN).with_properties(properties).build) } + .to raise_error(SecureNativeInvalidOptionsException) ensure event_manager.stop_event_persist end end it 'verifies an event' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY') + .with_api_url('https://api.securenative-stg.com/collector/api/v1') - # TODO - responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/verify', json = {:riskLevel => 'medium', :score => 0.32, :triggers => ['New IP', 'New City']}, 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) verify_result = VerifyResult.new(RiskLevel.LOW, 0, nil) event_manager = EventManager.new(options) @@ -61,7 +76,7 @@ result = api_manager.verify(:event_options) - expect(result).not_to be_empty + expect(result).not_to be_nil expect(result.risk_level).to eq(verify_result.risk_level) expect(result.score).to eq(verify_result.score) expect(result.triggers).to eq(verify_result.triggers) diff --git a/spec/spec_configuration_manager.rb b/spec/spec_configuration_manager.rb index 915c886..da2a201 100644 --- a/spec/spec_configuration_manager.rb +++ b/spec/spec_configuration_manager.rb @@ -2,30 +2,30 @@ describe ConfigurationManager do it 'parses a config file correctly' do - # code here + # TODO: code here end it 'ignores unknown config in properties file' do - # code here + # TODO: code here end it 'handles invalid config file' do - # code here + # TODO: code here end it 'ignores invalid config file entries' do - # code here + # TODO: code here end it 'loads default config' do - # code here + # TODO: code here end it 'gets config from env variables' do - # code here + # TODO: code here end it 'uses default values for invalid enum config props' do - # code here + # TODO: code here end end \ No newline at end of file diff --git a/spec/spec_context_builder.rb b/spec/spec_context_builder.rb index faffc16..2dde6f7 100644 --- a/spec/spec_context_builder.rb +++ b/spec/spec_context_builder.rb @@ -1,22 +1,41 @@ describe ContextBuilder do it 'creates context from request' do # TODO: code here + + context = ContextBuilder.from_http_request(request).build + + expect(context.client_token).to eq('71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') + expect(context.ip).to eq('51.68.201.122') + expect(context.method).to eq('Post') + expect(context.uri).to eq('www.securenative.com') + expect(context.remote_ip).to eq('') + expect(context.headers).to eq({ 'x-securenative': '71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a' }) + expect(context.body).to be_nil end it 'creates context from request with cookie' do # TODO: code here + + context = ContextBuilder.from_http_request(request).build + + expect(context.client_token).to eq('71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') + expect(context.ip).to eq('51.68.201.122') + expect(context.method).to eq('Post') + expect(context.uri).to eq('www.securenative.com') + expect(context.remote_ip).to eq('') + expect(context.body).to be_nil end it 'creates default context builder' do context = ContextBuilder.default_context_builder.build - expect(context.client_token).not_to be_empty - expect(context.ip).not_to be_empty - expect(context.method).not_to be_empty - expect(context.url).not_to be_empty - expect(context.remote_ip).not_to be_empty - expect(context.headers).not_to be_empty - expect(context.body).not_to be_empty + expect(context.client_token).not_to be_nil + expect(context.ip).not_to be_nil + expect(context.method).not_to be_nil + expect(context.url).not_to be_nil + expect(context.remote_ip).not_to be_nil + expect(context.headers).not_to be_nil + expect(context.body).not_to be_nil end it 'creates custom context with context builder' do diff --git a/spec/spec_encryption_utils.rb b/spec/spec_encryption_utils.rb index 5d08cb2..469d7c6 100644 --- a/spec/spec_encryption_utils.rb +++ b/spec/spec_encryption_utils.rb @@ -9,7 +9,7 @@ it 'decrypts' do result = EncryptionUtils.encrypt(:PAYLOAD, :SECRET_KEY) - expect(result).not_to be_empty + expect(result).not_to be_nil expect(result.length).to eq(:PAYLOAD.length) end diff --git a/spec/spec_event_manager.rb b/spec/spec_event_manager.rb index 92c262d..d4d9a37 100644 --- a/spec/spec_event_manager.rb +++ b/spec/spec_event_manager.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require 'webmock/rspec' + class SampleEvent attr_reader :event_type, :timestamp, :rid, :user_id, :user_traits, :request, :properties @@ -21,8 +23,8 @@ def initialize options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') res_body = '{"data": true}' - # TODO - responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api', json = json.loads(res_body), status = 200) + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api') + .with(body: JSON.parse(res_body)).to_return(status: 200) event_manager = EventManager.new(options) data = event_manager.send_sync(:event, 'some-path/to-api', false) @@ -32,8 +34,7 @@ def initialize it 'fails when send sync event status code is 401' do options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') - # TODO - responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api', json = {}, status = 401) + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api').to_return(status: 401) event_manager = EventManager.new(options) res = event_manager.send_sync(:event, 'some-path/to-api', false) @@ -43,8 +44,7 @@ def initialize it 'fails when send sync event status code is 500' do options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') - # TODO - responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api', json = {}, status = 500) + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api').to_return(status: 500) event_manager = EventManager.new(options) res = event_manager.send_sync(:event, 'some-path/to-api', false) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 63c2c04..baa347b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,14 +1,15 @@ -require "bundler/setup" +# frozen_string_literal: true +require 'bundler/setup' require 'simplecov' -SimpleCov.start - require 'codecov' + +SimpleCov.start SimpleCov.formatter = SimpleCov::Formatter::Codecov RSpec.configure do |config| # Enable flags like --only-failures and --next-failure - config.example_status_persistence_file_path = ".rspec_status" + config.example_status_persistence_file_path = '.rspec_status' # Disable RSpec exposing methods globally on `Module` and `main` config.disable_monkey_patching! diff --git a/spec/spec_securenative_http_client.rb b/spec/spec_securenative_http_client.rb index b491f62..0c48a39 100644 --- a/spec/spec_securenative_http_client.rb +++ b/spec/spec_securenative_http_client.rb @@ -4,8 +4,8 @@ it 'makes a simple post call' do options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') - # TODO - responses.add(responses.POST, 'https://api.securenative-stg.com/collector/api/v1/track', json={'event' => 'SOME_EVENT_NAME'}, status=200) + stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/track') + .with(body: { event: 'SOME_EVENT_NAME' }).to_return(status: 200) client = SecureNativeHttpClient(options) payload = '{"event": "SOME_EVENT_NAME"}' From 02d0150a00fdf4fbda1e5870677a2cc2a2e2396e Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Mon, 22 Jun 2020 11:47:20 +0300 Subject: [PATCH 30/32] Minor bug fix and code cleanup --- lib/securenative.rb | 7 +++++-- lib/utils/signature_utils.rb | 2 ++ spec/spec_configuration_manager.rb | 31 ------------------------------ spec/spec_context_builder.rb | 18 +++++++++++++++-- 4 files changed, 23 insertions(+), 35 deletions(-) delete mode 100644 spec/spec_configuration_manager.rb diff --git a/lib/securenative.rb b/lib/securenative.rb index fa09280..99cffb8 100644 --- a/lib/securenative.rb +++ b/lib/securenative.rb @@ -1,4 +1,5 @@ require_relative 'logger' +require_relative 'utils/signature_utils' class SecureNative attr_reader :options @@ -71,8 +72,10 @@ def self._flush @securenative = nil end - # TODO! def verify_request_payload(request) - # code here + request_signature = request.header[SignatureUtils.SIGNATURE_HEADER] + body = request.body + + SignatureUtils.valid_signature?(@options.api_key, body, request_signature) end end \ No newline at end of file diff --git a/lib/utils/signature_utils.rb b/lib/utils/signature_utils.rb index a465ced..9482563 100644 --- a/lib/utils/signature_utils.rb +++ b/lib/utils/signature_utils.rb @@ -1,6 +1,8 @@ require 'openssl' class SignatureUtils + SIGNATURE_HEADER = 'x-securenative'.freeze + def self.valid_signature?(api_key, payload, header_signature) key = api_key.encode('utf-8') body = payload.encode('utf-8') diff --git a/spec/spec_configuration_manager.rb b/spec/spec_configuration_manager.rb deleted file mode 100644 index da2a201..0000000 --- a/spec/spec_configuration_manager.rb +++ /dev/null @@ -1,31 +0,0 @@ -# frozen_string_literal: true - -describe ConfigurationManager do - it 'parses a config file correctly' do - # TODO: code here - end - - it 'ignores unknown config in properties file' do - # TODO: code here - end - - it 'handles invalid config file' do - # TODO: code here - end - - it 'ignores invalid config file entries' do - # TODO: code here - end - - it 'loads default config' do - # TODO: code here - end - - it 'gets config from env variables' do - # TODO: code here - end - - it 'uses default values for invalid enum config props' do - # TODO: code here - end -end \ No newline at end of file diff --git a/spec/spec_context_builder.rb b/spec/spec_context_builder.rb index 2dde6f7..06ddbbf 100644 --- a/spec/spec_context_builder.rb +++ b/spec/spec_context_builder.rb @@ -1,7 +1,16 @@ +# frozen_string_literal: true + +require 'webmock/rspec' + describe ContextBuilder do it 'creates context from request' do - # TODO: code here + stub_request(:any, 'www.example.com') + .to_return(body: nil, status: 200, + headers: { 'x-securenative': '71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a' }, + remote_ip: '', uri: 'www.securenative.com', method: 'Post', ip: '51.68.201.122', + client_token: '71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') + request = Net::HTTP.get('www.example.com', '/') context = ContextBuilder.from_http_request(request).build expect(context.client_token).to eq('71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') @@ -14,8 +23,13 @@ end it 'creates context from request with cookie' do - # TODO: code here + stub_request(:any, 'www.example.com') + .to_return(body: nil, status: 200, + cookies: { '_sn': '71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a' }, + remote_ip: '', uri: 'www.securenative.com', method: 'Post', ip: '51.68.201.122', + client_token: '71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') + request = Net::HTTP.get('www.example.com', '/') context = ContextBuilder.from_http_request(request).build expect(context.client_token).to eq('71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') From 3c827947bc97083c1b86c22a69174b7263c1c8a0 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Tue, 23 Jun 2020 12:40:08 +0300 Subject: [PATCH 31/32] Restructure project --- README.md | 44 ++++------- lib/config/configuration_builder.rb | 69 ----------------- lib/models/request_context.rb | 75 ------------------- lib/{ => securenative}/api_manager.rb | 0 .../config/configuration_builder.rb | 26 +++++++ .../config/configuration_manager.rb | 19 +++-- .../config/securenative_options.rb | 0 .../context/context_builder.rb | 42 ++++------- .../context/securenative_context.rb | 0 lib/{ => securenative}/enums/api_route.rb | 0 lib/{ => securenative}/enums/event_types.rb | 0 .../enums/failover_strategy.rb | 0 lib/{ => securenative}/enums/risk_level.rb | 0 lib/{ => securenative}/event_manager.rb | 0 .../event_options_builder.rb | 30 +------- .../securenative_config_exception.rb | 0 .../exceptions/securenative_http_exception.rb | 0 .../securenative_invalid_options_exception.rb | 0 .../securenative_invalid_uri_exception.rb | 0 .../securenative_parse_exception.rb | 0 ...ecurenative_sdk_Illegal_state_exception.rb | 0 .../exceptions/securenative_sdk_exception.rb | 0 lib/{ => securenative}/http/http_response.rb | 0 .../http/securenative_http_client.rb | 0 lib/{ => securenative}/logger.rb | 0 lib/{ => securenative}/models/client_token.rb | 0 lib/{ => securenative}/models/device.rb | 0 .../models/event_options.rb | 0 lib/securenative/models/request_context.rb | 15 ++++ .../models/request_options.rb | 0 lib/{ => securenative}/models/sdk_event.rb | 15 +--- lib/{ => securenative}/models/user_traits.rb | 0 .../models/verify_result.rb | 0 lib/securenative/securenative.iml | 9 +++ lib/{ => securenative}/securenative.rb | 13 ++-- lib/{ => securenative}/utils/date_utils.rb | 0 .../utils/encryption_utils.rb | 0 lib/{ => securenative}/utils/ip_utils.rb | 0 lib/{ => securenative}/utils/request_utils.rb | 0 .../utils/signature_utils.rb | 0 lib/{ => securenative}/utils/utils.rb | 0 lib/{ => securenative}/utils/version_utils.rb | 0 securenative.iml | 34 --------- spec/spec_api_manager.rb | 30 +++----- spec/spec_context_builder.rb | 6 +- spec/spec_event_manager.rb | 6 +- spec/spec_securenative.rb | 2 +- spec/spec_securenative_http_client.rb | 2 +- 48 files changed, 122 insertions(+), 315 deletions(-) delete mode 100644 lib/config/configuration_builder.rb delete mode 100644 lib/models/request_context.rb rename lib/{ => securenative}/api_manager.rb (100%) create mode 100644 lib/securenative/config/configuration_builder.rb rename lib/{ => securenative}/config/configuration_manager.rb (53%) rename lib/{ => securenative}/config/securenative_options.rb (100%) rename lib/{ => securenative}/context/context_builder.rb (52%) rename lib/{ => securenative}/context/securenative_context.rb (100%) rename lib/{ => securenative}/enums/api_route.rb (100%) rename lib/{ => securenative}/enums/event_types.rb (100%) rename lib/{ => securenative}/enums/failover_strategy.rb (100%) rename lib/{ => securenative}/enums/risk_level.rb (100%) rename lib/{ => securenative}/event_manager.rb (100%) rename lib/{ => securenative}/event_options_builder.rb (60%) rename lib/{ => securenative}/exceptions/securenative_config_exception.rb (100%) rename lib/{ => securenative}/exceptions/securenative_http_exception.rb (100%) rename lib/{ => securenative}/exceptions/securenative_invalid_options_exception.rb (100%) rename lib/{ => securenative}/exceptions/securenative_invalid_uri_exception.rb (100%) rename lib/{ => securenative}/exceptions/securenative_parse_exception.rb (100%) rename lib/{ => securenative}/exceptions/securenative_sdk_Illegal_state_exception.rb (100%) rename lib/{ => securenative}/exceptions/securenative_sdk_exception.rb (100%) rename lib/{ => securenative}/http/http_response.rb (100%) rename lib/{ => securenative}/http/securenative_http_client.rb (100%) rename lib/{ => securenative}/logger.rb (100%) rename lib/{ => securenative}/models/client_token.rb (100%) rename lib/{ => securenative}/models/device.rb (100%) rename lib/{ => securenative}/models/event_options.rb (100%) create mode 100644 lib/securenative/models/request_context.rb rename lib/{ => securenative}/models/request_options.rb (100%) rename lib/{ => securenative}/models/sdk_event.rb (59%) rename lib/{ => securenative}/models/user_traits.rb (100%) rename lib/{ => securenative}/models/verify_result.rb (100%) create mode 100644 lib/securenative/securenative.iml rename lib/{ => securenative}/securenative.rb (72%) rename lib/{ => securenative}/utils/date_utils.rb (100%) rename lib/{ => securenative}/utils/encryption_utils.rb (100%) rename lib/{ => securenative}/utils/ip_utils.rb (100%) rename lib/{ => securenative}/utils/request_utils.rb (100%) rename lib/{ => securenative}/utils/signature_utils.rb (100%) rename lib/{ => securenative}/utils/utils.rb (100%) rename lib/{ => securenative}/utils/version_utils.rb (100%) delete mode 100644 securenative.iml diff --git a/README.md b/README.md index 1e9ccfb..f12c8a4 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ + Gem Version

Documentation | @@ -60,7 +61,7 @@ secureative = SecureNative.init require 'securenative' -securenative = SecureNative.init_with_api_key("YOUR_API_KEY") +securenative = SecureNative.init_with_api_key('YOUR_API_KEY') ``` ### Option 3: Initialize via ConfigurationBuilder @@ -68,11 +69,7 @@ securenative = SecureNative.init_with_api_key("YOUR_API_KEY") require 'securenative' -securenative = SecureNative.init_with_options(SecureNative.config_builder - .with_api_key("API_KEY") - .with_max_events(10) - .with_log_level("ERROR") - .build) +securenative = SecureNative.init_with_options(SecureNative.config_builder(api_key = 'API_KEY', max_event = 10, log_level = 'ERROR')) ``` ## Getting SecureNative instance @@ -94,22 +91,17 @@ require 'securenative' require 'securenative/enums/event_types' require 'securenative/event_options_builder' require 'securenative/models/user_traits' +require 'securenative/context/context_builder' securenative = SecureNative.instance -context = SecureNative.context_builder - .with_ip("127.0.0.1") - .with_client_token("SECURED_CLIENT_TOKEN") - .with_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"}) - .build +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 = EventOptionsBuilder(EventTypes::LOG_IN) - .with_user_id("USER_ID") - .with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")) - .with_context(context) - .with_properties({"prop1" => "CUSTOM_PARAM_VALUE", "prop2" => true, "prop3" => 3}) - .build +event_options = EventOptionsBuilder(event_type = EventTypes::LOG_IN, + user_id = 'USER_ID', user_traits = UserTraits('USER_NAME', 'USER_EMAIL'), + context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build securenative.track(event_options) ``` @@ -127,12 +119,9 @@ def track(request) securenative = SecureNative.instance context = SecureNative.context_builder.from_http_request(request).build - event_options = EventOptionsBuilder(EventTypes::LOG_IN) - .with_user_id("USER_ID") - .with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")) - .with_context(context) - .with_properties({"prop1" => "CUSTOM_PARAM_VALUE", "prop2" => true, "prop3" => 3}) - .build + event_options = EventOptionsBuilder(event_type = EventTypes::LOG_IN, + user_id = 'USER_ID', user_traits = UserTraits('USER_NAME', 'USER_EMAIL'), + context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build securenative.track(event_options) end @@ -153,12 +142,9 @@ def track(request) securenative = SecureNative.instance context = SecureNative.context_builder.from_http_request(request).build - event_options = EventOptionsBuilder(EventTypes::LOG_IN) - .with_user_id("USER_ID") - .with_user_traits(UserTraits("USER_NAME", "USER_EMAIL")) - .with_context(context) - .with_properties({"prop1" => "CUSTOM_PARAM_VALUE", "prop2" => true, "prop3" => 3}) - .build + event_options = EventOptionsBuilder(event_type = EventTypes::LOG_IN, + user_id = 'USER_ID', user_traits = UserTraits('USER_NAME', 'USER_EMAIL'), + context = context, properties = {prop1 => 'CUSTOM_PARAM_VALUE', prop2 => true, prop3 => 3}).build verify_result = securenative.verify(event_options) verify_result.risk_level # Low, Medium, High diff --git a/lib/config/configuration_builder.rb b/lib/config/configuration_builder.rb deleted file mode 100644 index a7b7ecd..0000000 --- a/lib/config/configuration_builder.rb +++ /dev/null @@ -1,69 +0,0 @@ -class ConfigurationBuilder - def initialize - @api_key = nil - @api_url = 'https://api.securenative.com/collector/api/v1' - @interval = 1000 - @max_events = 1000 - @timeout = 1500 - @auto_send = true - @disable = false - @log_level = 'FATAL' - @fail_over_strategy = FailOverStrategy::FAIL_OPEN - end - - def self.default_config_builder - ConfigurationBuilder() - end - - def with_api_key(api_key) - @api_key = api_key - self - end - - def with_api_url(api_url) - @api_url = api_url - self - end - - def with_interval(interval) - @interval = interval - self - end - - def with_max_events(max_events) - @max_events = max_events - self - end - - def with_timeout(timeout) - @timeout = timeout - self - end - - def with_auto_send(auto_send) - @auto_send = auto_send - self - end - - def with_disable(disable) - @disable = disable - self - end - - def with_log_level(log_level) - @log_level = log_level - self - end - - def with_fail_over_strategy(fail_over_strategy) - if fail_over_strategy != FailOverStrategy::FAIL_OPEN && fail_over_strategy != FailOverStrategy::FAIL_CLOSED - @fail_over_strategy = FailOverStrategy::FAIL_OPEN - else - @fail_over_strategy = fail_over_strategy - end - end - - def self.default_securenative_options - SecureNativeOptions() - end -end \ No newline at end of file diff --git a/lib/models/request_context.rb b/lib/models/request_context.rb deleted file mode 100644 index 6eacd21..0000000 --- a/lib/models/request_context.rb +++ /dev/null @@ -1,75 +0,0 @@ -class RequestContext - attr_reader :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method - attr_writer :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method - - def initialize(cid = nil, vid = nil, fp = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil) - @cid = cid - @vid = vid - @fp = fp - @ip = ip - @remote_ip = remote_ip - @headers = headers - @url = url - @method = method - end -end - -class RequestContextBuilder - attr_reader :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method - attr_writer :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method - - def initialize(cid = nil, vid = nil, fp = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil) - @cid = cid - @vid = vid - @fp = fp - @ip = ip - @remote_ip = remote_ip - @headers = headers - @url = url - @method = method - end - - def with_cid(cid) - @cid = cid - self - end - - def with_vid(vid) - @vid = vid - self - end - - def with_fp(fp) - @fp = fp - self - end - - def with_ip(ip) - @ip = ip - self - end - - def with_remote_ip(remote_ip) - @remote_ip = remote_ip - self - end - - def with_headers(headers) - @headers = headers - self - end - - def with_url(url) - @url = url - self - end - - def with_method(method) - @method = method - self - end - - def build - RequestContext(@cid, @vid, @fp, @ip, @remote_ip, @headers, @url, @method) - end -end diff --git a/lib/api_manager.rb b/lib/securenative/api_manager.rb similarity index 100% rename from lib/api_manager.rb rename to lib/securenative/api_manager.rb diff --git a/lib/securenative/config/configuration_builder.rb b/lib/securenative/config/configuration_builder.rb new file mode 100644 index 0000000..8cd563b --- /dev/null +++ b/lib/securenative/config/configuration_builder.rb @@ -0,0 +1,26 @@ +class ConfigurationBuilder + attr_reader :api_key, :api_url, :interval, :max_events, :timeout, :auto_send, :disable, :log_level, :fail_over_strategy + attr_writer :api_key, :api_url, :interval, :max_events, :timeout, :auto_send, :disable, :log_level, :fail_over_strategy + + def initialize(api_key = nil, api_url = 'https://api.securenative.com/collector/api/v1', interval = 1000, + max_events = 1000, timeout = 1500, auto_send = true, disable = false, log_level = 'FATAL', + fail_over_strategy = FailOverStrategy::FAIL_OPEN) + @api_key = api_key + @api_url = api_url + @interval = interval + @max_events = max_events + @timeout = timeout + @auto_send = auto_send + @disable = disable + @log_level = log_level + @fail_over_strategy = fail_over_strategy + end + + def self.default_config_builder + ConfigurationBuilder() + end + + def self.default_securenative_options + SecureNativeOptions() + end +end \ No newline at end of file diff --git a/lib/config/configuration_manager.rb b/lib/securenative/config/configuration_manager.rb similarity index 53% rename from lib/config/configuration_manager.rb rename to lib/securenative/config/configuration_manager.rb index c52c8b8..cd28445 100644 --- a/lib/config/configuration_manager.rb +++ b/lib/securenative/config/configuration_manager.rb @@ -40,15 +40,14 @@ def self.load_config properties = read_resource_file(resource_path) - ConfigurationBuilder() - .with_api_key(_get_env_or_default(properties, 'SECURENATIVE_API_KEY', options.api_key)) - .with_api_url(_get_env_or_default(properties, 'SECURENATIVE_API_URL', options.api_url)) - .with_interval(_get_env_or_default(properties, 'SECURENATIVE_INTERVAL', options.interval)) - .with_max_events(_get_env_or_default(properties, 'SECURENATIVE_MAX_EVENTS', options.max_events)) - .with_timeout(_get_env_or_default(properties, 'SECURENATIVE_TIMEOUT', options.timeout)) - .with_auto_send(_get_env_or_default(properties, 'SECURENATIVE_AUTO_SEND', options.auto_send)) - .with_disable(_get_env_or_default(properties, 'SECURENATIVE_DISABLE', options.disable)) - .with_log_level(_get_env_or_default(properties, 'SECURENATIVE_LOG_LEVEL', options.log_level)) - .with_fail_over_strategy(_get_env_or_default(properties, 'SECURENATIVE_FAILOVER_STRATEGY', options.fail_over_strategy)) + 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)) end end \ No newline at end of file diff --git a/lib/config/securenative_options.rb b/lib/securenative/config/securenative_options.rb similarity index 100% rename from lib/config/securenative_options.rb rename to lib/securenative/config/securenative_options.rb diff --git a/lib/context/context_builder.rb b/lib/securenative/context/context_builder.rb similarity index 52% rename from lib/context/context_builder.rb rename to lib/securenative/context/context_builder.rb index 5f1f68a..297d42f 100644 --- a/lib/context/context_builder.rb +++ b/lib/securenative/context/context_builder.rb @@ -1,41 +1,36 @@ class ContextBuilder - def initialize - @context = SecureNativeContext() + attr_reader :context + + def initialize(client_token = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil, body = nil) + @context = SecureNativeContext(client_token, ip, remote_ip, headers, url, method, body) end - def with_client_token(client_token) + def client_token(client_token) @context.client_token = client_token - self end - def with_ip(ip) + def ip(ip) @context.ip = ip - self end - def with_remote_ip(remote_ip) + def remote_ip(remote_ip) @context.remote_ip = remote_ip - self end - def with_headers(headers) + def headers(headers) @context.headers = headers - self end - def with_url(url) + def url(url) @context.url = url - self end - def with_method(method) + def method(method) @context.method = method - self end - def with_body(body) + def body(body) @context.body = body - self end def self.default_context_builder @@ -57,17 +52,8 @@ def self.from_http_request(request) client_token = RequestUtils.get_secure_header_from_request(headers) if Utils.null_or_empty?(client_token) - ContextBuilder() - .with_url(request.url) - .with_method(request.method) - .with_headers(headers) - .with_client_token(client_token) - .with_ip(RequestUtils.get_client_ip_from_request(request)) - .with_remote_ip(RequestUtils.get_remote_ip_from_request(request)) - .with_body(nil) - end - - def build - @context + ContextBuilder(url = request.url, method = request.method, header = headers, client_token = client_token, + client_ip = RequestUtils.get_client_ip_from_request(request), + remote_ip = RequestUtils.get_remote_ip_from_request(request), nil) end end \ No newline at end of file diff --git a/lib/context/securenative_context.rb b/lib/securenative/context/securenative_context.rb similarity index 100% rename from lib/context/securenative_context.rb rename to lib/securenative/context/securenative_context.rb diff --git a/lib/enums/api_route.rb b/lib/securenative/enums/api_route.rb similarity index 100% rename from lib/enums/api_route.rb rename to lib/securenative/enums/api_route.rb diff --git a/lib/enums/event_types.rb b/lib/securenative/enums/event_types.rb similarity index 100% rename from lib/enums/event_types.rb rename to lib/securenative/enums/event_types.rb diff --git a/lib/enums/failover_strategy.rb b/lib/securenative/enums/failover_strategy.rb similarity index 100% rename from lib/enums/failover_strategy.rb rename to lib/securenative/enums/failover_strategy.rb diff --git a/lib/enums/risk_level.rb b/lib/securenative/enums/risk_level.rb similarity index 100% rename from lib/enums/risk_level.rb rename to lib/securenative/enums/risk_level.rb diff --git a/lib/event_manager.rb b/lib/securenative/event_manager.rb similarity index 100% rename from lib/event_manager.rb rename to lib/securenative/event_manager.rb diff --git a/lib/event_options_builder.rb b/lib/securenative/event_options_builder.rb similarity index 60% rename from lib/event_options_builder.rb rename to lib/securenative/event_options_builder.rb index e8ba3d8..f931a21 100644 --- a/lib/event_options_builder.rb +++ b/lib/securenative/event_options_builder.rb @@ -1,38 +1,14 @@ class EventOptionsBuilder MAX_PROPERTIES_SIZE = 10 - def initialize(event_type) + def initialize(event_type, user_id, user_traits, user_name, email, created_at, context, properties, timestamp) @event_options = EventOptions(event_type) - end - - def with_user_id(user_id) @event_options.user_id = user_id - self - end - - def with_user_traits(user_traits) - @event_options.user_traits = user_traits - self - end - - def with_user(name, email, created_at = nil) - @event_options.user_traits = UserTraits(name, email, created_at) - self - end - - def with_context(context) + @event_options.user_traits = user_traits if user_traits + @event_options.user_traits = UserTraits(name, email, created_at) if user_name && email && created_at @event_options.context = context - self - end - - def with_properties(properties) @event_options.properties = properties - self - end - - def with_timestamp(timestamp) @event_options.timestamp = timestamp - self end def build diff --git a/lib/exceptions/securenative_config_exception.rb b/lib/securenative/exceptions/securenative_config_exception.rb similarity index 100% rename from lib/exceptions/securenative_config_exception.rb rename to lib/securenative/exceptions/securenative_config_exception.rb diff --git a/lib/exceptions/securenative_http_exception.rb b/lib/securenative/exceptions/securenative_http_exception.rb similarity index 100% rename from lib/exceptions/securenative_http_exception.rb rename to lib/securenative/exceptions/securenative_http_exception.rb diff --git a/lib/exceptions/securenative_invalid_options_exception.rb b/lib/securenative/exceptions/securenative_invalid_options_exception.rb similarity index 100% rename from lib/exceptions/securenative_invalid_options_exception.rb rename to lib/securenative/exceptions/securenative_invalid_options_exception.rb diff --git a/lib/exceptions/securenative_invalid_uri_exception.rb b/lib/securenative/exceptions/securenative_invalid_uri_exception.rb similarity index 100% rename from lib/exceptions/securenative_invalid_uri_exception.rb rename to lib/securenative/exceptions/securenative_invalid_uri_exception.rb diff --git a/lib/exceptions/securenative_parse_exception.rb b/lib/securenative/exceptions/securenative_parse_exception.rb similarity index 100% rename from lib/exceptions/securenative_parse_exception.rb rename to lib/securenative/exceptions/securenative_parse_exception.rb diff --git a/lib/exceptions/securenative_sdk_Illegal_state_exception.rb b/lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb similarity index 100% rename from lib/exceptions/securenative_sdk_Illegal_state_exception.rb rename to lib/securenative/exceptions/securenative_sdk_Illegal_state_exception.rb diff --git a/lib/exceptions/securenative_sdk_exception.rb b/lib/securenative/exceptions/securenative_sdk_exception.rb similarity index 100% rename from lib/exceptions/securenative_sdk_exception.rb rename to lib/securenative/exceptions/securenative_sdk_exception.rb diff --git a/lib/http/http_response.rb b/lib/securenative/http/http_response.rb similarity index 100% rename from lib/http/http_response.rb rename to lib/securenative/http/http_response.rb diff --git a/lib/http/securenative_http_client.rb b/lib/securenative/http/securenative_http_client.rb similarity index 100% rename from lib/http/securenative_http_client.rb rename to lib/securenative/http/securenative_http_client.rb diff --git a/lib/logger.rb b/lib/securenative/logger.rb similarity index 100% rename from lib/logger.rb rename to lib/securenative/logger.rb diff --git a/lib/models/client_token.rb b/lib/securenative/models/client_token.rb similarity index 100% rename from lib/models/client_token.rb rename to lib/securenative/models/client_token.rb diff --git a/lib/models/device.rb b/lib/securenative/models/device.rb similarity index 100% rename from lib/models/device.rb rename to lib/securenative/models/device.rb diff --git a/lib/models/event_options.rb b/lib/securenative/models/event_options.rb similarity index 100% rename from lib/models/event_options.rb rename to lib/securenative/models/event_options.rb diff --git a/lib/securenative/models/request_context.rb b/lib/securenative/models/request_context.rb new file mode 100644 index 0000000..8995750 --- /dev/null +++ b/lib/securenative/models/request_context.rb @@ -0,0 +1,15 @@ +class RequestContext + attr_reader :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method + attr_writer :cid, :vid, :fp, :ip, :remote_ip, :headers, :url, :method + + def initialize(cid = nil, vid = nil, fp = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil) + @cid = cid + @vid = vid + @fp = fp + @ip = ip + @remote_ip = remote_ip + @headers = headers + @url = url + @method = method + end +end diff --git a/lib/models/request_options.rb b/lib/securenative/models/request_options.rb similarity index 100% rename from lib/models/request_options.rb rename to lib/securenative/models/request_options.rb diff --git a/lib/models/sdk_event.rb b/lib/securenative/models/sdk_event.rb similarity index 59% rename from lib/models/sdk_event.rb rename to lib/securenative/models/sdk_event.rb index 3265014..4195fae 100644 --- a/lib/models/sdk_event.rb +++ b/lib/securenative/models/sdk_event.rb @@ -6,7 +6,7 @@ def initialize(event_options, securenative_options) @context = if !event_options.context.nil? event_options.context else - ContextBuilder.default_context_builder.build + ContextBuilder.default_context_builder end client_token = EncryptionUtils.decrypt(@context.client_token, securenative_options.api_key) @@ -15,16 +15,9 @@ def initialize(event_options, securenative_options) @event_type = event_options.event @user_id = event_options.user_id @user_traits = event_options.user_traits - @request = RequestContextBuilder() - .with_cid(client_token ? client_token.cid : '') - .with_vid(client_token ? client_token.vid : '') - .with_fp(client_token ? client_token.fp : '') - .with_ip(@context.ip) - .with_remote_ip(@context.remote_ip) - .with_method(@context.method) - .with_url(@context.url) - .with_headers(@context.headers) - .build + @request = RequestContext(cid = client_token ? client_token.cid : '', vid = client_token ? client_token.vid : '', + fp = client_token ? client_token.fp : '', ip = @context.ip, remote_ip = @context.remote_ip, + method = @context.method, url = @context.url, headers = @context.headers) @timestamp = DateUtils.to_timestamp(event_options.timestamp) @properties = event_options.properties diff --git a/lib/models/user_traits.rb b/lib/securenative/models/user_traits.rb similarity index 100% rename from lib/models/user_traits.rb rename to lib/securenative/models/user_traits.rb diff --git a/lib/models/verify_result.rb b/lib/securenative/models/verify_result.rb similarity index 100% rename from lib/models/verify_result.rb rename to lib/securenative/models/verify_result.rb diff --git a/lib/securenative/securenative.iml b/lib/securenative/securenative.iml new file mode 100644 index 0000000..c87f26a --- /dev/null +++ b/lib/securenative/securenative.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/lib/securenative.rb b/lib/securenative/securenative.rb similarity index 72% rename from lib/securenative.rb rename to lib/securenative/securenative.rb index 99cffb8..dd83e58 100644 --- a/lib/securenative.rb +++ b/lib/securenative/securenative.rb @@ -31,8 +31,7 @@ def self.init_with_api_key(api_key) raise SecureNativeConfigException('You must pass your SecureNative api key') if Utils.null_or_empty?(api_key) if @securenative.nil? - builder = ConfigurationBuilder().default_config_builder - options = builder.with_api_key(api_key) + options = ConfigurationBuilder(api_key = api_key) @securenative = SecureNative.new(options) @securenative else @@ -52,12 +51,14 @@ def self.instance @securenative end - def self.config_builder - ConfigurationBuilder.default_config_builder + def self.config_builder(api_key = nil, api_url = 'https://api.securenative.com/collector/api/v1', interval = 1000, + max_events = 1000, timeout = 1500, auto_send = true, disable = false, log_level = 'FATAL', + fail_over_strategy = FailOverStrategy::FAIL_OPEN) + ConfigurationBuilder(api_key, api_url, interval, max_events, timeout, auto_send, disable, log_level, fail_over_strategy) end - def self.context_builder - ContextBuilder.default_context_builder + def self.context_builder(client_token = nil, ip = nil, remote_ip = nil, headers = nil, url = nil, method = nil, body = nil) + ContextBuilder(client_token, ip, remote_ip, headers, url, method, body) end def track(event_options) diff --git a/lib/utils/date_utils.rb b/lib/securenative/utils/date_utils.rb similarity index 100% rename from lib/utils/date_utils.rb rename to lib/securenative/utils/date_utils.rb diff --git a/lib/utils/encryption_utils.rb b/lib/securenative/utils/encryption_utils.rb similarity index 100% rename from lib/utils/encryption_utils.rb rename to lib/securenative/utils/encryption_utils.rb diff --git a/lib/utils/ip_utils.rb b/lib/securenative/utils/ip_utils.rb similarity index 100% rename from lib/utils/ip_utils.rb rename to lib/securenative/utils/ip_utils.rb diff --git a/lib/utils/request_utils.rb b/lib/securenative/utils/request_utils.rb similarity index 100% rename from lib/utils/request_utils.rb rename to lib/securenative/utils/request_utils.rb diff --git a/lib/utils/signature_utils.rb b/lib/securenative/utils/signature_utils.rb similarity index 100% rename from lib/utils/signature_utils.rb rename to lib/securenative/utils/signature_utils.rb diff --git a/lib/utils/utils.rb b/lib/securenative/utils/utils.rb similarity index 100% rename from lib/utils/utils.rb rename to lib/securenative/utils/utils.rb diff --git a/lib/utils/version_utils.rb b/lib/securenative/utils/version_utils.rb similarity index 100% rename from lib/utils/version_utils.rb rename to lib/securenative/utils/version_utils.rb diff --git a/securenative.iml b/securenative.iml deleted file mode 100644 index 4d969e7..0000000 --- a/securenative.iml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spec/spec_api_manager.rb b/spec/spec_api_manager.rb index 4cb8a49..74fb759 100644 --- a/spec/spec_api_manager.rb +++ b/spec/spec_api_manager.rb @@ -4,21 +4,17 @@ describe ApiManager do let(:context) do - ContextBuilder().with_ip('127.0.0.1').with_client_token('SECURED_CLIENT_TOKEN') - .with_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' }) - .build + ContextBuilder(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'}) end let(:event_options) do - EventOptionsBuilder(EventTypes.LOG_IN) - .with_user_id('USER_ID') - .with_user_traits(UserTraits('USER_NAME', 'USER_EMAIL')).with_context(:context) - .with_properties({ prop1: 'CUSTOM_PARAM_VALUE', prop2: true, prop3: 3 }).build + EventOptionsBuilder(event_type = EventTypes.LOG_IN, user_id = 'USER_ID', + user_traits = UserTraits('USER_NAME', 'USER_EMAIL'), + properties = {prop1: 'CUSTOM_PARAM_VALUE', prop2: true, prop3: 3}).build end it 'tracks an event' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_auto_send(true).with_interval(10) - .with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationBuilder(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","createdAt":null},"request":{' \ @@ -28,7 +24,7 @@ '"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) + .with(body: JSON.parse(expected)).to_return(status: 200) event_manager = EventManager.new(options) event_manager.start_event_persist api_manager = ApiManager.new(event_manager, options) @@ -41,8 +37,7 @@ end it 'uses invalid options' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_auto_send(true).with_interval(10) - .with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationBuilder(api_key = 'YOUR_API_KEY', auto_send = true, interval = 10, api_url = 'https://api.securenative-stg.com/collector/api/v1') properties = {} (0..12).each do |i| @@ -55,19 +50,18 @@ api_manager = ApiManager.new(event_manager, options) begin - expect { api_manager.track(EventOptionsBuilder(EventTypes.LOG_IN).with_properties(properties).build) } - .to raise_error(SecureNativeInvalidOptionsException) + expect { api_manager.track(EventOptionsBuilder(event_type = EventTypes.LOG_IN, properties = properties).build) } + .to raise_error(SecureNativeInvalidOptionsException) ensure event_manager.stop_event_persist end end it 'verifies an event' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY') - .with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationBuilder(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) + .with(body: {riskLevel: 'medium', score: 0.32, triggers: ['New IP', 'New City']}).to_return(status: 200) verify_result = VerifyResult.new(RiskLevel.LOW, 0, nil) event_manager = EventManager.new(options) diff --git a/spec/spec_context_builder.rb b/spec/spec_context_builder.rb index 06ddbbf..9c47f00 100644 --- a/spec/spec_context_builder.rb +++ b/spec/spec_context_builder.rb @@ -11,7 +11,7 @@ client_token: '71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') request = Net::HTTP.get('www.example.com', '/') - context = ContextBuilder.from_http_request(request).build + context = ContextBuilder.from_http_request(request) expect(context.client_token).to eq('71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') expect(context.ip).to eq('51.68.201.122') @@ -30,7 +30,7 @@ client_token: '71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') request = Net::HTTP.get('www.example.com', '/') - context = ContextBuilder.from_http_request(request).build + context = ContextBuilder.from_http_request(request) expect(context.client_token).to eq('71532c1fad2c7f56118f7969e401f3cf080239140d208e7934e6a530818c37e544a0c2330a487bcc6fe4f662a57f265a3ed9f37871e80529128a5e4f2ca02db0fb975ded401398f698f19bb0cafd68a239c6caff99f6f105286ab695eaf3477365bdef524f5d70d9be1d1d474506b433aed05d7ed9a435eeca357de57817b37c638b6bb417ffb101eaf856987615a77a') expect(context.ip).to eq('51.68.201.122') @@ -53,7 +53,7 @@ end it 'creates custom context with context builder' do - context = ContextBuilder.default_context_builder.with_url('/some-url').with_client_token('SECRET_TOKEN').with_ip('10.0.0.0').with_body('{ "name": "YOUR_NAME" }').with_method('Get').with_remote_ip('10.0.0.1').with_headers({ header1: 'value1' }).build + context = ContextBuilder(url = '/some-url', client_token = 'SECRET_TOKEN', ip = '10.0.0.0', body = '{ "name": "YOUR_NAME" }', method = 'Get', remote_ip = '10.0.0.1', headers = { header1: 'value1' }) expect(context.url).to eq('/some-url') expect(context.client_token).to eq('SECRET_TOKEN') diff --git a/spec/spec_event_manager.rb b/spec/spec_event_manager.rb index d4d9a37..9111381 100644 --- a/spec/spec_event_manager.rb +++ b/spec/spec_event_manager.rb @@ -20,7 +20,7 @@ def initialize let(:event) { SampleEvent() } it 'successfully sends sync event with status code 200' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationBuilder(api_key = 'YOUR_API_KEY', api_url = 'https://api.securenative-stg.com/collector/api/v1') res_body = '{"data": true}' stub_request(:post, 'https://api.securenative-stg.com/collector/api/v1/some-path/to-api') @@ -32,7 +32,7 @@ def initialize end it 'fails when send sync event status code is 401' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationBuilder(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/some-path/to-api').to_return(status: 401) event_manager = EventManager.new(options) @@ -42,7 +42,7 @@ def initialize end it 'fails when send sync event status code is 500' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationBuilder(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/some-path/to-api').to_return(status: 500) event_manager = EventManager.new(options) diff --git a/spec/spec_securenative.rb b/spec/spec_securenative.rb index eca56b3..7b85bc0 100644 --- a/spec/spec_securenative.rb +++ b/spec/spec_securenative.rb @@ -44,7 +44,7 @@ it 'inits sdk with builder' do SecureNative._flush - securenative = SecureNative.init_with_options(SecureNative.config_builder.with_api_key('API_KEY').with_max_events(10).with_log_level('ERROR')) + securenative = SecureNative.init_with_options(SecureNative.config_builder(api_key = 'API_KEY', max_events = 10, log_level = 'ERROR')) options = securenative.options expect(options.api_key).to eq('API_KEY') diff --git a/spec/spec_securenative_http_client.rb b/spec/spec_securenative_http_client.rb index 0c48a39..cc6e2ad 100644 --- a/spec/spec_securenative_http_client.rb +++ b/spec/spec_securenative_http_client.rb @@ -2,7 +2,7 @@ describe SecureNativeHttpClient do it 'makes a simple post call' do - options = ConfigurationManager.config_builder.with_api_key('YOUR_API_KEY').with_api_url('https://api.securenative-stg.com/collector/api/v1') + options = ConfigurationBuilder(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: { event: 'SOME_EVENT_NAME' }).to_return(status: 200) From a30044222755c614f3e42c855bbe5423135c11b5 Mon Sep 17 00:00:00 2001 From: Inbal Tako Date: Tue, 23 Jun 2020 12:59:28 +0300 Subject: [PATCH 32/32] Fix utils path --- securenative.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/securenative.gemspec b/securenative.gemspec index 221c990..0e2cc88 100644 --- a/securenative.gemspec +++ b/securenative.gemspec @@ -1,6 +1,6 @@ lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require_relative "lib/utils/version_utils" +require_relative "lib/securenative/utils/version_utils" Gem::Specification.new do |spec| spec.name = "securenative"