powerhome-attr_encrypted 1.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 +7 -0
- data/.gitignore +6 -0
- data/.travis.yml +67 -0
- data/CHANGELOG.md +98 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +465 -0
- data/Rakefile +25 -0
- data/attr_encrypted.gemspec +63 -0
- data/certs/saghaulor.pem +21 -0
- data/checksum/attr_encrypted-3.0.0.gem.sha256 +1 -0
- data/checksum/attr_encrypted-3.0.0.gem.sha512 +1 -0
- data/checksum/attr_encrypted-3.0.1.gem.sha256 +1 -0
- data/checksum/attr_encrypted-3.0.1.gem.sha512 +1 -0
- data/checksum/attr_encrypted-3.0.2.gem.sha256 +1 -0
- data/checksum/attr_encrypted-3.0.2.gem.sha512 +1 -0
- data/checksum/attr_encrypted-3.0.3.gem.sha256 +1 -0
- data/checksum/attr_encrypted-3.0.3.gem.sha512 +1 -0
- data/checksum/attr_encrypted-3.1.0.gem.sha256 +1 -0
- data/checksum/attr_encrypted-3.1.0.gem.sha512 +1 -0
- data/lib/attr_encrypted.rb +473 -0
- data/lib/attr_encrypted/adapters/active_record.rb +157 -0
- data/lib/attr_encrypted/adapters/data_mapper.rb +24 -0
- data/lib/attr_encrypted/adapters/sequel.rb +16 -0
- data/lib/attr_encrypted/version.rb +19 -0
- data/test/active_record_test.rb +365 -0
- data/test/attr_encrypted_test.rb +490 -0
- data/test/compatibility_test.rb +109 -0
- data/test/data_mapper_test.rb +59 -0
- data/test/legacy_active_record_test.rb +120 -0
- data/test/legacy_attr_encrypted_test.rb +300 -0
- data/test/legacy_compatibility_test.rb +95 -0
- data/test/legacy_data_mapper_test.rb +57 -0
- data/test/legacy_sequel_test.rb +54 -0
- data/test/run.sh +12 -0
- data/test/sequel_test.rb +55 -0
- data/test/test_helper.rb +61 -0
- metadata +294 -0
@@ -0,0 +1,490 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# encoding: UTF-8
|
4
|
+
require_relative 'test_helper'
|
5
|
+
|
6
|
+
class SillyEncryptor
|
7
|
+
def self.silly_encrypt(options)
|
8
|
+
(options[:value] + options[:some_arg]).reverse
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.silly_decrypt(options)
|
12
|
+
options[:value].reverse.gsub(/#{options[:some_arg]}$/, '')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class User
|
17
|
+
extend AttrEncrypted
|
18
|
+
self.attr_encrypted_options[:key] = Proc.new { |user| SECRET_KEY } # default key
|
19
|
+
self.attr_encrypted_options[:mode] = :per_attribute_iv_and_salt
|
20
|
+
|
21
|
+
attr_encrypted :email, :without_encoding, :key => SECRET_KEY
|
22
|
+
attr_encrypted :password, :prefix => 'crypted_', :suffix => '_test'
|
23
|
+
attr_encrypted :ssn, :key => :secret_key, :attribute => 'ssn_encrypted'
|
24
|
+
attr_encrypted :credit_card, :encryptor => SillyEncryptor, :encrypt_method => :silly_encrypt, :decrypt_method => :silly_decrypt, :some_arg => 'test'
|
25
|
+
attr_encrypted :with_encoding, :key => SECRET_KEY, :encode => true
|
26
|
+
attr_encrypted :with_custom_encoding, :key => SECRET_KEY, :encode => 'm'
|
27
|
+
attr_encrypted :with_marshaling, :key => SECRET_KEY, :marshal => true
|
28
|
+
attr_encrypted :with_true_if, :key => SECRET_KEY, :if => true, mode: :per_attribute_iv_and_salt
|
29
|
+
attr_encrypted :with_false_if, :key => SECRET_KEY, :if => false, mode: :per_attribute_iv_and_salt
|
30
|
+
attr_encrypted :with_true_unless, :key => SECRET_KEY, :unless => true, mode: :per_attribute_iv_and_salt
|
31
|
+
attr_encrypted :with_false_unless, :key => SECRET_KEY, :unless => false, mode: :per_attribute_iv_and_salt
|
32
|
+
attr_encrypted :with_if_changed, :key => SECRET_KEY, :if => :should_encrypt
|
33
|
+
attr_encrypted :with_allow_empty_value, key: SECRET_KEY, allow_empty_value: true, marshal: true
|
34
|
+
|
35
|
+
attr_encryptor :aliased, :key => SECRET_KEY
|
36
|
+
|
37
|
+
attr_accessor :salt
|
38
|
+
attr_accessor :should_encrypt
|
39
|
+
|
40
|
+
def initialize(email: nil)
|
41
|
+
self.email = email
|
42
|
+
self.salt = Time.now.to_i.to_s
|
43
|
+
self.should_encrypt = true
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def secret_key
|
48
|
+
SECRET_KEY
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Admin < User
|
53
|
+
attr_encrypted :testing
|
54
|
+
end
|
55
|
+
|
56
|
+
class SomeOtherClass
|
57
|
+
extend AttrEncrypted
|
58
|
+
def self.call(object)
|
59
|
+
object.class
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class YetAnotherClass
|
64
|
+
extend AttrEncrypted
|
65
|
+
self.attr_encrypted_options[:encode_iv] = false
|
66
|
+
|
67
|
+
attr_encrypted :email, :key => SECRET_KEY
|
68
|
+
attr_encrypted :phone_number, :key => SECRET_KEY, mode: Proc.new { |thing| thing.mode }, encode_iv: Proc.new { |thing| thing.encode_iv }, encode_salt: Proc.new { |thing| thing.encode_salt }
|
69
|
+
|
70
|
+
def initialize(email: nil, encode_iv: 'm', encode_salt: 'm', mode: :per_attribute_iv_and_salt)
|
71
|
+
self.email = email
|
72
|
+
@encode_iv = encode_iv
|
73
|
+
@encode_salt = encode_salt
|
74
|
+
@mode = mode
|
75
|
+
end
|
76
|
+
|
77
|
+
attr_reader :encode_iv, :encode_salt, :mode
|
78
|
+
end
|
79
|
+
|
80
|
+
class AttrEncryptedTest < Minitest::Test
|
81
|
+
def setup
|
82
|
+
@iv = SecureRandom.random_bytes(12)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_should_store_email_in_encrypted_attributes
|
86
|
+
assert User.encrypted_attributes.include?(:email)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_should_not_store_salt_in_encrypted_attributes
|
90
|
+
refute User.encrypted_attributes.include?(:salt)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_attr_encrypted_should_return_true_for_email
|
94
|
+
assert User.attr_encrypted?('email')
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_attr_encrypted_should_not_use_the_same_attribute_name_for_two_attributes_in_the_same_line
|
98
|
+
refute_equal User.encrypted_attributes[:email][:attribute], User.encrypted_attributes[:without_encoding][:attribute]
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_attr_encrypted_should_return_false_for_salt
|
102
|
+
assert !User.attr_encrypted?('salt')
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_should_generate_an_encrypted_attribute
|
106
|
+
assert User.new.respond_to?(:encrypted_email)
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_should_generate_an_encrypted_attribute_with_a_prefix_and_suffix
|
110
|
+
assert User.new.respond_to?(:crypted_password_test)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_should_generate_an_encrypted_attribute_with_the_attribute_option
|
114
|
+
assert User.new.respond_to?(:ssn_encrypted)
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_should_not_encrypt_nil_value
|
118
|
+
assert_nil User.encrypt_email(nil, iv: @iv)
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_should_not_encrypt_empty_string_by_default
|
122
|
+
assert_equal '', User.encrypt_email('', iv: @iv)
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_should_encrypt_email
|
126
|
+
refute_nil User.encrypt_email('test@example.com', iv: @iv)
|
127
|
+
refute_equal 'test@example.com', User.encrypt_email('test@example.com', iv: @iv)
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_should_encrypt_email_when_modifying_the_attr_writer
|
131
|
+
@user = User.new
|
132
|
+
assert_nil @user.encrypted_email
|
133
|
+
@user.email = 'test@example.com'
|
134
|
+
refute_nil @user.encrypted_email
|
135
|
+
iv = @user.encrypted_email_iv.unpack('m').first
|
136
|
+
salt = @user.encrypted_email_salt[1..-1].unpack('m').first
|
137
|
+
assert_equal User.encrypt_email('test@example.com', iv: iv, salt: salt), @user.encrypted_email
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_should_not_decrypt_nil_value
|
141
|
+
assert_nil User.decrypt_email(nil, iv: @iv)
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_should_not_decrypt_empty_string
|
145
|
+
assert_equal '', User.decrypt_email('', iv: @iv)
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_should_decrypt_email
|
149
|
+
encrypted_email = User.encrypt_email('test@example.com', iv: @iv)
|
150
|
+
refute_equal 'test@test.com', encrypted_email
|
151
|
+
assert_equal 'test@example.com', User.decrypt_email(encrypted_email, iv: @iv)
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_should_decrypt_email_when_reading
|
155
|
+
@user = User.new
|
156
|
+
assert_nil @user.email
|
157
|
+
options = @user.encrypted_attributes[:email]
|
158
|
+
iv = @user.send(:generate_iv, options[:algorithm])
|
159
|
+
encoded_iv = [iv].pack(options[:encode_iv])
|
160
|
+
salt = SecureRandom.random_bytes
|
161
|
+
encoded_salt = @user.send(:prefix_and_encode_salt, salt, options[:encode_salt])
|
162
|
+
@user.encrypted_email = User.encrypt_email('test@example.com', iv: iv, salt: salt)
|
163
|
+
@user.encrypted_email_iv = encoded_iv
|
164
|
+
@user.encrypted_email_salt = encoded_salt
|
165
|
+
assert_equal 'test@example.com', @user.email
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_should_encrypt_with_encoding
|
169
|
+
assert_equal User.encrypt_with_encoding('test', iv: @iv), [User.encrypt_without_encoding('test', iv: @iv)].pack('m')
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_should_decrypt_with_encoding
|
173
|
+
encrypted = User.encrypt_with_encoding('test', iv: @iv)
|
174
|
+
assert_equal 'test', User.decrypt_with_encoding(encrypted, iv: @iv)
|
175
|
+
assert_equal User.decrypt_with_encoding(encrypted, iv: @iv), User.decrypt_without_encoding(encrypted.unpack('m').first, iv: @iv)
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_should_encrypt_with_custom_encoding
|
179
|
+
assert_equal User.encrypt_with_encoding('test', iv: @iv), [User.encrypt_without_encoding('test', iv: @iv)].pack('m')
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_should_decrypt_with_custom_encoding
|
183
|
+
encrypted = User.encrypt_with_encoding('test', iv: @iv)
|
184
|
+
assert_equal 'test', User.decrypt_with_encoding(encrypted, iv: @iv)
|
185
|
+
assert_equal User.decrypt_with_encoding(encrypted, iv: @iv), User.decrypt_without_encoding(encrypted.unpack('m').first, iv: @iv)
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_should_encrypt_with_marshaling
|
189
|
+
@user = User.new
|
190
|
+
@user.with_marshaling = [1, 2, 3]
|
191
|
+
refute_nil @user.encrypted_with_marshaling
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_should_use_custom_encryptor_and_crypt_method_names_and_arguments
|
195
|
+
assert_equal SillyEncryptor.silly_encrypt(:value => 'testing', :some_arg => 'test'), User.encrypt_credit_card('testing')
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_should_evaluate_a_key_passed_as_a_symbol
|
199
|
+
@user = User.new
|
200
|
+
assert_nil @user.ssn_encrypted
|
201
|
+
@user.ssn = 'testing'
|
202
|
+
refute_nil @user.ssn_encrypted
|
203
|
+
encrypted = Encryptor.encrypt(:value => 'testing', :key => SECRET_KEY, :iv => @user.ssn_encrypted_iv.unpack("m").first, :salt => @user.ssn_encrypted_salt.unpack("m").first )
|
204
|
+
assert_equal encrypted, @user.ssn_encrypted
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_should_evaluate_a_key_passed_as_a_proc
|
208
|
+
@user = User.new
|
209
|
+
assert_nil @user.crypted_password_test
|
210
|
+
@user.password = 'testing'
|
211
|
+
refute_nil @user.crypted_password_test
|
212
|
+
encrypted = Encryptor.encrypt(:value => 'testing', :key => SECRET_KEY, :iv => @user.crypted_password_test_iv.unpack("m").first, :salt => @user.crypted_password_test_salt.unpack("m").first)
|
213
|
+
assert_equal encrypted, @user.crypted_password_test
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_should_use_options_found_in_the_attr_encrypted_options_attribute
|
217
|
+
@user = User.new
|
218
|
+
assert_nil @user.crypted_password_test
|
219
|
+
@user.password = 'testing'
|
220
|
+
refute_nil @user.crypted_password_test
|
221
|
+
encrypted = Encryptor.encrypt(:value => 'testing', :key => SECRET_KEY, :iv => @user.crypted_password_test_iv.unpack("m").first, :salt => @user.crypted_password_test_salt.unpack("m").first)
|
222
|
+
assert_equal encrypted, @user.crypted_password_test
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_should_inherit_encrypted_attributes
|
226
|
+
assert_equal [User.encrypted_attributes.keys, :testing].flatten.collect { |key| key.to_s }.sort, Admin.encrypted_attributes.keys.collect { |key| key.to_s }.sort
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_should_inherit_attr_encrypted_options
|
230
|
+
assert !User.attr_encrypted_options.empty?
|
231
|
+
assert_equal User.attr_encrypted_options, Admin.attr_encrypted_options
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_should_not_inherit_unrelated_attributes
|
235
|
+
assert SomeOtherClass.attr_encrypted_options.empty?
|
236
|
+
assert SomeOtherClass.encrypted_attributes.empty?
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_should_evaluate_a_symbol_option
|
240
|
+
assert_equal SomeOtherClass, SomeOtherClass.new.send(:evaluate_attr_encrypted_option, :class)
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_should_evaluate_a_proc_option
|
244
|
+
assert_equal SomeOtherClass, SomeOtherClass.new.send(:evaluate_attr_encrypted_option, proc { |object| object.class })
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_should_evaluate_a_lambda_option
|
248
|
+
assert_equal SomeOtherClass, SomeOtherClass.new.send(:evaluate_attr_encrypted_option, lambda { |object| object.class })
|
249
|
+
end
|
250
|
+
|
251
|
+
def test_should_evaluate_a_method_option
|
252
|
+
assert_equal SomeOtherClass, SomeOtherClass.new.send(:evaluate_attr_encrypted_option, SomeOtherClass.method(:call))
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_should_return_a_string_option
|
256
|
+
class_string = 'SomeOtherClass'
|
257
|
+
assert_equal class_string, SomeOtherClass.new.send(:evaluate_attr_encrypted_option, class_string)
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_should_encrypt_with_true_if
|
261
|
+
@user = User.new
|
262
|
+
assert_nil @user.encrypted_with_true_if
|
263
|
+
@user.with_true_if = 'testing'
|
264
|
+
refute_nil @user.encrypted_with_true_if
|
265
|
+
encrypted = Encryptor.encrypt(:value => 'testing', :key => SECRET_KEY, :iv => @user.encrypted_with_true_if_iv.unpack("m").first, :salt => @user.encrypted_with_true_if_salt.unpack("m").first)
|
266
|
+
assert_equal encrypted, @user.encrypted_with_true_if
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_should_not_encrypt_with_false_if
|
270
|
+
@user = User.new
|
271
|
+
assert_nil @user.encrypted_with_false_if
|
272
|
+
@user.with_false_if = 'testing'
|
273
|
+
refute_nil @user.encrypted_with_false_if
|
274
|
+
assert_equal 'testing', @user.encrypted_with_false_if
|
275
|
+
end
|
276
|
+
|
277
|
+
def test_should_encrypt_with_false_unless
|
278
|
+
@user = User.new
|
279
|
+
assert_nil @user.encrypted_with_false_unless
|
280
|
+
@user.with_false_unless = 'testing'
|
281
|
+
refute_nil @user.encrypted_with_false_unless
|
282
|
+
encrypted = Encryptor.encrypt(:value => 'testing', :key => SECRET_KEY, :iv => @user.encrypted_with_false_unless_iv.unpack("m").first, :salt => @user.encrypted_with_false_unless_salt.unpack("m").first)
|
283
|
+
assert_equal encrypted, @user.encrypted_with_false_unless
|
284
|
+
end
|
285
|
+
|
286
|
+
def test_should_not_encrypt_with_true_unless
|
287
|
+
@user = User.new
|
288
|
+
assert_nil @user.encrypted_with_true_unless
|
289
|
+
@user.with_true_unless = 'testing'
|
290
|
+
refute_nil @user.encrypted_with_true_unless
|
291
|
+
assert_equal 'testing', @user.encrypted_with_true_unless
|
292
|
+
end
|
293
|
+
|
294
|
+
def test_should_encrypt_empty_with_truthy_allow_empty_value_option
|
295
|
+
@user = User.new
|
296
|
+
assert_nil @user.encrypted_with_allow_empty_value
|
297
|
+
@user.with_allow_empty_value = ''
|
298
|
+
refute_nil @user.encrypted_with_allow_empty_value
|
299
|
+
assert_equal '', @user.with_allow_empty_value
|
300
|
+
@user = User.new
|
301
|
+
@user.with_allow_empty_value = nil
|
302
|
+
refute_nil @user.encrypted_with_allow_empty_value
|
303
|
+
assert_nil @user.with_allow_empty_value
|
304
|
+
end
|
305
|
+
|
306
|
+
def test_should_work_with_aliased_attr_encryptor
|
307
|
+
assert User.encrypted_attributes.include?(:aliased)
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_should_always_reset_options
|
311
|
+
@user = User.new
|
312
|
+
@user.with_if_changed = "encrypt_stuff"
|
313
|
+
|
314
|
+
@user = User.new
|
315
|
+
@user.should_encrypt = false
|
316
|
+
@user.with_if_changed = "not_encrypted_stuff"
|
317
|
+
assert_equal "not_encrypted_stuff", @user.with_if_changed
|
318
|
+
assert_equal "not_encrypted_stuff", @user.encrypted_with_if_changed
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_should_cast_values_as_strings_before_encrypting
|
322
|
+
string_encrypted_email = User.encrypt_email('3', iv: @iv)
|
323
|
+
assert_equal string_encrypted_email, User.encrypt_email(3, iv: @iv)
|
324
|
+
assert_equal '3', User.decrypt_email(string_encrypted_email, iv: @iv)
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_should_create_query_accessor
|
328
|
+
@user = User.new
|
329
|
+
assert !@user.email?
|
330
|
+
@user.email = ''
|
331
|
+
assert !@user.email?
|
332
|
+
@user.email = 'test@example.com'
|
333
|
+
assert @user.email?
|
334
|
+
end
|
335
|
+
|
336
|
+
def test_should_vary_iv_per_attribute
|
337
|
+
@user = User.new
|
338
|
+
@user.email = 'email@example.com'
|
339
|
+
@user.password = 'p455w0rd'
|
340
|
+
refute_equal @user.encrypted_email_iv, @user.crypted_password_test_iv
|
341
|
+
end
|
342
|
+
|
343
|
+
def test_should_generate_iv_per_attribute_by_default
|
344
|
+
thing = YetAnotherClass.new(email: 'thing@thing.com')
|
345
|
+
refute_nil thing.encrypted_email_iv
|
346
|
+
end
|
347
|
+
|
348
|
+
def test_should_vary_iv_per_instance
|
349
|
+
@user1 = User.new
|
350
|
+
@user1.email = 'email@example.com'
|
351
|
+
@user2 = User.new
|
352
|
+
@user2.email = 'email@example.com'
|
353
|
+
refute_equal @user1.encrypted_email_iv, @user2.encrypted_email_iv
|
354
|
+
refute_equal @user1.encrypted_email, @user2.encrypted_email
|
355
|
+
end
|
356
|
+
|
357
|
+
def test_should_vary_salt_per_attribute
|
358
|
+
@user = User.new
|
359
|
+
@user.email = 'email@example.com'
|
360
|
+
@user.password = 'p455w0rd'
|
361
|
+
refute_equal @user.encrypted_email_salt, @user.crypted_password_test_salt
|
362
|
+
end
|
363
|
+
|
364
|
+
def test_should_vary_salt_per_instance
|
365
|
+
@user1 = User.new
|
366
|
+
@user1.email = 'email@example.com'
|
367
|
+
@user2 = User.new
|
368
|
+
@user2.email = 'email@example.com'
|
369
|
+
refute_equal @user1.encrypted_email_salt, @user2.encrypted_email_salt
|
370
|
+
end
|
371
|
+
|
372
|
+
def test_should_not_generate_salt_per_attribute_by_default
|
373
|
+
thing = YetAnotherClass.new(email: 'thing@thing.com')
|
374
|
+
assert_nil thing.encrypted_email_salt
|
375
|
+
end
|
376
|
+
|
377
|
+
def test_should_decrypt_second_record
|
378
|
+
@user1 = User.new
|
379
|
+
@user1.email = 'test@example.com'
|
380
|
+
|
381
|
+
@user2 = User.new
|
382
|
+
@user2.email = 'test@example.com'
|
383
|
+
|
384
|
+
assert_equal 'test@example.com', @user1.decrypt(:email, @user1.encrypted_email)
|
385
|
+
end
|
386
|
+
|
387
|
+
def test_should_specify_the_default_algorithm
|
388
|
+
assert YetAnotherClass.encrypted_attributes[:email][:algorithm]
|
389
|
+
assert_equal YetAnotherClass.encrypted_attributes[:email][:algorithm], 'aes-256-gcm'
|
390
|
+
end
|
391
|
+
|
392
|
+
def test_should_not_encode_iv_when_encode_iv_is_false
|
393
|
+
email = 'thing@thing.com'
|
394
|
+
thing = YetAnotherClass.new(email: email)
|
395
|
+
refute thing.encrypted_email_iv =~ base64_encoding_regex
|
396
|
+
assert_equal thing.email, email
|
397
|
+
end
|
398
|
+
|
399
|
+
def test_should_base64_encode_iv_by_default
|
400
|
+
phone_number = '555-555-5555'
|
401
|
+
thing = YetAnotherClass.new
|
402
|
+
thing.phone_number = phone_number
|
403
|
+
assert thing.encrypted_phone_number_iv =~ base64_encoding_regex
|
404
|
+
assert_equal thing.phone_number, phone_number
|
405
|
+
end
|
406
|
+
|
407
|
+
def test_should_generate_unique_iv_for_every_encrypt_operation
|
408
|
+
user = User.new
|
409
|
+
user.email = 'initial_value@test.com'
|
410
|
+
original_iv = user.encrypted_email_iv
|
411
|
+
user.email = 'revised_value@test.com'
|
412
|
+
refute_equal original_iv, user.encrypted_email_iv
|
413
|
+
end
|
414
|
+
|
415
|
+
def test_should_not_generate_iv_for_attribute_when_if_option_is_false
|
416
|
+
user = User.new
|
417
|
+
user.with_false_if = 'derp'
|
418
|
+
assert_nil user.encrypted_with_false_if_iv
|
419
|
+
end
|
420
|
+
|
421
|
+
def test_should_generate_iv_for_attribute_when_if_option_is_true
|
422
|
+
user = User.new
|
423
|
+
user.with_true_if = 'derp'
|
424
|
+
refute_nil user.encrypted_with_true_if_iv
|
425
|
+
|
426
|
+
user.with_true_if = Object.new
|
427
|
+
refute_nil user.encrypted_with_true_if_iv
|
428
|
+
end
|
429
|
+
|
430
|
+
def test_should_not_generate_salt_for_attribute_when_if_option_is_false
|
431
|
+
user = User.new
|
432
|
+
user.with_false_if = 'derp'
|
433
|
+
assert_nil user.encrypted_with_false_if_salt
|
434
|
+
end
|
435
|
+
|
436
|
+
def test_should_generate_salt_for_attribute_when_if_option_is_true
|
437
|
+
user = User.new
|
438
|
+
user.with_true_if = 'derp'
|
439
|
+
refute_nil user.encrypted_with_true_if_salt
|
440
|
+
end
|
441
|
+
|
442
|
+
def test_should_generate_iv_for_attribute_when_unless_option_is_false
|
443
|
+
user = User.new
|
444
|
+
user.with_false_unless = 'derp'
|
445
|
+
refute_nil user.encrypted_with_false_unless_iv
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_should_not_generate_iv_for_attribute_when_unless_option_is_true
|
449
|
+
user = User.new
|
450
|
+
user.with_true_unless = 'derp'
|
451
|
+
assert_nil user.encrypted_with_true_unless_iv
|
452
|
+
end
|
453
|
+
|
454
|
+
def test_should_generate_salt_for_attribute_when_unless_option_is_false
|
455
|
+
user = User.new
|
456
|
+
user.with_false_unless = 'derp'
|
457
|
+
refute_nil user.encrypted_with_false_unless_salt
|
458
|
+
end
|
459
|
+
|
460
|
+
def test_should_not_generate_salt_for_attribute_when_unless_option_is_true
|
461
|
+
user = User.new
|
462
|
+
user.with_true_unless = 'derp'
|
463
|
+
assert_nil user.encrypted_with_true_unless_salt
|
464
|
+
end
|
465
|
+
|
466
|
+
def test_should_not_by_default_generate_iv_when_attribute_is_empty
|
467
|
+
user = User.new
|
468
|
+
user.with_true_if = nil
|
469
|
+
assert_nil user.encrypted_with_true_if_iv
|
470
|
+
end
|
471
|
+
|
472
|
+
def test_encrypted_attributes_state_is_not_shared
|
473
|
+
user = User.new
|
474
|
+
user.ssn = '123456789'
|
475
|
+
|
476
|
+
another_user = User.new
|
477
|
+
|
478
|
+
assert_equal :encrypting, user.encrypted_attributes[:ssn][:operation]
|
479
|
+
assert_nil another_user.encrypted_attributes[:ssn][:operation]
|
480
|
+
end
|
481
|
+
|
482
|
+
def test_should_not_by_default_generate_key_when_attribute_is_empty
|
483
|
+
user = User.new
|
484
|
+
calls = 0
|
485
|
+
user.stub(:secret_key, lambda { calls += 1; SECRET_KEY }) do
|
486
|
+
user.ssn
|
487
|
+
end
|
488
|
+
assert_equal 0, calls
|
489
|
+
end
|
490
|
+
end
|