attr_encrypted 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +14 -16
  3. data/CHANGELOG.md +60 -14
  4. data/README.md +27 -9
  5. data/Rakefile +3 -0
  6. data/attr_encrypted.gemspec +6 -13
  7. data/checksum/attr_encrypted-3.0.0.gem.sha256 +1 -0
  8. data/checksum/attr_encrypted-3.0.0.gem.sha512 +1 -0
  9. data/checksum/attr_encrypted-3.0.1.gem.sha256 +1 -0
  10. data/checksum/attr_encrypted-3.0.1.gem.sha512 +1 -0
  11. data/checksum/attr_encrypted-3.0.2.gem.sha256 +1 -0
  12. data/checksum/attr_encrypted-3.0.2.gem.sha512 +1 -0
  13. data/checksum/attr_encrypted-3.0.3.gem.sha256 +1 -0
  14. data/checksum/attr_encrypted-3.0.3.gem.sha512 +1 -0
  15. data/checksum/attr_encrypted-3.1.0.gem.sha256 +1 -0
  16. data/checksum/attr_encrypted-3.1.0.gem.sha512 +1 -0
  17. data/lib/attr_encrypted/adapters/active_record.rb +58 -30
  18. data/lib/attr_encrypted/adapters/data_mapper.rb +3 -1
  19. data/lib/attr_encrypted/adapters/sequel.rb +3 -1
  20. data/lib/attr_encrypted/version.rb +3 -1
  21. data/lib/attr_encrypted.rb +160 -129
  22. data/test/active_record_test.rb +130 -104
  23. data/test/attr_encrypted_test.rb +113 -16
  24. data/test/compatibility_test.rb +21 -21
  25. data/test/data_mapper_test.rb +2 -0
  26. data/test/legacy_active_record_test.rb +9 -9
  27. data/test/legacy_attr_encrypted_test.rb +8 -6
  28. data/test/legacy_compatibility_test.rb +15 -15
  29. data/test/legacy_data_mapper_test.rb +2 -0
  30. data/test/legacy_sequel_test.rb +2 -0
  31. data/test/run.sh +15 -7
  32. data/test/sequel_test.rb +2 -0
  33. data/test/test_helper.rb +11 -5
  34. metadata +27 -50
  35. checksums.yaml.gz.sig +0 -0
  36. data/certs/saghaulor.pem +0 -21
  37. data.tar.gz.sig +0 -0
  38. metadata.gz.sig +0 -0
@@ -1,61 +1,59 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'test_helper'
2
4
 
5
+ RAILS_VERSION = Gem::Version.new(::ActiveRecord::VERSION::STRING).freeze
3
6
  ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
4
7
 
5
8
  def create_tables
6
- silence_stream(STDOUT) do
7
- ActiveRecord::Schema.define(version: 1) do
8
- create_table :people do |t|
9
- t.string :encrypted_email
10
- t.string :password
11
- t.string :encrypted_credentials
12
- t.binary :salt
13
- t.binary :key_iv
14
- t.string :encrypted_email_salt
15
- t.string :encrypted_credentials_salt
16
- t.string :encrypted_email_iv
17
- t.string :encrypted_credentials_iv
18
- end
19
- create_table :accounts do |t|
20
- t.string :encrypted_password
21
- t.string :encrypted_password_iv
22
- t.string :encrypted_password_salt
23
- end
24
- create_table :users do |t|
25
- t.string :login
26
- t.string :encrypted_password
27
- t.string :encrypted_password_iv
28
- t.boolean :is_admin
29
- end
30
- create_table :prime_ministers do |t|
31
- t.string :encrypted_name
32
- t.string :encrypted_name_iv
33
- end
34
- create_table :addresses do |t|
35
- t.binary :encrypted_street
36
- t.binary :encrypted_street_iv
37
- t.binary :encrypted_zipcode
38
- t.string :mode
39
- end
9
+ ActiveRecord::Schema.define(version: 1) do
10
+ self.verbose = false
11
+ create_table :people do |t|
12
+ t.string :encrypted_email
13
+ t.string :password
14
+ t.string :encrypted_credentials
15
+ t.binary :salt
16
+ t.binary :key_iv
17
+ t.string :encrypted_email_salt
18
+ t.string :encrypted_credentials_salt
19
+ t.string :encrypted_email_iv
20
+ t.string :encrypted_credentials_iv
21
+ end
22
+ create_table :accounts do |t|
23
+ t.string :encrypted_password
24
+ t.string :encrypted_password_iv
25
+ t.string :encrypted_password_salt
26
+ t.string :key
27
+ end
28
+ create_table :users do |t|
29
+ t.string :login
30
+ t.string :encrypted_password
31
+ t.string :encrypted_password_iv
32
+ t.boolean :is_admin
33
+ end
34
+ create_table :prime_ministers do |t|
35
+ t.string :encrypted_name
36
+ t.string :encrypted_name_iv
37
+ end
38
+ create_table :addresses do |t|
39
+ t.binary :encrypted_street
40
+ t.binary :encrypted_street_iv
41
+ t.binary :encrypted_zipcode
42
+ t.string :mode
40
43
  end
