vault-rails 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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.