evervault 1.3.2 → 2.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/.github/workflows/release.yml +7 -7
- data/.github/workflows/run-tests.yml +7 -7
- data/README.md +26 -6
- data/lib/evervault/client.rb +32 -10
- data/lib/evervault/http/request.rb +30 -9
- data/lib/evervault/http/request_handler.rb +13 -32
- data/lib/evervault/utils/validation_utils.rb +31 -0
- data/lib/evervault/version.rb +1 -1
- data/lib/evervault.rb +8 -6
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c750c2a56b880d7ef8c5c0cef1bb856476d8fa88bf2cc06c72be2e45b14935dd
|
4
|
+
data.tar.gz: f162eb3e45b0d907642753b9f387cece1f49e3f3531b7cfb6570bcf6a00eba66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 322cc850f1d240e09ce26069af576efe8d588b2a939e67fb4bc4402cffc32a8eaaecc98abc4ced0f18ce6e912c52bab801f0b08197fb695a9e115edc8b5fc04d
|
7
|
+
data.tar.gz: fb7e6f187bdda3f361da65f6192424a6e09e20a97be40e486b29b9396d58a05a7d61f7df6d60338dce5133acecf3917091fa89f65005da93d29e69bb3c02a5ef
|
@@ -11,16 +11,16 @@ jobs:
|
|
11
11
|
fail-fast: false
|
12
12
|
matrix:
|
13
13
|
os: [ubuntu, macos]
|
14
|
-
ruby: [2.
|
14
|
+
ruby: [2.6, 2.7, 3.1, truffleruby]
|
15
15
|
runs-on: ${{ matrix.os }}-latest
|
16
16
|
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
|
17
17
|
steps:
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
- run: bundle install
|
23
|
+
- run: bundle exec rake
|
24
24
|
|
25
25
|
build:
|
26
26
|
runs-on: ubuntu-latest
|
@@ -7,13 +7,13 @@ jobs:
|
|
7
7
|
fail-fast: false
|
8
8
|
matrix:
|
9
9
|
os: [ubuntu, macos]
|
10
|
-
ruby: [2.
|
10
|
+
ruby: [2.6, 2.7, 3.1, truffleruby]
|
11
11
|
runs-on: ${{ matrix.os }}-latest
|
12
12
|
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
|
13
13
|
steps:
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
- uses: ruby/setup-ruby@v1
|
16
|
+
with:
|
17
|
+
ruby-version: ${{ matrix.ruby }}
|
18
|
+
- run: bundle install
|
19
|
+
- run: bundle exec rake
|
data/README.md
CHANGED
@@ -48,11 +48,15 @@ To make Evervault available for use in your app:
|
|
48
48
|
```ruby
|
49
49
|
require "evervault"
|
50
50
|
|
51
|
-
# Initialize the client with your
|
51
|
+
# Initialize the client with your App's ID and App's API key
|
52
|
+
Evervault.app_id = <YOUR-APP-ID>
|
52
53
|
Evervault.api_key = <YOUR-API-KEY>
|
53
54
|
|
54
55
|
# Encrypt your data
|
55
|
-
encrypted_data = Evervault.encrypt(
|
56
|
+
encrypted_data = Evervault.encrypt('Hello World!')
|
57
|
+
|
58
|
+
# Decrypt your data
|
59
|
+
decrypted = Evervault.decrypt(encrypted_data)
|
56
60
|
|
57
61
|
# Process the encrypted data using a Function
|
58
62
|
result = Evervault.run(<FUNCTION-NAME>, encrypted_data)
|
@@ -65,6 +69,7 @@ req.body = encrypted_data.to_json
|
|
65
69
|
http = Net::HTTP.new(uri.host, uri.port)
|
66
70
|
http.use_ssl = true
|
67
71
|
res = http.request(req)
|
72
|
+
|
68
73
|
```
|
69
74
|
|
70
75
|
## Reference
|
@@ -79,13 +84,26 @@ The Evervault Ruby SDK exposes four methods.
|
|
79
84
|
Evervault.encrypt(data = String | Number | Boolean | Hash | Array)
|
80
85
|
```
|
81
86
|
|
82
|
-
| Parameter | Type
|
83
|
-
| --------- |
|
84
|
-
| data
|
87
|
+
| Parameter | Type | Description |
|
88
|
+
| --------- | ---------------------------------------------- | -------------------- |
|
89
|
+
| data | `String`, `Number`, `Boolean`, `Hash`, `Array` | Data to be encrypted |
|
90
|
+
|
91
|
+
### Evervault.decrypt
|
92
|
+
|
93
|
+
`Evervault.decrypt` decrypts data previously encrypted with the `encrypt()` function or through Evervault's Relay (Evervault's encryption proxy).
|
94
|
+
An API Key with the `decrypt` permission must be used to perform this operation.
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
Evervault.decrypt(data = String | Array | Hash)
|
98
|
+
```
|
99
|
+
|
100
|
+
| Parameter | Type | Description |
|
101
|
+
| --------- | ------------------------- | -------------------- |
|
102
|
+
| data | `String`, `Array`, `Hash` | Data to be decrypted |
|
85
103
|
|
86
104
|
### Evervault.enable_outbound_relay
|
87
105
|
|
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.
|
106
|
+
`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.
|
89
107
|
|
90
108
|
```ruby
|
91
109
|
Evervault.enable_outbound_relay([decryption_domains = Array])
|
@@ -98,6 +116,7 @@ Evervault.enable_outbound_relay([decryption_domains = Array])
|
|
98
116
|
### Evervault.run
|
99
117
|
|
100
118
|
`Evervault.run` invokes a Function with a given payload.
|
119
|
+
An API Key with the `run Function` permission must be used to perform this operation.
|
101
120
|
|
102
121
|
```ruby
|
103
122
|
Evervault.run(function_name = String, data = Hash[, options = Hash])
|
@@ -119,6 +138,7 @@ Evervault.run(function_name = String, data = Hash[, options = Hash])
|
|
119
138
|
### Evervault.create_run_token
|
120
139
|
|
121
140
|
`Evervault.create_run_token` creates a single use, time bound token for invoking a Function.
|
141
|
+
An API Key with the `create Run Token` permission must be used to perform this operation.
|
122
142
|
|
123
143
|
```ruby
|
124
144
|
Evervault.create_run_token(function_name = String, data = Hash)
|
data/lib/evervault/client.rb
CHANGED
@@ -8,23 +8,25 @@ require_relative "crypto/client"
|
|
8
8
|
module Evervault
|
9
9
|
class Client
|
10
10
|
|
11
|
-
attr_accessor :
|
11
|
+
attr_accessor :function_run_url
|
12
12
|
def initialize(
|
13
|
+
app_uuid:,
|
13
14
|
api_key:,
|
14
15
|
base_url: "https://api.evervault.com/",
|
15
|
-
|
16
|
+
function_run_url: "https://run.evervault.com/",
|
16
17
|
relay_url: "https://relay.evervault.com:8443",
|
17
18
|
ca_host: "https://ca.evervault.com",
|
18
19
|
request_timeout: 30,
|
19
20
|
curve: 'prime256v1'
|
20
21
|
)
|
21
|
-
@
|
22
|
+
@function_run_url = function_run_url
|
23
|
+
@request = Evervault::Http::Request.new(timeout: request_timeout, app_uuid: app_uuid, api_key: api_key)
|
22
24
|
@intercept = Evervault::Http::RequestIntercept.new(
|
23
25
|
request: @request, ca_host: ca_host, api_key: api_key, base_url: base_url, relay_url: relay_url
|
24
26
|
)
|
25
27
|
@request_handler =
|
26
28
|
Evervault::Http::RequestHandler.new(
|
27
|
-
request: @request, base_url: base_url,
|
29
|
+
request: @request, base_url: base_url, cert: @intercept
|
28
30
|
)
|
29
31
|
@crypto_client = Evervault::Crypto::Client.new(request_handler: @request_handler, curve: curve)
|
30
32
|
@intercept.setup()
|
@@ -34,8 +36,32 @@ module Evervault
|
|
34
36
|
@crypto_client.encrypt(data)
|
35
37
|
end
|
36
38
|
|
37
|
-
def
|
38
|
-
|
39
|
+
def decrypt(data)
|
40
|
+
unless data.is_a?(String) || data.is_a?(Array) || data.is_a?(Hash)
|
41
|
+
raise Evervault::Errors::ArgumentError.new("data is of invalid type")
|
42
|
+
end
|
43
|
+
payload = { data: data }
|
44
|
+
response = @request_handler.post("decrypt", payload, nil, nil, true)
|
45
|
+
response["data"]
|
46
|
+
end
|
47
|
+
|
48
|
+
def run(function_name, payload, options = {})
|
49
|
+
optional_headers = {}
|
50
|
+
if options.key?(:async)
|
51
|
+
if options[:async]
|
52
|
+
optional_headers["x-async"] = "true"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
if options.key?(:version)
|
56
|
+
if options[:version].is_a? Integer
|
57
|
+
optional_headers["x-version-id"] = options[:version].to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
@request_handler.post(function_name, payload, optional_headers, @function_run_url)
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_run_token(function_name, data = {})
|
64
|
+
@request_handler.post("v2/functions/#{function_name}/run-token", data)
|
39
65
|
end
|
40
66
|
|
41
67
|
def enable_outbound_relay(decryption_domains = nil)
|
@@ -45,9 +71,5 @@ module Evervault
|
|
45
71
|
@intercept.setup_decryption_domains(decryption_domains)
|
46
72
|
end
|
47
73
|
end
|
48
|
-
|
49
|
-
def create_run_token(function_name, data = {})
|
50
|
-
@request_handler.post("v2/functions/#{function_name}/run-token", data)
|
51
|
-
end
|
52
74
|
end
|
53
75
|
end
|
@@ -6,31 +6,52 @@ require_relative "../errors/error_map"
|
|
6
6
|
module Evervault
|
7
7
|
module Http
|
8
8
|
class Request
|
9
|
-
def initialize(timeout:, api_key:)
|
9
|
+
def initialize(timeout:, app_uuid:, api_key:)
|
10
10
|
@timeout = timeout
|
11
|
+
@app_uuid = app_uuid
|
11
12
|
@api_key = api_key
|
12
13
|
end
|
13
14
|
|
14
|
-
def execute(method, url,
|
15
|
-
resp =
|
16
|
-
req.body =
|
17
|
-
req.headers = build_headers(optional_headers)
|
15
|
+
def execute(method, url, body = nil, optional_headers = {}, basic_auth = false)
|
16
|
+
resp = faraday(basic_auth).public_send(method, url) do |req, url|
|
17
|
+
req.body = body.nil? || body.empty? ? nil : body.to_json
|
18
|
+
req.headers = build_headers(optional_headers, basic_auth)
|
18
19
|
req.options.timeout = @timeout
|
19
20
|
end
|
21
|
+
|
20
22
|
if resp.status >= 200 && resp.status <= 300
|
21
23
|
return resp
|
22
24
|
end
|
25
|
+
|
23
26
|
Evervault::Errors::ErrorMap.raise_errors_on_failure(resp.status, resp.body, resp.headers)
|
24
27
|
end
|
25
28
|
|
26
|
-
private
|
27
|
-
|
29
|
+
private
|
30
|
+
|
31
|
+
def faraday(basic_auth = false)
|
32
|
+
Faraday.new do |conn|
|
33
|
+
if basic_auth
|
34
|
+
conn.request :authorization, :basic, @app_uuid, @api_key
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def build_headers(optional_headers = {}, basic_auth = false)
|
40
|
+
headers = {
|
28
41
|
"AcceptEncoding": "gzip, deflate",
|
29
42
|
"Accept": "application/json",
|
30
43
|
"Content-Type": "application/json",
|
31
44
|
"User-Agent": "evervault-ruby/#{VERSION}",
|
32
|
-
|
33
|
-
|
45
|
+
}
|
46
|
+
unless optional_headers.nil? || optional_headers.empty?
|
47
|
+
headers = headers.merge(optional_headers)
|
48
|
+
end
|
49
|
+
if !basic_auth
|
50
|
+
headers = headers.merge({
|
51
|
+
"Api-Key": @api_key,
|
52
|
+
})
|
53
|
+
end
|
54
|
+
headers
|
34
55
|
end
|
35
56
|
end
|
36
57
|
end
|
@@ -6,70 +6,51 @@ require_relative "../errors/error_map"
|
|
6
6
|
module Evervault
|
7
7
|
module Http
|
8
8
|
class RequestHandler
|
9
|
-
def initialize(request:, base_url:,
|
9
|
+
def initialize(request:, base_url:, cert:)
|
10
10
|
@request = request
|
11
11
|
@base_url = base_url
|
12
|
-
@cage_run_url = cage_run_url
|
13
12
|
@cert = cert
|
14
13
|
end
|
15
14
|
|
16
|
-
def get(path
|
15
|
+
def get(path)
|
17
16
|
if @cert.is_certificate_expired()
|
18
17
|
@cert.setup()
|
19
18
|
end
|
20
|
-
resp = @request.execute(:get, build_url(path)
|
19
|
+
resp = @request.execute(:get, build_url(path))
|
21
20
|
parse_json_body(resp.body)
|
22
21
|
end
|
23
22
|
|
24
|
-
def put(path,
|
23
|
+
def put(path, body)
|
25
24
|
if @cert.is_certificate_expired()
|
26
25
|
@cert.setup()
|
27
26
|
end
|
28
|
-
resp = @request.execute(:put, build_url(path),
|
27
|
+
resp = @request.execute(:put, build_url(path), body)
|
29
28
|
parse_json_body(resp.body)
|
30
29
|
end
|
31
30
|
|
32
|
-
def delete(path
|
31
|
+
def delete(path)
|
33
32
|
if @cert.is_certificate_expired()
|
34
33
|
@cert.setup()
|
35
34
|
end
|
36
|
-
resp = @request.execute(:delete, build_url(path)
|
35
|
+
resp = @request.execute(:delete, build_url(path))
|
37
36
|
parse_json_body(resp.body)
|
38
37
|
end
|
39
38
|
|
40
|
-
def post(path,
|
39
|
+
def post(path, body, optional_headers = {}, alternative_base_url = nil, basic_auth = false)
|
41
40
|
if @cert.is_certificate_expired()
|
42
41
|
@cert.setup()
|
43
42
|
end
|
44
|
-
resp = @request.execute(:post, build_url(path,
|
45
|
-
parse_json_body(resp.body)
|
43
|
+
resp = @request.execute(:post, build_url(path, alternative_base_url), body, optional_headers, basic_auth)
|
44
|
+
return parse_json_body(resp.body) unless resp.body.empty?
|
46
45
|
end
|
47
46
|
|
48
47
|
private def parse_json_body(body)
|
49
48
|
JSON.parse(body)
|
50
49
|
end
|
51
50
|
|
52
|
-
private def build_url(path,
|
53
|
-
return "#{@base_url}#{path}" unless
|
54
|
-
"#{
|
55
|
-
end
|
56
|
-
|
57
|
-
private def build_cage_run_headers(options, cage_run = false)
|
58
|
-
optional_headers = {}
|
59
|
-
return optional_headers unless cage_run
|
60
|
-
if options.key?(:async)
|
61
|
-
if options[:async]
|
62
|
-
optional_headers["x-async"] = "true"
|
63
|
-
end
|
64
|
-
options.delete(:async)
|
65
|
-
end
|
66
|
-
if options.key?(:version)
|
67
|
-
if options[:version].is_a? Integer
|
68
|
-
optional_headers["x-version-id"] = options[:version].to_s
|
69
|
-
end
|
70
|
-
options.delete(:version)
|
71
|
-
end
|
72
|
-
optional_headers.merge(options)
|
51
|
+
private def build_url(path, alternative_base_url = nil)
|
52
|
+
return "#{@base_url}#{path}" unless alternative_base_url
|
53
|
+
"#{alternative_base_url}#{path}"
|
73
54
|
end
|
74
55
|
end
|
75
56
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module Evervault
|
4
|
+
module Utils
|
5
|
+
class ValidationUtils
|
6
|
+
|
7
|
+
def self.validate_app_uuid_and_api_key(app_uuid, api_key)
|
8
|
+
if app_uuid.nil?
|
9
|
+
raise Evervault::Errors::AuthenticationError.new(
|
10
|
+
"No App ID provided. The App ID can be retrieved in the Evervault dashboard (App Settings)."
|
11
|
+
)
|
12
|
+
end
|
13
|
+
if api_key.nil?
|
14
|
+
raise Evervault::Errors::AuthenticationError.new(
|
15
|
+
"The provided App ID is invalid. The App ID can be retrieved in the Evervault dashboard (App Settings)."
|
16
|
+
)
|
17
|
+
end
|
18
|
+
if api_key.start_with?('ev:key')
|
19
|
+
# Scoped API key
|
20
|
+
app_uuid_hash = Digest::SHA512.base64digest(app_uuid)[0, 6]
|
21
|
+
app_uuid_hash_from_api_key = api_key.split(':')[4]
|
22
|
+
if app_uuid_hash != app_uuid_hash_from_api_key
|
23
|
+
raise Evervault::Errors::AuthenticationError.new(
|
24
|
+
"The API key is not valid for app #{app_uuid}. Make sure to use an API key belonging to the app #{app_uuid}."
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/evervault/version.rb
CHANGED
data/lib/evervault.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
require_relative "evervault/version"
|
2
2
|
require_relative "evervault/client"
|
3
3
|
require_relative "evervault/errors/errors"
|
4
|
+
require_relative "evervault/utils/validation_utils"
|
4
5
|
|
5
6
|
module Evervault
|
6
7
|
class << self
|
8
|
+
attr_accessor :app_id
|
7
9
|
attr_accessor :api_key
|
8
10
|
|
9
11
|
def encrypt(data)
|
10
12
|
client.encrypt(data)
|
11
13
|
end
|
12
14
|
|
15
|
+
def decrypt(data)
|
16
|
+
client.decrypt(data)
|
17
|
+
end
|
18
|
+
|
13
19
|
def run(function_name, encrypted_data, options = {})
|
14
20
|
client.run(function_name, encrypted_data, options)
|
15
21
|
end
|
@@ -23,12 +29,8 @@ module Evervault
|
|
23
29
|
end
|
24
30
|
|
25
31
|
private def client
|
26
|
-
|
27
|
-
|
28
|
-
"Please enter your team's API Key"
|
29
|
-
)
|
30
|
-
end
|
31
|
-
@client ||= Evervault::Client.new(api_key: api_key)
|
32
|
+
Evervault::Utils::ValidationUtils.validate_app_uuid_and_api_key(app_id, api_key)
|
33
|
+
@client ||= Evervault::Client.new(app_uuid: app_id, api_key: api_key)
|
32
34
|
end
|
33
35
|
end
|
34
36
|
end
|
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:
|
4
|
+
version: 2.0.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: 2023-
|
11
|
+
date: 2023-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- lib/evervault/http/request_handler.rb
|
43
43
|
- lib/evervault/http/request_intercept.rb
|
44
44
|
- lib/evervault/threading/repeated_timer.rb
|
45
|
+
- lib/evervault/utils/validation_utils.rb
|
45
46
|
- lib/evervault/version.rb
|
46
47
|
- res/logo.svg
|
47
48
|
- res/logo512.png
|