castle-rb 3.2.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a15270851803a5228a22931ccea95fc873bab7e1
4
- data.tar.gz: 03741fc4fda242401a8e33e3ffab915e59ef0809
2
+ SHA256:
3
+ metadata.gz: ef681fe4eea20aa8dacb69718809e49103e17060a5f2b0a57331982c9d36b59f
4
+ data.tar.gz: 6ab1e89bdefc563ce78ca7ae9666fb86f2b22ce0b740250a10f67fa3eaa1a98b
5
5
  SHA512:
6
- metadata.gz: 26b1cb4d6eeee9fff4d11f51f2fd6a2ed4f562a44754355d041653b4730fe99e07883d3759f14ec40e6923f94be2325c537a69d8aa37be25e372ca857657f219
7
- data.tar.gz: '089bd3ca463c5fccd1e62f7669fb18933e39bd83de93ad02c2a2bbe154a71135a488a33965b7a0184a9eaff5ce18e0434ee415192fad0aced90889ec8c0b716a'
6
+ metadata.gz: cbd67d2101f93caa9c3c793171759bdf0401313ff6c3dbccacc0843674a6ec36d8b0c63e1c705a54e7f27d0b10b59990b85131ad6f492f02ba1e8b2673679583
7
+ data.tar.gz: c56cbdb356049465687277a388d39c62fe41a90e8b02436c38568fd7d8e18e7f8fcd12ad37e5f87c6b6b2a0fce0651da1a2863d3f14034b90da41cc5a876cf6e
data/README.md CHANGED
@@ -122,7 +122,7 @@ end
122
122
 
123
123
  ```ruby
124
124
  request_context = ::Castle::Client.to_context(request)
125
- track_options = {
125
+ track_options = ::Castle::Client.to_options({
126
126
  event: '$login.succeeded',
127
127
  user_id: user.id,
128
128
  properties: {
@@ -131,6 +131,6 @@ track_options = {
131
131
  traits: {
132
132
  key: 'value'
133
133
  }
134
- }
134
+ })
135
135
  CastleTrackingWorker.perform_async(request_context, track_options)
136
136
  ```
@@ -3,6 +3,7 @@
3
3
  require 'openssl'
4
4
  require 'net/http'
5
5
  require 'json'
6
+ require 'time'
6
7
 
7
8
  require 'castle/version'
8
9
  require 'castle/errors'
@@ -10,9 +11,10 @@ require 'castle/command'
10
11
  require 'castle/utils'
11
12
  require 'castle/utils/merger'
12
13
  require 'castle/utils/cloner'
14
+ require 'castle/utils/timestamp'
13
15
  require 'castle/context_merger'
16
+ require 'castle/context_sanitizer'
14
17
  require 'castle/default_context'
15
- require 'castle/commands/with_context'
16
18
  require 'castle/commands/identify'
17
19
  require 'castle/commands/authenticate'
18
20
  require 'castle/commands/track'
@@ -4,19 +4,28 @@ module Castle
4
4
  class Client
5
5
  class << self
6
6
  def from_request(request, options = {})
7
- new(to_context(request, options), options[:do_not_track])
7
+ new(
8
+ to_context(request, options),
9
+ to_options(options)
10
+ )
8
11
  end
9
12
 
10
13
  def to_context(request, options = {})
11
14
  default_context = Castle::DefaultContext.new(request, options[:cookies]).call
12
- Castle::ContextMerger.new(default_context).call(options[:context] || {})
15
+ Castle::ContextMerger.call(default_context, options[:context])
16
+ end
17
+
18
+ def to_options(options = {})
19
+ options[:timestamp] ||= Castle::Utils::Timestamp.call
20
+ options
13
21
  end
14
22
  end
15
23
 
16
24
  attr_accessor :api
17
25
 
18
- def initialize(context, do_not_track = false)
19
- @do_not_track = do_not_track
26
+ def initialize(context, options = {})
27
+ @do_not_track = options[:do_not_track]
28
+ @timestamp = options[:timestamp]
20
29
  @context = context
21
30
  @api = API.new
22
31
  end
@@ -25,6 +34,7 @@ module Castle
25
34
  options = Castle::Utils.deep_symbolize_keys(options || {})
