attr_encrypted 3.0.2 → 3.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f35a7b7559ac43fbc20bf110b06c48457195c35
4
- data.tar.gz: a99c8beb7a082c64d21f123aeb5c342dffbb80c2
3
+ metadata.gz: 5c1a2bcf5e2b7fc8937e96cb0fcd99926bd98d1e
4
+ data.tar.gz: 40112aef07bda5ba8145b2fb634a9bdbfea34d7a
5
5
  SHA512:
6
- metadata.gz: 25d196cdd13c8c8f0b677583e734cd85e5eea7cf148c33c9317d9bc966481dd549a5513d1f89ac598e53086a4913ba2873184830d57dbc5b740413464397e89e
7
- data.tar.gz: 344729a1eb162560e4519b851e0a736f81dddaad4c652338b1af568549d7ba5036c1a7f935b01a7805a1da4972aeb054ffa7b3980e571213ca10a08b75227e8b
6
+ metadata.gz: cbb4fb1d4fa7e22f791139ab1b9a96324cbb8e07f7e8472561a3dd0ce1fcb0a7c048c0ba413b5bccb876dade09f9528ccc7d23caa4378de3da8ef2c540ba76ad
7
+ data.tar.gz: ef6b487235f2f92ccdf73de3c806b3b3f9161c2ebcd78b2102e1975edc3150cda28a7b458136a051100e939a271b2e92ca690cd38360ec5c43c9c33db22dc1f4
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,5 +1,8 @@
1
1
  # attr_encrypted #
2
2
 
3
+ ## 3.0.3 ##
4
+ * Fixed: attr_was would decrypt the attribute upon every call. This is inefficient and introduces problems when the options change between decrypting an old value and encrypting a new value; for example, when rotating the encryption key. As such, the new approach caches the decrypted value of the old encrypted value such that the old options are no longer needed. (@johnny-lai) (@saghaulor)
5
+
3
6
  ## 3.0.2 ##
4
7
  * Changed: Removed alias_method_chain for compatibility with Rails v5.x (@grosser)
5
8
  * Changed: Updated Travis build matrix to include Rails 5. (@saghaulor) (@connorshea)
@@ -0,0 +1 @@
1
+ c1256b459336d4a2012a0d0c70ce5cd3dac46acb5e78da6f77f6f104cb1e8b7b
@@ -0,0 +1 @@
1
+ dca0c8a729974c0e26fde4cd4216c7d0f66d9eca9f6cf0ccca64999f5180a00bf7c05b630c1d420ec1673141a2923946e8bd28b12e711faf64a4cd42c7a3ac9e
@@ -53,22 +53,32 @@ if defined?(ActiveRecord::Base)
53
53
  attr = attrs.pop
54
54
  options.merge! encrypted_attributes[attr]
55
55
 
56
- define_method("#{attr}_changed?") do
57
- if send("#{options[:attribute]}_changed?")
58
- send(attr) != send("#{attr}_was")
56
+ define_method("#{attr}_was") do
57
+ attribute_was(attr)
58
+ end
59
+
60
+ if ::ActiveRecord::VERSION::STRING >= "4.1"
61
+ define_method("#{attr}_changed?") do |options = {}|
62
+ attribute_changed?(attr, options)
63
+ end
64
+ else
65
+ define_method("#{attr}_changed?") do
66
+ attribute_changed?(attr)
59
67
  end
60
68
  end
61
69
 
62
- define_method("#{attr}_was") do
63
- attr_was_options = { operation: :decrypting }
64
- attr_was_options[:iv]= send("#{options[:attribute]}_iv_was") if respond_to?("#{options[:attribute]}_iv_was")
65
- attr_was_options[:salt]= send("#{options[:attribute]}_salt_was") if respond_to?("#{options[:attribute]}_salt_was")
66
- encrypted_attributes[attr].merge!(attr_was_options)
67
- evaluated_options = evaluated_attr_encrypted_options_for(attr)
68
- [:iv, :salt, :operation].each { |key| encrypted_attributes[attr].delete(key) }
69
- self.class.decrypt(attr, send("#{options[:attribute]}_was"), evaluated_options)
70
+ define_method("#{attr}_change") do
71
+ attribute_change(attr)
72
+ end
73
+
74
+ define_method("#{attr}_with_dirtiness=") do |value|
75
+ attribute_will_change!(attr) if value != __send__(attr)
76
+ __send__("#{attr}_without_dirtiness=", value)
70
77
  end
71
78
 
79
+ alias_method "#{attr}_without_dirtiness=", "#{attr}="
80
+ alias_method "#{attr}=", "#{attr}_with_dirtiness="
81
+
72
82
  alias_method "#{attr}_before_type_cast", attr
73
83
  end
74
84
 
@@ -3,7 +3,7 @@ module AttrEncrypted
3
3
  module Version
4
4
  MAJOR = 3
5
5
  MINOR = 0
6
- PATCH = 2
6
+ PATCH = 3
7
7
 