41
44
  end
42
45
  end
43
46
 
44
- # The table needs to exist before defining the class
45
- create_tables
46
-
47
47
  ActiveRecord::MissingAttributeError = ActiveModel::MissingAttributeError unless defined?(ActiveRecord::MissingAttributeError)
48
48
 
49
- if ::ActiveRecord::VERSION::STRING > "4.0"
50
- module Rack
51
- module Test
52
- class UploadedFile; end
53
- end
49
+ module Rack
50
+ module Test
51
+ class UploadedFile; end
54
52
  end
55
-
56
- require 'action_controller/metal/strong_parameters'
57
53
  end
58
54
 
55
+ require 'action_controller/metal/strong_parameters'
56
+
59
57
  class Person < ActiveRecord::Base
60
58
  self.attr_encrypted_options[:mode] = :per_attribute_iv_and_salt
61
59
  attr_encrypted :email, key: SECRET_KEY
@@ -82,8 +80,20 @@ class PersonWithProcMode < Person
82
80
  end
83
81
 
84
82
  class Account < ActiveRecord::Base
85
- attr_accessor :key
86
- attr_encrypted :password, key: Proc.new {|account| account.key}
83
+ ACCOUNT_ENCRYPTION_KEY = SecureRandom.urlsafe_base64(24)
84
+ attr_encrypted :password, key: :password_encryption_key
85
+
86
+ def encrypting?(attr)
87
+ attr_encrypted_encrypted_attributes[attr][:operation] == :encrypting
88
+ end
89
+
90
+ def password_encryption_key
91
+ if encrypting?(:password)
92
+ self.key = ACCOUNT_ENCRYPTION_KEY
93
+ else
94
+ self.key
95
+ end
96
+ end
87
97
  end
88
98
 
89
99
  class PersonWithSerialization < ActiveRecord::Base
@@ -95,7 +105,6 @@ end
95
105
  class UserWithProtectedAttribute < ActiveRecord::Base
96
106
  self.table_name = 'users'
97
107
  attr_encrypted :password, key: SECRET_KEY
98
- attr_protected :is_admin if ::ActiveRecord::VERSION::STRING < "4.0"
99
108
  end
100
109
 
101
110
  class PersonUsingAlias < ActiveRecord::Base
@@ -117,9 +126,8 @@ end
117
126
  class ActiveRecordTest < Minitest::Test
118
127
 
119
128
  def setup
120
- ActiveRecord::Base.connection.tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
129
+ drop_all_tables
121
130
  create_tables
122
- Account.create!(key: SECRET_KEY, password: "password")
123
131
  end
124
132
 
125
133
  def test_should_encrypt_email
@@ -169,12 +177,6 @@ class ActiveRecordTest < Minitest::Test
169
177
  Account.new.attributes = { password: "password", key: SECRET_KEY }
170
178
  end
171
179
 
172
- def test_should_preserve_hash_key_type
173
- hash = { foo: 'bar' }
174
- account = Account.create!(key: hash)
175
- assert_equal account.key, hash
176
- end
177
-
178
180
  def test_should_create_changed_predicate
179
181
  person = Person.create!(email: 'test@example.com')
180
182
  refute person.email_changed?
@@ -192,54 +194,78 @@ class ActiveRecordTest < Minitest::Test
192
194
  assert_equal original_email, person.email_was
193
195
  person.email = 'test2@example.com'
194
196
  assert_equal original_email, person.email_was
197
+ old_pm_name = "Winston Churchill"
198
+ pm = PrimeMinister.create!(name: old_pm_name)
199
+ assert_equal old_pm_name, pm.name_was
200
+ old_zipcode = "90210"
201
+ address = Address.create!(zipcode: old_zipcode, mode: "single_iv_and_salt")
202
+ assert_equal old_zipcode, address.zipcode_was
195
203
  end