26
35
 
27
36
  if tracked?
37
+ options[:timestamp] ||= @timestamp if @timestamp
28
38
  command = Castle::Commands::Authenticate.new(@context).build(options)
29
39
  begin
30
40
  @api.request(command).merge(failover: false, failover_reason: nil)
@@ -40,6 +50,7 @@ module Castle
40
50
  options = Castle::Utils.deep_symbolize_keys(options || {})
41
51
 
42
52
  return unless tracked?
53
+ options[:timestamp] ||= @timestamp if @timestamp
43
54
 
44
55
  command = Castle::Commands::Identify.new(@context).build(options)
45
56
  @api.request(command)
@@ -49,6 +60,7 @@ module Castle
49
60
  options = Castle::Utils.deep_symbolize_keys(options || {})
50
61
 
51
62
  return unless tracked?
63
+ options[:timestamp] ||= @timestamp if @timestamp
52
64
 
53
65
  command = Castle::Commands::Track.new(@context).build(options)
54
66
  @api.request(command)
@@ -70,7 +82,7 @@ module Castle
70
82
 
71
83
  def setup_context(request, cookies, additional_context)
72
84
  default_context = Castle::DefaultContext.new(request, cookies).call
73
- Castle::ContextMerger.new(default_context).call(additional_context || {})
85
+ Castle::ContextMerger.call(default_context, additional_context)
74
86
  end
75
87
 
76
88
  def failover_response_or_raise(failover_response, error)
@@ -3,13 +3,19 @@
3
3
  module Castle
4
4
  module Commands
5
5
  class Authenticate
6
- include WithContext
6
+ def initialize(context)
7
+ @context = context
8
+ end
7
9
 
8
10
  def build(options = {})
9
11
  validate!(options)
10
- build_context!(options)
12
+ context = ContextMerger.call(@context, options[:context])
13
+ context = ContextSanitizer.call(context)
11
14
 
12
- Castle::Command.new('authenticate', options, :post)
15
+ Castle::Command.new('authenticate',
16
+ options.merge(context: context,
17
+ sent_at: Castle::Utils::Timestamp.call),
18
+ :post)
13
19
  end
14
20
 
15
21
  private
@@ -3,13 +3,19 @@
3
3
  module Castle
4
4
  module Commands
5
5
  class Identify
6
- include WithContext
6
+ def initialize(context)
7
+ @context = context
8
+ end
7
9
 
8
10
  def build(options = {})
9
11
  validate!(options)
10
- build_context!(options)
12
+ context = ContextMerger.call(@context, options[:context])
13
+ context = ContextSanitizer.call(context)
11
14
 
12
- Castle::Command.new('identify', options, :post)
15
+ Castle::Command.new('identify',
16
+ options.merge(context: context,
17
+ sent_at: Castle::Utils::Timestamp.call),
18
+ :post)
13
19
  end
14
20
 
15
21
  private
@@ -3,13 +3,19 @@
3
3
  module Castle
4
4
  module Commands
5
5
  class Track
6
- include WithContext
6
+ def initialize(context)
7
+ @context = context
8
+ end
7
9
 
8
10
  def build(options = {})
9
11
  validate!(options)
10
- build_context!(options)
12
+ context = ContextMerger.call(@context, options[:context])
13
+ context = ContextSanitizer.call(context)
11
14
 
12
- Castle::Command.new('track', options, :post)
15
+ Castle::Command.new('track',
16
+ options.merge(context: context,
17
+ sent_at: Castle::Utils::Timestamp.call),
18
+ :post)
13
19
  end
14
20
 
15
21
  private
@@ -2,12 +2,11 @@
2
2
 
3
3
  module Castle
4
4
  class ContextMerger
5
- def initialize(context)
6
- @main_context = Castle::Utils::Cloner.call(context)
7
- end
8
-
9
- def call(request_context)
10
- Castle::Utils::Merger.call(@main_context, request_context)
5
+ class << self
6
+ def call(initial_context, request_context)
7
+ main_context = Castle::Utils::Cloner.call(initial_context)
8
+ Castle::Utils::Merger.call(main_context, request_context || {})
9
+ end
11
10
  end
