vault-rails 0.2.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2372e9033c1ad9acaed9ba40d0a16ecaf9255389
4
- data.tar.gz: 1ad8eba93c1e7214da702473a92729131902ccb5
3
+ metadata.gz: 7c8f664265ab1fa257f49bae1035a07ce66ab25c
4
+ data.tar.gz: 0afe845824aa882453dd07574e895b4a09e8fda1
5
5
  SHA512:
6
- metadata.gz: 5fb7fc74a89248efa68c5dd0698fa08940b44d1cf129957b30922b19765b2d5a121f34c1aa821f9c9b944794a488d31ef97932d31c55aaab7867c2b382824fb8
7
- data.tar.gz: 685d0b2d9a6ea88c0308defc8e7dd06f806b0dbf06d19bc3faf8d4e58353564cc37df8cf009063d5b6a61db35a4adf385e25c5140d711f0e3d92912fd41c67c2
6
+ metadata.gz: c7dd41623f7b78a7fe21aaaa0d53ff6be679dfc211d6f4da409216d58505663f71f615170a619eb9a5a1304903761ef7a46b754c90024b1d40d0a56cda8299b7
7
+ data.tar.gz: 0421c3b2d52fd8dd1355e5a9f4a41b4607c946ba5477d7d6c3c7592fc220ed6fc4ef7968dd05709d84dd93bb36fed31bb306c9b8bc1f6d2a918dca62137e08fd
@@ -11,8 +11,6 @@ require_relative "rails/version"
11
11
 
12
12
  module Vault
13
13
  module Rails
14
- extend Vault::Rails::Configurable
15
-
16
14
  # The list of serializers.
17
15
  #
18
16
  # @return [Hash<Symbol, Module>]
@@ -29,199 +27,208 @@ module Vault
29
27
  DEV_WARNING = "[vault-rails] Using in-memory cipher - this is not secure " \
30
28
  "and should never be used in production-like environments!".freeze
31
29
 
32
- # API client object based off the configured options in
33
- # {Vault::Configurable}.
34
- #
35
- # @return [Vault::Client]
36
- def self.client
37
- if !defined?(@client) || !@client.same_options?(options)
38
- @client = Vault::Client.new(options)
39
- end
40
- return @client
41
- end
30
+ class << self
31
+ # API client object based off the configured options in {Configurable}.
32
+ #
33
+ # @return [Vault::Client]
34
+ attr_reader :client
42
35
 
43
- # Delegate all methods to the client object, essentially making the module
44
- # object behave like a {Vault::Client}.
45
- def self.method_missing(m, *args, &block)
46
- if client.respond_to?(m)
47
- client.public_send(m, *args, &block)
48
- else
49
- super
50
- end
51
- end
36
+ def setup!
37
+ Vault.setup!
52
38
 
53
- # Delegating `respond_to` to the {Vault::Client}.
54
- def self.respond_to_missing?(m, include_private = false)
55
- client.respond_to?(m) || super
56
- end
39
+ @client = Vault.client
40
+ @client.class.instance_eval do
41
+ include Vault::Rails::Configurable
42
+ end
57
43
 
58
- # Encrypt the given plaintext data using the provided mount and key.
59
- #
60
- # @param [String] path
61
- # the mount point
62
- # @param [String] key
63
- # the key to encrypt at
64
- # @param [String] plaintext
65
- # the plaintext to encrypt
66
- # @param [Vault::Client] client
67
- # the Vault client to use
68
- #
69
- # @return [String]
70
- # the encrypted cipher text
71
- def self.encrypt(path, key, plaintext, client = self.client)
72
- if plaintext.blank?
73
- return plaintext
44
+ self
74
45
  end
75
46
 
76
- path = path.to_s if !path.is_a?(String)
77
- key = key.to_s if !key.is_a?(String)
78
-
79
- with_retries do
80
- if self.enabled?
81
- result = self.vault_encrypt(path, key, plaintext, client)
47
+ # Delegate all methods to the client object, essentially making the module
48
+ # object behave like a {Vault::Client}.
49
+ def method_missing(m, *args, &block)
50
+ if client.respond_to?(m)
51
+ client.public_send(m, *args, &block)
82
52
  else
83
- result = self.memory_encrypt(path, key, plaintext, client)
53
+ super
84
54
  end
85
-
86
- return self.force_encoding(result)
87
55
  end
88
- end
89
56
 