196
204
 
197
- if ::ActiveRecord::VERSION::STRING > "4.0"
198
- def test_should_assign_attributes
199
- @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
200
- @user.attributes = ActionController::Parameters.new(login: 'modified', is_admin: true).permit(:login)
201
- assert_equal 'modified', @user.login
202
- end
205
+ def test_attribute_was_works_when_options_for_old_encrypted_value_are_different_than_options_for_new_encrypted_value
206
+ pw = 'password'
207
+ crypto_key = SecureRandom.urlsafe_base64(24)
208
+ old_iv = SecureRandom.random_bytes(12)
209
+ account = Account.create
210
+ encrypted_value = Encryptor.encrypt(value: pw, iv: old_iv, key: crypto_key)
211
+ Account.where(id: account.id).update_all(key: crypto_key, encrypted_password_iv: [old_iv].pack('m'), encrypted_password: [encrypted_value].pack('m'))
212
+ account = Account.find(account.id)
213
+ assert_equal pw, account.password
214
+ account.password = pw.reverse
215
+ assert_equal pw, account.password_was
216
+ account.save
217
+ account.reload
218
+ assert_equal Account::ACCOUNT_ENCRYPTION_KEY, account.key
219
+ assert_equal pw.reverse, account.password
220
+ end
203
221
 
204
- def test_should_not_assign_protected_attributes
205
- @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
206
- @user.attributes = ActionController::Parameters.new(login: 'modified', is_admin: true).permit(:login)
207
- assert !@user.is_admin?
222
+ if Gem::Requirement.new('>= 5.2').satisfied_by?(RAILS_VERSION)
223
+ def test_should_create_will_save_change_to_predicate
224
+ person = Person.create!(email: 'test@example.com')
225
+ refute person.will_save_change_to_email?
226
+ person.email = 'test@example.com'
227
+ refute person.will_save_change_to_email?
228
+ person.email = 'test2@example.com'
229
+ assert person.will_save_change_to_email?
208
230
  end
209
231
 
210
- def test_should_raise_exception_if_not_permitted
211
- @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
212
- assert_raises ActiveModel::ForbiddenAttributesError do
213
- @user.attributes = ActionController::Parameters.new(login: 'modified', is_admin: true)
214
- end
232
+ def test_should_create_saved_change_to_predicate
233
+ person = Person.create!(email: 'test@example.com')
234
+ assert person.saved_change_to_email?
235
+ person.reload
236
+ person.email = 'test@example.com'
237
+ refute person.saved_change_to_email?
238
+ person.email = nil
239
+ refute person.saved_change_to_email?
240
+ person.email = 'test2@example.com'
241
+ refute person.saved_change_to_email?
242
+ person.save
243
+ assert person.saved_change_to_email?
215
244
  end
245
+ end
216
246
 
217
- def test_should_raise_exception_on_init_if_not_permitted
218
- assert_raises ActiveModel::ForbiddenAttributesError do
219
- @user = UserWithProtectedAttribute.new ActionController::Parameters.new(login: 'modified', is_admin: true)
220
- end
221
- end
222
- else
223
- def test_should_assign_attributes
224
- @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
225
- @user.attributes = { login: 'modified', is_admin: true }
226
- assert_equal 'modified', @user.login
227
- end
247
+ def test_should_assign_attributes
248
+ @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
249
+ @user.attributes = ActionController::Parameters.new(login: 'modified', is_admin: true).permit(:login)
250
+ assert_equal 'modified', @user.login
251
+ end
252
+
253
+ def test_should_not_assign_protected_attributes
254
+ @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
255
+ @user.attributes = ActionController::Parameters.new(login: 'modified', is_admin: true).permit(:login)
256
+ assert !@user.is_admin?
257
+ end
228
258
 
229
- def test_should_not_assign_protected_attributes
230
- @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
231
- @user.attributes = { login: 'modified', is_admin: true }
232
- assert !@user.is_admin?
259
+ def test_should_raise_exception_if_not_permitted
260
+ @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
261
+ assert_raises ActiveModel::ForbiddenAttributesError do
262
+ @user.attributes = ActionController::Parameters.new(login: 'modified', is_admin: true)
233
263
  end
264
+ end
234
265
 