12
11
  end
13
12
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ # removes not proper active flag values
5
+ class ContextSanitizer
6
+ class << self
7
+ def call(context)
8
+ sanitized_active_mode(context) || {}
9
+ end
10
+
11
+ private
12
+
13
+ def sanitized_active_mode(context)
14
+ return context unless context && context.key?(:active)
15
+ return context if [true, false].include?(context[:active])
16
+ context.reject { |key| key == :active }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -4,19 +4,19 @@ module Castle
4
4
  module Utils
5
5
  class Merger
6
6
  def self.call(first, second)
7
- Castle::Utils.deep_symbolize_keys!(first)
8
- Castle::Utils.deep_symbolize_keys!(second)
7
+ first_s = Castle::Utils.deep_symbolize_keys(first)
8
+ second_s = Castle::Utils.deep_symbolize_keys(second)
9
9
 
10
- second.each do |name, value|
10
+ second_s.each do |name, value|
11
11
  if value.nil?
12
- first.delete(name)
13
- elsif value.is_a?(Hash) && first[name].is_a?(Hash)
14
- call(first[name], value)
12
+ first_s.delete(name)
13
+ elsif value.is_a?(Hash) && first_s[name].is_a?(Hash)
14
+ first_s[name] = call(first_s[name], value)
15
15
  else
16
- first[name] = value
16
+ first_s[name] = value
17
17
  end
18
18
  end
19
- first
19
+ first_s
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Utils
5
+ # generates proper timestamp
6
+ class Timestamp
7
+ def self.call
8
+ Time.now.utc.iso8601(3)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Castle
4
- VERSION = '3.2.0'
4
+ VERSION = '3.3.0'
5
5
  end
@@ -12,25 +12,40 @@ describe Castle::Client do
12
12
  end
13
13
  let(:request) { Rack::Request.new(env) }
14
14
  let(:client) { described_class.from_request(request) }
15
+ let(:request_to_context) { described_class.to_context(request) }
16
+ let(:client_with_user_timestamp) do
17
+ described_class.new(request_to_context, timestamp: time_user)
18
+ end
19
+ let(:client_with_no_timestamp) { described_class.new(request_to_context) }
20
+
15
21
  let(:headers) { { 'X-Forwarded-For' => ip.to_s } }
16
22
  let(:context) do
17
23
  {
18
24
  client_id: 'abcd',
19
25
  active: true,
20
26
  origin: 'web',
21
- headers: headers,
27
+ headers: { 'X-Forwarded-For': ip.to_s },
22
28
  ip: ip,
23
29
  library: { name: 'castle-rb', version: '2.2.0' }
24
30
  }
25
31
  end
26
32
 
33
+ let(:time_now) { Time.now }
34
+ let(:time_auto) { time_now.utc.iso8601(3) }
35
+ let(:time_user) { (Time.now - 10_000).utc.iso8601(3) }
36
+
27
37
  before do
38
+ Timecop.freeze(time_now)
28
39
  stub_const('Castle::VERSION', '2.2.0')
29
40
  stub_request(:any, /api.castle.io/).with(
30
41
  basic_auth: ['', 'secret']
31
42
  ).to_return(status: 200, body: '{}', headers: {})
32
43
  end
33
44
 
45
+ after do
46
+ Timecop.return
47
+ end
48
+
34
49
  describe 'parses the request' do
35
50
  before do
36
51
  allow(Castle::API).to receive(:new).and_call_original
@@ -42,8 +57,26 @@ describe Castle::Client do
42
57
  end
43
58
  end
44
59
 
60
+ describe 'to_context' do
61
+ it do
62
+ expect(described_class.to_context(request)).to eql(context)
63
+ end
64
+ end
65
+
66
+ describe 'to_options' do
67
+ let(:options) { { user_id: '1234', traits: { name: 'Jo' } } }
68
+ let(:result) { { user_id: '1234', traits: { name: 'Jo' }, timestamp: time_auto } }
69
+
70
+ it do
71
+ expect(described_class.to_options(options)).to eql(result)
72
+ end
73
+ end
74
+
45
75
  describe 'identify' do