90
- # Decrypt the given ciphertext data using the provided mount and key.
91
- #
92
- # @param [String] path
93
- # the mount point
94
- # @param [String] key
95
- # the key to decrypt at
96
- # @param [String] ciphertext
97
- # the ciphertext to decrypt
98
- # @param [Vault::Client] client
99
- # the Vault client to use
100
- #
101
- # @return [String]
102
- # the decrypted plaintext text
103
- def self.decrypt(path, key, ciphertext, client = self.client)
104
- if ciphertext.blank?
105
- return ciphertext
57
+ # Delegating `respond_to` to the {Vault::Client}.
58
+ def respond_to_missing?(m, include_private = false)
59
+ client.respond_to?(m, include_private) || super
106
60
  end
107
61
 
108
- path = path.to_s if !path.is_a?(String)
109
- key = key.to_s if !key.is_a?(String)
62
+ # Encrypt the given plaintext data using the provided mount and key.
63
+ #
64
+ # @param [String] path
65
+ # the mount point
66
+ # @param [String] key
67
+ # the key to encrypt at
68
+ # @param [String] plaintext
69
+ # the plaintext to encrypt
70
+ # @param [Vault::Client] client
71
+ # the Vault client to use
72
+ #
73
+ # @return [String]
74
+ # the encrypted cipher text
75
+ def encrypt(path, key, plaintext, client = self.client)
76
+ if plaintext.blank?
77
+ return plaintext
78
+ end
110
79
 
111
- with_retries do
112
- if self.enabled?
113
- result = self.vault_decrypt(path, key, ciphertext, client)
114
- else
115
- result = self.memory_decrypt(path, key, ciphertext, client)
80
+ path = path.to_s if !path.is_a?(String)
81
+ key = key.to_s if !key.is_a?(String)
82
+
83
+ with_retries do
84
+ if self.enabled?
85
+ result = self.vault_encrypt(path, key, plaintext, client)
86
+ else
87
+ result = self.memory_encrypt(path, key, plaintext, client)
88
+ end
89
+
90
+ return self.force_encoding(result)
91
+ end
92
+ end
93
+
94
+ # Decrypt the given ciphertext data using the provided mount and key.
95
+ #
96
+ # @param [String] path
97
+ # the mount point
98
+ # @param [String] key
99
+ # the key to decrypt at
100
+ # @param [String] ciphertext
101
+ # the ciphertext to decrypt
102
+ # @param [Vault::Client] client
103
+ # the Vault client to use
104
+ #
105
+ # @return [String]
106
+ # the decrypted plaintext text
107
+ def decrypt(path, key, ciphertext, client = self.client)
108
+ if ciphertext.blank?
109
+ return ciphertext
116
110
  end
117
111
 
118
- return self.force_encoding(result)
112
+ path = path.to_s if !path.is_a?(String)
113
+ key = key.to_s if !key.is_a?(String)
114
+
115
+ with_retries do
116
+ if self.enabled?
117
+ result = self.vault_decrypt(path, key, ciphertext, client)
118
+ else
119
+ result = self.memory_decrypt(path, key, ciphertext, client)
120
+ end
121
+
122
+ return self.force_encoding(result)
123
+ end
119
124
  end
120
- end
121
125
 
122
- # Get the serializer that corresponds to the given key. If the key does not
123
- # correspond to a known serializer, an exception will be raised.
124
- #
125
- # @param [#to_sym] key
126
- # the name of the serializer
127
- #
128
- # @return [~Serializer]
129
- def self.serializer_for(key)
130
- key = key.to_sym if !key.is_a?(Symbol)
131
-
132
- if serializer = SERIALIZERS[key]
133
- return serializer
134
- else
135
- raise Vault::Rails::UnknownSerializerError.new(key)
126
+ # Get the serializer that corresponds to the given key. If the key does not
127
+ # correspond to a known serializer, an exception will be raised.
128
+ #
129
+ # @param [#to_sym] key
130
+ # the name of the serializer
131
+ #
132
+ # @return [~Serializer]
133
+ def serializer_for(key)
134
+ key = key.to_sym if !key.is_a?(Symbol)
135
+
136
+ if serializer = SERIALIZERS[key]
137
+ return serializer
138
+ else
139
+ raise Vault::Rails::UnknownSerializerError.new(key)
140
+ end
136
141
  end
137
- end
138
142
 
139
- private
143
+ protected
140
144
 
