attr_encrypted 3.0.0 → 4.0.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 +5 -5
- data/.travis.yml +14 -16
- data/CHANGELOG.md +60 -14
- data/README.md +27 -9
- data/Rakefile +3 -0
- data/attr_encrypted.gemspec +6 -13
- 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/adapters/active_record.rb +58 -30
- data/lib/attr_encrypted/adapters/data_mapper.rb +3 -1
- data/lib/attr_encrypted/adapters/sequel.rb +3 -1
- data/lib/attr_encrypted/version.rb +3 -1
- data/lib/attr_encrypted.rb +160 -129
- data/test/active_record_test.rb +130 -104
- data/test/attr_encrypted_test.rb +113 -16
- data/test/compatibility_test.rb +21 -21
- data/test/data_mapper_test.rb +2 -0
- data/test/legacy_active_record_test.rb +9 -9
- data/test/legacy_attr_encrypted_test.rb +8 -6
- data/test/legacy_compatibility_test.rb +15 -15
- data/test/legacy_data_mapper_test.rb +2 -0
- data/test/legacy_sequel_test.rb +2 -0
- data/test/run.sh +15 -7
- data/test/sequel_test.rb +2 -0
- data/test/test_helper.rb +11 -5
- metadata +27 -50
- checksums.yaml.gz.sig +0 -0
- data/certs/saghaulor.pem +0 -21
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
data/test/active_record_test.rb
CHANGED
@@ -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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
50
|
-
module
|
51
|
-
|
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
|
-
|
86
|
-
attr_encrypted :password, 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
|
-
|
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
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
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
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
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
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
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
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
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
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
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
|
-
|
236
|
-
|
237
|
-
|
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.
|
256
|
-
assert_equal @person.class.
|
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.
|
262
|
-
assert_equal @person.class.
|
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
|
-
|
268
|
-
|
269
|
-
|
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.
|
309
|
-
|
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
|
data/test/attr_encrypted_test.rb
CHANGED
@@ -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.
|
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.
|
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.
|
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
|
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
|
-
|
154
|
-
|
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.
|
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.
|
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.
|
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.
|
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.
|
368
|
-
assert_equal YetAnotherClass.
|
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
|
data/test/compatibility_test.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
data/test/data_mapper_test.rb
CHANGED
@@ -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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
55
|
+
drop_all_tables
|
56
56
|
create_people_table
|
57
57
|
end
|
58
58
|
|