46
- let(:request_body) { { user_id: '1234', context: context, traits: { name: 'Jo' } } }
76
+ let(:request_body) do
77
+ { user_id: '1234', timestamp: time_auto,
78
+ sent_at: time_auto, context: context, traits: { name: 'Jo' } }
79
+ end
47
80
 
48
81
  before { client.identify(options) }
49
82
 
@@ -55,6 +88,35 @@ describe Castle::Client do
55
88
  JSON.parse(req.body) == JSON.parse(request_body.to_json)
56
89
  end
57
90
  end
91
+
92
+ context 'when passed timestamp in options and no defined timestamp' do
93
+ let(:client) { client_with_no_timestamp }
94
+ let(:options) { { user_id: '1234', traits: { name: 'Jo' }, timestamp: time_user } }
95
+ let(:request_body) do
96
+ { user_id: '1234', traits: { name: 'Jo' }, context: context,
97
+ timestamp: time_user, sent_at: time_auto }
98
+ end
99
+
100
+ it do
101
+ assert_requested :post, 'https://api.castle.io/v1/identify', times: 1 do |req|
102
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
103
+ end
104
+ end
105
+ end
106
+
107
+ context 'with client initialized with timestamp' do
108
+ let(:client) { client_with_user_timestamp }
109
+ let(:request_body) do
110
+ { user_id: '1234', timestamp: time_user, sent_at: time_auto,
111
+ context: context, traits: { name: 'Jo' } }
112
+ end
113
+
114
+ it do
115
+ assert_requested :post, 'https://api.castle.io/v1/identify', times: 1 do |req|
116
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
117
+ end
118
+ end
119
+ end
58
120
  end
59
121
 
60
122
  context 'string keys' do
@@ -71,14 +133,46 @@ describe Castle::Client do
71
133
  describe 'authenticate' do
72
134
  let(:options) { { event: '$login.succeeded', user_id: '1234' } }
73
135
  let(:request_response) { client.authenticate(options) }
74
- let(:request_body) { { event: '$login.succeeded', user_id: '1234', context: context } }
136
+ let(:request_body) do
137
+ { event: '$login.succeeded', user_id: '1234', context: context,
138
+ timestamp: time_auto, sent_at: time_auto }
139
+ end
75
140
 
76
141
  context 'symbol keys' do
77
142
  before { request_response }
78
143
 
79
144
  it do
80
145
  assert_requested :post, 'https://api.castle.io/v1/authenticate', times: 1 do |req|
81
- req.body == request_body.to_json
146
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
147
+ end
148
+ end
149
+
150
+ context 'when passed timestamp in options and no defined timestamp' do
151
+ let(:client) { client_with_no_timestamp }
152
+ let(:options) { { event: '$login.succeeded', user_id: '1234', timestamp: time_user } }
153
+ let(:request_body) do
154
+ { event: '$login.succeeded', user_id: '1234', context: context,
155
+ timestamp: time_user, sent_at: time_auto }
156
+ end
157
+
158
+ it do
159
+ assert_requested :post, 'https://api.castle.io/v1/authenticate', times: 1 do |req|
160
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
161
+ end
162
+ end
163
+ end
164
+
165
+ context 'with client initialized with timestamp' do
166
+ let(:client) { client_with_user_timestamp }
167
+ let(:request_body) do
168
+ { event: '$login.succeeded', user_id: '1234', context: context,
169
+ timestamp: time_user, sent_at: time_auto }
170
+ end
171
+
172
+ it do
173
+ assert_requested :post, 'https://api.castle.io/v1/authenticate', times: 1 do |req|
174
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
175
+ end
82
176
  end
83
177
  end
84
178
  end
@@ -90,7 +184,7 @@ describe Castle::Client do
90
184
 
91
185
  it do
92
186
  assert_requested :post, 'https://api.castle.io/v1/authenticate', times: 1 do |req|
93
- req.body == request_body.to_json
187
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
94
188
  end
95
189
  end
96
190
  end
@@ -100,7 +194,7 @@ describe Castle::Client do
100
194
 
101
195
  it do