141
- # Perform in-memory encryption. This is useful for testing and development.
142
- def self.memory_encrypt(path, key, plaintext, client)
143
- log_warning(DEV_WARNING)
145
+ # Perform in-memory encryption. This is useful for testing and development.
146
+ def memory_encrypt(path, key, plaintext, client)
147
+ log_warning(DEV_WARNING)
144
148
 
145
- return nil if plaintext.nil?
149
+ return nil if plaintext.nil?
146
150
 
147
- cipher = OpenSSL::Cipher::AES.new(128, :CBC)
148
- cipher.encrypt
149
- cipher.key = memory_key_for(path, key)
150
- return Base64.strict_encode64(cipher.update(plaintext) + cipher.final)
151
- end
151
+ cipher = OpenSSL::Cipher::AES.new(128, :CBC)
152
+ cipher.encrypt
153
+ cipher.key = memory_key_for(path, key)
154
+ return Base64.strict_encode64(cipher.update(plaintext) + cipher.final)
155
+ end
152
156
 
153
- # Perform in-memory decryption. This is useful for testing and development.
154
- def self.memory_decrypt(path, key, ciphertext, client)
155
- log_warning(DEV_WARNING)
157
+ # Perform in-memory decryption. This is useful for testing and development.
158
+ def memory_decrypt(path, key, ciphertext, client)
159
+ log_warning(DEV_WARNING)
156
160
 
157
- return nil if ciphertext.nil?
161
+ return nil if ciphertext.nil?
158
162
 
159
- cipher = OpenSSL::Cipher::AES.new(128, :CBC)
160
- cipher.decrypt
161
- cipher.key = memory_key_for(path, key)
162
- return cipher.update(Base64.strict_decode64(ciphertext)) + cipher.final
163
- end
163
+ cipher = OpenSSL::Cipher::AES.new(128, :CBC)
164
+ cipher.decrypt
165
+ cipher.key = memory_key_for(path, key)
166
+ return cipher.update(Base64.strict_decode64(ciphertext)) + cipher.final
167
+ end
164
168
 
165
- # Perform encryption using Vault. This will raise exceptions if Vault is
166
- # unavailable.
167
- def self.vault_encrypt(path, key, plaintext, client)
168
- return nil if plaintext.nil?
169
+ # Perform encryption using Vault. This will raise exceptions if Vault is
170
+ # unavailable.
171
+ def vault_encrypt(path, key, plaintext, client)
172
+ return nil if plaintext.nil?
169
173
 
170
- route = File.join(path, "encrypt", key)
171
- secret = client.logical.write(route,
172
- plaintext: Base64.strict_encode64(plaintext),
173
- )
174
- return secret.data[:ciphertext]
175
- end
174
+ route = File.join(path, "encrypt", key)
175
+ secret = client.logical.write(route,
176
+ plaintext: Base64.strict_encode64(plaintext),
177
+ )
178
+ return secret.data[:ciphertext]
179
+ end
176
180
 
177
- # Perform decryption using Vault. This will raise exceptions if Vault is
178
- # unavailable.
179
- def self.vault_decrypt(path, key, ciphertext, client)
180
- return nil if ciphertext.nil?
181
+ # Perform decryption using Vault. This will raise exceptions if Vault is
182
+ # unavailable.
183
+ def vault_decrypt(path, key, ciphertext, client)
184
+ return nil if ciphertext.nil?
181
185
 
182
- route = File.join(path, "decrypt", key)
183
- secret = client.logical.write(route, ciphertext: ciphertext)
184
- return Base64.strict_decode64(secret.data[:plaintext])
185
- end
186
+ route = File.join(path, "decrypt", key)
187
+ secret = client.logical.write(route, ciphertext: ciphertext)
188
+ return Base64.strict_decode64(secret.data[:plaintext])
189
+ end
186
190
 
187
- # The symmetric key for the given params.
188
- # @return [String]
189
- def self.memory_key_for(path, key)
190
- return Base64.strict_encode64("#{path}/#{key}".ljust(32, "x"))
191
- end
191
+ # The symmetric key for the given params.
192
+ # @return [String]
193
+ def memory_key_for(path, key)
194
+ return Base64.strict_encode64("#{path}/#{key}".ljust(32, "x"))
195
+ end
192
196
 