235
- def test_should_assign_protected_attributes
236
- @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
237
- if ::ActiveRecord::VERSION::STRING > "3.1"
238
- @user.send(:assign_attributes, { login: 'modified', is_admin: true }, without_protection: true)
239
- else
240
- @user.send(:attributes=, { login: 'modified', is_admin: true }, false)
241
- end
242
- assert @user.is_admin?
266
+ def test_should_raise_exception_on_init_if_not_permitted
267
+ assert_raises ActiveModel::ForbiddenAttributesError do
268
+ @user = UserWithProtectedAttribute.new ActionController::Parameters.new(login: 'modified', is_admin: true)
243
269
  end
244
270
  end
245
271
 
@@ -252,23 +278,21 @@ class ActiveRecordTest < Minitest::Test
252
278
  @person = PersonWithProcMode.create(email: 'test@example.com', credentials: 'password123')
253
279
 
254
280
  # Email is :per_attribute_iv_and_salt
255
- assert_equal @person.class.encrypted_attributes[:email][:mode].class, Proc
256
- assert_equal @person.class.encrypted_attributes[:email][:mode].call, :per_attribute_iv_and_salt
281
+ assert_equal @person.class.attr_encrypted_encrypted_attributes[:email][:mode].class, Proc
282
+ assert_equal @person.class.attr_encrypted_encrypted_attributes[:email][:mode].call, :per_attribute_iv_and_salt
257
283
  refute_nil @person.encrypted_email_salt
258
284
  refute_nil @person.encrypted_email_iv
259
285
 
260
286
  # Credentials is :single_iv_and_salt
261
- assert_equal @person.class.encrypted_attributes[:credentials][:mode].class, Proc
262
- assert_equal @person.class.encrypted_attributes[:credentials][:mode].call, :single_iv_and_salt
287
+ assert_equal @person.class.attr_encrypted_encrypted_attributes[:credentials][:mode].class, Proc
288
+ assert_equal @person.class.attr_encrypted_encrypted_attributes[:credentials][:mode].call, :single_iv_and_salt
263
289
  assert_nil @person.encrypted_credentials_salt
264
290
  assert_nil @person.encrypted_credentials_iv
265
291
  end
266
292
 
267
- if ::ActiveRecord::VERSION::STRING > "3.1"
268
- def test_should_allow_assign_attributes_with_nil
269
- @person = Person.new
270
- assert_nil(@person.assign_attributes nil)
271
- end
293
+ def test_should_allow_assign_attributes_with_nil
294
+ @person = Person.new
295
+ assert_nil(@person.assign_attributes nil)
272
296
  end
273
297
 
274
298
  def test_that_alias_encrypts_column
@@ -305,7 +329,9 @@ class ActiveRecordTest < Minitest::Test
305
329
  def test_should_evaluate_proc_based_mode
306
330
  street = '123 Elm'
307
331
  zipcode = '12345'
308
- address = Address.new(street: street, zipcode: zipcode, mode: :single_iv_and_salt)
309
- assert_nil address.encrypted_zipcode_iv
332
+ address = Address.create(street: street, zipcode: zipcode, mode: :single_iv_and_salt)
333
+ address.reload
334
+ refute_equal address.encrypted_zipcode, zipcode
335
+ assert_equal address.zipcode, zipcode
310
336
  end
311
337
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # encoding: UTF-8
2
4
  require_relative 'test_helper'
3
5
 
@@ -23,11 +25,12 @@ class User
23
25
  attr_encrypted :with_encoding, :key => SECRET_KEY, :encode => true
24
26
  attr_encrypted :with_custom_encoding, :key => SECRET_KEY, :encode => 'm'
25
27
  attr_encrypted :with_marshaling, :key => SECRET_KEY, :marshal => true
26
- attr_encrypted :with_true_if, :key => SECRET_KEY, :if => true
27
- attr_encrypted :with_false_if, :key => SECRET_KEY, :if => false
28
- attr_encrypted :with_true_unless, :key => SECRET_KEY, :unless => true
29
- attr_encrypted :with_false_unless, :key => SECRET_KEY, :unless => false
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
30
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
31
34
 
32
35
  attr_encryptor :aliased, :key => SECRET_KEY
33
36
 
@@ -40,6 +43,7 @@ class User
40
43
  self.should_encrypt = true
41
44
  end
42
45
 
46
+ private
43
47
  def secret_key
44
48
  SECRET_KEY