102
196
  assert_requested :post, 'https://api.castle.io/v1/authenticate', times: 1 do |req|
103
- req.body == request_body.to_json
197
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
104
198
  end
105
199
  end
106
200
 
@@ -159,7 +253,10 @@ describe Castle::Client do
159
253
  end
160
254
 
161
255
  describe 'track' do
162
- let(:request_body) { { event: '$login.succeeded', context: context, user_id: '1234' } }
256
+ let(:request_body) do
257
+ { event: '$login.succeeded', context: context, user_id: '1234',
258
+ timestamp: time_auto, sent_at: time_auto }
259
+ end
163
260
 
164
261
  before { client.track(options) }
165
262
 
@@ -171,6 +268,35 @@ describe Castle::Client do
171
268
  JSON.parse(req.body) == JSON.parse(request_body.to_json)
172
269
  end
173
270
  end
271
+
272
+ context 'when passed timestamp in options and no defined timestamp' do
273
+ let(:client) { client_with_no_timestamp }
274
+ let(:options) { { event: '$login.succeeded', user_id: '1234', timestamp: time_user } }
275
+ let(:request_body) do
276
+ { event: '$login.succeeded', user_id: '1234', context: context,
277
+ timestamp: time_user, sent_at: time_auto }
278
+ end
279
+
280
+ it do
281
+ assert_requested :post, 'https://api.castle.io/v1/track', times: 1 do |req|
282
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
283
+ end
284
+ end
285
+ end
286
+
287
+ context 'with client initialized with timestamp' do
288
+ let(:client) { client_with_user_timestamp }
289
+ let(:request_body) do
290
+ { event: '$login.succeeded', context: context, user_id: '1234',
291
+ timestamp: time_user, sent_at: time_auto }
292
+ end
293
+
294
+ it do
295
+ assert_requested :post, 'https://api.castle.io/v1/track', times: 1 do |req|
296
+ JSON.parse(req.body) == JSON.parse(request_body.to_json)
297
+ end
298
+ end
299
+ end
174
300
  end
175
301
 
176
302
  context 'string keys' do
@@ -4,7 +4,18 @@ describe Castle::Commands::Authenticate do
4
4
  subject(:instance) { described_class.new(context) }
5
5
 
6
6
  let(:context) { { test: { test1: '1' } } }
7
- let(:default_payload) { { event: '$login.authenticate', user_id: '1234' } }
7
+ let(:default_payload) { { event: '$login.authenticate', user_id: '1234', sent_at: time_auto } }
8
+
9
+ let(:time_now) { Time.now }
10
+ let(:time_auto) { time_now.utc.iso8601(3) }
11
+
12
+ before do
13
+ Timecop.freeze(time_now)
14
+ end
15
+
16
+ after do
17
+ Timecop.return
18
+ end
8
19
 
9
20
  describe '.build' do
10
21
  subject(:command) { instance.build(payload) }
@@ -4,7 +4,18 @@ describe Castle::Commands::Identify do
4
4
  subject(:instance) { described_class.new(context) }
5
5
 
6
6
  let(:context) { { test: { test1: '1' } } }
7
- let(:default_payload) { { user_id: '1234' } }
7
+ let(:default_payload) { { user_id: '1234', sent_at: time_auto } }
8
+
9
+ let(:time_now) { Time.now }
10
+ let(:time_auto) { time_now.utc.iso8601(3) }
11
+
12
+ before do
13
+ Timecop.freeze(time_now)
14
+ end
15
+
16
+ after do
17
+ Timecop.return
18
+ end
8
19
 
9
20
  describe '.build' do
10
21
  subject(:command) { instance.build(payload) }
@@ -4,7 +4,18 @@ describe Castle::Commands::Track do
4
4
  subject(:instance) { described_class.new(context) }
5
5
 
6
6
  let(:context) { { test: { test1: '1' } } }
7
- let(:default_payload) { { event: '$login.track' } }
7
+ let(:default_payload) { { event: '$login.track', sent_at: time_auto } }
8
+
9
+ let(:time_now) { Time.now }
10
+ let(:time_auto) { time_now.utc.iso8601(3) }
11
+
12
+ before do
13
+ Timecop.freeze(time_now)
14
+ end
15
+
16
+ after do
17
+ Timecop.return
18
+ end
8
19
 
