evervault 1.1.0 → 1.2.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/.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
|