45
49
  end
@@ -79,11 +83,11 @@ class AttrEncryptedTest < Minitest::Test
79
83
  end
80
84
 
81
85
  def test_should_store_email_in_encrypted_attributes
82
- assert User.encrypted_attributes.include?(:email)
86
+ assert User.attr_encrypted_encrypted_attributes.include?(:email)
83
87
  end
84
88
 
85
89
  def test_should_not_store_salt_in_encrypted_attributes
86
- refute User.encrypted_attributes.include?(:salt)
90
+ refute User.attr_encrypted_encrypted_attributes.include?(:salt)
87
91
  end
88
92
 
89
93
  def test_attr_encrypted_should_return_true_for_email
@@ -91,7 +95,7 @@ class AttrEncryptedTest < Minitest::Test
91
95
  end
92
96
 
93
97
  def test_attr_encrypted_should_not_use_the_same_attribute_name_for_two_attributes_in_the_same_line
94
- refute_equal User.encrypted_attributes[:email][:attribute], User.encrypted_attributes[:without_encoding][:attribute]
98
+ refute_equal User.attr_encrypted_encrypted_attributes[:email][:attribute], User.attr_encrypted_encrypted_attributes[:without_encoding][:attribute]
95
99
  end
96
100
 
97
101
  def test_attr_encrypted_should_return_false_for_salt
@@ -114,7 +118,7 @@ class AttrEncryptedTest < Minitest::Test
114
118
  assert_nil User.encrypt_email(nil, iv: @iv)
115
119
  end
116
120
 
117
- def test_should_not_encrypt_empty_string
121
+ def test_should_not_encrypt_empty_string_by_default
118
122
  assert_equal '', User.encrypt_email('', iv: @iv)
119
123
  end
120
124
 
@@ -150,9 +154,14 @@ class AttrEncryptedTest < Minitest::Test
150
154
  def test_should_decrypt_email_when_reading
151
155
  @user = User.new
152
156
  assert_nil @user.email
153
- iv = @user.encrypted_email_iv.unpack('m').first
154
- salt = @user.encrypted_email_salt[1..-1].unpack('m').first
157
+ options = @user.attr_encrypted_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])
155
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
156
165
  assert_equal 'test@example.com', @user.email
157
166
  end
158
167
 
@@ -214,7 +223,7 @@ class AttrEncryptedTest < Minitest::Test
214
223
  end
215
224
 
216
225
  def test_should_inherit_encrypted_attributes
217
- assert_equal [User.encrypted_attributes.keys, :testing].flatten.collect { |key| key.to_s }.sort, Admin.encrypted_attributes.keys.collect { |key| key.to_s }.sort
226
+ assert_equal [User.attr_encrypted_encrypted_attributes.keys, :testing].flatten.collect { |key| key.to_s }.sort, Admin.attr_encrypted_encrypted_attributes.keys.collect { |key| key.to_s }.sort
218
227
  end
219
228
 
220
229
  def test_should_inherit_attr_encrypted_options
@@ -224,7 +233,7 @@ class AttrEncryptedTest < Minitest::Test
224
233
 
225
234
  def test_should_not_inherit_unrelated_attributes
226
235
  assert SomeOtherClass.attr_encrypted_options.empty?
227
- assert SomeOtherClass.encrypted_attributes.empty?
236
+ assert SomeOtherClass.attr_encrypted_encrypted_attributes.empty?
228
237
  end
229
238
 
230
239
  def test_should_evaluate_a_symbol_option
@@ -282,8 +291,20 @@ class AttrEncryptedTest < Minitest::Test
282
291
  assert_equal 'testing', @user.encrypted_with_true_unless
283
292
  end
284
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
+
285
306
  def test_should_work_with_aliased_attr_encryptor
286
- assert User.encrypted_attributes.include?(:aliased)
307
+ assert User.attr_encrypted_encrypted_attributes.include?(:aliased)
287
308
  end
288
309
 
289
310
  def test_should_always_reset_options
@@ -360,12 +381,12 @@ class AttrEncryptedTest < Minitest::Test
360
381
  @user2 = User.new
361
382
  @user2.email = 'test@example.com'
362
383
 
363
- assert_equal 'test@example.com', @user1.decrypt(:email, @user1.encrypted_email)
384
+ assert_equal 'test@example.com', @user1.attr_encrypted_decrypt(:email, @user1.encrypted_email)
364
385
  end
