castle-rb 7.1.2 → 8.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 +14 -159
- data/lib/castle/api/authenticate.rb +3 -12
- data/lib/castle/api/end_impersonation.rb +1 -3
- data/lib/castle/api/filter.rb +2 -10
- data/lib/castle/api/log.rb +2 -10
- data/lib/castle/api/risk.rb +2 -10
- data/lib/castle/api/start_impersonation.rb +1 -3
- data/lib/castle/api/track.rb +1 -3
- data/lib/castle/client.rb +1 -5
- data/lib/castle/commands/log.rb +1 -5
- data/lib/castle/commands/risk.rb +1 -5
- data/lib/castle/configuration.rb +2 -6
- data/lib/castle/core/process_response.rb +25 -2
- data/lib/castle/core/process_webhook.rb +4 -7
- data/lib/castle/core/send_request.rb +1 -3
- data/lib/castle/errors.rb +8 -0
- data/lib/castle/headers/extract.rb +1 -3
- data/lib/castle/headers/filter.rb +2 -3
- data/lib/castle/payload/prepare.rb +1 -2
- data/lib/castle/session.rb +1 -1
- data/lib/castle/version.rb +1 -1
- data/lib/castle.rb +1 -3
- data/spec/integration/rails/rails_spec.rb +9 -3
- data/spec/integration/rails/support/application.rb +2 -2
- data/spec/integration/rails/support/home_controller.rb +4 -30
- data/spec/lib/castle/api/approve_device_spec.rb +2 -6
- data/spec/lib/castle/api/authenticate_spec.rb +22 -25
- data/spec/lib/castle/api/end_impersonation_spec.rb +8 -14
- data/spec/lib/castle/api/get_device_spec.rb +1 -3
- data/spec/lib/castle/api/get_devices_for_user_spec.rb +1 -3
- data/spec/lib/castle/api/report_device_spec.rb +2 -6
- data/spec/lib/castle/api/start_impersonation_spec.rb +8 -14
- data/spec/lib/castle/api/track_spec.rb +9 -16
- data/spec/lib/castle/client_id/extract_spec.rb +2 -9
- data/spec/lib/castle/client_spec.rb +37 -78
- data/spec/lib/castle/command_spec.rb +3 -3
- data/spec/lib/castle/commands/approve_device_spec.rb +2 -2
- data/spec/lib/castle/commands/authenticate_spec.rb +17 -24
- data/spec/lib/castle/commands/end_impersonation_spec.rb +14 -21
- data/spec/lib/castle/commands/filter_spec.rb +15 -15
- data/spec/lib/castle/commands/get_device_spec.rb +2 -2
- data/spec/lib/castle/commands/get_devices_for_user_spec.rb +2 -2
- data/spec/lib/castle/commands/log_spec.rb +15 -15
- data/spec/lib/castle/commands/report_device_spec.rb +2 -2
- data/spec/lib/castle/commands/risk_spec.rb +15 -15
- data/spec/lib/castle/commands/start_impersonation_spec.rb +14 -21
- data/spec/lib/castle/commands/track_spec.rb +19 -24
- data/spec/lib/castle/configuration_spec.rb +1 -1
- data/spec/lib/castle/context/get_default_spec.rb +9 -8
- data/spec/lib/castle/context/prepare_spec.rb +3 -4
- data/spec/lib/castle/core/process_response_spec.rb +3 -6
- data/spec/lib/castle/core/process_webhook_spec.rb +12 -6
- data/spec/lib/castle/core/send_request_spec.rb +7 -11
- data/spec/lib/castle/failover/strategy_spec.rb +5 -5
- data/spec/lib/castle/headers/extract_spec.rb +1 -1
- data/spec/lib/castle/headers/filter_spec.rb +6 -3
- data/spec/lib/castle/headers/format_spec.rb +5 -5
- data/spec/lib/castle/ips/extract_spec.rb +2 -6
- data/spec/lib/castle/logger_spec.rb +2 -1
- data/spec/lib/castle/payload/prepare_spec.rb +4 -7
- data/spec/lib/castle/secure_mode_spec.rb +1 -3
- data/spec/lib/castle/session_spec.rb +1 -5
- data/spec/lib/castle/singleton_configuration_spec.rb +1 -1
- data/spec/lib/castle/utils/clone_spec.rb +1 -1
- data/spec/lib/castle/utils/merge_spec.rb +2 -4
- data/spec/lib/castle/validators/not_supported_spec.rb +1 -6
- data/spec/lib/castle/validators/present_spec.rb +2 -9
- data/spec/lib/castle/verdict_spec.rb +3 -3
- data/spec/lib/castle/webhooks/verify_spec.rb +12 -6
- data/spec/lib/castle_spec.rb +5 -7
- data/spec/support/shared_examples/action_request.rb +37 -25
- data/spec/support/shared_examples/configuration.rb +14 -16
- metadata +48 -48
@@ -4,16 +4,7 @@ class HomeController < ActionController::Base
|
|
4
4
|
# prepare context and calling track with client example
|
5
5
|
def index1
|
6
6
|
request_context = ::Castle::Context::Prepare.call(request)
|
7
|
-
payload = {
|
8
|
-
event: '$login.succeeded',
|
9
|
-
user_id: '123',
|
10
|
-
properties: {
|
11
|
-
key: 'value'
|
12
|
-
},
|
13
|
-
user_traits: {
|
14
|
-
key: 'value'
|
15
|
-
}
|
16
|
-
}
|
7
|
+
payload = { event: '$login.succeeded', user_id: '123', properties: { key: 'value' }, user_traits: { key: 'value' } }
|
17
8
|
client = ::Castle::Client.new(context: request_context)
|
18
9
|
client.track(payload)
|
19
10
|
|
@@ -24,16 +15,7 @@ class HomeController < ActionController::Base
|
|
24
15
|
def index2
|
25
16
|
payload =
|
26
17
|
::Castle::Payload::Prepare.call(
|
27
|
-
{
|
28
|
-
event: '$login.succeeded',
|
29
|
-
user_id: '123',
|
30
|
-
properties: {
|
31
|
-
key: 'value'
|
32
|
-
},
|
33
|
-
user_traits: {
|
34
|
-
key: 'value'
|
35
|
-
}
|
36
|
-
},
|
18
|
+
{ event: '$login.succeeded', user_id: '123', properties: { key: 'value' }, user_traits: { key: 'value' } },
|
37
19
|
request
|
38
20
|
)
|
39
21
|
client = ::Castle::Client.new
|
@@ -46,18 +28,10 @@ class HomeController < ActionController::Base
|
|
46
28
|
def index3
|
47
29
|
payload =
|
48
30
|
::Castle::Payload::Prepare.call(
|
49
|
-
{
|
50
|
-
event: '$login.succeeded',
|
51
|
-
user_id: '123',
|
52
|
-
properties: {
|
53
|
-
key: 'value'
|
54
|
-
},
|
55
|
-
user_traits: {
|
56
|
-
key: 'value'
|
57
|
-
}
|
58
|
-
},
|
31
|
+
{ event: '$login.succeeded', user_id: '123', properties: { key: 'value' }, user_traits: { key: 'value' } },
|
59
32
|
request
|
60
33
|
)
|
34
|
+
|
61
35
|
Castle::API::Track.call(payload)
|
62
36
|
|
63
37
|
render inline: 'hello'
|
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
describe Castle::API::ApproveDevice do
|
4
4
|
before do
|
5
|
-
stub_request(:any, /api.castle.io/)
|
6
|
-
.with(basic_auth: ['', 'secret'])
|
7
|
-
.to_return(status: 200, body: '{}', headers: {})
|
5
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(status: 200, body: '{}', headers: {})
|
8
6
|
end
|
9
7
|
|
10
8
|
describe '.call' do
|
@@ -14,8 +12,6 @@ describe Castle::API::ApproveDevice do
|
|
14
12
|
|
15
13
|
before { retrieve }
|
16
14
|
|
17
|
-
it
|
18
|
-
assert_requested :put, "https://api.castle.io/v1/devices/#{device_token}/approve", times: 1
|
19
|
-
end
|
15
|
+
it { assert_requested :put, "https://api.castle.io/v1/devices/#{device_token}/approve", times: 1 }
|
20
16
|
end
|
21
17
|
end
|
@@ -29,15 +29,16 @@ describe Castle::API::Authenticate do
|
|
29
29
|
after { Timecop.return }
|
30
30
|
|
31
31
|
describe '.call' do
|
32
|
-
let(:request_body)
|
33
|
-
{ event: '$login.succeeded', context: context, user_id: '1234', sent_at: time_auto }
|
34
|
-
end
|
32
|
+
let(:request_body) { { event: '$login.succeeded', context: context, user_id: '1234', sent_at: time_auto } }
|
35
33
|
|
36
34
|
context 'when used with symbol keys' do
|
37
35
|
before do
|
38
|
-
stub_request(:any, /api.castle.io/)
|
39
|
-
|
40
|
-
|
36
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(
|
37
|
+
status: 200,
|
38
|
+
body: response_body,
|
39
|
+
headers: {
|
40
|
+
}
|
41
|
+
)
|
41
42
|
call_subject
|
42
43
|
end
|
43
44
|
|
@@ -50,17 +51,9 @@ describe Castle::API::Authenticate do
|
|
50
51
|
end
|
51
52
|
|
52
53
|
context 'when passed timestamp in options and no defined timestamp' do
|
53
|
-
let(:options)
|
54
|
-
{ event: '$login.succeeded', user_id: '1234', timestamp: time_user, context: context }
|
55
|
-
end
|
54
|
+
let(:options) { { event: '$login.succeeded', user_id: '1234', timestamp: time_user, context: context } }
|
56
55
|
let(:request_body) do
|
57
|
-
{
|
58
|
-
event: '$login.succeeded',
|
59
|
-
user_id: '1234',
|
60
|
-
context: context,
|
61
|
-
timestamp: time_user,
|
62
|
-
sent_at: time_auto
|
63
|
-
}
|
56
|
+
{ event: '$login.succeeded', user_id: '1234', context: context, timestamp: time_user, sent_at: time_auto }
|
64
57
|
end
|
65
58
|
|
66
59
|
it do
|
@@ -78,15 +71,16 @@ describe Castle::API::Authenticate do
|
|
78
71
|
|
79
72
|
context 'when denied without any risk policy' do
|
80
73
|
let(:response_body) { deny_response_without_rp.to_json }
|
81
|
-
let(:deny_response_without_rp)
|
82
|
-
{ action: 'deny', user_id: '12345', device_token: 'abcdefg1234' }
|
83
|
-
end
|
74
|
+
let(:deny_response_without_rp) { { action: 'deny', user_id: '12345', device_token: 'abcdefg1234' } }
|
84
75
|
let(:deny_without_rp_failover_result) { deny_response_without_rp.merge(failover_appendix) }
|
85
76
|
|
86
77
|
before do
|
87
|
-
stub_request(:any, /api.castle.io/)
|
88
|
-
|
89
|
-
|
78
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(
|
79
|
+
status: 200,
|
80
|
+
body: deny_response_without_rp.to_json,
|
81
|
+
headers: {
|
82
|
+
}
|
83
|
+
)
|
90
84
|
call_subject
|
91
85
|
end
|
92
86
|
|
@@ -117,9 +111,12 @@ describe Castle::API::Authenticate do
|
|
117
111
|
let(:deny_with_rp_failover_result) { deny_response_with_rp.merge(failover_appendix) }
|
118
112
|
|
119
113
|
before do
|
120
|
-
stub_request(:any, /api.castle.io/)
|
121
|
-
|
122
|
-
|
114
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(
|
115
|
+
status: 200,
|
116
|
+
body: deny_response_with_rp.to_json,
|
117
|
+
headers: {
|
118
|
+
}
|
119
|
+
)
|
123
120
|
call_subject
|
124
121
|
end
|
125
122
|
|
@@ -22,9 +22,12 @@ describe Castle::API::EndImpersonation do
|
|
22
22
|
before do
|
23
23
|
Timecop.freeze(time_now)
|
24
24
|
stub_const('Castle::VERSION', '2.2.0')
|
25
|
-
stub_request(:any, /api.castle.io/)
|
26
|
-
|
27
|
-
|
25
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(
|
26
|
+
status: 200,
|
27
|
+
body: response_body,
|
28
|
+
headers: {
|
29
|
+
}
|
30
|
+
)
|
28
31
|
end
|
29
32
|
|
30
33
|
after { Timecop.return }
|
@@ -32,19 +35,10 @@ describe Castle::API::EndImpersonation do
|
|
32
35
|
describe 'call' do
|
33
36
|
let(:impersonator) { 'test@castle.io' }
|
34
37
|
let(:request_body) do
|
35
|
-
{
|
36
|
-
user_id: '1234',
|
37
|
-
sent_at: time_auto,
|
38
|
-
properties: {
|
39
|
-
impersonator: impersonator
|
40
|
-
},
|
41
|
-
context: context
|
42
|
-
}
|
38
|
+
{ user_id: '1234', sent_at: time_auto, properties: { impersonator: impersonator }, context: context }
|
43
39
|
end
|
44
40
|
let(:response_body) { { success: true }.to_json }
|
45
|
-
let(:options)
|
46
|
-
{ user_id: '1234', properties: { impersonator: impersonator }, context: context }
|
47
|
-
end
|
41
|
+
let(:options) { { user_id: '1234', properties: { impersonator: impersonator }, context: context } }
|
48
42
|
|
49
43
|
context 'when used with symbol keys' do
|
50
44
|
before { call }
|
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
describe Castle::API::GetDevice do
|
4
4
|
before do
|
5
|
-
stub_request(:any, /api.castle.io/)
|
6
|
-
.with(basic_auth: ['', 'secret'])
|
7
|
-
.to_return(status: 200, body: '{}', headers: {})
|
5
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(status: 200, body: '{}', headers: {})
|
8
6
|
end
|
9
7
|
|
10
8
|
describe '.call' do
|
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
describe Castle::API::GetDevicesForUser do
|
4
4
|
before do
|
5
|
-
stub_request(:any, /api.castle.io/)
|
6
|
-
.with(basic_auth: ['', 'secret'])
|
7
|
-
.to_return(status: 200, body: '{}', headers: {})
|
5
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(status: 200, body: '{}', headers: {})
|
8
6
|
end
|
9
7
|
|
10
8
|
describe '.call' do
|
@@ -2,9 +2,7 @@
|
|
2
2
|
|
3
3
|
describe Castle::API::ReportDevice do
|
4
4
|
before do
|
5
|
-
stub_request(:any, /api.castle.io/)
|
6
|
-
.with(basic_auth: ['', 'secret'])
|
7
|
-
.to_return(status: 200, body: '{}', headers: {})
|
5
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(status: 200, body: '{}', headers: {})
|
8
6
|
end
|
9
7
|
|
10
8
|
describe '.call' do
|
@@ -14,8 +12,6 @@ describe Castle::API::ReportDevice do
|
|
14
12
|
|
15
13
|
before { retrieve }
|
16
14
|
|
17
|
-
it
|
18
|
-
assert_requested :put, "https://api.castle.io/v1/devices/#{device_token}/report", times: 1
|
19
|
-
end
|
15
|
+
it { assert_requested :put, "https://api.castle.io/v1/devices/#{device_token}/report", times: 1 }
|
20
16
|
end
|
21
17
|
end
|
@@ -22,9 +22,12 @@ describe Castle::API::StartImpersonation do
|
|
22
22
|
before do
|
23
23
|
Timecop.freeze(time_now)
|
24
24
|
stub_const('Castle::VERSION', '2.2.0')
|
25
|
-
stub_request(:any, /api.castle.io/)
|
26
|
-
|
27
|
-
|
25
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(
|
26
|
+
status: 200,
|
27
|
+
body: response_body,
|
28
|
+
headers: {
|
29
|
+
}
|
30
|
+
)
|
28
31
|
end
|
29
32
|
|
30
33
|
after { Timecop.return }
|
@@ -32,19 +35,10 @@ describe Castle::API::StartImpersonation do
|
|
32
35
|
describe 'call' do
|
33
36
|
let(:impersonator) { 'test@castle.io' }
|
34
37
|
let(:request_body) do
|
35
|
-
{
|
36
|
-
user_id: '1234',
|
37
|
-
sent_at: time_auto,
|
38
|
-
properties: {
|
39
|
-
impersonator: impersonator
|
40
|
-
},
|
41
|
-
context: context
|
42
|
-
}
|
38
|
+
{ user_id: '1234', sent_at: time_auto, properties: { impersonator: impersonator }, context: context }
|
43
39
|
end
|
44
40
|
let(:response_body) { { success: true }.to_json }
|
45
|
-
let(:options)
|
46
|
-
{ user_id: '1234', properties: { impersonator: impersonator }, context: context }
|
47
|
-
end
|
41
|
+
let(:options) { { user_id: '1234', properties: { impersonator: impersonator }, context: context } }
|
48
42
|
|
49
43
|
context 'when used with symbol keys' do
|
50
44
|
before { call }
|
@@ -24,17 +24,18 @@ describe Castle::API::Track do
|
|
24
24
|
before do
|
25
25
|
Timecop.freeze(time_now)
|
26
26
|
stub_const('Castle::VERSION', '2.2.0')
|
27
|
-
stub_request(:any, /api.castle.io/)
|
28
|
-
|
29
|
-
|
27
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(
|
28
|
+
status: 200,
|
29
|
+
body: response_body,
|
30
|
+
headers: {
|
31
|
+
}
|
32
|
+
)
|
30
33
|
end
|
31
34
|
|
32
35
|
after { Timecop.return }
|
33
36
|
|
34
37
|
describe 'track' do
|
35
|
-
let(:request_body)
|
36
|
-
{ event: '$login.succeeded', context: context, user_id: '1234', sent_at: time_auto }
|
37
|
-
end
|
38
|
+
let(:request_body) { { event: '$login.succeeded', context: context, user_id: '1234', sent_at: time_auto } }
|
38
39
|
|
39
40
|
before { call }
|
40
41
|
|
@@ -48,17 +49,9 @@ describe Castle::API::Track do
|
|
48
49
|
end
|
49
50
|
|
50
51
|
context 'when passed timestamp in options and no defined timestamp' do
|
51
|
-
let(:options)
|
52
|
-
{ event: '$login.succeeded', user_id: '1234', timestamp: time_user, context: context }
|
53
|
-
end
|
52
|
+
let(:options) { { event: '$login.succeeded', user_id: '1234', timestamp: time_user, context: context } }
|
54
53
|
let(:request_body) do
|
55
|
-
{
|
56
|
-
event: '$login.succeeded',
|
57
|
-
user_id: '1234',
|
58
|
-
context: context,
|
59
|
-
timestamp: time_user,
|
60
|
-
sent_at: time_auto
|
61
|
-
}
|
54
|
+
{ event: '$login.succeeded', user_id: '1234', context: context, timestamp: time_user, sent_at: time_auto }
|
62
55
|
end
|
63
56
|
|
64
57
|
it do
|
@@ -11,20 +11,13 @@ describe Castle::ClientId::Extract do
|
|
11
11
|
let(:env) { Rack::MockRequest.env_for('/', headers) }
|
12
12
|
|
13
13
|
context 'with client_id' do
|
14
|
-
let(:headers)
|
15
|
-
{
|
16
|
-
'HTTP_X_FORWARDED_FOR' => '1.2.3.4',
|
17
|
-
'HTTP_COOKIE' => "__cid=#{client_id_cookie};other=efgh"
|
18
|
-
}
|
19
|
-
end
|
14
|
+
let(:headers) { { 'HTTP_X_FORWARDED_FOR' => '1.2.3.4', 'HTTP_COOKIE' => "__cid=#{client_id_cookie};other=efgh" } }
|
20
15
|
|
21
16
|
it { expect(extractor.call).to eql(client_id_cookie) }
|
22
17
|
end
|
23
18
|
|
24
19
|
context 'with X-Castle-Client-Id header' do
|
25
|
-
let(:headers)
|
26
|
-
{ 'HTTP_X_FORWARDED_FOR' => '1.2.3.4', 'HTTP_X_CASTLE_CLIENT_ID' => client_id_header }
|
27
|
-
end
|
20
|
+
let(:headers) { { 'HTTP_X_FORWARDED_FOR' => '1.2.3.4', 'HTTP_X_CASTLE_CLIENT_ID' => client_id_header } }
|
28
21
|
|
29
22
|
it 'appends the client_id' do
|
30
23
|
expect(extractor.call).to eql(client_id_header)
|
@@ -9,20 +9,17 @@ describe Castle::Client do
|
|
9
9
|
'/',
|
10
10
|
'HTTP_USER_AGENT' => ua,
|
11
11
|
'HTTP_X_FORWARDED_FOR' => ip,
|
12
|
-
'HTTP_COOKIE' => "__cid=#{cookie_id};other=efgh"
|
12
|
+
'HTTP_COOKIE' => "__cid=#{cookie_id};other=efgh",
|
13
|
+
'HTTP_CONTENT_LENGTH' => '0'
|
13
14
|
)
|
14
15
|
end
|
15
16
|
let(:request) { Rack::Request.new(env) }
|
16
17
|
let(:client) { described_class.from_request(request) }
|
17
18
|
let(:request_to_context) { Castle::Context::Prepare.call(request) }
|
18
|
-
let(:client_with_user_timestamp)
|
19
|
-
described_class.new(context: request_to_context, timestamp: time_user)
|
20
|
-
end
|
19
|
+
let(:client_with_user_timestamp) { described_class.new(context: request_to_context, timestamp: time_user) }
|
21
20
|
let(:client_with_no_timestamp) { described_class.new(context: request_to_context) }
|
22
21
|
|
23
|
-
let(:headers)
|
24
|
-
{ 'Content-Length': '0', 'User-Agent': ua, 'X-Forwarded-For': ip.to_s, 'Cookie': true }
|
25
|
-
end
|
22
|
+
let(:headers) { { 'Content-Length': '0', 'User-Agent': ua, 'X-Forwarded-For': ip.to_s, Cookie: true } }
|
26
23
|
let(:context) do
|
27
24
|
{
|
28
25
|
client_id: 'abcd',
|
@@ -41,13 +38,21 @@ describe Castle::Client do
|
|
41
38
|
let(:time_auto) { time_now.utc.iso8601(3) }
|
42
39
|
let(:time_user) { (Time.now - 10_000).utc.iso8601(3) }
|
43
40
|
let(:response_body) { {}.to_json }
|
41
|
+
let(:response_code) { 200 }
|
42
|
+
|
43
|
+
let(:stub_response) do
|
44
|
+
stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return(
|
45
|
+
status: response_code,
|
46
|
+
body: response_body,
|
47
|
+
headers: {
|
48
|
+
}
|
49
|
+
)
|
50
|
+
end
|
44
51
|
|
45
52
|
before do
|
46
53
|
Timecop.freeze(time_now)
|
47
54
|
stub_const('Castle::VERSION', '2.2.0')
|
48
|
-
|
49
|
-
.with(basic_auth: ['', 'secret'])
|
50
|
-
.to_return(status: 200, body: response_body, headers: {})
|
55
|
+
stub_response
|
51
56
|
end
|
52
57
|
|
53
58
|
after { Timecop.return }
|
@@ -90,9 +95,7 @@ describe Castle::Client do
|
|
90
95
|
context 'when request is not successful' do
|
91
96
|
let(:response_body) { {}.to_json }
|
92
97
|
|
93
|
-
it
|
94
|
-
expect { client.end_impersonation(options) }.to raise_error(Castle::ImpersonationFailed)
|
95
|
-
end
|
98
|
+
it { expect { client.end_impersonation(options) }.to raise_error(Castle::ImpersonationFailed) }
|
96
99
|
end
|
97
100
|
end
|
98
101
|
|
@@ -125,9 +128,7 @@ describe Castle::Client do
|
|
125
128
|
context 'when request is not successful' do
|
126
129
|
let(:response_body) { {}.to_json }
|
127
130
|
|
128
|
-
it
|
129
|
-
expect { client.start_impersonation(options) }.to raise_error(Castle::ImpersonationFailed)
|
130
|
-
end
|
131
|
+
it { expect { client.start_impersonation(options) }.to raise_error(Castle::ImpersonationFailed) }
|
131
132
|
end
|
132
133
|
end
|
133
134
|
|
@@ -135,13 +136,7 @@ describe Castle::Client do
|
|
135
136
|
let(:options) { { event: '$login.succeeded', user_id: '1234' } }
|
136
137
|
let(:request_response) { client.authenticate(options) }
|
137
138
|
let(:request_body) do
|
138
|
-
{
|
139
|
-
event: '$login.succeeded',
|
140
|
-
user_id: '1234',
|
141
|
-
context: context,
|
142
|
-
timestamp: time_auto,
|
143
|
-
sent_at: time_auto
|
144
|
-
}
|
139
|
+
{ event: '$login.succeeded', user_id: '1234', context: context, timestamp: time_auto, sent_at: time_auto }
|
145
140
|
end
|
146
141
|
|
147
142
|
context 'when used with symbol keys' do
|
@@ -157,13 +152,7 @@ describe Castle::Client do
|
|
157
152
|
let(:client) { client_with_no_timestamp }
|
158
153
|
let(:options) { { event: '$login.succeeded', user_id: '1234', timestamp: time_user } }
|
159
154
|
let(:request_body) do
|
160
|
-
{
|
161
|
-
event: '$login.succeeded',
|
162
|
-
user_id: '1234',
|
163
|
-
context: context,
|
164
|
-
timestamp: time_user,
|
165
|
-
sent_at: time_auto
|
166
|
-
}
|
155
|
+
{ event: '$login.succeeded', user_id: '1234', context: context, timestamp: time_user, sent_at: time_auto }
|
167
156
|
end
|
168
157
|
|
169
158
|
it do
|
@@ -176,13 +165,7 @@ describe Castle::Client do
|
|
176
165
|
context 'with client initialized with timestamp' do
|
177
166
|
let(:client) { client_with_user_timestamp }
|
178
167
|
let(:request_body) do
|
179
|
-
{
|
180
|
-
event: '$login.succeeded',
|
181
|
-
user_id: '1234',
|
182
|
-
context: context,
|
183
|
-
timestamp: time_user,
|
184
|
-
sent_at: time_auto
|
185
|
-
}
|
168
|
+
{ event: '$login.succeeded', user_id: '1234', context: context, timestamp: time_user, sent_at: time_auto }
|
186
169
|
end
|
187
170
|
|
188
171
|
it do
|
@@ -225,19 +208,15 @@ describe Castle::Client do
|
|
225
208
|
end
|
226
209
|
|
227
210
|
it { assert_not_requested :post, 'https://api.castle.io/v1/authenticate' }
|
228
|
-
it { expect(request_response[:policy][:action]).to
|
229
|
-
it { expect(request_response[:action]).to
|
230
|
-
it { expect(request_response[:user_id]).to
|
211
|
+
it { expect(request_response[:policy][:action]).to eql(Castle::Verdict::ALLOW) }
|
212
|
+
it { expect(request_response[:action]).to eql(Castle::Verdict::ALLOW) }
|
213
|
+
it { expect(request_response[:user_id]).to eql('1234') }
|
231
214
|
it { expect(request_response[:failover]).to be true }
|
232
|
-
it { expect(request_response[:failover_reason]).to
|
215
|
+
it { expect(request_response[:failover_reason]).to eql('Castle is set to do not track.') }
|
233
216
|
end
|
234
217
|
|
235
218
|
context 'when request with fail' do
|
236
|
-
before
|
237
|
-
allow(Castle::API).to receive(:send_request).and_raise(
|
238
|
-
Castle::RequestError.new(Timeout::Error)
|
239
|
-
)
|
240
|
-
end
|
219
|
+
before { allow(Castle::API).to receive(:send_request).and_raise(Castle::RequestError.new(Timeout::Error)) }
|
241
220
|
|
242
221
|
context 'with request error and throw strategy' do
|
243
222
|
before { allow(Castle.config).to receive(:failover_strategy).and_return(:throw) }
|
@@ -247,18 +226,16 @@ describe Castle::Client do
|
|
247
226
|
|
248
227
|
context 'with request error and not throw on eg deny strategy' do
|
249
228
|
it { assert_not_requested :post, 'https://:secret@api.castle.io/v1/authenticate' }
|
250
|
-
it { expect(request_response[:policy][:action]).to
|
251
|
-
it { expect(request_response[:action]).to
|
252
|
-
it { expect(request_response[:user_id]).to
|
229
|
+
it { expect(request_response[:policy][:action]).to eql('allow') }
|
230
|
+
it { expect(request_response[:action]).to eql('allow') }
|
231
|
+
it { expect(request_response[:user_id]).to eql('1234') }
|
253
232
|
it { expect(request_response[:failover]).to be true }
|
254
|
-
it { expect(request_response[:failover_reason]).to
|
233
|
+
it { expect(request_response[:failover_reason]).to eql('Castle::RequestError') }
|
255
234
|
end
|
256
235
|
end
|
257
236
|
|
258
237
|
context 'when request is internal server error' do
|
259
|
-
before
|
260
|
-
allow(Castle::API).to receive(:send_request).and_raise(Castle::InternalServerError)
|
261
|
-
end
|
238
|
+
before { allow(Castle::API).to receive(:send_request).and_raise(Castle::InternalServerError) }
|
262
239
|
|
263
240
|
describe 'throw strategy' do
|
264
241
|
before { allow(Castle.config).to receive(:failover_strategy).and_return(:throw) }
|
@@ -268,24 +245,18 @@ describe Castle::Client do
|
|
268
245
|
|
269
246
|
describe 'not throw on eg deny strategy' do
|
270
247
|
it { assert_not_requested :post, 'https://:secret@api.castle.io/v1/authenticate' }
|
271
|
-
it { expect(request_response[:policy][:action]).to
|
272
|
-
it { expect(request_response[:action]).to
|
273
|
-
it { expect(request_response[:user_id]).to
|
248
|
+
it { expect(request_response[:policy][:action]).to eql('allow') }
|
249
|
+
it { expect(request_response[:action]).to eql('allow') }
|
250
|
+
it { expect(request_response[:user_id]).to eql('1234') }
|
274
251
|
it { expect(request_response[:failover]).to be true }
|
275
|
-
it { expect(request_response[:failover_reason]).to
|
252
|
+
it { expect(request_response[:failover_reason]).to eql('Castle::InternalServerError') }
|
276
253
|
end
|
277
254
|
end
|
278
255
|
end
|
279
256
|
|
280
257
|
describe 'track' do
|
281
258
|
let(:request_body) do
|
282
|
-
{
|
283
|
-
event: '$login.succeeded',
|
284
|
-
context: context,
|
285
|
-
user_id: '1234',
|
286
|
-
timestamp: time_auto,
|
287
|
-
sent_at: time_auto
|
288
|
-
}
|
259
|
+
{ event: '$login.succeeded', context: context, user_id: '1234', timestamp: time_auto, sent_at: time_auto }
|
289
260
|
end
|
290
261
|
|
291
262
|
before { client.track(options) }
|
@@ -303,13 +274,7 @@ describe Castle::Client do
|
|
303
274
|
let(:client) { client_with_no_timestamp }
|
304
275
|
let(:options) { { event: '$login.succeeded', user_id: '1234', timestamp: time_user } }
|
305
276
|
let(:request_body) do
|
306
|
-
{
|
307
|
-
event: '$login.succeeded',
|
308
|
-
user_id: '1234',
|
309
|
-
context: context,
|
310
|
-
timestamp: time_user,
|
311
|
-
sent_at: time_auto
|
312
|
-
}
|
277
|
+
{ event: '$login.succeeded', user_id: '1234', context: context, timestamp: time_user, sent_at: time_auto }
|
313
278
|
end
|
314
279
|
|
315
280
|
it do
|
@@ -322,13 +287,7 @@ describe Castle::Client do
|
|
322
287
|
context 'with client initialized with timestamp' do
|
323
288
|
let(:client) { client_with_user_timestamp }
|
324
289
|
let(:request_body) do
|
325
|
-
{
|
326
|
-
event: '$login.succeeded',
|
327
|
-
context: context,
|
328
|
-
user_id: '1234',
|
329
|
-
timestamp: time_user,
|
330
|
-
sent_at: time_auto
|
331
|
-
}
|
290
|
+
{ event: '$login.succeeded', context: context, user_id: '1234', timestamp: time_user, sent_at: time_auto }
|
332
291
|
end
|
333
292
|
|
334
293
|
it do
|
@@ -3,7 +3,7 @@
|
|
3
3
|
describe Castle::Command do
|
4
4
|
subject(:command) { described_class.new('go', { id: '1' }, :post) }
|
5
5
|
|
6
|
-
it { expect(command.path).to
|
7
|
-
it { expect(command.data).to
|
8
|
-
it { expect(command.method).to
|
6
|
+
it { expect(command.path).to eql('go') }
|
7
|
+
it { expect(command.data).to eql(id: '1') }
|
8
|
+
it { expect(command.method).to be(:post) }
|
9
9
|
end
|
@@ -16,8 +16,8 @@ describe Castle::Commands::ApproveDevice do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
context 'with device_token' do
|
19
|
-
it { expect(command.method).to
|
20
|
-
it { expect(command.path).to
|
19
|
+
it { expect(command.method).to be(:put) }
|
20
|
+
it { expect(command.path).to eql("devices/#{device_token}/approve") }
|
21
21
|
it { expect(command.data).to be_nil }
|
22
22
|
end
|
23
23
|
end
|