castle-rb 5.0.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +107 -33
- data/lib/castle.rb +46 -22
- data/lib/castle/api.rb +22 -13
- 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 +48 -62
- 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 +17 -19
- 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/{extractors/headers.rb → headers/extract.rb} +8 -6
- data/lib/castle/headers/filter.rb +37 -0
- data/lib/castle/headers/format.rb +24 -0
- data/lib/castle/{extractors/ip.rb → ip/extract.rb} +8 -7
- 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 +39 -21
- 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} +7 -32
- 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/{api/connection_spec.rb → core/get_connection_spec.rb} +3 -3
- 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/{api/request_spec.rb → core/send_request_spec.rb} +20 -16
- data/spec/lib/castle/failover/strategy_spec.rb +12 -0
- data/spec/lib/castle/{extractors/headers_spec.rb → headers/extract_spec.rb} +7 -7
- data/spec/lib/castle/{headers_filter_spec.rb → headers/filter_spec.rb} +3 -3
- data/spec/lib/castle/headers/format_spec.rb +25 -0
- data/spec/lib/castle/{extractors/ip_spec.rb → ip/extract_spec.rb} +1 -1
- data/spec/lib/castle/logger_spec.rb +42 -0
- data/spec/lib/castle/payload/prepare_spec.rb +54 -0
- data/spec/lib/castle/{api/session_spec.rb → session_spec.rb} +6 -4
- 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 +129 -57
- data/lib/castle/api/connection.rb +0 -24
- data/lib/castle/api/request.rb +0 -42
- data/lib/castle/api/session.rb +0 -20
- data/lib/castle/commands/impersonate.rb +0 -26
- 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/headers_formatter_spec.rb +0 -25
- data/spec/lib/castle/utils_spec.rb +0 -156
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e4354fd7a96d78e03da9bbe10015e375af34636a2e5e186c4de361d0851a6ca
|
4
|
+
data.tar.gz: 15c6bbf6f34ba315b5f42db490754a92e238f66a006a91e3986b9b1ba540d47a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7bb580056e70ed854014054791ef5987874e52b2471838605a90092f70269ba095d40ef5df5310636b0fbd652dfa9460bb95a314e6e2dae5074732672c77122b
|
7
|
+
data.tar.gz: 22fb6013ec018e8c983ecf8051041eb62f69f4b54f73528f185f783ab2343e23f5504e3d420143fb3a19f0f49e094a2d56c2fc873411d697b95be645b7cefb47
|
data/README.md
CHANGED
@@ -62,8 +62,14 @@ Castle.configure do |config|
|
|
62
62
|
# For authenticate method you can set failover strategies: allow(default), deny, challenge, throw
|
63
63
|
config.failover_strategy = :deny
|
64
64
|
|
65
|
-
# Castle::RequestError is raised when timing out in milliseconds (default:
|
66
|
-
config.request_timeout =
|
65
|
+
# Castle::RequestError is raised when timing out in milliseconds (default: 1000 milliseconds)
|
66
|
+
config.request_timeout = 1500
|
67
|
+
|
68
|
+
# Base Castle API url
|
69
|
+
# config.base_url = "https://api.castle.io/v1"
|
70
|
+
|
71
|
+
# Logger (need to respond to info method) - logs Castle API requests and responses
|
72
|
+
# config.logger = Logger.new(STDOUT)
|
67
73
|
|
68
74
|
# Allowlisted and Denylisted headers are case insensitive and allow to use _ and - as a separator, http prefixes are removed
|
69
75
|
# Allowlisted headers
|
@@ -95,13 +101,14 @@ Castle.configure do |config|
|
|
95
101
|
# Sometimes, Cloud providers do not use consistent IP addresses to proxy requests.
|
96
102
|
# In this case, the client IP is usually preserved in a custom header. Example:
|
97
103
|
# Cloudflare preserves the client request in the 'Cf-Connecting-Ip' header.
|
98
|
-
# It would be used like so:
|
99
|
-
|
104
|
+
# It would be used like so: config.ip_headers=['Cf-Connecting-Ip']
|
105
|
+
config.ip_headers = []
|
100
106
|
|
101
107
|
# If the specified header or X-Forwarded-For default contains a proxy chain with public IP addresses,
|
102
|
-
# then one of the following
|
103
|
-
# 1. The trusted_proxies value must match the known proxy IP
|
104
|
-
# 2. The trusted_proxy_depth value must be set to the number of known trusted proxies in the chain (see below)
|
108
|
+
# then you must choose only one of the following (but not both):
|
109
|
+
# 1. The trusted_proxies value must match the known proxy IPs. This option is preferable if the IP is static.
|
110
|
+
# 2. The trusted_proxy_depth value must be set to the number of known trusted proxies in the chain (see below).
|
111
|
+
# This option is preferable if the IPs are ephemeral, but the depth is consistent.
|
105
112
|
|
106
113
|
# Additionally to make X-Forwarded-For and other headers work better discovering client ip address,
|
107
114
|
# and not the address of a reverse proxy server, you can define trusted proxies
|
@@ -110,29 +117,48 @@ Castle.configure do |config|
|
|
110
117
|
# In order to extract the client IP of the X-Forwarded-For header
|
111
118
|
# and not the address of a reverse proxy server, you must define all trusted public proxies
|
112
119
|
# you can achieve this by listing all the proxies ip defined by string or regular expressions
|
113
|
-
# in trusted_proxies setting
|
114
|
-
|
120
|
+
# in the trusted_proxies setting
|
121
|
+
config.trusted_proxies = []
|
115
122
|
# or by providing number of trusted proxies used in the chain
|
116
|
-
|
123
|
+
config.trusted_proxy_depth = 0
|
124
|
+
# note that you must pick one approach over the other.
|
117
125
|
|
118
|
-
# If there is no possibility to define options above and there is no other header
|
119
|
-
# then you may set trust_proxy_chain = true to trust all of the proxy
|
120
|
-
|
126
|
+
# If there is no possibility to define options above and there is no other header that holds the client IP,
|
127
|
+
# then you may set trust_proxy_chain = true to trust all of the proxy IPs in X-Forwarded-For
|
128
|
+
config.trust_proxy_chain = false
|
129
|
+
# *Warning*: this mode is highly promiscuous and could lead to wrongly trusting a spoofed IP if the request passes through a malicious proxy
|
121
130
|
|
122
|
-
# *Note: default list of proxies
|
131
|
+
# *Note: the default list of proxies that are always marked as "trusted" can be found in: Castle::Configuration::TRUSTED_PROXIES
|
123
132
|
end
|
124
133
|
```
|
125
134
|
|
135
|
+
### Multi-environment configuration
|
136
|
+
|
137
|
+
It is also possible to define multiple configs within one application.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
# Initialize new instance of Castle::Configuration
|
141
|
+
config = Castle::Configuration.new.tap do |c|
|
142
|
+
# and set any attribute
|
143
|
+
c.api_secret = 'YOUR_API_SECRET'
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
After a successful setup, you can pass the config to any API command as follows:
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
::Castle::API::GetDevice.call(device_token: device_token, config: config)
|
151
|
+
```
|
152
|
+
|
126
153
|
## Event Context
|
127
154
|
|
128
155
|
The client will automatically configure the context for each request.
|
129
156
|
|
130
157
|
### Overriding Default Context Properties
|
131
158
|
|
132
|
-
If you need to modify the event context properties or if you desire to add additional properties such as user traits to the context, you can pass the properties
|
159
|
+
If you need to modify the event context properties or if you desire to add additional properties such as user traits to the context, you can pass the properties along with the other data. For example:
|
133
160
|
```ruby
|
134
|
-
|
135
|
-
track_options = ::Castle::Client.to_options({
|
161
|
+
{
|
136
162
|
event: ::Castle::Events::LOGIN_SUCCEEDED,
|
137
163
|
user_id: user.id,
|
138
164
|
properties: {
|
@@ -140,8 +166,11 @@ track_options = ::Castle::Client.to_options({
|
|
140
166
|
},
|
141
167
|
user_traits: {
|
142
168
|
key: 'value'
|
169
|
+
},
|
170
|
+
context: {
|
171
|
+
section: 'mobile'
|
143
172
|
}
|
144
|
-
}
|
173
|
+
}
|
145
174
|
```
|
146
175
|
|
147
176
|
## Tracking
|
@@ -173,9 +202,8 @@ By default Castle sends requests synchronously. To eg. use Sidekiq to send reque
|
|
173
202
|
class CastleTrackingWorker
|
174
203
|
include Sidekiq::Worker
|
175
204
|
|
176
|
-
def perform(
|
177
|
-
|
178
|
-
client.track(track_options)
|
205
|
+
def perform(payload = {})
|
206
|
+
::Castle::API::Track.call(payload)
|
179
207
|
end
|
180
208
|
end
|
181
209
|
```
|
@@ -183,18 +211,20 @@ end
|
|
183
211
|
#### tracking_controller.rb
|
184
212
|
|
185
213
|
```ruby
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
214
|
+
payload = ::Castle::Payload::Prepare.call(
|
215
|
+
{
|
216
|
+
event: ::Castle::Events::LOGIN_SUCCEEDED,
|
217
|
+
user_id: user.id,
|
218
|
+
properties: {
|
219
|
+
key: 'value'
|
220
|
+
},
|
221
|
+
user_traits: {
|
222
|
+
key: 'value'
|
223
|
+
}
|
192
224
|
},
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
})
|
197
|
-
CastleTrackingWorker.perform_async(request_context, track_options)
|
225
|
+
request
|
226
|
+
)
|
227
|
+
CastleTrackingWorker.perform_async(payload)
|
198
228
|
```
|
199
229
|
|
200
230
|
## Connection reuse
|
@@ -202,7 +232,7 @@ CastleTrackingWorker.perform_async(request_context, track_options)
|
|
202
232
|
If you want to reuse the connection to send multiple events:
|
203
233
|
|
204
234
|
```ruby
|
205
|
-
Castle::
|
235
|
+
Castle::Session.call do |http|
|
206
236
|
castle.track(
|
207
237
|
event: ::Castle::Events::LOGOUT_SUCCEEDED,
|
208
238
|
user_id: user2.id
|
@@ -220,6 +250,40 @@ end
|
|
220
250
|
|
221
251
|
List of Recognized Events can be found [here](https://github.com/castle/castle-ruby/tree/master/lib/castle/events.rb) or in the [docs](https://docs.castle.io/api_reference/#list-of-recognized-events)
|
222
252
|
|
253
|
+
## Device management
|
254
|
+
|
255
|
+
This SDK allows issuing requests to [Castle's Device Management Endpoints](https://docs.castle.io/device_management_tool/). Use these endpoints for admin-level management of end-user devices (i.e., for an internal dashboard).
|
256
|
+
|
257
|
+
Fetching device data, approving a device, reporting a device requires a valid `device_token`.
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
# Get device data
|
261
|
+
::Castle::API::GetDevice.call(device_token: device_token)
|
262
|
+
# Approve a device
|
263
|
+
::Castle::API::ApproveDevice.call(device_token: device_token)
|
264
|
+
# Report a device
|
265
|
+
::Castle::API::ReportDevice.call(device_token: device_token)
|
266
|
+
```
|
267
|
+
|
268
|
+
#### castle_device_reporting_worker.rb
|
269
|
+
|
270
|
+
```ruby
|
271
|
+
class CastleDeviceReportingWorker
|
272
|
+
include Sidekiq::Worker
|
273
|
+
|
274
|
+
def perform(device_token)
|
275
|
+
::Castle::API::ReportDevice.call(device_token: device_token)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
```
|
279
|
+
|
280
|
+
Fetching available devices that belong to a given user requires a valid `user_id`.
|
281
|
+
|
282
|
+
```ruby
|
283
|
+
# Get user's devices data
|
284
|
+
::Castle::API::GetDevicesForUser.call(user_id: user.id)
|
285
|
+
```
|
286
|
+
|
223
287
|
## Impersonation mode
|
224
288
|
|
225
289
|
https://castle.io/docs/impersonation_mode
|
@@ -229,6 +293,16 @@ https://castle.io/docs/impersonation_mode
|
|
229
293
|
`Castle::Error` will be thrown if the Castle API returns a 400 or a 500 level HTTP response.
|
230
294
|
You can also choose to catch a more [finegrained error](https://github.com/castle/castle-ruby/blob/master/lib/castle/errors.rb).
|
231
295
|
|
296
|
+
## Webhooks
|
297
|
+
|
298
|
+
Castle uses webhooks to notify about `$incident.confirmed` or `$review.opened` events. Each webhook has `X-Castle-Signature` header that allows verifying webhook's source.
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
# Verify the webhook, passed as a Request object
|
302
|
+
::Castle::Webhooks::Verify.call(webhook_request)
|
303
|
+
# Castle::WebhookVerificationError is raised when the signature is not matching
|
304
|
+
```
|
305
|
+
|
232
306
|
## Documentation
|
233
307
|
|
234
308
|
[Official Castle docs](https://castle.io/docs)
|
data/lib/castle.rb
CHANGED
@@ -9,37 +9,61 @@
|
|
9
9
|
|
10
10
|
%w[
|
11
11
|
castle/version
|
12
|
+
castle/verdict
|
12
13
|
castle/events
|
13
14
|
castle/errors
|
14
15
|
castle/command
|
15
|
-
castle/utils
|
16
|
-
castle/utils/
|
17
|
-
castle/utils/
|
18
|
-
castle/utils/
|
16
|
+
castle/utils/deep_symbolize_keys
|
17
|
+
castle/utils/clean_invalid_chars
|
18
|
+
castle/utils/merge
|
19
|
+
castle/utils/clone
|
20
|
+
castle/utils/get_timestamp
|
21
|
+
castle/utils/secure_compare
|
19
22
|
castle/validators/present
|
20
23
|
castle/validators/not_supported
|
21
|
-
castle/
|
22
|
-
castle/context/
|
23
|
-
castle/context/
|
24
|
-
castle/
|
24
|
+
castle/webhooks/verify
|
25
|
+
castle/context/merge
|
26
|
+
castle/context/sanitize
|
27
|
+
castle/context/get_default
|
28
|
+
castle/context/prepare
|
29
|
+
castle/commands/approve_device
|
25
30
|
castle/commands/authenticate
|
26
|
-
castle/commands/
|
31
|
+
castle/commands/end_impersonation
|
32
|
+
castle/commands/get_device
|
33
|
+
castle/commands/get_devices_for_user
|
34
|
+
castle/commands/identify
|
35
|
+
castle/commands/report_device
|
27
36
|
castle/commands/review
|
28
|
-
castle/commands/
|
37
|
+
castle/commands/start_impersonation
|
38
|
+
castle/commands/track
|
39
|
+
castle/api/approve_device
|
40
|
+
castle/api/authenticate
|
41
|
+
castle/api/end_impersonation
|
42
|
+
castle/api/get_device
|
43
|
+
castle/api/get_devices_for_user
|
44
|
+
castle/api/identify
|
45
|
+
castle/api/report_device
|
46
|
+
castle/api/review
|
47
|
+
castle/api/start_impersonation
|
48
|
+
castle/api/track
|
49
|
+
castle/payload/prepare
|
29
50
|
castle/configuration
|
30
|
-
castle/
|
51
|
+
castle/singleton_configuration
|
52
|
+
castle/logger
|
53
|
+
castle/failover/prepare_response
|
54
|
+
castle/failover/strategy
|
31
55
|
castle/client
|
32
|
-
castle/
|
33
|
-
castle/
|
56
|
+
castle/headers/filter
|
57
|
+
castle/headers/format
|
58
|
+
castle/headers/extract
|
34
59
|
castle/secure_mode
|
35
|
-
castle/
|
36
|
-
castle/
|
37
|
-
castle/
|
38
|
-
castle/
|
39
|
-
castle/
|
40
|
-
castle/
|
41
|
-
castle/
|
42
|
-
castle/review
|
60
|
+
castle/client_id/extract
|
61
|
+
castle/ip/extract
|
62
|
+
castle/core/get_connection
|
63
|
+
castle/core/process_response
|
64
|
+
castle/core/send_request
|
65
|
+
castle/core/process_webhook
|
66
|
+
castle/session
|
43
67
|
castle/api
|
44
68
|
].each(&method(:require))
|
45
69
|
|
@@ -55,7 +79,7 @@ module Castle
|
|
55
79
|
end
|
56
80
|
|
57
81
|
def config
|
58
|
-
|
82
|
+
SingletonConfiguration.instance
|
59
83
|
end
|
60
84
|
|
61
85
|
def api_secret=(api_secret)
|
data/lib/castle/api.rb
CHANGED
@@ -20,30 +20,39 @@ module Castle
|
|
20
20
|
# @param command [String]
|
21
21
|
# @param headers [Hash]
|
22
22
|
# @param http [Net::HTTP]
|
23
|
-
|
24
|
-
|
23
|
+
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
|
24
|
+
# @return [Hash]
|
25
|
+
def call(command, headers = {}, http = nil, config = Castle.config)
|
26
|
+
Castle::Core::ProcessResponse.call(
|
27
|
+
send_request(command, headers, http, config)
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# @param command [String]
|
34
|
+
# @param headers [Hash]
|
35
|
+
# @param http [Net::HTTP]
|
36
|
+
# @param config [Castle::Configuration, Castle::SingletonConfiguration]
|
37
|
+
def send_request(command, headers = {}, http = nil, config = Castle.config)
|
38
|
+
raise Castle::ConfigurationError, 'configuration is not valid' unless config.valid?
|
25
39
|
|
26
40
|
begin
|
27
|
-
Castle::
|
41
|
+
Castle::Core::SendRequest.call(
|
28
42
|
command,
|
29
|
-
Castle.config.api_secret,
|
30
43
|
headers,
|
31
|
-
http
|
44
|
+
http,
|
45
|
+
config
|
32
46
|
)
|
33
47
|
rescue *HANDLED_ERRORS => e
|
34
48
|
# @note We need to initialize the error, as the original error is a cause for this
|
35
49
|
# custom exception. If we would do it the default Ruby way, the original error
|
36
50
|
# would get converted into a string
|
37
|
-
|
51
|
+
# rubocop:disable Style/RaiseArgs
|
52
|
+
raise Castle::RequestError.new(e)
|
53
|
+
# rubocop:enable Style/RaiseArgs
|
38
54
|
end
|
39
55
|
end
|
40
|
-
|
41
|
-
# @param command [String]
|
42
|
-
# @param headers [Hash]
|
43
|
-
# @param http [Net::HTTP]
|
44
|
-
def call(command, headers = {}, http = nil)
|
45
|
-
Castle::API::Response.call(request(command, headers, http))
|
46
|
-
end
|
47
56
|
end
|
48
57
|
end
|
49
58
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module API
|
5
|
+
# Sends PUT devices/#{device_token}/approve request
|
6
|
+
module ApproveDevice
|
7
|
+
class << self
|
8
|
+
# @param options [Hash]
|
9
|
+
# return [Hash]
|
10
|
+
def call(options = {})
|
11
|
+
options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
|
12
|
+
http = options.delete(:http)
|
13
|
+
config = options.delete(:config) || Castle.config
|
14
|
+
|
15
|
+
Castle::API.call(
|
16
|
+
Castle::Commands::ApproveDevice.build(options),
|
17
|
+
{},
|
18
|
+
http,
|
19
|
+
config
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module API
|
5
|
+
module Authenticate
|
6
|
+
class << self
|
7
|
+
# @param options [Hash]
|
8
|
+
# return [Hash]
|
9
|
+
def call(options = {})
|
10
|
+
unless options[:no_symbolize]
|
11
|
+
options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
|
12
|
+
end
|
13
|
+
options.delete(:no_symbolize)
|
14
|
+
http = options.delete(:http)
|
15
|
+
config = options.delete(:config) || Castle.config
|
16
|
+
|
17
|
+
response = Castle::API.call(
|
18
|
+
Castle::Commands::Authenticate.build(options),
|
19
|
+
{},
|
20
|
+
http,
|
21
|
+
config
|
22
|
+
)
|
23
|
+
response.merge(failover: false, failover_reason: nil)
|
24
|
+
rescue Castle::RequestError, Castle::InternalServerError => e
|
25
|
+
unless config.failover_strategy == :throw
|
26
|
+
return Castle::Failover::PrepareResponse.new(options[:user_id], reason: e.to_s).call
|
27
|
+
end
|
28
|
+
|
29
|
+
raise e
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Castle
|
4
|
+
module API
|
5
|
+
# Sends DELETE impersonate request
|
6
|
+
module EndImpersonation
|
7
|
+
class << self
|
8
|
+
# @param options [Hash]
|
9
|
+
def call(options = {})
|
10
|
+
unless options[:no_symbolize]
|
11
|
+
options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
|
12
|
+
end
|
13
|
+
options.delete(:no_symbolize)
|
14
|
+
http = options.delete(:http)
|
15
|
+
config = options.delete(:config) || Castle.config
|
16
|
+
|
17
|
+
Castle::API.call(
|
18
|
+
Castle::Commands::EndImpersonation.build(options),
|
19
|
+
{},
|
20
|
+
http,
|
21
|
+
config
|
22
|
+
).tap do |response|
|
23
|
+
raise Castle::ImpersonationFailed unless response[:success]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|