365
386
 
366
387
  def test_should_specify_the_default_algorithm
367
- assert YetAnotherClass.encrypted_attributes[:email][:algorithm]
368
- assert_equal YetAnotherClass.encrypted_attributes[:email][:algorithm], 'aes-256-gcm'
388
+ assert YetAnotherClass.attr_encrypted_encrypted_attributes[:email][:algorithm]
389
+ assert_equal YetAnotherClass.attr_encrypted_encrypted_attributes[:email][:algorithm], 'aes-256-gcm'
369
390
  end
370
391
 
371
392
  def test_should_not_encode_iv_when_encode_iv_is_false
@@ -390,4 +411,80 @@ class AttrEncryptedTest < Minitest::Test
390
411
  user.email = 'revised_value@test.com'
391
412
  refute_equal original_iv, user.encrypted_email_iv
392
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.attr_encrypted_encrypted_attributes[:ssn][:operation]
479
+ assert_nil another_user.attr_encrypted_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
393
490
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # -*- encoding: utf-8 -*-
2
4
  require_relative 'test_helper'
3
5
 
@@ -41,7 +43,7 @@ class CompatibilityTest < Minitest::Test
41
43
  end
42
44
 
43
45
  def setup
44
- ActiveRecord::Base.connection.tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
46
+ drop_all_tables
45
47
  create_tables
46
48
  end
47
49
 
@@ -81,26 +83,24 @@ class CompatibilityTest < Minitest::Test
81
83
  private
82
84
 
83
85
  def create_tables
84
- silence_stream(STDOUT) do
85
- ActiveRecord::Schema.define(:version => 1) do
86
- create_table :nonmarshalling_pets do |t|
87
- t.string :name
88
- t.string :encrypted_nickname
89
- t.string :encrypted_nickname_iv
90
- t.string :encrypted_nickname_salt
91
- t.string :encrypted_birthdate
92
- t.string :encrypted_birthdate_iv
93
- t.string :encrypted_birthdate_salt
94
- end
95
- create_table :marshalling_pets do |t|
96
- t.string :name
97
- t.string :encrypted_nickname
98
- t.string :encrypted_nickname_iv
99
- t.string :encrypted_nickname_salt
100
- t.string :encrypted_birthdate
101
- t.string :encrypted_birthdate_iv
102
- t.string :encrypted_birthdate_salt
103
- end
86
+ ActiveRecord::Schema.define(:version => 1) do
87
+ create_table :nonmarshalling_pets do |t|
88
+ t.string :name
89
+ t.string :encrypted_nickname
90
+ t.string :encrypted_nickname_iv
91
+ t.string :encrypted_nickname_salt
92
+ t.string :encrypted_birthdate
93
+ t.string :encrypted_birthdate_iv
94
+ t.string :encrypted_birthdate_salt
95
+ end
96
+ create_table :marshalling_pets do |t|
97
+ t.string :name
98
+ t.string :encrypted_nickname
99
+ t.string :encrypted_nickname_iv
100
+ t.string :encrypted_nickname_salt
101
+ t.string :encrypted_birthdate
102
+ t.string :encrypted_birthdate_iv
103
+ t.string :encrypted_birthdate_salt
104
104
  end
105
105
  end
106
106
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'test_helper'
2
4
 
3
5
  DataMapper.setup(:default, 'sqlite3::memory:')
@@ -1,17 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # -*- encoding: utf-8 -*-
2
4
  require_relative 'test_helper'
3
5
 
4
6
  ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
5
7
 
6
8
  def create_people_table
7
- silence_stream(STDOUT) do
8
- ActiveRecord::Schema.define(:version => 1) do
9
- create_table :legacy_people do |t|
10
- t.string :encrypted_email
11
- t.string :password
12
- t.string :encrypted_credentials
13
- t.string :salt
14
- end
9
+ ActiveRecord::Schema.define(:version => 1) do
10
+ create_table :legacy_people do |t|
11
+ t.string :encrypted_email
12
+ t.string :password
13
+ t.string :encrypted_credentials
14
+ t.string :salt
15
15
  end
16
16
  end
17
17
  end
@@ -52,7 +52,7 @@ end
52
52
  class LegacyActiveRecordTest < Minitest::Test
53
53
 
54
54
  def setup
55
- ActiveRecord::Base.connection.tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
55
+ drop_all_tables
56
56
  create_people_table
57
57
  end
58
58