193
- # Forces the encoding into the default Rails encoding and returns the
194
- # newly encoded string.
195
- # @return [String]
196
- def self.force_encoding(str)
197
- encoding = ::Rails.application.config.encoding || DEFAULT_ENCODING
198
- str.force_encoding(encoding).encode(encoding)
199
- end
197
+ # Forces the encoding into the default Rails encoding and returns the
198
+ # newly encoded string.
199
+ # @return [String]
200
+ def force_encoding(str)
201
+ encoding = ::Rails.application.config.encoding || DEFAULT_ENCODING
202
+ str.force_encoding(encoding).encode(encoding)
203
+ end
200
204
 
201
- private
205
+ private
202
206
 
203
- def self.with_retries(client = self.client, &block)
204
- exceptions = [Vault::HTTPConnectionError, Vault::HTTPServerError]
205
- options = {
206
- attempts: self.retry_attempts,
207
- base: self.retry_base,
208
- max_wait: self.retry_max_wait,
209
- }
207
+ def with_retries(client = self.client, &block)
208
+ exceptions = [Vault::HTTPConnectionError, Vault::HTTPServerError]
209
+ options = {
210
+ attempts: self.retry_attempts,
211
+ base: self.retry_base,
212
+ max_wait: self.retry_max_wait,
213
+ }
210
214
 
211
- client.with_retries(exceptions, options) do |i, e|
212
- if !e.nil?
213
- log_warning "[vault-rails] (#{i}) An error occurred when trying to " \
214
- "communicate with Vault: #{e.message}"
215
- end
215
+ client.with_retries(*exceptions, options) do |i, e|
216
+ if !e.nil?
217
+ log_warning "[vault-rails] (#{i}) An error occurred when trying to " \
218
+ "communicate with Vault: #{e.message}"
219
+ end
216
220
 
217
- yield
221
+ yield
222
+ end
218
223
  end
219
- end
220
224
 
221
- def self.log_warning(msg)
222
- if defined?(::Rails) && ::Rails.logger != nil
223
- ::Rails.logger.warn { msg }
225
+ def log_warning(msg)
226
+ if defined?(::Rails) && ::Rails.logger != nil
227
+ ::Rails.logger.warn { msg }
228
+ end
224
229
  end
225
230
  end
226
231
  end
227
232
  end
233
+
234
+ Vault::Rails.setup!
@@ -1,5 +1,5 @@
1
1
  module Vault
2
2
  module Rails
3
- VERSION = "0.2.0"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -22,15 +22,17 @@ Rails.application.configure do
22
22
  # Raise an error on page load if there are pending migrations.
23
23
  config.active_record.migration_error = :page_load
24
24
 
25
- # Debug mode disables concatenation and preprocessing of assets.
26
- # This option may cause significant delays in view rendering with a large
27
- # number of complex assets.
28
- config.assets.debug = true
29
-
30
- # Adds additional error checking when serving assets at runtime.
31
- # Checks for improperly declared sprockets dependencies.
32
- # Raises helpful error messages.
33
- config.assets.raise_runtime_errors = true
25
+ if config.respond_to?(:assets)
26
+ # Debug mode disables concatenation and preprocessing of assets.
27
+ # This option may cause significant delays in view rendering with a large
28
+ # number of complex assets.
29
+ config.assets.debug = true
30
+
31
+ # Adds additional error checking when serving assets at runtime.
32
+ # Checks for improperly declared sprockets dependencies.
33
+ # Raises helpful error messages.
34
+ config.assets.raise_runtime_errors = true
35
+ end
34
36
 
35
37
  # Raises error for missing translations
36
38
  # config.action_view.raise_on_missing_translations = true
@@ -13,8 +13,13 @@ Rails.application.configure do
13
13
  config.eager_load = false
14
14
 
15
15
  # Configure static asset server for tests with Cache-Control for performance.
16
- config.serve_static_files = true
17
- config.static_cache_control = 'public, max-age=3600'
16
+ if config.respond_to?(:public_file_server)
17
+ config.public_file_server.enabled = true
18
+ config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
19
+ else
20
+ config.serve_static_files = true
21
+ config.static_cache_control = 'public, max-age=3600'
22
+ end
18
23
 
19
24
  # Show full error reports and disable caching.
20
25
  config.consider_all_requests_local = true
@@ -1,7 +1,9 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
3
  # Version of your assets, change this if you want to expire all your assets.
4
- Rails.application.config.assets.version = '1.0'
4
+ if Rails.application.config.respond_to?(:assets)
5
+ Rails.application.config.assets.version = '1.0'
6
+ end
5
7
 
6
8
  # Precompile additional assets.
7
9
  # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.