9
20
  describe '#build' do
10
21
  subject(:command) { instance.build(payload) }
@@ -1,21 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe Castle::ContextMerger do
4
- subject(:command) { described_class.new('go', { id: '1' }, :post) }
5
-
6
4
  let(:first) { { test: { test1: { c: '4' } } } }
7
5
 
8
- context '.new' do
9
- subject(:instance) { described_class.new(first) }
10
-
11
- it { expect(instance.instance_variable_get(:@main_context)).to eq(first) }
12
- it do
13
- expect(instance.instance_variable_get(:@main_context).object_id).not_to eq(first.object_id)
14
- end
15
- end
16
-
17
6
  context '#call' do
18
- subject { described_class.new(first).call(second) }
7
+ subject { described_class.call(first, second) }
19
8
 
20
9
  let(:result) { { test: { test1: { c: '4', d: '5' } } } }
21
10
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Castle::ContextSanitizer do
4
+ let(:paylod) { { test: 'test' } }
5
+
6
+ describe '#call' do
7
+ subject { described_class.call(context) }
8
+
9
+ context 'when active true' do
10
+ let(:context) { paylod.merge(active: true) }
11
+
12
+ it { is_expected.to eql(context) }
13
+ end
14
+
15
+ context 'when active false' do
16
+ let(:context) { paylod.merge(active: false) }
17
+
18
+ it { is_expected.to eql(context) }
19
+ end
20
+
21
+ context 'when active string' do
22
+ let(:context) { paylod.merge(active: 'uknown') }
23
+
24
+ it { is_expected.to eql(paylod) }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Castle::Utils::Timestamp do
4
+ subject { described_class.call }
5
+
6
+ let(:time_string) { '2018-01-10T14:14:24.407Z' }
7
+ let(:time) { Time.parse(time_string) }
8
+
9
+ before do
10
+ Timecop.freeze(time)
11
+ end
12
+
13
+ after do
14
+ Timecop.return
15
+ end
16
+
17
+ describe '#call' do
18
+ it do
19
+ is_expected.to eql(time_string)
20
+ end
21
+ end
22
+ end
@@ -5,6 +5,7 @@ require 'bundler/setup'
5
5
  require 'rack'
6
6
  require 'webmock/rspec'
7
7
  require 'byebug'
8
+ require 'timecop'
8
9
 
9
10
  require 'coveralls'
10
11
  Coveralls.wear!
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: castle-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johan Brissmyr
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-15 00:00:00.000000000 Z
11
+ date: 2018-01-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Castle protects your users from account compromise
14
14
  email: johan@castle.io
@@ -26,9 +26,9 @@ files:
26
26
  - lib/castle/commands/identify.rb
27
27
  - lib/castle/commands/review.rb
28
28
  - lib/castle/commands/track.rb
29
- - lib/castle/commands/with_context.rb
30
29
  - lib/castle/configuration.rb
31
30
  - lib/castle/context_merger.rb
31
+ - lib/castle/context_sanitizer.rb
32
32
  - lib/castle/default_context.rb
33
33
  - lib/castle/errors.rb
34
34
  - lib/castle/extractors/client_id.rb
@@ -47,6 +47,7 @@ files:
47
47
  - lib/castle/utils.rb
48
48
  - lib/castle/utils/cloner.rb
49
49
  - lib/castle/utils/merger.rb
50
+ - lib/castle/utils/timestamp.rb
50
51
  - lib/castle/version.rb
51
52
  - spec/lib/castle/api_spec.rb
52
53
  - spec/lib/castle/client_spec.rb
@@ -57,6 +58,7 @@ files:
57
58
  - spec/lib/castle/commands/track_spec.rb
58
59
  - spec/lib/castle/configuration_spec.rb
59
60
  - spec/lib/castle/context_merger_spec.rb
61
+ - spec/lib/castle/context_sanitizer_spec.rb
60
62
  - spec/lib/castle/default_context_spec.rb
61
63
  - spec/lib/castle/extractors/client_id_spec.rb
