Skip to content

Commit

Permalink
Castle.config singleton initialization fixes and allowing passing con…
Browse files Browse the repository at this point in the history
…fig to the logger(#242)
  • Loading branch information
bartes authored Apr 26, 2021
1 parent 77c137a commit b882384
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .rubocop-rspec.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require: rubocop-rspec

AllCops:
TargetRubyVersion: 2.4
TargetRubyVersion: 2.5
Exclude:
- bin/**/*
- db/schema.rb
Expand Down
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
AllCops:
TargetRubyVersion: 2.4
TargetRubyVersion: 2.5
Exclude:
- bin/**/*
- db/schema.rb
Expand Down
16 changes: 8 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ GEM
thor (>= 0.14.0)
ast (2.4.2)
byebug (11.1.3)
coveralls_reborn (0.20.0)
coveralls_reborn (0.21.0)
simplecov (>= 0.18.1, < 0.22.0)
term-ansicolor (~> 1.6)
thor (>= 0.20.3, < 2.0)
Expand All @@ -25,15 +25,15 @@ GEM
docile (1.3.5)
hashdiff (1.0.1)
parallel (1.20.1)
parser (3.0.0.0)
parser (3.0.1.0)
ast (~> 2.4.1)
prettier (1.5.2)
prettier (1.5.5)
public_suffix (4.0.6)
rack (2.2.3)
rainbow (3.0.0)
rake (13.0.3)
regexp_parser (2.1.1)
rexml (3.2.4)
rexml (3.2.5)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
Expand All @@ -47,7 +47,7 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-support (3.10.2)
rubocop (1.10.0)
rubocop (1.13.0)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
Expand All @@ -58,8 +58,8 @@ GEM
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.4.1)
parser (>= 2.7.1.5)
rubocop-performance (1.9.2)
rubocop (>= 0.90.0, < 2.0)
rubocop-performance (1.11.0)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
rubocop-rspec (2.2.0)
rubocop (~> 1.0)
Expand All @@ -79,7 +79,7 @@ GEM
tins (1.28.0)
sync
unicode-display_width (2.0.0)
webmock (3.12.0)
webmock (3.12.2)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
Expand Down
10 changes: 6 additions & 4 deletions lib/castle/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ class << self
# @param command [String]
# @param headers [Hash]
# @param http [Net::HTTP]
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
# @return [Hash]
def call(command, headers = {}, http = nil, config = Castle.config)
Castle::Core::ProcessResponse.call(send_request(command, headers, http, config))
def call(command, headers = {}, http = nil, config = nil)
Castle::Core::ProcessResponse.call(send_request(command, headers, http, config), config)
end

private
Expand All @@ -32,7 +32,9 @@ def call(command, headers = {}, http = nil, config = Castle.config)
# @param headers [Hash]
# @param http [Net::HTTP]
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
def send_request(command, headers = {}, http = nil, config = Castle.config)
def send_request(command, headers = {}, http = nil, config = nil)
config ||= Castle.config

raise Castle::ConfigurationError, 'configuration is not valid' unless config.valid?

begin
Expand Down
9 changes: 8 additions & 1 deletion lib/castle/api/authenticate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ def call(options = {})
response.merge(failover: false, failover_reason: nil)
rescue Castle::RequestError, Castle::InternalServerError => e
unless config.failover_strategy == :throw
return Castle::Failover::PrepareResponse.new(options[:user_id], reason: e.to_s).call
strategy = (config || Castle.config).failover_strategy
return(
Castle::Failover::PrepareResponse.new(
options[:user_id],
reason: e.to_s,
strategy: strategy
).call
)
end

raise e
Expand Down
4 changes: 3 additions & 1 deletion lib/castle/core/get_connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ module GetConnection

class << self
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
def call(config = Castle.config)
# @return [Net::HTTP]
def call(config = nil)
config ||= Castle.config
http = Net::HTTP.new(config.base_url.host, config.base_url.port)
http.read_timeout = config.request_timeout / 1000.0

Expand Down
7 changes: 5 additions & 2 deletions lib/castle/core/process_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ module ProcessResponse
}.freeze

class << self
def call(response)
# @param response [Response]
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
# @return [Hash]
def call(response, config = nil)
verify!(response)

Castle::Logger.call('response:', response.body.to_s)
Castle::Logger.call('response:', response.body.to_s, config)

return {} if response.body.nil? || response.body.empty?

Expand Down
6 changes: 4 additions & 2 deletions lib/castle/core/process_webhook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ module ProcessWebhook
class << self
# Checks if webhook is valid
# @param webhook [Request]
def call(webhook)
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
# @return [String]
def call(webhook, config = nil)
webhook
.body
.read
.tap do |result|
raise Castle::ApiError, 'Invalid webhook from Castle API' if result.blank?

