evervault 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/README.md +34 -161
- data/lib/evervault/client.rb +13 -22
- data/lib/evervault/crypto/client.rb +1 -2
- data/lib/evervault/http/relay_outbound_config.rb +55 -0
- data/lib/evervault/http/request.rb +2 -5
- data/lib/evervault/http/request_handler.rb +12 -4
- data/lib/evervault/http/request_intercept.rb +32 -23
- data/lib/evervault/threading/repeated_timer.rb +40 -0
- data/lib/evervault/version.rb +1 -1
- metadata +4 -4
- data/lib/evervault/models/cage.rb +0 -18
- data/lib/evervault/models/cage_list.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55a549b875f2600cd9de284bdb68f304f4eb89648f133a8cbdbe1a939e074e47
|
4
|
+
data.tar.gz: b9513f5951c014666e2084002cdb980dfb6d3f9f53053b4423802c2d1454e513
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9debf55ef13bc0960edd10b5560fec41ef31b81aa442e4639e78ea2e00c07af024a95b554e972f7cbc17fe00b5c22c5a1ed53fc7a769685f388eb945439fc36c
|
7
|
+
data.tar.gz: 3dc9c66c55e519156c7c5d046027f5b0a6273494c72d0a644242d518b7b9140b2c6fab16754d8eaec9612087669f9bd2db26436f3af432e75a91ce493833f95e
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -4,17 +4,17 @@
|
|
4
4
|
|
5
5
|
# Evervault Ruby SDK
|
6
6
|
|
7
|
-
The [Evervault](https://evervault.com) Ruby SDK is a toolkit for encrypting data as it enters your server, working with
|
7
|
+
The [Evervault](https://evervault.com) Ruby SDK is a toolkit for encrypting data as it enters your server, working with Functions, and proxying your outbound API requests to specific domains through [Outbound Relay](https://docs.evervault.com/concepts/outbound-relay/overview) to allow them to be decrypted before reaching their target.
|
8
8
|
|
9
9
|
## Getting Started
|
10
10
|
|
11
11
|
Before starting with the Evervault Ruby SDK, you will need to [create an account](https://app.evervault.com/register) and a team.
|
12
12
|
|
13
|
-
For full installation support, [book time here](https://calendly.com/evervault/
|
13
|
+
For full installation support, [book time here](https://calendly.com/evervault/support).
|
14
14
|
|
15
15
|
## Documentation
|
16
16
|
|
17
|
-
See the Evervault [Ruby SDK documentation](https://docs.evervault.com/ruby).
|
17
|
+
See the Evervault [Ruby SDK documentation](https://docs.evervault.com/reference/ruby-sdk).
|
18
18
|
|
19
19
|
## Installation
|
20
20
|
|
@@ -51,20 +51,29 @@ require "evervault"
|
|
51
51
|
# Initialize the client with your team's API key
|
52
52
|
Evervault.api_key = <YOUR-API-KEY>
|
53
53
|
|
54
|
-
# Encrypt your data
|
54
|
+
# Encrypt your data
|
55
55
|
encrypted_data = Evervault.encrypt({ hello: 'World!' })
|
56
56
|
|
57
|
-
# Process the encrypted data
|
58
|
-
result = Evervault.run(<
|
57
|
+
# Process the encrypted data using a Function
|
58
|
+
result = Evervault.run(<FUNCTION-NAME>, encrypted_data)
|
59
|
+
|
60
|
+
# Send the decrypted data to a third-party API
|
61
|
+
Evervault.enable_outbound_relay
|
62
|
+
uri = URI('https://example.com')
|
63
|
+
req = Net::HTTP::Post.new(uri.path, 'Content-Type' => 'application/json')
|
64
|
+
req.body = encrypted_data.to_json
|
65
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
66
|
+
http.use_ssl = true
|
67
|
+
res = http.request(req)
|
59
68
|
```
|
60
69
|
|
61
70
|
## Reference
|
62
71
|
|
63
|
-
The Evervault Ruby SDK exposes
|
72
|
+
The Evervault Ruby SDK exposes four methods.
|
64
73
|
|
65
74
|
### Evervault.encrypt
|
66
75
|
|
67
|
-
`Evervault.encrypt` encrypts data for use in your [Evervault
|
76
|
+
`Evervault.encrypt` encrypts data for use in your [Evervault Functions](https://docs.evervault.com/concepts/functions/overview). To encrypt data on your server, simply pass a supported value into the `Evervault.encrypt` method and then you can store the encrypted data in your database as normal.
|
68
77
|
|
69
78
|
```ruby
|
70
79
|
Evervault.encrypt(data = String | Number | Boolean | Hash | Array)
|
@@ -74,196 +83,60 @@ Evervault.encrypt(data = String | Number | Boolean | Hash | Array)
|
|
74
83
|
| --------- | ---- | ----------- |
|
75
84
|
| data | `String`, `Number`, `Boolean`, `Hash`, `Array` | Data to be encrypted |
|
76
85
|
|
77
|
-
### Evervault.
|
86
|
+
### Evervault.enable_outbound_relay
|
78
87
|
|
79
|
-
`Evervault.
|
88
|
+
`Evervault.enable_outbound_relay` configures your application to proxy HTTP requests using Outbound Relay based on the configuration created in the Evervault UI. See [Outbound Relay](https://docs.evervault.com/concepts/outbound-relay/overview) to learn more.
|
80
89
|
|
81
90
|
```ruby
|
82
|
-
Evervault.
|
91
|
+
Evervault.enable_outbound_relay([decryption_domains = Array])
|
83
92
|
```
|
84
93
|
|
85
94
|
| Parameter | Type | Description |
|
86
95
|
| --------- | ---- | ----------- |
|
87
|
-
| decryption_domains | `Array` | Requests sent to any of the domains listed will be proxied through
|
96
|
+
| decryption_domains | `Array` | Optional -- Requests sent to any of the domains listed will be proxied through Outbound Relay. This will override the configuration created using the Evervault UI. |
|
88
97
|
|
89
98
|
### Evervault.run
|
90
99
|
|
91
|
-
`Evervault.run` invokes a
|
100
|
+
`Evervault.run` invokes a Function with a given payload.
|
92
101
|
|
93
102
|
```ruby
|
94
|
-
Evervault.run(
|
103
|
+
Evervault.run(function_name = String, data = Hash[, options = Hash])
|
95
104
|
```
|
96
105
|
|
97
106
|
| Parameter | Type | Description |
|
98
107
|
| --------- | ---- | ----------- |
|
99
|
-
|
|
100
|
-
| data | Hash | Payload for the
|
101
|
-
| options | Hash | [Options for the
|
108
|
+
| function_name | String | Name of the Function to be run |
|
109
|
+
| data | Hash | Payload for the Function |
|
110
|
+
| options | Hash | [Options for the Function run](#Function-Run-Options) |
|
102
111
|
|
103
|
-
####
|
112
|
+
#### Function Run Options
|
104
113
|
|
105
114
|
| Option | Type | Default | Description |
|
106
115
|
| ------ | ---- | ------- | ----------- |
|
107
|
-
| `async` | `Boolean` | `false` | Run your
|
108
|
-
| `version` | `Integer` | `nil` | Specify the version of your
|
109
|
-
|
110
|
-
### Evervault.encrypt_and_run
|
111
|
-
|
112
|
-
Encrypt your data and use it as the payload to invoke the Cage.
|
113
|
-
|
114
|
-
```ruby
|
115
|
-
Evervault.encrypt_and_run(cage_name = String, data = Hash)
|
116
|
-
```
|
117
|
-
|
118
|
-
| Parameter | Type | Description |
|
119
|
-
| --------- | ---- | ----------- |
|
120
|
-
| cage_name | String | Name of the Cage to be run |
|
121
|
-
| data | dict | Data to be encrypted |
|
116
|
+
| `async` | `Boolean` | `false` | Run your Function in async mode. Async Function runs will be queued for processing. |
|
117
|
+
| `version` | `Integer` | `nil` | Specify the version of your Function to run. By default, the latest version will be run. |
|
122
118
|
|
123
119
|
### Evervault.create_run_token
|
124
120
|
|
125
|
-
`Evervault.create_run_token` creates a single use, time bound token for invoking a
|
121
|
+
`Evervault.create_run_token` creates a single use, time bound token for invoking a Function.
|
126
122
|
|
127
123
|
```ruby
|
128
|
-
Evervault.create_run_token(
|
124
|
+
Evervault.create_run_token(function_name = String, data = Hash)
|
129
125
|
```
|
130
126
|
|
131
127
|
| Parameter | Type | Description |
|
132
128
|
| --------- | ------ | ---------------------------------------------------- |
|
133
|
-
|
|
129
|
+
| function_name | String | Name of the Function the run token should be created for |
|
134
130
|
| data | Hash | Payload that the token can be used with |
|
135
131
|
|
136
|
-
### Evervault.cages
|
137
|
-
|
138
|
-
Return a hash of your team's Cage objects in hash format, with cage-name as keys
|
139
|
-
|
140
|
-
```ruby
|
141
|
-
Evervault.cages
|
142
|
-
=> {"hello-cage-chilly-plum"=>
|
143
|
-
#<Evervault::Models::Cage:0x00007f8b900b4438
|
144
|
-
@name="hello-cage-chilly-plum",
|
145
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
146
|
-
@uuid="c8a7ed58-4858-4510-a542-43125ccd1183">,
|
147
|
-
"hello-cage-filthy-fuchsia"=>
|
148
|
-
#<Evervault::Models::Cage:0x00007f8b900b43e8
|
149
|
-
@name="hello-cage-filthy-fuchsia",
|
150
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
151
|
-
@uuid="9af32d2b-53fa-406a-9abf-6a240648b45b">,
|
152
|
-
"hello-cage-extra-amaranth"=>
|
153
|
-
#<Evervault::Models::Cage:0x00007f8b900b4398
|
154
|
-
@name="hello-cage-extra-amaranth",
|
155
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
156
|
-
@uuid="5b99011e-a64d-4af7-bf81-619c8cb8c67f">,
|
157
|
-
"twilio-cage-explicit-salmon"=>
|
158
|
-
#<Evervault::Models::Cage:0x00007f8b900b4348
|
159
|
-
@name="twilio-cage-explicit-salmon",
|
160
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
161
|
-
@uuid="55986772-4db7-4695-ba44-1b807290ddea">}
|
162
|
-
```
|
163
|
-
|
164
|
-
### Evervault.cage_list
|
165
|
-
|
166
|
-
Return a `CageList` object, containing a list of your team's Cages
|
167
|
-
|
168
|
-
```ruby
|
169
|
-
Evervault.cage_list
|
170
|
-
=> #<Evervault::Models::CageList:0x00007f8b900b44b0
|
171
|
-
@cages=
|
172
|
-
[#<Evervault::Models::Cage:0x00007f8b900b4438
|
173
|
-
@name="hello-cage-chilly-plum",
|
174
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
175
|
-
@uuid="c8a7ed58-4858-4510-a542-43125ccd1183">,
|
176
|
-
#<Evervault::Models::Cage:0x00007f8b900b43e8
|
177
|
-
@name="hello-cage-filthy-fuchsia",
|
178
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
179
|
-
@uuid="9af32d2b-53fa-406a-9abf-6a240648b45b">,
|
180
|
-
#<Evervault::Models::Cage:0x00007f8b900b4398
|
181
|
-
@name="hello-cage-extra-amaranth",
|
182
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
183
|
-
@uuid="5b99011e-a64d-4af7-bf81-619c8cb8c67f">,
|
184
|
-
#<Evervault::Models::Cage:0x00007f8b900b4348
|
185
|
-
@name="twilio-cage-explicit-salmon",
|
186
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
187
|
-
@uuid="55986772-4db7-4695-ba44-1b807290ddea">,
|
188
|
-
#<Evervault::Models::Cage:0x00007f8b900b42f8
|
189
|
-
@name="hello-cage-collective-aquamarine",
|
190
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
191
|
-
@uuid="01691e76-691b-473e-aad5-44bf813ef146">,
|
192
|
-
#<Evervault::Models::Cage:0x00007f8b900b42a8
|
193
|
-
@name="twilio-cage-bored-scarlet",
|
194
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
195
|
-
@uuid="dc056e8b-faf3-445b-9c95-0885b983c302">,
|
196
|
-
#<Evervault::Models::Cage:0x00007f8b900b4258
|
197
|
-
@name="hello-cage-front-emerald",
|
198
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
199
|
-
@uuid="a30295e6-91fc-4d1d-837c-ac4c9b87d02d">]>
|
200
|
-
```
|
201
|
-
|
202
|
-
#### CageList.to_hash
|
203
|
-
|
204
|
-
Converts a list of Cages to a hash with keys of CageName => Cage Model
|
205
|
-
|
206
|
-
```ruby
|
207
|
-
Evervault.cage_list.to_hash
|
208
|
-
=> {"hello-cage-chilly-plum"=>
|
209
|
-
#<Evervault::Models::Cage:0x00007f8b900b4438
|
210
|
-
@name="hello-cage-chilly-plum",
|
211
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
212
|
-
@uuid="c8a7ed58-4858-4510-a542-43125ccd1183">,
|
213
|
-
"hello-cage-filthy-fuchsia"=>
|
214
|
-
#<Evervault::Models::Cage:0x00007f8b900b43e8
|
215
|
-
@name="hello-cage-filthy-fuchsia",
|
216
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
217
|
-
@uuid="9af32d2b-53fa-406a-9abf-6a240648b45b">,
|
218
|
-
"hello-cage-extra-amaranth"=>
|
219
|
-
#<Evervault::Models::Cage:0x00007f8b900b4398
|
220
|
-
@name="hello-cage-extra-amaranth",
|
221
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
222
|
-
@uuid="5b99011e-a64d-4af7-bf81-619c8cb8c67f">,
|
223
|
-
"twilio-cage-explicit-salmon"=>
|
224
|
-
#<Evervault::Models::Cage:0x00007f8b900b4348
|
225
|
-
@name="twilio-cage-explicit-salmon",
|
226
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
227
|
-
@uuid="55986772-4db7-4695-ba44-1b807290ddea">,
|
228
|
-
"hello-cage-collective-aquamarine"=>
|
229
|
-
#<Evervault::Models::Cage:0x00007f8b900b42f8
|
230
|
-
@name="hello-cage-collective-aquamarine",
|
231
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
232
|
-
@uuid="01691e76-691b-473e-aad5-44bf813ef146">,
|
233
|
-
"twilio-cage-bored-scarlet"=>
|
234
|
-
#<Evervault::Models::Cage:0x00007f8b900b42a8
|
235
|
-
@name="twilio-cage-bored-scarlet",
|
236
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
237
|
-
@uuid="dc056e8b-faf3-445b-9c95-0885b983c302">,
|
238
|
-
"hello-cage-front-emerald"=>
|
239
|
-
#<Evervault::Models::Cage:0x00007f8b900b4258
|
240
|
-
@name="hello-cage-front-emerald",
|
241
|
-
@request=#<Evervault::Http::Request:0x00007f8b900b7d40 @api_key="API-KEY", @base_url="https://api.evervault.com/", @cage_run_url="https://cage.run/", @timeout=30>,
|
242
|
-
@uuid="a30295e6-91fc-4d1d-837c-ac4c9b87d02d">}
|
243
|
-
```
|
244
|
-
|
245
|
-
### Evervault::Models::Cage.run
|
246
|
-
|
247
|
-
Each Cage model exposes a `run` method, which allows you to run that particular Cage.
|
248
|
-
|
249
|
-
*Note*: this does not encrypt data before running the Cage.
|
250
|
-
```ruby
|
251
|
-
cage = Evervault.cage_list.cages[0]
|
252
|
-
cage.run({'name': 'testing'})
|
253
|
-
=> {"result"=>{"message"=>"Hello, world!", "details"=>"Please send an encrypted `name` parameter to show cage decryption in action"}, "runId"=>"5428800061ff"}
|
254
|
-
```
|
255
|
-
|
256
|
-
| Parameter | Type | Description |
|
257
|
-
| --------- | ---- | ----------- |
|
258
|
-
| data | Hash | Payload for the Cage |
|
259
|
-
| options | Hash | [Options for the Cage run](#Cage-Run-Options) |
|
260
|
-
|
261
132
|
## Development
|
262
133
|
|
263
134
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
264
135
|
|
265
136
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
266
137
|
|
138
|
+
[Rbenv](https://github.com/rbenv/rbenv) can also be used to install specific versions of Ruby.
|
139
|
+
|
267
140
|
## Contributing
|
268
141
|
|
269
142
|
Bug reports and pull requests are welcome on GitHub at https://github.com/evervault/evervault-ruby.
|
data/lib/evervault/client.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require_relative "http/request"
|
2
2
|
require_relative "http/request_handler"
|
3
3
|
require_relative "http/request_intercept"
|
4
|
+
require_relative "http/relay_outbound_config"
|
5
|
+
require_relative "threading/repeated_timer"
|
4
6
|
require_relative "crypto/client"
|
5
|
-
require_relative "models/cage_list"
|
6
7
|
|
7
8
|
module Evervault
|
8
9
|
class Client
|
@@ -19,7 +20,7 @@ module Evervault
|
|
19
20
|
)
|
20
21
|
@request = Evervault::Http::Request.new(timeout: request_timeout, api_key: api_key)
|
21
22
|
@intercept = Evervault::Http::RequestIntercept.new(
|
22
|
-
request: @request, ca_host: ca_host, api_key: api_key, relay_url: relay_url
|
23
|
+
request: @request, ca_host: ca_host, api_key: api_key, base_url: base_url, relay_url: relay_url
|
23
24
|
)
|
24
25
|
@request_handler =
|
25
26
|
Evervault::Http::RequestHandler.new(
|
@@ -33,30 +34,20 @@ module Evervault
|
|
33
34
|
@crypto_client.encrypt(data)
|
34
35
|
end
|
35
36
|
|
36
|
-
def run(
|
37
|
-
@request_handler.post(
|
37
|
+
def run(function_name, encrypted_data, options = {})
|
38
|
+
@request_handler.post(function_name, encrypted_data, options: options, cage_run: true)
|
38
39
|
end
|
39
40
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
41
|
+
def enable_outbound_relay(decryption_domains = nil)
|
42
|
+
if decryption_domains.nil?
|
43
|
+
@intercept.setup_outbound_relay_config
|
44
|
+
else
|
45
|
+
@intercept.setup_decryption_domains(decryption_domains)
|
46
|
+
end
|
43
47
|
end
|
44
48
|
|
45
|
-
def
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
def cage_list
|
50
|
-
cages = @request_handler.get("cages")
|
51
|
-
@cage_list ||= Evervault::Models::CageList.new(cages: cages["cages"], request: @request)
|
52
|
-
end
|
53
|
-
|
54
|
-
def relay(decryption_domains=[])
|
55
|
-
@intercept.setup_domains(decryption_domains)
|
56
|
-
end
|
57
|
-
|
58
|
-
def create_run_token(cage_name, data)
|
59
|
-
@request_handler.post("v2/functions/#{cage_name}/run-token", data)
|
49
|
+
def create_run_token(function_name, data)
|
50
|
+
@request_handler.post("v2/functions/#{function_name}/run-token", data)
|
60
51
|
end
|
61
52
|
end
|
62
53
|
end
|
@@ -77,8 +77,7 @@ module Evervault
|
|
77
77
|
end
|
78
78
|
|
79
79
|
private def generate_shared_key()
|
80
|
-
ec = OpenSSL::PKey::EC.
|
81
|
-
ec.generate_key
|
80
|
+
ec = OpenSSL::PKey::EC.generate(@curve)
|
82
81
|
@ephemeral_public_key = ec.public_key
|
83
82
|
|
84
83
|
decoded_team_key = OpenSSL::BN.new(Base64.strict_decode64(@team_key), 2)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Evervault
|
2
|
+
module Http
|
3
|
+
class RelayOutboundConfig
|
4
|
+
DEFAULT_POLL_INTERVAL = 5
|
5
|
+
RELAY_OUTBOUND_CONFIG_API_ENDPOINT = "v2/relay-outbound"
|
6
|
+
|
7
|
+
@@destination_domains_cache = nil
|
8
|
+
@@poll_interval = DEFAULT_POLL_INTERVAL
|
9
|
+
@@timer = nil
|
10
|
+
|
11
|
+
def initialize(base_url:, request:)
|
12
|
+
@base_url = base_url
|
13
|
+
@request = request
|
14
|
+
if @@destination_domains_cache.nil?
|
15
|
+
get_relay_outbound_config
|
16
|
+
end
|
17
|
+
if @@timer.nil?
|
18
|
+
@@timer = Evervault::Threading::RepeatedTimer.new(@@poll_interval, -> { get_relay_outbound_config })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_destination_domains
|
23
|
+
@@destination_domains_cache
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.disable_polling
|
27
|
+
unless @@timer.nil?
|
28
|
+
@@timer.stop
|
29
|
+
@@timer = nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.clear_cache
|
34
|
+
@@destination_domains_cache = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
private def get_relay_outbound_config
|
38
|
+
resp = @request.execute(:get, "#{@base_url}#{RELAY_OUTBOUND_CONFIG_API_ENDPOINT}", nil)
|
39
|
+
poll_interval = resp.headers["x-poll-interval"]
|
40
|
+
unless poll_interval.nil?
|
41
|
+
update_poll_interval(poll_interval.to_f)
|
42
|
+
end
|
43
|
+
resp_body = JSON.parse(resp.body)
|
44
|
+
@@destination_domains_cache = resp_body["outboundDestinations"].values.map{ |outbound_destination| outbound_destination["destinationDomain"] }
|
45
|
+
end
|
46
|
+
|
47
|
+
private def update_poll_interval(poll_interval)
|
48
|
+
@@poll_interval = poll_interval
|
49
|
+
unless @@timer.nil?
|
50
|
+
@@timer.update_interval(poll_interval)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -11,17 +11,14 @@ module Evervault
|
|
11
11
|
@api_key = api_key
|
12
12
|
end
|
13
13
|
|
14
|
-
def execute(method, url, params, optional_headers = {}
|
14
|
+
def execute(method, url, params, optional_headers = {})
|
15
15
|
resp = Faraday.send(method, url) do |req|
|
16
16
|
req.body = params.nil? || params.empty? ? nil : params.to_json
|
17
17
|
req.headers = build_headers(optional_headers)
|
18
18
|
req.options.timeout = @timeout
|
19
19
|
end
|
20
20
|
if resp.status >= 200 && resp.status <= 300
|
21
|
-
|
22
|
-
return resp.body
|
23
|
-
end
|
24
|
-
return JSON.parse(resp.body)
|
21
|
+
return resp
|
25
22
|
end
|
26
23
|
Evervault::Errors::ErrorMap.raise_errors_on_failure(resp.status, resp.body, resp.headers)
|
27
24
|
end
|
@@ -17,28 +17,36 @@ module Evervault
|
|
17
17
|
if @cert.is_certificate_expired()
|
18
18
|
@cert.setup()
|
19
19
|
end
|
20
|
-
@request.execute(:get, build_url(path), params)
|
20
|
+
resp = @request.execute(:get, build_url(path), params)
|
21
|
+
parse_json_body(resp.body)
|
21
22
|
end
|
22
23
|
|
23
24
|
def put(path, params)
|
24
25
|
if @cert.is_certificate_expired()
|
25
26
|
@cert.setup()
|
26
27
|
end
|
27
|
-
@request.execute(:put, build_url(path), params)
|
28
|
+
resp = @request.execute(:put, build_url(path), params)
|
29
|
+
parse_json_body(resp.body)
|
28
30
|
end
|
29
31
|
|
30
32
|
def delete(path, params)
|
31
33
|
if @cert.is_certificate_expired()
|
32
34
|
@cert.setup()
|
33
35
|
end
|
34
|
-
@request.execute(:delete, build_url(path), params)
|
36
|
+
resp = @request.execute(:delete, build_url(path), params)
|
37
|
+
parse_json_body(resp.body)
|
35
38
|
end
|
36
39
|
|
37
40
|
def post(path, params, options: {}, cage_run: false)
|
38
41
|
if @cert.is_certificate_expired()
|
39
42
|
@cert.setup()
|
40
43
|
end
|
41
|
-
@request.execute(:post, build_url(path, cage_run), params, build_cage_run_headers(options, cage_run))
|
44
|
+
resp = @request.execute(:post, build_url(path, cage_run), params, build_cage_run_headers(options, cage_run))
|
45
|
+
parse_json_body(resp.body)
|
46
|
+
end
|
47
|
+
|
48
|
+
private def parse_json_body(body)
|
49
|
+
JSON.parse(body)
|
42
50
|
end
|
43
51
|
|
44
52
|
private def build_url(path, cage_run = false)
|
@@ -11,8 +11,7 @@ module NetHTTPOverride
|
|
11
11
|
@@relay_url = nil
|
12
12
|
@@relay_port = nil
|
13
13
|
@@cert = nil
|
14
|
-
@@
|
15
|
-
@@decrypt_if_ends_with = []
|
14
|
+
@@get_decryption_domains_func = nil
|
16
15
|
|
17
16
|
def self.set_api_key(value)
|
18
17
|
@@api_key = value
|
@@ -28,20 +27,27 @@ module NetHTTPOverride
|
|
28
27
|
@@cert = value
|
29
28
|
end
|
30
29
|
|
31
|
-
def self.
|
32
|
-
@@
|
30
|
+
def self.add_get_decryption_domains_func(get_decryption_domains_func)
|
31
|
+
@@get_decryption_domains_func = get_decryption_domains_func
|
33
32
|
end
|
34
33
|
|
35
|
-
def self.
|
36
|
-
@@
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
def self.should_decrypt(domain)
|
35
|
+
if @@get_decryption_domains_func.nil?
|
36
|
+
false
|
37
|
+
else
|
38
|
+
decryption_domains = @@get_decryption_domains_func.call()
|
39
|
+
decryption_domains.any? { |decryption_domain|
|
40
|
+
if decryption_domain.start_with?("*")
|
41
|
+
domain.end_with?(decryption_domain[1..-1])
|
42
|
+
else
|
43
|
+
domain == decryption_domain
|
44
|
+
end
|
45
|
+
}
|
46
|
+
end
|
41
47
|
end
|
42
48
|
|
43
49
|
def connect
|
44
|
-
if should_decrypt(conn_address)
|
50
|
+
if NetHTTPOverride.should_decrypt(conn_address)
|
45
51
|
@cert_store = OpenSSL::X509::Store.new
|
46
52
|
@cert_store.add_cert(@@cert)
|
47
53
|
@proxy_from_env = false
|
@@ -52,7 +58,7 @@ module NetHTTPOverride
|
|
52
58
|
end
|
53
59
|
|
54
60
|
def request(req, body = nil, &block)
|
55
|
-
should_decrypt = should_decrypt(@address)
|
61
|
+
should_decrypt = NetHTTPOverride.should_decrypt(@address)
|
56
62
|
if should_decrypt
|
57
63
|
req["Proxy-Authorization"] = @@api_key
|
58
64
|
end
|
@@ -65,11 +71,12 @@ Net::HTTP.send :prepend, NetHTTPOverride
|
|
65
71
|
module Evervault
|
66
72
|
module Http
|
67
73
|
class RequestIntercept
|
68
|
-
def initialize(request:, ca_host:, api_key:, relay_url:)
|
74
|
+
def initialize(request:, ca_host:, api_key:, base_url:, relay_url:)
|
69
75
|
NetHTTPOverride.set_api_key(api_key)
|
70
76
|
NetHTTPOverride.set_relay_url(relay_url)
|
71
77
|
|
72
78
|
@request = request
|
79
|
+
@base_url = base_url
|
73
80
|
@ca_host = ca_host
|
74
81
|
@expire_date = nil
|
75
82
|
@initial_date = nil
|
@@ -85,15 +92,17 @@ module Evervault
|
|
85
92
|
return false
|
86
93
|
end
|
87
94
|
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
95
|
+
def setup_decryption_domains(decryption_domains)
|
96
|
+
NetHTTPOverride.add_get_decryption_domains_func(-> {
|
97
|
+
decryption_domains
|
98
|
+
})
|
99
|
+
end
|
100
|
+
|
101
|
+
def setup_outbound_relay_config
|
102
|
+
@relay_outbound_config = Evervault::Http::RelayOutboundConfig.new(base_url: @base_url, request: @request)
|
103
|
+
NetHTTPOverride.add_get_decryption_domains_func(-> {
|
104
|
+
@relay_outbound_config.get_destination_domains
|
105
|
+
})
|
97
106
|
end
|
98
107
|
|
99
108
|
def setup
|
@@ -107,7 +116,7 @@ module Evervault
|
|
107
116
|
while !ca_content && i < 1
|
108
117
|
i += 1
|
109
118
|
begin
|
110
|
-
ca_content = @request.execute("get", @ca_host, nil, {}
|
119
|
+
ca_content = @request.execute("get", @ca_host, nil, {}).body
|
111
120
|
rescue;
|
112
121
|
end
|
113
122
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Evervault
|
2
|
+
module Threading
|
3
|
+
class RepeatedTimer
|
4
|
+
def initialize(interval, func)
|
5
|
+
@thread = nil
|
6
|
+
@interval = interval
|
7
|
+
@func = func
|
8
|
+
start
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
if !running?
|
13
|
+
@thread = Thread.new do
|
14
|
+
loop do
|
15
|
+
sleep @interval
|
16
|
+
begin
|
17
|
+
@func.call
|
18
|
+
rescue => e
|
19
|
+
# Silently ignore exceptions
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def running?
|
27
|
+
!@thread.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
def stop
|
31
|
+
@thread.exit
|
32
|
+
@thread = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def update_interval(new_interval)
|
36
|
+
@interval = new_interval
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/evervault/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: evervault
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonny O'Mahony
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -37,11 +37,11 @@ files:
|
|
37
37
|
- lib/evervault/crypto/curves/p256.rb
|
38
38
|
- lib/evervault/errors/error_map.rb
|
39
39
|
- lib/evervault/errors/errors.rb
|
40
|
+
- lib/evervault/http/relay_outbound_config.rb
|
40
41
|
- lib/evervault/http/request.rb
|
41
42
|
- lib/evervault/http/request_handler.rb
|
42
43
|
- lib/evervault/http/request_intercept.rb
|
43
|
-
- lib/evervault/
|
44
|
-
- lib/evervault/models/cage_list.rb
|
44
|
+
- lib/evervault/threading/repeated_timer.rb
|
45
45
|
- lib/evervault/version.rb
|
46
46
|
- res/logo.svg
|
47
47
|
- res/logo512.png
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Evervault
|
2
|
-
module Models
|
3
|
-
class Cage
|
4
|
-
|
5
|
-
attr_reader :name, :uuid
|
6
|
-
def initialize(name:, uuid:, request:)
|
7
|
-
@name = name
|
8
|
-
@uuid = uuid
|
9
|
-
@request = request
|
10
|
-
end
|
11
|
-
|
12
|
-
def run(params, options = {})
|
13
|
-
@request.post(self.name, params, options: options, cage_run: true)
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require_relative "cage"
|
2
|
-
|
3
|
-
module Evervault
|
4
|
-
module Models
|
5
|
-
class CageList
|
6
|
-
attr_reader :cages
|
7
|
-
def initialize(cages:, request:)
|
8
|
-
@cages = build_cage_list(cages, request)
|
9
|
-
end
|
10
|
-
|
11
|
-
def to_hash
|
12
|
-
cage_hash = {}
|
13
|
-
cages.each { |cage| cage_hash[cage.name] = cage }
|
14
|
-
cage_hash
|
15
|
-
end
|
16
|
-
|
17
|
-
private def build_cage_list(cages, request)
|
18
|
-
cages.map { |cage| Cage.new(name: cage["name"], uuid: cage["uuid"], request: request) }
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|