62
64
  - spec/lib/castle/extractors/headers_spec.rb
@@ -68,6 +70,7 @@ files:
68
70
  - spec/lib/castle/secure_mode_spec.rb
69
71
  - spec/lib/castle/utils/cloner_spec.rb
70
72
  - spec/lib/castle/utils/merger_spec.rb
73
+ - spec/lib/castle/utils/timestamp_spec.rb
71
74
  - spec/lib/castle/utils_spec.rb
72
75
  - spec/lib/castle/version_spec.rb
73
76
  - spec/lib/castle_spec.rb
@@ -92,32 +95,34 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
95
  version: '0'
93
96
  requirements: []
94
97
  rubyforge_project:
95
- rubygems_version: 2.6.13
98
+ rubygems_version: 2.7.4
96
99
  signing_key:
97
100
  specification_version: 4
98
101
  summary: Castle
99
102
  test_files:
100
- - spec/lib/castle/api_spec.rb
103
+ - spec/spec_helper.rb
104
+ - spec/lib/castle_spec.rb
105
+ - spec/lib/castle/context_sanitizer_spec.rb
106
+ - spec/lib/castle/review_spec.rb
101
107
  - spec/lib/castle/client_spec.rb
102
- - spec/lib/castle/command_spec.rb
103
- - spec/lib/castle/commands/authenticate_spec.rb
104
- - spec/lib/castle/commands/identify_spec.rb
105
- - spec/lib/castle/commands/review_spec.rb
106
- - spec/lib/castle/commands/track_spec.rb
108
+ - spec/lib/castle/api_spec.rb
107
109
  - spec/lib/castle/configuration_spec.rb
108
- - spec/lib/castle/context_merger_spec.rb
110
+ - spec/lib/castle/version_spec.rb
109
111
  - spec/lib/castle/default_context_spec.rb
110
- - spec/lib/castle/extractors/client_id_spec.rb
111
- - spec/lib/castle/extractors/headers_spec.rb
112
- - spec/lib/castle/extractors/ip_spec.rb
113
112
  - spec/lib/castle/header_formatter_spec.rb
114
- - spec/lib/castle/request_spec.rb
115
- - spec/lib/castle/response_spec.rb
116
- - spec/lib/castle/review_spec.rb
117
- - spec/lib/castle/secure_mode_spec.rb
118
113
  - spec/lib/castle/utils/cloner_spec.rb
114
+ - spec/lib/castle/utils/timestamp_spec.rb
119
115
  - spec/lib/castle/utils/merger_spec.rb
116
+ - spec/lib/castle/command_spec.rb
117
+ - spec/lib/castle/request_spec.rb
118
+ - spec/lib/castle/response_spec.rb
119
+ - spec/lib/castle/commands/review_spec.rb
120
+ - spec/lib/castle/commands/authenticate_spec.rb
121
+ - spec/lib/castle/commands/track_spec.rb
122
+ - spec/lib/castle/commands/identify_spec.rb
123
+ - spec/lib/castle/context_merger_spec.rb
124
+ - spec/lib/castle/extractors/ip_spec.rb
125
+ - spec/lib/castle/extractors/headers_spec.rb
126
+ - spec/lib/castle/extractors/client_id_spec.rb
120
127
  - spec/lib/castle/utils_spec.rb
121
- - spec/lib/castle/version_spec.rb
122
- - spec/lib/castle_spec.rb
123
- - spec/spec_helper.rb
128
+ - spec/lib/castle/secure_mode_spec.rb
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Castle
4
- module Commands
5
- module WithContext
6
- def initialize(context)
7
- @context_merger = ContextMerger.new(context)
8
- end
9
-
10
- private
11
-
12
- def build_context!(options)
13
- sanitize_active_mode!(options)
14
- options[:context] = merge_context(options[:context])
15
- end
16
-
17
- def sanitize_active_mode!(options)
18
- return unless options[:context] && options[:context].key?(:active)
19
- return if [true, false].include?(options[:context][:active])
20
- options[:context].delete(:active)
21
- end
22
-
23
- def merge_context(request_context)
24
- @context_merger.call(request_context || {})
25
- end
26
- end
27
- end
28
- end