evervault 2.0.0 → 3.0.1
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/.changeset/config.json +15 -0
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/e2e.yml +25 -0
- data/.github/workflows/linters.yml +23 -0
- data/.github/workflows/release.yml +51 -32
- data/.github/workflows/run-tests.yml +5 -5
- data/.gitignore +7 -1
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +43 -0
- data/Gemfile +11 -8
- data/LICENSE.txt +1 -1
- data/README.md +1 -152
- data/Rakefile +21 -4
- data/bin/console +7 -4
- data/evervault.gemspec +18 -12
- data/lib/evervault/client.rb +66 -49
- data/lib/evervault/config.rb +17 -0
- data/lib/evervault/crypto/client.rb +151 -81
- data/lib/evervault/crypto/curves/base.rb +20 -10
- data/lib/evervault/crypto/curves/koblitz.rb +26 -0
- data/lib/evervault/crypto/curves/p256.rb +12 -9
- data/lib/evervault/errors/error_map.rb +24 -36
- data/lib/evervault/errors/errors.rb +15 -22
- data/lib/evervault/errors/legacy_error_map.rb +52 -0
- data/lib/evervault/http/relay_outbound_config.rb +25 -23
- data/lib/evervault/http/request.rb +26 -31
- data/lib/evervault/http/request_handler.rb +22 -25
- data/lib/evervault/http/request_intercept.rb +39 -42
- data/lib/evervault/threading/repeated_timer.rb +12 -10
- data/lib/evervault/utils/validation_utils.rb +17 -18
- data/lib/evervault/version.rb +4 -2
- data/lib/evervault.rb +35 -19
- data/package.json +11 -0
- metadata +66 -9
@@ -1,33 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Evervault
|
2
4
|
module Errors
|
3
5
|
class EvervaultError < StandardError; end
|
4
6
|
|
5
|
-
class
|
6
|
-
|
7
|
-
class HttpError < EvervaultError; end
|
8
|
-
|
9
|
-
class ResourceNotFoundError < EvervaultError; end
|
10
|
-
|
11
|
-
class AuthenticationError < EvervaultError; end
|
12
|
-
|
13
|
-
class ServerError < EvervaultError; end
|
14
|
-
|
15
|
-
class BadGatewayError < EvervaultError; end
|
16
|
-
|
17
|
-
class ServiceUnavailableError < EvervaultError; end
|
18
|
-
|
19
|
-
class BadRequestError < EvervaultError; end
|
20
|
-
|
21
|
-
class UndefinedDataError < EvervaultError; end
|
7
|
+
class FunctionError < EvervaultError; end
|
22
8
|
|
23
|
-
class
|
9
|
+
class ForbiddenIPError < FunctionError; end
|
24
10
|
|
25
|
-
class
|
11
|
+
class FunctionTimeoutError < FunctionError; end
|
26
12
|
|
27
|
-
class
|
13
|
+
class FunctionNotReadyError < FunctionError; end
|
28
14
|
|
29
|
-
class
|
15
|
+
class FunctionRuntimeError < FunctionError
|
16
|
+
attr_reader :message, :stack, :id
|
30
17
|
|
31
|
-
|
18
|
+
def initialize(message, stack, id)
|
19
|
+
@message = message
|
20
|
+
@stack = stack
|
21
|
+
@id = id
|
22
|
+
super(message.to_s)
|
23
|
+
end
|
24
|
+
end
|
32
25
|
end
|
33
26
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'errors'
|
4
|
+
|
5
|
+
module Evervault
|
6
|
+
module Errors
|
7
|
+
class LegacyErrorMap
|
8
|
+
def self.raise_errors_on_failure(status_code, body, headers)
|
9
|
+
return if status_code < 400
|
10
|
+
|
11
|
+
case status_code
|
12
|
+
when 404
|
13
|
+
raise EvervaultError, 'Resource not found'
|
14
|
+
when 400
|
15
|
+
raise EvervaultError, 'Bad request'
|
16
|
+
when 401
|
17
|
+
raise EvervaultError, 'Unauthorized'
|
18
|
+
when 403
|
19
|
+
if (headers.include? 'x-evervault-error-code') && (headers['x-evervault-error-code'] == 'forbidden-ip-error')
|
20
|
+
raise ForbiddenIPError, 'IP is not present in Cage whitelist'
|
21
|
+
end
|
22
|
+
|
23
|
+
raise EvervaultError, 'Forbidden'
|
24
|
+
|
25
|
+
when 500
|
26
|
+
raise EvervaultError, 'Server error'
|
27
|
+
when 502
|
28
|
+
raise EvervaultError, 'Bad gateway error'
|
29
|
+
when 503
|
30
|
+
raise EvervaultError, 'Service unavailable'
|
31
|
+
else
|
32
|
+
raise EvervaultError, message_for_unexpected_error_without_type(body)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def message_for_unexpected_error_without_type(error_details)
|
39
|
+
if error_details.nil?
|
40
|
+
return(
|
41
|
+
'An unexpected error occurred without message or status code. Please contact Evervault support'
|
42
|
+
)
|
43
|
+
end
|
44
|
+
message = error_details['message']
|
45
|
+
status_code = error_details['statusCode']
|
46
|
+
"An unexpected error occured. It occurred with the message: #{
|
47
|
+
message
|
48
|
+
} and http_code: '#{status_code}'. Please contact Evervault support"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Evervault
|
2
4
|
module Http
|
3
5
|
class RelayOutboundConfig
|
4
6
|
DEFAULT_POLL_INTERVAL = 5
|
5
|
-
RELAY_OUTBOUND_CONFIG_API_ENDPOINT =
|
7
|
+
RELAY_OUTBOUND_CONFIG_API_ENDPOINT = 'v2/relay-outbound'
|
6
8
|
|
7
9
|
@@destination_domains_cache = nil
|
8
10
|
@@poll_interval = DEFAULT_POLL_INTERVAL
|
@@ -11,12 +13,10 @@ module Evervault
|
|
11
13
|
def initialize(base_url:, request:)
|
12
14
|
@base_url = base_url
|
13
15
|
@request = request
|
14
|
-
if @@destination_domains_cache.nil?
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@@timer = Evervault::Threading::RepeatedTimer.new(@@poll_interval, -> { get_relay_outbound_config })
|
19
|
-
end
|
16
|
+
get_relay_outbound_config if @@destination_domains_cache.nil?
|
17
|
+
return unless @@timer.nil?
|
18
|
+
|
19
|
+
@@timer = Evervault::Threading::RepeatedTimer.new(@@poll_interval, -> { get_relay_outbound_config })
|
20
20
|
end
|
21
21
|
|
22
22
|
def get_destination_domains
|
@@ -24,32 +24,34 @@ module Evervault
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.disable_polling
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
return if @@timer.nil?
|
28
|
+
|
29
|
+
@@timer.stop
|
30
|
+
@@timer = nil
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.clear_cache
|
34
34
|
@@destination_domains_cache = nil
|
35
35
|
end
|
36
36
|
|
37
|
-
private
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
private
|
38
|
+
|
39
|
+
def get_relay_outbound_config
|
40
|
+
resp = @request.execute(:get, "#{@base_url}#{RELAY_OUTBOUND_CONFIG_API_ENDPOINT}")
|
41
|
+
poll_interval = resp.headers['x-poll-interval']
|
42
|
+
update_poll_interval(poll_interval.to_f) unless poll_interval.nil?
|
43
43
|
resp_body = JSON.parse(resp.body)
|
44
|
-
@@destination_domains_cache = resp_body[
|
44
|
+
@@destination_domains_cache = resp_body['outboundDestinations'].values.map do |outbound_destination|
|
45
|
+
outbound_destination['destinationDomain']
|
46
|
+
end
|
45
47
|
end
|
46
48
|
|
47
|
-
|
49
|
+
def update_poll_interval(poll_interval)
|
48
50
|
@@poll_interval = poll_interval
|
49
|
-
|
50
|
-
|
51
|
-
|
51
|
+
return if @@timer.nil?
|
52
|
+
|
53
|
+
@@timer.update_interval(poll_interval)
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
55
|
-
end
|
57
|
+
end
|
@@ -1,55 +1,50 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'json'
|
5
|
+
require_relative '../version'
|
6
|
+
require_relative '../errors/legacy_error_map'
|
5
7
|
|
6
8
|
module Evervault
|
7
9
|
module Http
|
8
10
|
class Request
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@
|
11
|
+
attr_reader :config
|
12
|
+
|
13
|
+
def initialize(config:)
|
14
|
+
@config = config
|
13
15
|
end
|
14
16
|
|
15
|
-
def execute(method, url, body = nil,
|
16
|
-
resp = faraday(basic_auth).public_send(method, url) do |req,
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
def execute(method, url, body = nil, basic_auth = false, error_map = Evervault::Errors::LegacyErrorMap)
|
18
|
+
resp = faraday(basic_auth).public_send(method, url) do |req, _url|
|
19
|
+
req.body = body.nil? || body.empty? ? nil : body.to_json
|
20
|
+
req.headers = build_headers(basic_auth)
|
21
|
+
req.options.timeout = config.request_timeout
|
20
22
|
end
|
21
23
|
|
22
|
-
if resp.status >= 200 && resp.status <= 300
|
23
|
-
return resp
|
24
|
-
end
|
24
|
+
return resp if resp.status >= 200 && resp.status <= 300
|
25
25
|
|
26
|
-
|
26
|
+
error_map.raise_errors_on_failure(resp.status, resp.body, resp.headers)
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
31
|
def faraday(basic_auth = false)
|
32
32
|
Faraday.new do |conn|
|
33
|
-
if basic_auth
|
34
|
-
conn.request :authorization, :basic, @app_uuid, @api_key
|
35
|
-
end
|
33
|
+
conn.request :authorization, :basic, config.app_id, config.api_key if basic_auth
|
36
34
|
end
|
37
35
|
end
|
38
36
|
|
39
|
-
def build_headers(
|
37
|
+
def build_headers(basic_auth = false)
|
40
38
|
headers = {
|
41
|
-
"AcceptEncoding":
|
42
|
-
"Accept":
|
43
|
-
"Content-Type":
|
44
|
-
"User-Agent": "evervault-ruby/#{VERSION}"
|
39
|
+
"AcceptEncoding": 'gzip, deflate',
|
40
|
+
"Accept": 'application/json',
|
41
|
+
"Content-Type": 'application/json',
|
42
|
+
"User-Agent": "evervault-ruby/#{VERSION}"
|
45
43
|
}
|
46
|
-
unless
|
47
|
-
headers = headers.merge(optional_headers)
|
48
|
-
end
|
49
|
-
if !basic_auth
|
44
|
+
unless basic_auth
|
50
45
|
headers = headers.merge({
|
51
|
-
|
52
|
-
|
46
|
+
"Api-Key": config.api_key
|
47
|
+
})
|
53
48
|
end
|
54
49
|
headers
|
55
50
|
end
|
@@ -1,56 +1,53 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'json'
|
5
|
+
require_relative '../version'
|
6
|
+
require_relative '../errors/error_map'
|
5
7
|
|
6
8
|
module Evervault
|
7
9
|
module Http
|
8
10
|
class RequestHandler
|
9
|
-
|
11
|
+
attr_reader :config
|
12
|
+
|
13
|
+
def initialize(request:, config:, cert:)
|
10
14
|
@request = request
|
11
|
-
@
|
15
|
+
@config = config
|
12
16
|
@cert = cert
|
13
17
|
end
|
14
18
|
|
15
19
|
def get(path)
|
16
|
-
if @cert.is_certificate_expired
|
17
|
-
@cert.setup()
|
18
|
-
end
|
20
|
+
@cert.setup if @cert.is_certificate_expired
|
19
21
|
resp = @request.execute(:get, build_url(path))
|
20
22
|
parse_json_body(resp.body)
|
21
23
|
end
|
22
24
|
|
23
25
|
def put(path, body)
|
24
|
-
if @cert.is_certificate_expired
|
25
|
-
@cert.setup()
|
26
|
-
end
|
26
|
+
@cert.setup if @cert.is_certificate_expired
|
27
27
|
resp = @request.execute(:put, build_url(path), body)
|
28
28
|
parse_json_body(resp.body)
|
29
29
|
end
|
30
30
|
|
31
31
|
def delete(path)
|
32
|
-
if @cert.is_certificate_expired
|
33
|
-
@cert.setup()
|
34
|
-
end
|
32
|
+
@cert.setup if @cert.is_certificate_expired
|
35
33
|
resp = @request.execute(:delete, build_url(path))
|
36
34
|
parse_json_body(resp.body)
|
37
35
|
end
|
38
36
|
|
39
|
-
def post(path, body,
|
40
|
-
if @cert.is_certificate_expired
|
41
|
-
|
42
|
-
|
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?
|
37
|
+
def post(path, body, basic_auth = false, error_map = Evervault::Errors::LegacyErrorMap)
|
38
|
+
@cert.setup if @cert.is_certificate_expired
|
39
|
+
resp = @request.execute(:post, build_url(path), body, basic_auth, error_map)
|
40
|
+
parse_json_body(resp.body) unless resp.body.empty?
|
45
41
|
end
|
46
42
|
|
47
|
-
private
|
43
|
+
private
|
44
|
+
|
45
|
+
def parse_json_body(body)
|
48
46
|
JSON.parse(body)
|
49
47
|
end
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
"#{alternative_base_url}#{path}"
|
49
|
+
def build_url(path)
|
50
|
+
"#{config.base_url}#{path}"
|
54
51
|
end
|
55
52
|
end
|
56
53
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'json'
|
5
|
+
require 'tempfile'
|
6
|
+
require 'openssl'
|
5
7
|
require 'net/http'
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
+
require_relative '../version'
|
9
|
+
require_relative '../errors/errors'
|
8
10
|
|
9
11
|
module NetHTTPOverride
|
10
12
|
@@api_key = nil
|
@@ -18,7 +20,7 @@ module NetHTTPOverride
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def self.set_relay_url(value)
|
21
|
-
relay_address_and_port = value.gsub(
|
23
|
+
relay_address_and_port = value.gsub(%r{(^\w+:|^)//}, '').split(':')
|
22
24
|
@@relay_url = relay_address_and_port[0]
|
23
25
|
@@relay_port = relay_address_and_port[1]
|
24
26
|
end
|
@@ -35,14 +37,14 @@ module NetHTTPOverride
|
|
35
37
|
if @@get_decryption_domains_func.nil?
|
36
38
|
false
|
37
39
|
else
|
38
|
-
decryption_domains = @@get_decryption_domains_func.call
|
39
|
-
decryption_domains.any?
|
40
|
-
if decryption_domain.start_with?(
|
41
|
-
domain.end_with?(decryption_domain[1
|
40
|
+
decryption_domains = @@get_decryption_domains_func.call
|
41
|
+
decryption_domains.any? do |decryption_domain|
|
42
|
+
if decryption_domain.start_with?('*')
|
43
|
+
domain.end_with?(decryption_domain[1..])
|
42
44
|
else
|
43
45
|
domain == decryption_domain
|
44
46
|
end
|
45
|
-
|
47
|
+
end
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
@@ -59,9 +61,7 @@ module NetHTTPOverride
|
|
59
61
|
|
60
62
|
def request_with_intercept(req, body = nil, &block)
|
61
63
|
should_decrypt = NetHTTPOverride.should_decrypt(@address)
|
62
|
-
if should_decrypt
|
63
|
-
req["Proxy-Authorization"] = @@api_key
|
64
|
-
end
|
64
|
+
req['Proxy-Authorization'] = @@api_key if should_decrypt
|
65
65
|
request_without_intercept(req, body, &block)
|
66
66
|
end
|
67
67
|
end
|
@@ -77,58 +77,58 @@ end
|
|
77
77
|
module Evervault
|
78
78
|
module Http
|
79
79
|
class RequestIntercept
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
80
|
+
attr_reader :config
|
81
|
+
|
82
|
+
def initialize(request:, config:)
|
83
|
+
@config = config
|
84
|
+
NetHTTPOverride.set_api_key(config.api_key)
|
85
|
+
NetHTTPOverride.set_relay_url(config.relay_url)
|
86
|
+
|
84
87
|
@request = request
|
85
|
-
@base_url = base_url
|
86
|
-
@ca_host = ca_host
|
87
88
|
@expire_date = nil
|
88
89
|
@initial_date = nil
|
89
90
|
end
|
90
91
|
|
91
|
-
def is_certificate_expired
|
92
|
+
def is_certificate_expired
|
92
93
|
if @expire_date
|
93
94
|
now = Time.now
|
94
|
-
if now > @expire_date || now < @initial_date
|
95
|
-
return true
|
96
|
-
end
|
95
|
+
return true if now > @expire_date || now < @initial_date
|
97
96
|
end
|
98
|
-
|
97
|
+
false
|
99
98
|
end
|
100
99
|
|
101
100
|
def setup_decryption_domains(decryption_domains)
|
102
|
-
NetHTTPOverride.add_get_decryption_domains_func(
|
101
|
+
NetHTTPOverride.add_get_decryption_domains_func(lambda {
|
103
102
|
decryption_domains
|
104
103
|
})
|
105
104
|
end
|
106
105
|
|
107
106
|
def setup_outbound_relay_config
|
108
|
-
@relay_outbound_config = Evervault::Http::RelayOutboundConfig.new(base_url:
|
109
|
-
NetHTTPOverride.add_get_decryption_domains_func(
|
107
|
+
@relay_outbound_config = Evervault::Http::RelayOutboundConfig.new(base_url: config.base_url, request: @request)
|
108
|
+
NetHTTPOverride.add_get_decryption_domains_func(lambda {
|
110
109
|
@relay_outbound_config.get_destination_domains
|
111
110
|
})
|
112
111
|
end
|
113
112
|
|
114
113
|
def setup
|
115
|
-
get_cert
|
114
|
+
get_cert
|
116
115
|
end
|
117
116
|
|
118
|
-
def get_cert
|
117
|
+
def get_cert
|
119
118
|
ca_content = nil
|
120
119
|
i = 0
|
121
120
|
|
122
121
|
while !ca_content && i < 1
|
123
122
|
i += 1
|
124
123
|
begin
|
125
|
-
ca_content = @request.execute(
|
126
|
-
rescue
|
124
|
+
ca_content = @request.execute('get', config.ca_host).body
|
125
|
+
rescue StandardError
|
127
126
|
end
|
128
127
|
end
|
129
128
|
|
130
|
-
if !ca_content || ca_content ==
|
131
|
-
raise Evervault::Errors::
|
129
|
+
if !ca_content || ca_content == ''
|
130
|
+
raise Evervault::Errors::EvervaultError,
|
131
|
+
"Unable to install the Evervault root certificate from #{config.ca_host}"
|
132
132
|
end
|
133
133
|
|
134
134
|
cert = OpenSSL::X509::Certificate.new ca_content
|
@@ -137,14 +137,11 @@ module Evervault
|
|
137
137
|
end
|
138
138
|
|
139
139
|
def set_cert_expire_date(cert)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
@expire_date = nil
|
145
|
-
end
|
140
|
+
@expire_date = cert.not_after
|
141
|
+
@initial_date = cert.not_before
|
142
|
+
rescue StandardError
|
143
|
+
@expire_date = nil
|
146
144
|
end
|
147
145
|
end
|
148
146
|
end
|
149
147
|
end
|
150
|
-
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Evervault
|
2
4
|
module Threading
|
3
5
|
class RepeatedTimer
|
@@ -9,15 +11,15 @@ module Evervault
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def start
|
12
|
-
if
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
return if running?
|
15
|
+
|
16
|
+
@thread = Thread.new do
|
17
|
+
loop do
|
18
|
+
sleep @interval
|
19
|
+
begin
|
20
|
+
@func.call
|
21
|
+
rescue StandardError
|
22
|
+
# Silently ignore exceptions
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
@@ -37,4 +39,4 @@ module Evervault
|
|
37
39
|
end
|
38
40
|
end
|
39
41
|
end
|
40
|
-
end
|
42
|
+
end
|
@@ -1,31 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'digest'
|
2
4
|
|
3
5
|
module Evervault
|
4
6
|
module Utils
|
5
7
|
class ValidationUtils
|
6
|
-
|
7
8
|
def self.validate_app_uuid_and_api_key(app_uuid, api_key)
|
8
9
|
if app_uuid.nil?
|
9
|
-
raise Evervault::Errors::
|
10
|
-
|
11
|
-
)
|
10
|
+
raise Evervault::Errors::EvervaultError,
|
11
|
+
'No App ID provided. The App ID can be retrieved in the Evervault dashboard (App Settings).'
|
12
12
|
end
|
13
13
|
if api_key.nil?
|
14
|
-
raise Evervault::Errors::
|
15
|
-
|
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
|
14
|
+
raise Evervault::Errors::EvervaultError,
|
15
|
+
'The provided App ID is invalid. The App ID can be retrieved in the Evervault dashboard (App Settings).'
|
27
16
|
end
|
17
|
+
return unless api_key.start_with?('ev:key')
|
18
|
+
|
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
|
+
return unless app_uuid_hash != app_uuid_hash_from_api_key
|
23
|
+
|
24
|
+
raise Evervault::Errors::EvervaultError,
|
25
|
+
"The API key is not valid for app #{app_uuid}. Make sure to use an API key belonging to the ap'\
|
26
|
+
'p #{app_uuid}."
|
28
27
|
end
|
29
28
|
end
|
30
29
|
end
|
31
|
-
end
|
30
|
+
end
|
data/lib/evervault/version.rb
CHANGED
data/lib/evervault.rb
CHANGED
@@ -1,36 +1,52 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require_relative
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
require_relative 'evervault/version'
|
5
|
+
require_relative 'evervault/client'
|
6
|
+
require_relative 'evervault/config'
|
7
|
+
require_relative 'evervault/errors/errors'
|
8
|
+
require_relative 'evervault/utils/validation_utils'
|
5
9
|
|
6
10
|
module Evervault
|
7
11
|
class << self
|
8
|
-
attr_accessor :app_id
|
9
|
-
|
12
|
+
attr_accessor :app_id, :api_key
|
13
|
+
|
14
|
+
def encrypt(...)
|
15
|
+
client.encrypt(...)
|
16
|
+
end
|
10
17
|
|
11
|
-
def
|
12
|
-
client.
|
18
|
+
def decrypt(...)
|
19
|
+
client.decrypt(...)
|
13
20
|
end
|
14
21
|
|
15
|
-
def
|
16
|
-
client.
|
22
|
+
def run(...)
|
23
|
+
client.run(...)
|
17
24
|
end
|
18
25
|
|
19
|
-
def
|
20
|
-
client.
|
26
|
+
def enable_outbound_relay(...)
|
27
|
+
client.enable_outbound_relay(...)
|
21
28
|
end
|
22
29
|
|
23
|
-
def
|
24
|
-
client.
|
30
|
+
def create_run_token(...)
|
31
|
+
client.create_run_token(...)
|
25
32
|
end
|
26
33
|
|
27
|
-
def
|
28
|
-
|
34
|
+
def create_client_side_decrypt_token(data, expiry = nil)
|
35
|
+
expiry = (expiry.to_f * 1000).to_i unless expiry.nil?
|
36
|
+
client.create_token('api:decrypt', data, expiry)
|
29
37
|
end
|
30
38
|
|
31
|
-
|
32
|
-
|
33
|
-
|
39
|
+
def configure(...)
|
40
|
+
client.configure(...)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def client
|
46
|
+
@client ||= begin
|
47
|
+
Evervault::Utils::ValidationUtils.validate_app_uuid_and_api_key(app_id, api_key)
|
48
|
+
Evervault::Client.new(app_uuid: app_id, api_key: api_key)
|
49
|
+
end
|
34
50
|
end
|
35
51
|
end
|
36
52
|
end
|