symmetric-encryption 3.8.3 → 3.9.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/README.md +2 -2
- data/Rakefile +16 -16
- data/examples/symmetric-encryption.yml +33 -38
- data/lib/rails/generators/symmetric_encryption/config/templates/symmetric-encryption.yml +10 -14
- data/lib/rails/generators/symmetric_encryption/heroku_config/templates/symmetric-encryption.yml +28 -25
- data/lib/symmetric_encryption.rb +14 -6
- data/lib/symmetric_encryption/cipher.rb +151 -130
- data/lib/symmetric_encryption/config.rb +0 -1
- data/lib/symmetric_encryption/encoder.rb +79 -0
- data/lib/symmetric_encryption/extensions/active_record/base.rb +94 -134
- data/lib/symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key.rb +3 -89
- data/lib/symmetric_encryption/key_encryption_key.rb +32 -0
- data/lib/symmetric_encryption/railtie.rb +3 -3
- data/lib/symmetric_encryption/symmetric_encryption.rb +41 -8
- data/lib/symmetric_encryption/utils/re_encrypt_config_files.rb +82 -0
- data/lib/symmetric_encryption/version.rb +1 -1
- data/test/active_record_test.rb +149 -140
- data/test/cipher_test.rb +98 -6
- data/test/config/{mongoid_v5.yml → mongoid.yml} +0 -0
- data/test/config/symmetric-encryption.yml +4 -10
- data/test/config/test_new.key +2 -2
- data/test/encoder_test.rb +61 -0
- data/test/mongoid_test.rb +12 -22
- data/test/reader_test.rb +16 -11
- data/test/symmetric_encryption_test.rb +23 -3
- data/test/test_db.sqlite3 +0 -0
- data/test/test_helper.rb +2 -16
- data/test/writer_test.rb +1 -5
- metadata +11 -12
- data/test/config/mongoid_v2.yml +0 -6
- data/test/config/mongoid_v3.yml +0 -9
- data/test/mongo_mapper_test.rb +0 -599
@@ -8,7 +8,7 @@ module SymmetricEncryption #:nodoc:
|
|
8
8
|
# module MyApplication
|
9
9
|
# class Application < Rails::Application
|
10
10
|
# config.symmetric_encryption.cipher = SymmetricEncryption::Cipher.new(
|
11
|
-
# key: '
|
11
|
+
# key: '1234567890ABCDEF',
|
12
12
|
# iv: '1234567890ABCDEF',
|
13
13
|
# cipher_name: 'aes-128-cbc'
|
14
14
|
# )
|
@@ -26,8 +26,8 @@ module SymmetricEncryption #:nodoc:
|
|
26
26
|
# @example symmetric-encryption.yml
|
27
27
|
#
|
28
28
|
# development:
|
29
|
-
# cipher_name: aes-
|
30
|
-
# key:
|
29
|
+
# cipher_name: aes-128-cbc
|
30
|
+
# key: 1234567890ABCDEF
|
31
31
|
# iv: 1234567890ABCDEF
|
32
32
|
#
|
33
33
|
# Loaded before Active Record initializes since database.yml can have encrypted
|
@@ -33,7 +33,7 @@ module SymmetricEncryption
|
|
33
33
|
# Example: For testing purposes the following test cipher can be used:
|
34
34
|
#
|
35
35
|
# SymmetricEncryption.cipher = SymmetricEncryption::Cipher.new(
|
36
|
-
# key: '
|
36
|
+
# key: '1234567890ABCDEF',
|
37
37
|
# iv: '1234567890ABCDEF',
|
38
38
|
# cipher: 'aes-128-cbc'
|
39
39
|
# )
|
@@ -253,7 +253,7 @@ module SymmetricEncryption
|
|
253
253
|
# environment:
|
254
254
|
# Which environments config to load. Usually: production, development, etc.
|
255
255
|
# Default: Rails.env
|
256
|
-
def self.load!(filename=nil, environment=nil)
|
256
|
+
def self.load!(filename = nil, environment = nil)
|
257
257
|
Config.load!(filename, environment)
|
258
258
|
end
|
259
259
|
|
@@ -261,18 +261,51 @@ module SymmetricEncryption
|
|
261
261
|
#
|
262
262
|
# Note: Only the current Encryption key settings are used
|
263
263
|
#
|
264
|
-
# Creates Symmetric Key .key
|
265
|
-
#
|
266
|
-
# which is encrypted with the above Public key
|
264
|
+
# Creates Symmetric Key .key and initialization vector .iv
|
265
|
+
# which is encrypted with the key encryption key.
|
267
266
|
#
|
268
267
|
# Existing key files will be renamed if present
|
269
|
-
def self.generate_symmetric_key_files(filename=nil, environment=nil)
|
268
|
+
def self.generate_symmetric_key_files(filename = nil, environment = nil)
|
270
269
|
config = Config.read_config(filename, environment)
|
271
270
|
|
272
271
|
# Only regenerating the first configured cipher
|
273
272
|
cipher_config = config[:ciphers].first
|
274
|
-
|
275
|
-
|
273
|
+
|
274
|
+
# Delete unused config keys to generate new random keys
|
275
|
+
[:version, :always_add_header].each do |key|
|
276
|
+
cipher_config.delete(key)
|
277
|
+
end
|
278
|
+
|
279
|
+
key_config = {private_rsa_key: config[:private_rsa_key]}
|
280
|
+
cipher_cfg = Cipher.generate_random_keys(key_config.merge(cipher_config))
|
281
|
+
|
282
|
+
puts
|
283
|
+
if encoded_encrypted_key = cipher_cfg[:encrypted_key]
|
284
|
+
puts 'If running in Heroku, add the environment specific key:'
|
285
|
+
puts "heroku config:add #{environment.upcase}_KEY1=#{encoded_encrypted_key}\n"
|
286
|
+
end
|
287
|
+
|
288
|
+
if encoded_encrypted_iv = cipher_cfg[:encrypted_iv]
|
289
|
+
puts 'If running in Heroku, add the environment specific key:'
|
290
|
+
puts "heroku config:add #{environment.upcase}_IV1=#{encoded_encrypted_iv}"
|
291
|
+
end
|
292
|
+
|
293
|
+
if key = cipher_cfg[:key]
|
294
|
+
puts "Please add the key: #{key} to your config file"
|
295
|
+
end
|
296
|
+
|
297
|
+
if iv = cipher_cfg[:iv]
|
298
|
+
puts "Please add the iv: #{iv} to your config file"
|
299
|
+
end
|
300
|
+
|
301
|
+
if file_name = cipher_cfg[:key_filename]
|
302
|
+
puts("Please copy #{file_name} to the other servers in #{environment}.")
|
303
|
+
end
|
304
|
+
|
305
|
+
if file_name = cipher_cfg[:iv_filename]
|
306
|
+
puts("Please copy #{file_name} to the other servers in #{environment}.")
|
307
|
+
end
|
308
|
+
cipher_cfg
|
276
309
|
end
|
277
310
|
|
278
311
|
# Generate a 22 character random password
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# Used for re-encrypting encrypted passwords stored in configuration files.
|
2
|
+
#
|
3
|
+
# Search for `SymmetricEncryption.try_decrypt` in config files and replace the
|
4
|
+
# encrypted value with one encrypted using the new encryption key.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# re_encrypt = SymmetricEncryption::Utils::ReEncryptConfigFiles.new(version: 4)
|
8
|
+
# re_encrypt.process_directory('../../**/*.yml')
|
9
|
+
module SymmetricEncryption
|
10
|
+
module Utils
|
11
|
+
class ReEncryptConfigFiles
|
12
|
+
DEFAULT_REGEXP = /\A(.*)SymmetricEncryption.try_decrypt[\s\(\"\'].([\w@=+\/\\]+)[\'\"](.*)\Z/
|
13
|
+
|
14
|
+
attr_accessor :cipher, :path, :search_regexp
|
15
|
+
|
16
|
+
# Parameters:
|
17
|
+
# version: [Integer]
|
18
|
+
# Version of the encryption key to use when re-encrypting the value.
|
19
|
+
# Default: Default cipher ( first in the list of configured ciphers )
|
20
|
+
def initialize(params={})
|
21
|
+
params = params.dup
|
22
|
+
version = params.delete(:version)
|
23
|
+
@path = params.delete(:path)
|
24
|
+
@search_regexp = params.delete(:search_regexp) || DEFAULT_REGEXP
|
25
|
+
@cipher = SymmetricEncryption.cipher(version)
|
26
|
+
raise(ArgumentError, "Undefined encryption key version: #{version}") if @cipher.nil?
|
27
|
+
raise(ArgumentError, "Unknown parameters: #{params.inspect}") if params.size > 0
|
28
|
+
end
|
29
|
+
|
30
|
+
# Re-encrypt the supplied enctrypted value with the new cipher
|
31
|
+
def re_encrypt(encrypted)
|
32
|
+
if unencrypted = SymmetricEncryption.try_decrypt(encrypted)
|
33
|
+
cipher.encrypt(unencrypted)
|
34
|
+
else
|
35
|
+
encrypted
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Process a single file.
|
40
|
+
#
|
41
|
+
# Returns [true|false] whether the file was modified
|
42
|
+
def process_file(file_name)
|
43
|
+
match = false
|
44
|
+
lines = File.read(file_name)
|
45
|
+
output_lines = ''
|
46
|
+
lines.each_line do |line|
|
47
|
+
if result = line.match(search_regexp)
|
48
|
+
before_str = result[1]
|
49
|
+
encrypted = result[2]
|
50
|
+
after_str = result[3]
|
51
|
+
after_str = after_str[1..-1] if after_str.starts_with?(')')
|
52
|
+
new_value = re_encrypt(encrypted)
|
53
|
+
if new_value != encrypted
|
54
|
+
match = true
|
55
|
+
output_lines << "#{before_str}SymmetricEncryption.try_decrypt('#{new_value}')#{after_str}\n"
|
56
|
+
else
|
57
|
+
output_lines << line
|
58
|
+
end
|
59
|
+
else
|
60
|
+
output_lines << line
|
61
|
+
end
|
62
|
+
end
|
63
|
+
if match
|
64
|
+
File.open(file_name, 'wb') { |file| file.write(output_lines) }
|
65
|
+
end
|
66
|
+
match
|
67
|
+
end
|
68
|
+
|
69
|
+
# Process a directory of files.
|
70
|
+
#
|
71
|
+
# Parameters:
|
72
|
+
# path: [String]
|
73
|
+
# Search path to look for files in.
|
74
|
+
# Example: '../../**/*.yml'
|
75
|
+
def process_directory(path)
|
76
|
+
Dir[path].each do |file_name|
|
77
|
+
process_file(file_name)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/test/active_record_test.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
|
-
ActiveRecord::Base.logger = SemanticLogger[ActiveRecord]
|
4
3
|
ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read('test/config/database.yml')).result)
|
5
4
|
ActiveRecord::Base.establish_connection(:test)
|
6
5
|
|
@@ -138,7 +137,7 @@ class ActiveRecordTest < Minitest::Test
|
|
138
137
|
)
|
139
138
|
end
|
140
139
|
|
141
|
-
it '
|
140
|
+
it 'has encrypted methods' do
|
142
141
|
assert_equal true, @user.respond_to?(:encrypted_bank_account_number)
|
143
142
|
assert_equal true, @user.respond_to?(:bank_account_number)
|
144
143
|
assert_equal true, @user.respond_to?(:encrypted_social_security_number)
|
@@ -150,153 +149,155 @@ class ActiveRecordTest < Minitest::Test
|
|
150
149
|
assert_equal true, @user.respond_to?(:bank_account_number_changed?)
|
151
150
|
end
|
152
151
|
|
153
|
-
it '
|
152
|
+
it 'has unencrypted values' do
|
154
153
|
assert_equal @bank_account_number, @user.bank_account_number
|
155
154
|
assert_equal @social_security_number, @user.social_security_number
|
156
155
|
end
|
157
156
|
|
158
|
-
it '
|
157
|
+
it 'has encrypted values' do
|
159
158
|
assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
|
160
159
|
assert_equal @social_security_number_encrypted, @user.encrypted_social_security_number
|
161
160
|
end
|
162
161
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
it 'support a random iv' do
|
172
|
-
@user.string_value = STRING_VALUE
|
173
|
-
assert first_value = @user.encrypted_string_value
|
174
|
-
# Assign the same value
|
175
|
-
@user.string_value = STRING_VALUE.dup
|
176
|
-
assert first_value != @user.encrypted_string_value
|
177
|
-
end
|
162
|
+
describe ':random_iv' do
|
163
|
+
it 'false' do
|
164
|
+
@user.social_security_number = @social_security_number
|
165
|
+
assert first_value = @user.social_security_number
|
166
|
+
# Assign the same value
|
167
|
+
@user.social_security_number = @social_security_number
|
168
|
+
assert_equal first_value, @user.social_security_number
|
169
|
+
end
|
178
170
|
|
179
|
-
|
180
|
-
|
181
|
-
|
171
|
+
it 'true' do
|
172
|
+
@user.string_value = STRING_VALUE
|
173
|
+
assert first_value = @user.encrypted_string_value
|
174
|
+
# Assign the same value
|
175
|
+
@user.string_value = STRING_VALUE.dup
|
176
|
+
assert first_value != @user.encrypted_string_value
|
177
|
+
end
|
182
178
|
|
183
|
-
|
184
|
-
|
179
|
+
it 'true and compress: true' do
|
180
|
+
@user.string_value = STRING_VALUE
|
181
|
+
@user.long_string_value = STRING_VALUE
|
185
182
|
|
186
|
-
|
187
|
-
|
188
|
-
user.bank_account_number = @bank_account_number
|
189
|
-
assert_equal @bank_account_number, user.bank_account_number
|
190
|
-
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
183
|
+
refute_equal @user.encrypted_long_string_value, @user.encrypted_string_value
|
184
|
+
end
|
191
185
|
end
|
192
186
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
assert_equal @
|
199
|
-
assert_equal @bank_account_number_encrypted, inq.encrypted_bank_account_number
|
200
|
-
|
201
|
-
@user.delete
|
187
|
+
describe 'attribute=' do
|
188
|
+
it 'encrypt' do
|
189
|
+
user = User.new
|
190
|
+
user.bank_account_number = @bank_account_number
|
191
|
+
assert_equal @bank_account_number, user.bank_account_number
|
192
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
202
193
|
end
|
203
|
-
end
|
204
194
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
195
|
+
it 'all paths it lead to the same result' do
|
196
|
+
assert_equal @bank_account_number_encrypted, (@user.encrypted_social_security_number = @bank_account_number_encrypted)
|
197
|
+
assert_equal @bank_account_number, @user.social_security_number
|
198
|
+
assert_equal @bank_account_number_encrypted, @user.encrypted_social_security_number
|
199
|
+
end
|
210
200
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
201
|
+
it 'all paths it lead to the same result 2' do
|
202
|
+
assert_equal @bank_account_number, (@user.social_security_number = @bank_account_number)
|
203
|
+
assert_equal @bank_account_number_encrypted, @user.encrypted_social_security_number
|
204
|
+
assert_equal @bank_account_number, @user.social_security_number
|
205
|
+
end
|
216
206
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
207
|
+
it 'all paths it lead to the same result, check uninitialized' do
|
208
|
+
user = User.new
|
209
|
+
assert_nil user.social_security_number
|
210
|
+
assert_equal @bank_account_number, (user.social_security_number = @bank_account_number)
|
211
|
+
assert_equal @bank_account_number, user.social_security_number
|
212
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_social_security_number
|
223
213
|
|
224
|
-
|
225
|
-
|
226
|
-
|
214
|
+
assert_nil (user.social_security_number = nil)
|
215
|
+
assert_nil user.social_security_number
|
216
|
+
assert_nil user.encrypted_social_security_number
|
217
|
+
end
|
227
218
|
end
|
228
219
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
220
|
+
describe '.new' do
|
221
|
+
it 'allows unencrypted values to be passed to the constructor' do
|
222
|
+
user = User.new(bank_account_number: @bank_account_number, social_security_number: @social_security_number)
|
223
|
+
assert_equal @bank_account_number, user.bank_account_number
|
224
|
+
assert_equal @social_security_number, user.social_security_number
|
225
|
+
assert_equal @bank_account_number_encrypted, user.encrypted_bank_account_number
|
226
|
+
assert_equal @social_security_number_encrypted, user.encrypted_social_security_number
|
227
|
+
end
|
235
228
|
end
|
236
229
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
230
|
+
describe '.encrypted_attributes' do
|
231
|
+
it 'returns encrypted attributes for the class' do
|
232
|
+
expect = {social_security_number: :encrypted_social_security_number, bank_account_number: :encrypted_bank_account_number}
|
233
|
+
result = User.encrypted_attributes
|
234
|
+
expect.each_pair { |k, v| assert_equal expect[k], result[k] }
|
235
|
+
end
|
241
236
|
end
|
242
237
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
238
|
+
describe '.encrypted_keys' do
|
239
|
+
it 'return encrypted keys for the class' do
|
240
|
+
expect = [:social_security_number, :bank_account_number]
|
241
|
+
result = User.encrypted_keys
|
242
|
+
expect.each { |val| assert result.include?(val) }
|
247
243
|
|
248
|
-
|
249
|
-
|
244
|
+
# Also check encrypted_attribute?
|
245
|
+
expect.each { |val| assert User.encrypted_attribute?(val) }
|
246
|
+
end
|
250
247
|
end
|
251
248
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
249
|
+
describe '.encrypted_columns' do
|
250
|
+
it 'return encrypted columns for the class' do
|
251
|
+
expect = [:encrypted_social_security_number, :encrypted_bank_account_number]
|
252
|
+
result = User.encrypted_columns
|
253
|
+
expect.each { |val| assert result.include?(val) }
|
256
254
|
|
257
|
-
|
258
|
-
|
255
|
+
# Also check encrypted_column?
|
256
|
+
expect.each { |val| assert User.encrypted_column?(val) }
|
257
|
+
end
|
259
258
|
end
|
260
259
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
260
|
+
describe '#valid?' do
|
261
|
+
it 'validate encrypted data' do
|
262
|
+
assert @user.valid?
|
263
|
+
@user.encrypted_bank_account_number = '123'
|
264
|
+
assert_equal false, @user.valid?
|
265
|
+
assert_equal ['must be a value encrypted using SymmetricEncryption.encrypt'], @user.errors[:encrypted_bank_account_number]
|
266
|
+
@user.encrypted_bank_account_number = SymmetricEncryption.encrypt('123')
|
267
|
+
assert @user.valid?
|
268
|
+
@user.bank_account_number = '123'
|
269
|
+
assert @user.valid?
|
270
|
+
end
|
271
271
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
272
|
+
it 'validate un-encrypted string data' do
|
273
|
+
assert @user.valid?
|
274
|
+
@user.text = '123'
|
275
|
+
assert_equal false, @user.valid?
|
276
|
+
assert_equal ['only allows letters'], @user.errors[:text]
|
277
|
+
@user.text = nil
|
278
|
+
assert_equal false, @user.valid?
|
279
|
+
assert_equal ['only allows letters', "can't be blank"], @user.errors[:text]
|
280
|
+
@user.text = ''
|
281
|
+
assert_equal false, @user.valid?
|
282
|
+
assert_equal ['only allows letters', "can't be blank"], @user.errors[:text]
|
283
|
+
end
|
284
284
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
285
|
+
it 'validate un-encrypted integer data with coercion' do
|
286
|
+
assert @user.valid?
|
287
|
+
@user.number = '123'
|
288
|
+
assert @user.valid?
|
289
|
+
assert_equal 123, @user.number
|
290
|
+
assert @user.valid?
|
291
|
+
@user.number = ''
|
292
|
+
assert_equal false, @user.valid?
|
293
|
+
assert_nil @user.number
|
294
|
+
assert_equal ["can't be blank"], @user.errors[:number]
|
295
|
+
@user.number = nil
|
296
|
+
assert_nil @user.number
|
297
|
+
assert_nil @user.encrypted_number
|
298
|
+
assert_equal false, @user.valid?
|
299
|
+
assert_equal ["can't be blank"], @user.errors[:number]
|
300
|
+
end
|
300
301
|
end
|
301
302
|
|
302
303
|
describe 'with saved user' do
|
@@ -329,28 +330,30 @@ class ActiveRecordTest < Minitest::Test
|
|
329
330
|
end
|
330
331
|
end
|
331
332
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
# Reload User model from the database
|
338
|
-
@user.reload
|
339
|
-
assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
|
340
|
-
assert_equal @bank_account_number, @user.bank_account_number
|
341
|
-
end
|
333
|
+
describe '#reload' do
|
334
|
+
it 'reverts changes' do
|
335
|
+
new_bank_account_number = '444444444'
|
336
|
+
@user.bank_account_number = new_bank_account_number
|
337
|
+
assert_equal new_bank_account_number, @user.bank_account_number
|
342
338
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
assert_equal new_bank_account_number, @user.bank_account_number
|
339
|
+
# Reload User model from the database
|
340
|
+
@user.reload
|
341
|
+
assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
|
342
|
+
assert_equal @bank_account_number, @user.bank_account_number
|
343
|
+
end
|
349
344
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
345
|
+
it 'reverts changes to encrypted field' do
|
346
|
+
new_bank_account_number = '111111111'
|
347
|
+
new_encrypted_bank_account_number = SymmetricEncryption.encrypt(new_bank_account_number)
|
348
|
+
@user.encrypted_bank_account_number = new_encrypted_bank_account_number
|
349
|
+
assert_equal new_encrypted_bank_account_number, @user.encrypted_bank_account_number
|
350
|
+
assert_equal new_bank_account_number, @user.bank_account_number
|
351
|
+
|
352
|
+
# Reload User model from the database
|
353
|
+
@user.reload
|
354
|
+
assert_equal @bank_account_number_encrypted, @user.encrypted_bank_account_number
|
355
|
+
assert_equal @bank_account_number, @user.bank_account_number
|
356
|
+
end
|
354
357
|
end
|
355
358
|
|
356
359
|
describe 'data types' do
|
@@ -383,8 +386,11 @@ class ActiveRecordTest < Minitest::Test
|
|
383
386
|
end
|
384
387
|
|
385
388
|
it 'return correct data type' do
|
386
|
-
|
387
|
-
|
389
|
+
val = @user_clone.send(@attribute)
|
390
|
+
# Need to dup since minitest attempts to modify the decrypted value which is frozen
|
391
|
+
val = val.dup if val.duplicable?
|
392
|
+
assert_equal @value, val, @user_clone.attributes.ai
|
393
|
+
assert @user.send(@attribute).kind_of?(@klass)
|
388
394
|
end
|
389
395
|
|
390
396
|
it 'coerce data type before save' do
|
@@ -425,7 +431,10 @@ class ActiveRecordTest < Minitest::Test
|
|
425
431
|
@user_clone.save!
|
426
432
|
|
427
433
|
@user.reload
|
428
|
-
|
434
|
+
val = @user.send(@attribute)
|
435
|
+
# Need to dup since minitest attempts to modify the decrypted value which is frozen
|
436
|
+
val = val.dup if val.duplicable?
|
437
|
+
assert_equal @new_value, val
|
429
438
|
end
|
430
439
|
end
|
431
440
|
end
|