Castle::Logger.call('webhook:', result.to_s)
Castle::Logger.call('webhook:', result.to_s, config)
end
end
end
Expand Down
10 changes: 5 additions & 5 deletions lib/castle/core/send_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,25 @@ class << self
# @param command [String]
# @param headers [Hash]
# @param http [Net::HTTP]
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
def call(command, headers, http = nil, config = Castle.config)
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
def call(command, headers, http = nil, config = nil)
(http || Castle::Core::GetConnection.call).request(
build(command, headers.merge(DEFAULT_HEADERS), config)
)
end

# @param command [String]
# @param headers [Hash]
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
def build(command, headers, config = Castle.config)
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
def build(command, headers, config)
url = "#{config.base_url.path}/#{command.path}"
request_obj = Net::HTTP.const_get(command.method.to_s.capitalize).new(url, headers)

unless command.method == :get
request_obj.body = ::Castle::Utils::CleanInvalidChars.call(command.data).to_json
end

Castle::Logger.call("#{url}:", request_obj.body)
Castle::Logger.call("#{url}:", request_obj.body, config)

request_obj.basic_auth('', config.api_secret)
request_obj
Expand Down
2 changes: 1 addition & 1 deletion lib/castle/failover/prepare_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Castle
module Failover
# generate failover authentication response
class PrepareResponse
def initialize(user_id, reason:, strategy: Castle.config.failover_strategy)
def initialize(user_id, reason:, strategy:)
@strategy = strategy
@reason = reason
@user_id = user_id
Expand Down
8 changes: 4 additions & 4 deletions lib/castle/headers/extract.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ class Extract
private_constant :ALWAYS_ALLOWLISTED, :ALWAYS_DENYLISTED

# @param headers [Hash]
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
def initialize(headers, config = Castle.config)
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
def initialize(headers, config = nil)
@headers = headers
@config = config
@no_allowlist = config.allowlisted.empty?
@config = config || Castle.config
@no_allowlist = @config.allowlisted.empty?
end

# Serialize HTTP headers
Expand Down
5 changes: 3 additions & 2 deletions lib/castle/ips/extract.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ class Extract
private_constant :DEFAULT

# @param headers [Hash]
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
def initialize(headers, config = Castle.config)
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
def initialize(headers, config = nil)
config ||= Castle.config
@headers = headers
@ip_headers = config.ip_headers.empty? ? DEFAULT : config.ip_headers
@proxies = config.trusted_proxies + Castle::Configuration::TRUSTED_PROXIES
Expand Down
6 changes: 3 additions & 3 deletions lib/castle/logger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ module Logger
class << self
# @param message [String]
# @param data [String]
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
def call(message, data = nil, config = Castle.config)
logger = config.logger
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
def call(message, data = nil, config = nil)
logger = (config || Castle.config).logger

return unless logger

Expand Down
5 changes: 3 additions & 2 deletions lib/castle/secure_mode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ module Castle
module SecureMode
class << self
# @param user_id [String]
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
def signature(user_id, config = Castle.config)
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
def signature(user_id, config = nil)
config ||= Castle.config
OpenSSL::HMAC.hexdigest('sha256', config.api_secret, user_id.to_s)
end
end
Expand Down
16 changes: 9 additions & 7 deletions lib/castle/webhooks/verify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ class Verify
class << self
# Checks if webhook is valid
# @param webhook [Request]
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
def call(webhook, config = Castle.config)
expected_signature = compute_signature(webhook, config.api_secret)
# @param config [Castle::Configuration, Castle::SingletonConfiguration, nil]
def call(webhook, config = nil)
config ||= Castle.config
expected_signature = compute_signature(webhook, config)
signature = webhook.env['HTTP_X_CASTLE_SIGNATURE']
verify_signature(signature, expected_signature)
end
Expand All @@ -18,13 +19,14 @@ def call(webhook, config = Castle.config)

# Computes a webhook signature using provided user_id
# @param webhook [Request]
# @param api_secret [String]
def compute_signature(webhook, api_secret)
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
# @return [String]
def compute_signature(webhook, config)
Base64.encode64(
OpenSSL::HMAC.digest(
OpenSSL::Digest.new('sha256'),
api_secret,
Castle::Core::ProcessWebhook.call(webhook)
config.api_secret,
Castle::Core::ProcessWebhook.call(webhook, config)
)
).strip
end
Expand Down

0 comments on commit b882384

Please sign in to comment.