8
8
  # Returns a version string by joining <tt>MAJOR</tt>, <tt>MINOR</tt>, and <tt>PATCH</tt> with <tt>'.'</tt>
9
9
  #
@@ -19,6 +19,7 @@ def create_tables
19
19
  t.string :encrypted_password
20
20
  t.string :encrypted_password_iv
21
21
  t.string :encrypted_password_salt
22
+ t.binary :key
22
23
  end
23
24
  create_table :users do |t|
24
25
  t.string :login
@@ -80,8 +81,20 @@ class PersonWithProcMode < Person
80
81
  end
81
82
 
82
83
  class Account < ActiveRecord::Base
83
- attr_accessor :key
84
- attr_encrypted :password, key: Proc.new {|account| account.key}
84
+ ACCOUNT_ENCRYPTION_KEY = SecureRandom.base64(32)
85
+ attr_encrypted :password, key: :password_encryption_key
86
+
87
+ def encrypting?(attr)
88
+ encrypted_attributes[attr][:operation] == :encrypting
89
+ end
90
+
91
+ def password_encryption_key
92
+ if encrypting?(:password)
93
+ self.key = ACCOUNT_ENCRYPTION_KEY
94
+ else
95
+ self.key
96
+ end
97
+ end
85
98
  end
86
99
 
87
100
  class PersonWithSerialization < ActiveRecord::Base
@@ -117,7 +130,6 @@ class ActiveRecordTest < Minitest::Test
117
130
  def setup
118
131
  ActiveRecord::Base.connection.tables.each { |table| ActiveRecord::Base.connection.drop_table(table) }
119
132
  create_tables
120
- Account.create!(key: SECRET_KEY, password: "password")
121
133
  end
122
134
 
123
135
  def test_should_encrypt_email
@@ -167,12 +179,6 @@ class ActiveRecordTest < Minitest::Test
167
179
  Account.new.attributes = { password: "password", key: SECRET_KEY }
168
180
  end
169
181
 
170
- def test_should_preserve_hash_key_type
171
- hash = { foo: 'bar' }
172
- account = Account.create!(key: hash)
173
- assert_equal account.key, hash
174
- end
175
-
176
182
  def test_should_create_changed_predicate
177
183
  person = Person.create!(email: 'test@example.com')
178
184
  refute person.email_changed?
@@ -198,6 +204,23 @@ class ActiveRecordTest < Minitest::Test
198
204
  assert_equal old_zipcode, address.zipcode_was
199
205
  end
200
206
 
207
+ def test_attribute_was_works_when_options_for_old_encrypted_value_are_different_than_options_for_new_encrypted_value
208
+ pw = 'password'
209
+ crypto_key = SecureRandom.base64(32)
210
+ old_iv = SecureRandom.random_bytes(12)
211
+ account = Account.create
212
+ encrypted_value = Encryptor.encrypt(value: pw, iv: old_iv, key: crypto_key)
213
+ Account.where(id: account.id).update_all(key: crypto_key, encrypted_password_iv: [old_iv].pack('m'), encrypted_password: [encrypted_value].pack('m'))
214
+ account = Account.find(account.id)
215
+ assert_equal pw, account.password
216
+ account.password = pw.reverse
217
+ assert_equal pw, account.password_was
218
+ account.save
219
+ account.reload
220
+ assert_equal Account::ACCOUNT_ENCRYPTION_KEY, account.key
221
+ assert_equal pw.reverse, account.password
222
+ end
223
+
201
224
  if ::ActiveRecord::VERSION::STRING > "4.0"
202
225
  def test_should_assign_attributes
203
226
  @user = UserWithProtectedAttribute.new(login: 'login', is_admin: false)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attr_encrypted
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.2
4
+ version: 3.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Huber
@@ -33,7 +33,7 @@ cert_chain:
33
33
  ZjeLmnSDiwL6doiP5IiwALH/dcHU67ck3NGf6XyqNwQrrmtPY0mv1WVVL4Uh+vYE
34
34
  kHoFzE2no0BfBg78Re8fY69P5yES5ncC
35
35
  -----END CERTIFICATE-----
36
- date: 2016-07-15 00:00:00.000000000 Z
36
+ date: 2016-07-22 00:00:00.000000000 Z
37
37
  dependencies:
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: encryptor
@@ -226,6 +226,8 @@ files:
226
226
  - checksum/attr_encrypted-3.0.0.gem.sha512
227
227
  - checksum/attr_encrypted-3.0.1.gem.sha256
228
228
  - checksum/attr_encrypted-3.0.1.gem.sha512
229
+ - checksum/attr_encrypted-3.0.2.gem.sha256
230
+ - checksum/attr_encrypted-3.0.2.gem.sha512
229
231
  - lib/attr_encrypted.rb
230
232
  - lib/attr_encrypted/adapters/active_record.rb
231
233
  - lib/attr_encrypted/adapters/data_mapper.rb
metadata.gz.sig CHANGED
Binary file