castle-rb 4.1.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +158 -43
- data/lib/castle.rb +46 -21
- data/lib/castle/api.rb +24 -12
- data/lib/castle/api/approve_device.rb +25 -0
- data/lib/castle/api/authenticate.rb +34 -0
- data/lib/castle/api/end_impersonation.rb +29 -0
- data/lib/castle/api/get_device.rb +25 -0
- data/lib/castle/api/get_devices_for_user.rb +25 -0
- data/lib/castle/api/identify.rb +26 -0
- data/lib/castle/api/report_device.rb +25 -0
- data/lib/castle/api/review.rb +24 -0
- data/lib/castle/api/start_impersonation.rb +29 -0
- data/lib/castle/api/track.rb +26 -0
- data/lib/castle/client.rb +52 -45
- data/lib/castle/{extractors/client_id.rb → client_id/extract.rb} +2 -2
- data/lib/castle/commands/approve_device.rb +21 -0
- data/lib/castle/commands/authenticate.rb +13 -13
- data/lib/castle/commands/end_impersonation.rb +25 -0
- data/lib/castle/commands/get_device.rb +21 -0
- data/lib/castle/commands/get_devices_for_user.rb +21 -0
- data/lib/castle/commands/identify.rb +12 -13
- data/lib/castle/commands/report_device.rb +21 -0
- data/lib/castle/commands/review.rb +6 -3
- data/lib/castle/commands/start_impersonation.rb +25 -0
- data/lib/castle/commands/track.rb +12 -13
- data/lib/castle/configuration.rb +45 -28
- data/lib/castle/context/{default.rb → get_default.rb} +5 -6
- data/lib/castle/context/{merger.rb → merge.rb} +3 -3
- data/lib/castle/context/prepare.rb +18 -0
- data/lib/castle/context/{sanitizer.rb → sanitize.rb} +1 -1
- data/lib/castle/core/get_connection.rb +25 -0
- data/lib/castle/{api/response.rb → core/process_response.rb} +4 -2
- data/lib/castle/core/process_webhook.rb +20 -0
- data/lib/castle/core/send_request.rb +50 -0
- data/lib/castle/errors.rb +2 -0
- data/lib/castle/events.rb +1 -1
- data/lib/castle/failover/prepare_response.rb +23 -0
- data/lib/castle/failover/strategy.rb +20 -0
- data/lib/castle/headers/extract.rb +47 -0
- data/lib/castle/headers/filter.rb +37 -0
- data/lib/castle/headers/format.rb +24 -0
- data/lib/castle/ip/extract.rb +83 -0
- data/lib/castle/logger.rb +19 -0
- data/lib/castle/payload/prepare.rb +27 -0
- data/lib/castle/secure_mode.rb +6 -2
- data/lib/castle/session.rb +18 -0
- data/lib/castle/singleton_configuration.rb +9 -0
- data/lib/castle/utils/clean_invalid_chars.rb +24 -0
- data/lib/castle/utils/clone.rb +15 -0
- data/lib/castle/utils/deep_symbolize_keys.rb +45 -0
- data/lib/castle/utils/get_timestamp.rb +15 -0
- data/lib/castle/utils/{merger.rb → merge.rb} +3 -3
- data/lib/castle/utils/secure_compare.rb +22 -0
- data/lib/castle/validators/not_supported.rb +1 -0
- data/lib/castle/validators/present.rb +1 -0
- data/lib/castle/verdict.rb +13 -0
- data/lib/castle/version.rb +1 -1
- data/lib/castle/webhooks/verify.rb +43 -0
- data/spec/integration/rails/rails_spec.rb +33 -7
- data/spec/integration/rails/support/application.rb +3 -1
- data/spec/integration/rails/support/home_controller.rb +47 -5
- data/spec/lib/castle/api/approve_device_spec.rb +21 -0
- data/spec/lib/castle/api/authenticate_spec.rb +140 -0
- data/spec/lib/castle/api/end_impersonation_spec.rb +59 -0
- data/spec/lib/castle/api/get_device_spec.rb +19 -0
- data/spec/lib/castle/api/get_devices_for_user_spec.rb +19 -0
- data/spec/lib/castle/api/identify_spec.rb +68 -0
- data/spec/lib/castle/api/report_device_spec.rb +21 -0
- data/spec/lib/castle/{review_spec.rb → api/review_spec.rb} +3 -3
- data/spec/lib/castle/api/start_impersonation_spec.rb +59 -0
- data/spec/lib/castle/api/track_spec.rb +68 -0
- data/spec/lib/castle/api_spec.rb +16 -1
- data/spec/lib/castle/{extractors/client_id_spec.rb → client_id/extract_spec.rb} +2 -2
- data/spec/lib/castle/client_spec.rb +41 -23
- data/spec/lib/castle/commands/approve_device_spec.rb +24 -0
- data/spec/lib/castle/commands/authenticate_spec.rb +7 -16
- data/spec/lib/castle/commands/end_impersonation_spec.rb +82 -0
- data/spec/lib/castle/commands/get_device_spec.rb +24 -0
- data/spec/lib/castle/commands/get_devices_for_user_spec.rb +24 -0
- data/spec/lib/castle/commands/identify_spec.rb +5 -16
- data/spec/lib/castle/commands/report_device_spec.rb +24 -0
- data/spec/lib/castle/commands/review_spec.rb +1 -1
- data/spec/lib/castle/commands/{impersonate_spec.rb → start_impersonation_spec.rb} +9 -34
- data/spec/lib/castle/commands/track_spec.rb +5 -16
- data/spec/lib/castle/configuration_spec.rb +9 -138
- data/spec/lib/castle/context/{default_spec.rb → get_default_spec.rb} +1 -2
- data/spec/lib/castle/context/{merger_spec.rb → merge_spec.rb} +1 -1
- data/spec/lib/castle/context/prepare_spec.rb +44 -0
- data/spec/lib/castle/context/{sanitizer_spec.rb → sanitize_spec.rb} +1 -1
- data/spec/lib/castle/core/get_connection_spec.rb +59 -0
- data/spec/lib/castle/{api/response_spec.rb → core/process_response_spec.rb} +56 -1
- data/spec/lib/castle/core/process_webhook_spec.rb +46 -0
- data/spec/lib/castle/core/send_request_spec.rb +102 -0
- data/spec/lib/castle/failover/strategy_spec.rb +12 -0
- data/spec/lib/castle/{extractors/headers_spec.rb → headers/extract_spec.rb} +18 -18
- data/spec/lib/castle/{headers_filter_spec.rb → headers/filter_spec.rb} +6 -5
- data/spec/lib/castle/headers/format_spec.rb +25 -0
- data/spec/lib/castle/{extractors/ip_spec.rb → ip/extract_spec.rb} +35 -7
- data/spec/lib/castle/logger_spec.rb +42 -0
- data/spec/lib/castle/payload/prepare_spec.rb +54 -0
- data/spec/lib/castle/session_spec.rb +88 -0
- data/spec/lib/castle/singleton_configuration_spec.rb +18 -0
- data/spec/lib/castle/utils/clean_invalid_chars_spec.rb +69 -0
- data/spec/lib/castle/utils/{cloner_spec.rb → clone_spec.rb} +3 -3
- data/spec/lib/castle/utils/deep_symbolize_keys_spec.rb +50 -0
- data/spec/lib/castle/utils/{timestamp_spec.rb → get_timestamp_spec.rb} +1 -1
- data/spec/lib/castle/utils/{merger_spec.rb → merge_spec.rb} +3 -3
- data/spec/lib/castle/verdict_spec.rb +9 -0
- data/spec/lib/castle/webhooks/verify_spec.rb +69 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/shared_examples/configuration.rb +129 -0
- metadata +133 -56
- data/lib/castle/api/request.rb +0 -42
- data/lib/castle/api/session.rb +0 -39
- data/lib/castle/commands/impersonate.rb +0 -26
- data/lib/castle/extractors/headers.rb +0 -45
- data/lib/castle/extractors/ip.rb +0 -68
- data/lib/castle/failover_auth_response.rb +0 -21
- data/lib/castle/headers_filter.rb +0 -35
- data/lib/castle/headers_formatter.rb +0 -22
- data/lib/castle/review.rb +0 -11
- data/lib/castle/utils.rb +0 -55
- data/lib/castle/utils/cloner.rb +0 -11
- data/lib/castle/utils/timestamp.rb +0 -12
- data/spec/lib/castle/api/request_spec.rb +0 -72
- data/spec/lib/castle/headers_formatter_spec.rb +0 -25
- data/spec/lib/castle/utils_spec.rb +0 -156
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Commands
|
5
|
+
# builder for impersonate command
|
6
|
+
class EndImpersonation
|
7
|
+
class << self
|
8
|
+
# @param options [Hash]
|
9
|
+
# @return [Castle::Command]
|
10
|
+
def build(options = {})
|
11
|
+
Castle::Validators::Present.call(options, %i[user_id])
|
12
|
+
context = Castle::Context::Sanitize.call(options[:context])
|
13
|
+
|
14
|
+
Castle::Validators::Present.call(context, %i[user_agent ip])
|
15
|
+
|
16
|
+
Castle::Command.new(
|
17
|
+
'impersonate',
|
18
|
+
options.merge(context: context, sent_at: Castle::Utils::GetTimestamp.call),
|
19
|
+
:delete
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Commands
|
5
|
+
# Generates the payload for the GET devices/#{device_token} request
|
6
|
+
class GetDevice
|
7
|
+
class << self
|
8
|
+
# @param options [Hash]
|
9
|
+
# @return [Castle::Command]
|
10
|
+
def build(options = {})
|
11
|
+
Castle::Validators::Present.call(options, %i[device_token])
|
12
|
+
Castle::Command.new(
|
13
|
+
"devices/#{options[:device_token]}",
|
14
|
+
nil,
|
15
|
+
:get
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Commands
|
5
|
+
# Generates the payload for the GET users/#{user_id}/devices request
|
6
|
+
class GetDevicesForUser
|
7
|
+
class << self
|
8
|
+
# @param options [Hash]
|
9
|
+
# @return [Castle::Command]
|
10
|
+
def build(options = {})
|
11
|
+
Castle::Validators::Present.call(options, %i[user_id])
|
12
|
+
Castle::Command.new(
|
13
|
+
"users/#{options[:user_id]}/devices",
|
14
|
+
nil,
|
15
|
+
:get
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -3,20 +3,19 @@
|
|
3
3
|
module Castle
|
4
4
|
module Commands
|
5
5
|
class Identify
|
6
|
-
|
7
|
-
@
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
context = Castle::Context::Merger.call(@context, options[:context])
|
13
|
-
context = Castle::Context::Sanitizer.call(context)
|
6
|
+
class << self
|
7
|
+
# @param options [Hash]
|
8
|
+
# @return [Castle::Command]
|
9
|
+
def build(options = {})
|
10
|
+
Castle::Validators::NotSupported.call(options, %i[properties])
|
11
|
+
context = Castle::Context::Sanitize.call(options[:context])
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
Castle::Command.new(
|
14
|
+
'identify',
|
15
|
+
options.merge(context: context, sent_at: Castle::Utils::GetTimestamp.call),
|
16
|
+
:post
|
17
|
+
)
|
18
|
+
end
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Commands
|
5
|
+
# Generates the payload for the PUT devices/#{device_token}/report request
|
6
|
+
class ReportDevice
|
7
|
+
class << self
|
8
|
+
# @param options [Hash]
|
9
|
+
# @return [Castle::Command]
|
10
|
+
def build(options = {})
|
11
|
+
Castle::Validators::Present.call(options, %i[device_token])
|
12
|
+
Castle::Command.new(
|
13
|
+
"devices/#{options[:device_token]}/report",
|
14
|
+
nil,
|
15
|
+
:put
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -2,11 +2,14 @@
|
|
2
2
|
|
3
3
|
module Castle
|
4
4
|
module Commands
|
5
|
+
# Generates the payload for the GET reviews/#{review_id} request
|
5
6
|
class Review
|
6
7
|
class << self
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
# @param options [Hash]
|
9
|
+
# @return [Castle::Command]
|
10
|
+
def build(options = {})
|
11
|
+
Castle::Validators::Present.call(options, %i[review_id])
|
12
|
+
Castle::Command.new("reviews/#{options[:review_id]}", nil, :get)
|
10
13
|
end
|
11
14
|
end
|
12
15
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Commands
|
5
|
+
# builder for impersonate command
|
6
|
+
class StartImpersonation
|
7
|
+
class << self
|
8
|
+
# @param options [Hash]
|
9
|
+
# @return [Castle::Command]
|
10
|
+
def build(options = {})
|
11
|
+
Castle::Validators::Present.call(options, %i[user_id])
|
12
|
+
context = Castle::Context::Sanitize.call(options[:context])
|
13
|
+
|
14
|
+
Castle::Validators::Present.call(context, %i[user_agent ip])
|
15
|
+
|
16
|
+
Castle::Command.new(
|
17
|
+
'impersonate',
|
18
|
+
options.merge(context: context, sent_at: Castle::Utils::GetTimestamp.call),
|
19
|
+
:post
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -3,20 +3,19 @@
|
|
3
3
|
module Castle
|
4
4
|
module Commands
|
5
5
|
class Track
|
6
|
-
|
7
|
-
@
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
context = Castle::Context::Merger.call(@context, options[:context])
|
13
|
-
context = Castle::Context::Sanitizer.call(context)
|
6
|
+
class << self
|
7
|
+
# @param options [Hash]
|
8
|
+
# @return [Castle::Command]
|
9
|
+
def build(options = {})
|
10
|
+
Castle::Validators::Present.call(options, %i[event])
|
11
|
+
context = Castle::Context::Sanitize.call(options[:context])
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
Castle::Command.new(
|
14
|
+
'track',
|
15
|
+
options.merge(context: context, sent_at: Castle::Utils::GetTimestamp.call),
|
16
|
+
:post
|
17
|
+
)
|
18
|
+
end
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
data/lib/castle/configuration.rb
CHANGED
@@ -1,16 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'uri'
|
4
|
+
|
3
5
|
module Castle
|
4
6
|
# manages configuration variables
|
5
7
|
class Configuration
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
PORT = 443
|
10
|
-
URL_PREFIX = '/v1'
|
11
|
-
FAILOVER_STRATEGY = :allow
|
12
|
-
REQUEST_TIMEOUT = 500 # in milliseconds
|
13
|
-
FAILOVER_STRATEGIES = %i[allow deny challenge throw].freeze
|
8
|
+
# API endpoint
|
9
|
+
BASE_URL = 'https://api.castle.io/v1'
|
10
|
+
REQUEST_TIMEOUT = 1000 # in milliseconds
|
14
11
|
# regexp of trusted proxies which is always appended to the trusted proxy list
|
15
12
|
TRUSTED_PROXIES = [/
|
16
13
|
\A127\.0\.0\.1\Z|
|
@@ -21,9 +18,9 @@ module Castle
|
|
21
18
|
\Aunix:
|
22
19
|
/ix].freeze
|
23
20
|
|
24
|
-
# @note this value is not assigned as we don't recommend using a
|
21
|
+
# @note this value is not assigned as we don't recommend using a allowlist. If you need to use
|
25
22
|
# one, this constant is provided as a good default.
|
26
|
-
|
23
|
+
DEFAULT_ALLOWLIST = %w[
|
27
24
|
Accept
|
28
25
|
Accept-Charset
|
29
26
|
Accept-Datetime
|
@@ -33,46 +30,59 @@ module Castle
|
|
33
30
|
Connection
|
34
31
|
Content-Length
|
35
32
|
Content-Type
|
33
|
+
Dnt
|
36
34
|
Host
|
37
35
|
Origin
|
38
36
|
Pragma
|
39
37
|
Referer
|
40
|
-
|
38
|
+
Sec-Fetch-Dest
|
39
|
+
Sec-Fetch-Mode
|
40
|
+
Sec-Fetch-Site
|
41
|
+
Sec-Fetch-User
|
42
|
+
Te
|
41
43
|
Upgrade-Insecure-Requests
|
44
|
+
User-Agent
|
42
45
|
X-Castle-Client-Id
|
46
|
+
X-Requested-With
|
43
47
|
].freeze
|
44
48
|
|
45
|
-
attr_accessor :
|
46
|
-
attr_reader :api_secret, :
|
49
|
+
attr_accessor :request_timeout, :trust_proxy_chain, :logger
|
50
|
+
attr_reader :api_secret, :allowlisted, :denylisted, :failover_strategy, :ip_headers,
|
51
|
+
:trusted_proxies, :trusted_proxy_depth, :base_url
|
47
52
|
|
48
53
|
def initialize
|
49
|
-
@
|
54
|
+
@header_format = Castle::Headers::Format
|
50
55
|
@request_timeout = REQUEST_TIMEOUT
|
51
56
|
reset
|
52
57
|
end
|
53
58
|
|
54
59
|
def reset
|
55
|
-
self.failover_strategy =
|
56
|
-
self.
|
57
|
-
self.
|
58
|
-
self.
|
59
|
-
self.whitelisted = [].freeze
|
60
|
-
self.blacklisted = [].freeze
|
60
|
+
self.failover_strategy = Castle::Failover::Strategy::ALLOW
|
61
|
+
self.base_url = BASE_URL
|
62
|
+
self.allowlisted = [].freeze
|
63
|
+
self.denylisted = [].freeze
|
61
64
|
self.api_secret = ENV.fetch('CASTLE_API_SECRET', '')
|
62
65
|
self.ip_headers = [].freeze
|
63
66
|
self.trusted_proxies = [].freeze
|
67
|
+
self.trust_proxy_chain = false
|
68
|
+
self.trusted_proxy_depth = nil
|
69
|
+
self.logger = nil
|
70
|
+
end
|
71
|
+
|
72
|
+
def base_url=(value)
|
73
|
+
@base_url = URI(value)
|
64
74
|
end
|
65
75
|
|
66
76
|
def api_secret=(value)
|
67
77
|
@api_secret = value.to_s
|
68
78
|
end
|
69
79
|
|
70
|
-
def
|
71
|
-
@
|
80
|
+
def allowlisted=(value)
|
81
|
+
@allowlisted = (value ? value.map { |header| @header_format.call(header) } : []).freeze
|
72
82
|
end
|
73
83
|
|
74
|
-
def
|
75
|
-
@
|
84
|
+
def denylisted=(value)
|
85
|
+
@denylisted = (value ? value.map { |header| @header_format.call(header) } : []).freeze
|
76
86
|
end
|
77
87
|
|
78
88
|
# sets ip headers
|
@@ -80,23 +90,30 @@ module Castle
|
|
80
90
|
def ip_headers=(value)
|
81
91
|
raise Castle::ConfigurationError, 'ip headers must be an Array' unless value.is_a?(Array)
|
82
92
|
|
83
|
-
@ip_headers = value.map { |header| @
|
93
|
+
@ip_headers = value.map { |header| @header_format.call(header) }.freeze
|
84
94
|
end
|
85
95
|
|
86
96
|
# sets trusted proxies
|
87
|
-
# @param value [Array<String
|
97
|
+
# @param value [Array<String,Regexp>]
|
88
98
|
def trusted_proxies=(value)
|
89
99
|
raise Castle::ConfigurationError, 'trusted proxies must be an Array' unless value.is_a?(Array)
|
90
100
|
|
91
101
|
@trusted_proxies = value
|
92
102
|
end
|
93
103
|
|
104
|
+
# @param value [String,Number,NilClass]
|
105
|
+
def trusted_proxy_depth=(value)
|
106
|
+
@trusted_proxy_depth = value.to_i
|
107
|
+
end
|
108
|
+
|
94
109
|
def valid?
|
95
|
-
!api_secret.to_s.empty? && !host.to_s.empty? && !port.to_s.empty?
|
110
|
+
!api_secret.to_s.empty? && !base_url.host.to_s.empty? && !base_url.port.to_s.empty?
|
96
111
|
end
|
97
112
|
|
98
113
|
def failover_strategy=(value)
|
99
|
-
@failover_strategy =
|
114
|
+
@failover_strategy = Castle::Failover::STRATEGIES.detect do |strategy|
|
115
|
+
strategy == value.to_sym
|
116
|
+
end
|
100
117
|
raise Castle::ConfigurationError, 'unrecognized failover strategy' if @failover_strategy.nil?
|
101
118
|
end
|
102
119
|
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module Castle
|
4
4
|
module Context
|
5
|
-
class
|
5
|
+
class GetDefault
|
6
6
|
def initialize(request, cookies = nil)
|
7
|
-
@pre_headers =
|
7
|
+
@pre_headers = Castle::Headers::Filter.new(request).call
|
8
8
|
@cookies = cookies || request.cookies
|
9
9
|
@request = request
|
10
10
|
end
|
@@ -13,7 +13,6 @@ module Castle
|
|
13
13
|
{
|
14
14
|
client_id: client_id,
|
15
15
|
active: true,
|
16
|
-
origin: 'web',
|
17
16
|
headers: headers,
|
18
17
|
ip: ip,
|
19
18
|
library: {
|
@@ -40,18 +39,18 @@ module Castle
|
|
40
39
|
|
41
40
|
# @return [String]
|
42
41
|
def ip
|
43
|
-
|
42
|
+
Castle::IP::Extract.new(@pre_headers).call
|
44
43
|
end
|
45
44
|
|
46
45
|
# @return [String]
|
47
46
|
def client_id
|
48
|
-
|
47
|
+
Castle::ClientId::Extract.new(@pre_headers, @cookies).call
|
49
48
|
end
|
50
49
|
|
51
50
|
# formatted and filtered headers
|
52
51
|
# @return [Hash]
|
53
52
|
def headers
|
54
|
-
|
53
|
+
Castle::Headers::Extract.new(@pre_headers).call
|
55
54
|
end
|
56
55
|
end
|
57
56
|
end
|
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module Castle
|
4
4
|
module Context
|
5
|
-
class
|
5
|
+
class Merge
|
6
6
|
class << self
|
7
7
|
def call(initial_context, request_context)
|
8
|
-
main_context = Castle::Utils::
|
9
|
-
Castle::Utils::
|
8
|
+
main_context = Castle::Utils::Clone.call(initial_context)
|
9
|
+
Castle::Utils::Merge.call(main_context, request_context || {})
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Context
|
5
|
+
# prepares the context from the request
|
6
|
+
module Prepare
|
7
|
+
class << self
|
8
|
+
# @param request [Request]
|
9
|
+
# @param options [Hash]
|
10
|
+
# @return [Hash]
|
11
|
+
def call(request, options = {})
|
12
|
+
default_context = Castle::Context::GetDefault.new(request, options[:cookies]).call
|
13
|
+
Castle::Context::Merge.call(default_context, options[:context])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module Core
|
5
|
+
# this module returns a new configured Net::HTTP object
|
6
|
+
module GetConnection
|
7
|
+
HTTPS_SCHEME = 'https'
|
8
|
+
|
9
|
+
class << self
|
10
|
+
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
|
11
|
+
def call(config = Castle.config)
|
12
|
+
http = Net::HTTP.new(config.base_url.host, config.base_url.port)
|
13
|
+
http.read_timeout = config.request_timeout / 1000.0
|
14
|
+
|
15
|
+
if config.base_url.scheme == HTTPS_SCHEME
|
16
|
+
http.use_ssl = true
|
17
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
18
|
+
end
|
19
|
+
|
20
|
+
http
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|