symmetric-encryption 3.4.0 → 3.6.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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +102 -55
  3. data/Rakefile +13 -8
  4. data/lib/rails/generators/symmetric_encryption/config/config_generator.rb +1 -1
  5. data/lib/rails/generators/symmetric_encryption/heroku_config/templates/symmetric-encryption.yml +2 -2
  6. data/lib/rails/generators/symmetric_encryption/new_keys/new_keys_generator.rb +2 -2
  7. data/lib/symmetric_encryption.rb +7 -6
  8. data/lib/symmetric_encryption/cipher.rb +4 -4
  9. data/lib/symmetric_encryption/extensions/active_record/base.rb +6 -46
  10. data/lib/symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key.rb +129 -0
  11. data/lib/symmetric_encryption/{mongoid.rb → extensions/mongoid/encrypted.rb} +12 -46
  12. data/lib/symmetric_encryption/generator.rb +54 -0
  13. data/lib/symmetric_encryption/railtie.rb +3 -3
  14. data/lib/symmetric_encryption/railties/symmetric_encryption.rake +1 -1
  15. data/lib/symmetric_encryption/railties/symmetric_encryption_validator.rb +1 -1
  16. data/lib/symmetric_encryption/reader.rb +3 -3
  17. data/lib/symmetric_encryption/symmetric_encryption.rb +25 -15
  18. data/lib/symmetric_encryption/version.rb +1 -1
  19. data/lib/symmetric_encryption/writer.rb +4 -4
  20. data/test/active_record_test.rb +474 -0
  21. data/test/cipher_test.rb +15 -15
  22. data/test/config/mongo_mapper.yml +7 -0
  23. data/test/{field_encrypted_test.rb → mongo_mapper_test.rb} +68 -67
  24. data/test/mongoid_test.rb +535 -0
  25. data/test/reader_test.rb +10 -10
  26. data/test/symmetric_encryption_test.rb +27 -27
  27. data/test/test_db.sqlite3 +0 -0
  28. data/test/test_helper.rb +0 -1
  29. data/test/writer_test.rb +2 -2
  30. metadata +14 -8
  31. data/test/attr_encrypted_test.rb +0 -622
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6c78c33fe68704b26ebd996fd8ea8785d73c6fa1
4
- data.tar.gz: 5f1534c06fae8c76cfc0dccf5a2612ce45fbf683
3
+ metadata.gz: 888fb42ac32f310999fea9a5cfa4449e6c3802df
4
+ data.tar.gz: 4709db73139a8c5654b37f7fd8a8a2dd8cb2f00b
5
5
  SHA512:
6
- metadata.gz: 1fdf134465788b41776a086b5f86d0e2c43778899263bb9c3c702124779b5cad0d61466c1af15a11338959f76b7f6435598be7cb0f80d2c92a8d50727c21d372
7
- data.tar.gz: 99a8de3d8d8aa73832f9541b7ab1b448685cd99739a59c600e543f4b27ef55b7c7025b3aaa62d2a0ae91c086aea30e9d9ac08209c2bfb1df7b4bf45ae8ac28eb
6
+ metadata.gz: 85cc771aa2e69f51a386880353f42a5253974b89cd2fc5153dfe3ab5a01d5e43aad7b1fb995f961579271d245a0477bbc926cbc860896ad26a7ebed92e755103
7
+ data.tar.gz: bc0ca28f71e48111c594439de184ebe6b46110b0ce25c93da96afc01c2ceeeed21d46daa11ec91c626fb14147dc3ed2c8e932f541e765b0225ee0d03bbb2dc78
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- symmetric-encryption
1
+ symmetric-encryption [![Build Status](https://secure.travis-ci.org/reidmorrison/symmetric-encryption.png?branch=master)](http://travis-ci.org/reidmorrison/symmetric-encryption)
2
2
  ====================
3
3
 
4
4
  * http://github.com/reidmorrison/symmetric-encryption
@@ -15,30 +15,6 @@ and consistent way
15
15
  Symmetric Encryption uses OpenSSL to encrypt and decrypt data, and can therefore
16
16
  expose all the encryption algorithms supported by OpenSSL.
17
17
 
18
- ## Upgrading from earlier versions to SymmetricEncryption V3
19
-
20
- In version 3 of SymmetricEncryption, the following changes have been made that
21
- may have backward compatibility issues:
22
-
23
- * SymmetricEncryption.decrypt no longer rotates through all the decryption keys
24
- when previous ciphers fail to decrypt the encrypted string.
25
- In a very small, yet significant number of cases it was possible to decrypt data
26
- using the incorrect key. Clearly the data returned was garbage, but it still
27
- returned a string of data instead of throwing an exception.
28
- See SymmetricEncryption.select_cipher to supply your own custom logic to
29
- determine the correct cipher to use when the encrypted string does not have a
30
- header and multiple ciphers are defined.
31
-
32
- * Configuration file format prior to V1 is no longer supported
33
-
34
- * New configuration option has been added to support setting encryption keys
35
- from environment variables
36
-
37
- * Cipher.parse_magic_header! now returns a Struct instead of an Array
38
-
39
- * New config options :encrypted_key and :encrypted_iv to support setting
40
- the encryption key in environment variables
41
-
42
18
  ## Security
43
19
 
44
20
  Many solutions that encrypt data require the encryption keys to be stored in the
@@ -100,7 +76,7 @@ is available when reading back the encrypted file/stream. The key is placed
100
76
  in a header on the file in encrypted form using the current global key/cipher.
101
77
 
102
78
  The ActiveRecord attr_encrypted method supports the :random_iv => true option.
103
- Similarly for Mongoid the :random_iv => true option can be added.
79
+ Similarly for MongoMapper and Mongoid the :random_iv => true option can be added.
104
80
 
105
81
  Note that encrypting the same input string with the same key and :random_iv => true
106
82
  option will result in different encrypted output every time it is encrypted.
@@ -110,6 +86,7 @@ option will result in different encrypted output every time it is encrypted.
110
86
  * Encryption of passwords in configuration files
111
87
  * Encryption of ActiveRecord model attributes by prefixing attributes / column
112
88
  names with encrypted_
89
+ * Encryption of MongoMapper keys by using :encrypted_key
113
90
  * Encryption of Mongoid model fields by adding :encrypted option to field
114
91
  definitions
115
92
  * Externalization of symmetric encryption keys so that they are not in the
@@ -134,8 +111,8 @@ option will result in different encrypted output every time it is encrypted.
134
111
  * Add the encryption header to all encrypted strings.
135
112
  See the _always_add_header_ option in the configuration file.
136
113
 
137
- * Set :random_iv => true for all ActiveRecord attributes and Mongoid fields
138
- which are not used in indexes and will not be used as part of a query.
114
+ * Add `random_iv: true` for all ActiveRecord attributes, MongoMapper keys, and
115
+ Mongoid fields which are not used in indexes and will not be used as part of a query.
139
116
 
140
117
  ## Binary Data
141
118
 
@@ -174,19 +151,19 @@ class User < ActiveRecord::Base
174
151
  # encrypted string
175
152
  #
176
153
  # Requires users table to have a column called encrypted_age of type string
177
- attr_encrypted :age, :type => :integer
154
+ attr_encrypted :age, type: integer
178
155
 
179
156
  # Since string and long_string are not used in the where clause of any SQL
180
157
  # queries it is better to ensure that the encrypted value is always different
181
158
  # by encrypting every value with a random Initialization Vector.
182
159
  #
183
160
  # Note: Encrypting the same value twice will result in different encrypted
184
- # values when :random_iv => true
185
- attr_encrypted :string, :random_iv => true
161
+ # values when :random_iv is true
162
+ attr_encrypted :string, random_iv: true
186
163
 
187
164
  # Long encrypted strings can also be compressed prior to encryption to save
188
165
  # disk space
189
- attr_encrypted :long_string, :random_iv => true, :compress => true
166
+ attr_encrypted :long_string, random_iv: true, compress: true
190
167
 
191
168
  # By specifying the type as :json the value will be serialized to JSON
192
169
  # before encryption and deserialized from JSON after decryption.
@@ -195,10 +172,10 @@ class User < ActiveRecord::Base
195
172
  # compression before the string is encrypted
196
173
  #
197
174
  # Requires users table to have a column called encrypted_values of type string
198
- attr_encrypted :values, :type => :json, :compress => true
175
+ attr_encrypted :values, type: :json, compress: true
199
176
 
200
- validates :encrypted_bank_account_number, :symmetric_encryption => true
201
- validates :encrypted_social_security_number, :symmetric_encryption => true
177
+ validates :encrypted_bank_account_number, symmetric_encryption: true
178
+ validates :encrypted_social_security_number, symmetric_encryption: true
202
179
  end
203
180
 
204
181
  # Create a new user instance assigning a bank account number
@@ -210,7 +187,7 @@ user.bank_account_number = '12345'
210
187
  user.save!
211
188
 
212
189
  # Short example using create
213
- User.create(:bank_account_number => '12345')
190
+ User.create(bank_account_number: '12345')
214
191
  ```
215
192
 
216
193
  Several types are supported for ActiveRecord models when encrypting or decrypting data.
@@ -226,9 +203,57 @@ Each type maps to the built-in Ruby types as follows:
226
203
  - :json => Uses JSON serialization, useful for hashes and arrays
227
204
  - :yaml => Uses YAML serialization, useful for hashes and arrays
228
205
 
206
+ ### MongoMapper Example
207
+
208
+ To encrypt a field in a MongoMapper document, use `encrypted_key` instead of `key`
209
+ when specifying a key.
210
+
211
+ ```ruby
212
+ field :encrypted_age, type: String, encrypted: {type: :integer}
213
+ end
214
+
215
+ # User model MongoMapper
216
+ class User
217
+ include MongoMapper::Document
218
+
219
+ key :name, String
220
+ encrypted_key :bank_account_number, String
221
+ encrypted_key :social_security_number, String
222
+ encrypted_key :life_history, String, encrypted: { random_iv: true, compress: true }
223
+
224
+ # Encrypted fields are _always_ stored in Mongo as a String
225
+ # To get the result back as an Integer, Symmetric Encryption will automatically
226
+ # perform the necessary conversions
227
+ encrypted_key :integer_value, Integer
228
+ encrypted_key :float_value, Float
229
+ encrypted_key :decimal_value, BigDecimal
230
+ encrypted_key :datetime_value, DateTime
231
+ encrypted_key :time_value, Time
232
+ encrypted_key :date_value, Date
233
+ encrypted_key :true_value, Boolean
234
+ encrypted_key :data_json, Hash, encrypted: {random_iv: true, compress: true}
235
+ # By default Hash is saved as JSON, to save as YAML add the type specifier:
236
+ encrypted_key :data_yaml, Hash, encrypted: {random_iv: true, compress: true, type: :yaml}
237
+
238
+ # Optionally add validation to ensure that encrypted fields are in fact encrypted
239
+ # before the data is saved
240
+ validates :encrypted_bank_account_number, symmetric_encryption: true
241
+ validates :encrypted_social_security_number, symmetric_encryption: true
242
+ end
243
+
244
+ # Create a new user document
245
+ User.create(bank_account_number: '12345')
246
+
247
+ # When finding a document, always use the encrypted form of the field name
248
+ user = User.where(encrypted_bank_account_number: SymmetricEncryption.encrypt('12345')).first
249
+
250
+ # Fields can be accessed using their unencrypted names
251
+ puts user.bank_account_number
252
+ ```
253
+
229
254
  ### Mongoid Example
230
255
 
231
- To encrypt a field in a Mongoid document, just add ":encrypted => true" at the end
256
+ To encrypt a field in a Mongoid document, just add "encrypted: true" at the end
232
257
  of the field specifier. The field name must currently begin with "encrypted_"
233
258
 
234
259
  ```ruby
@@ -236,36 +261,34 @@ of the field specifier. The field name must currently begin with "encrypted_"
236
261
  class User
237
262
  include Mongoid::Document
238
263
 
239
- field :name, :type => String
240
- field :encrypted_bank_account_number, :type => String, :encrypted => true
241
- field :encrypted_social_security_number, :type => String, :encrypted => true
242
- field :encrypted_life_history, :type => String, :encrypted => {:compress => true, :random_iv => true}
264
+ field :name, type: String
265
+ field :encrypted_bank_account_number, type: String, encrypted: true
266
+ field :encrypted_social_security_number, type: String, encrypted: true
267
+ field :encrypted_life_history, type: String, encrypted: {compress: true, random_iv: true}
243
268
 
244
269
  # Encrypted fields are _always_ stored in Mongo as a String
245
270
  # To get the result back as an Integer, Symmetric Encryption can do the
246
271
  # necessary conversions by specifying the internal type as an option
247
272
  # to :encrypted
248
273
  # #see SymmetricEncryption::COERCION_TYPES for full list of types
249
- field :encrypted_age, :type => String, :encrypted => {:type => :integer}
274
+ field :encrypted_age, type: String, encrypted: {type: :integer}
250
275
  end
251
276
 
252
277
  # Create a new user document
253
- User.create(:bank_account_number => '12345')
278
+ User.create(bank_account_number: '12345')
254
279
 
255
280
  # When finding a document, always use the encrypted form of the field name
256
- user = User.where(:encrypted_bank_account_number => SymmetricEncryption.encrypt('12345')).first
281
+ user = User.where(encrypted_bank_account_number: SymmetricEncryption.encrypt('12345')).first
257
282
 
258
283
  # Fields can be accessed using their unencrypted names
259
284
  puts user.bank_account_number
260
285
  ```
261
286
 
262
- Note: At this time Symmetric Encryption only supports Mongoid fields with a type of String
263
-
264
287
  ### Validation Example
265
288
 
266
289
  ```ruby
267
290
  class MyModel < ActiveRecord::Base
268
- validates :encrypted_ssn, :symmetric_encryption => true
291
+ validates :encrypted_ssn, symmetric_encryption: true
269
292
  end
270
293
 
271
294
  m = MyModel.new
@@ -330,7 +353,7 @@ end
330
353
  Example: Compress, Encrypt and write data to a file
331
354
 
332
355
  ```ruby
333
- SymmetricEncryption::Writer.open('encrypted_compressed.zip', :compress => true) do |file|
356
+ SymmetricEncryption::Writer.open('encrypted_compressed.zip', compress: true) do |file|
334
357
  file.write "Hello World\n"
335
358
  file.write "Compress this\n"
336
359
  file.write "Keep this safe and secure\n"
@@ -344,9 +367,9 @@ Before generating keys we can use SymmetricEncryption in a standalone test envir
344
367
  ```ruby
345
368
  # Use test encryption keys
346
369
  SymmetricEncryption.cipher = SymmetricEncryption::Cipher.new(
347
- :key => '1234567890ABCDEF1234567890ABCDEF',
348
- :iv => '1234567890ABCDEF',
349
- :cipher_name => 'aes-128-cbc'
370
+ key: '1234567890ABCDEF1234567890ABCDEF',
371
+ iv: '1234567890ABCDEF',
372
+ cipher_name: 'aes-128-cbc'
350
373
  )
351
374
  encrypted = SymmetricEncryption.encrypt('hello world')
352
375
  puts SymmetricEncryption.decrypt(encrypted)
@@ -685,6 +708,30 @@ production:
685
708
  Default: false
686
709
  ```
687
710
 
711
+ ## Upgrading from earlier versions to SymmetricEncryption V3
712
+
713
+ In version 3 of SymmetricEncryption, the following changes have been made that
714
+ may have backward compatibility issues:
715
+
716
+ * SymmetricEncryption.decrypt no longer rotates through all the decryption keys
717
+ when previous ciphers fail to decrypt the encrypted string.
718
+ In a very small, yet significant number of cases it was possible to decrypt data
719
+ using the incorrect key. Clearly the data returned was garbage, but it still
720
+ returned a string of data instead of throwing an exception.
721
+ See SymmetricEncryption.select_cipher to supply your own custom logic to
722
+ determine the correct cipher to use when the encrypted string does not have a
723
+ header and multiple ciphers are defined.
724
+
725
+ * Configuration file format prior to V1 is no longer supported
726
+
727
+ * New configuration option has been added to support setting encryption keys
728
+ from environment variables
729
+
730
+ * Cipher.parse_magic_header! now returns a Struct instead of an Array
731
+
732
+ * New config options :encrypted_key and :encrypted_iv to support setting
733
+ the encryption key in environment variables
734
+
688
735
  Meta
689
736
  ----
690
737
 
@@ -695,16 +742,16 @@ Meta
695
742
 
696
743
  This project uses [Semantic Versioning](http://semver.org/).
697
744
 
698
- Authors
699
- -------
745
+ Author
746
+ ------
700
747
 
701
748
  [Reid Morrison](https://github.com/reidmorrison)
702
749
 
703
750
  Contributors
704
751
  ------------
705
752
 
706
- [M. Scott Ford](https://github.com/mscottford)
707
- [Adam St. John](https://github.com/astjohn)
753
+ * [M. Scott Ford](https://github.com/mscottford)
754
+ * [Adam St. John](https://github.com/astjohn)
708
755
 
709
756
  License
710
757
  -------
data/Rakefile CHANGED
@@ -1,15 +1,18 @@
1
- lib = File.expand_path('../lib/', __FILE__)
2
- $:.unshift lib unless $:.include?(lib)
3
-
4
- require 'rubygems'
5
- require 'rubygems/package'
6
1
  require 'rake/clean'
7
2
  require 'rake/testtask'
3
+
4
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
8
5
  require 'symmetric_encryption/version'
9
6
 
10
- desc "Build gem"
11
- task :gem do |t|
12
- Gem::Package.build(Gem::Specification.load('symmetric-encryption.gemspec'))
7
+ task :gem do
8
+ system "gem build symmetric-encryption.gemspec"
9
+ end
10
+
11
+ task :publish => :gem do
12
+ system "git tag -a v#{SymmetricEncryption::VERSION} -m 'Tagging #{SymmetricEncryption::VERSION}'"
13
+ system "git push --tags"
14
+ system "gem push symmetric-encryption-#{SymmetricEncryption::VERSION}.gem"
15
+ system "rm symmetric-encryption-#{SymmetricEncryption::VERSION}.gem"
13
16
  end
14
17
 
15
18
  desc "Run Test Suite"
@@ -24,3 +27,5 @@ task :test do
24
27
 
25
28
  Rake::Task['functional'].invoke
26
29
  end
30
+
31
+ task :default => :test
@@ -3,7 +3,7 @@ module SymmetricEncryption
3
3
  class ConfigGenerator < Rails::Generators::Base
4
4
  desc "Creates a SymmetricEncryption configuration file at config/symmetric-encryption.yml"
5
5
 
6
- argument :key_path, :type => :string, :optional => false
6
+ argument :key_path, type: :string, optional: false
7
7
 
8
8
  def self.source_root
9
9
  @_symmetric_encryption_source_root ||= File.expand_path("../templates", __FILE__)
@@ -23,7 +23,7 @@ encrypted_key = ::Base64.strict_encode64(rsa_key.public_encrypt(key_pair[:key]))
23
23
 
24
24
  puts "\n\n********************************************************************************"
25
25
  puts "Add the release environment key to Heroku: (Optional)\n\n"
26
- puts " heroku config:add RELEASE_KEY1:#{encrypted_key}\n\n"
26
+ puts " heroku config:add RELEASE_KEY1=#{encrypted_key}\n\n"
27
27
  -%>
28
28
  release:
29
29
  # Since the key to encrypt and decrypt with must NOT be stored along with the
@@ -52,7 +52,7 @@ iv = ::Base64.strict_encode64(key_pair[:iv])
52
52
  encrypted_key = ::Base64.strict_encode64(rsa_key.public_encrypt(key_pair[:key]))
53
53
 
54
54
  puts "Add the production key to Heroku:\n\n"
55
- puts " heroku config:add PRODUCTION_KEY1:#{encrypted_key}\n\n"
55
+ puts " heroku config:add PRODUCTION_KEY1=#{encrypted_key}\n\n"
56
56
  puts "********************************************************************************\n\n\n"
57
57
  -%>
58
58
  production:
@@ -2,8 +2,8 @@ module SymmetricEncryption
2
2
  module Generators
3
3
  class NewKeysGenerator < Rails::Generators::Base
4
4
  desc "Generate new Symmetric key and initialization vector based on values in config/symmetric-encryption.yml"
5
-
6
- argument :environment, :type => :string, :optional => false
5
+
6
+ argument :environment, type: :string, optional: false
7
7
 
8
8
  def create_config_file
9
9
  SymmetricEncryption.generate_symmetric_key_files(File.join('config', "symmetric-encryption.yml"), environment)
@@ -8,13 +8,14 @@ require 'symmetric_encryption/cipher'
8
8
  require 'symmetric_encryption/symmetric_encryption'
9
9
 
10
10
  module SymmetricEncryption
11
- autoload :Reader, 'symmetric_encryption/reader'
12
- autoload :Writer, 'symmetric_encryption/writer'
13
- end
14
- if defined?(Rails)
15
- require 'symmetric_encryption/railtie'
11
+ autoload :Reader, 'symmetric_encryption/reader'
12
+ autoload :Writer, 'symmetric_encryption/writer'
13
+ autoload :Generator, 'symmetric_encryption/generator'
16
14
  end
17
15
 
16
+ # Add support for other libraries only if they have already been loaded
17
+ require 'symmetric_encryption/railtie' if defined?(Rails)
18
18
  require 'symmetric_encryption/extensions/active_record/base' if defined?(ActiveRecord::Base)
19
19
  require 'symmetric_encryption/railties/symmetric_encryption_validator' if defined?(ActiveModel)
20
- require 'symmetric_encryption/mongoid' if defined?(Mongoid)
20
+ require 'symmetric_encryption/extensions/mongoid/encrypted' if defined?(Mongoid)
21
+ require 'symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key' if defined?(MongoMapper)
@@ -23,7 +23,7 @@ module SymmetricEncryption
23
23
  :key, # [String] Key used to encrypt the data, if supplied in the header
24
24
  :cipher_name, # [String] Name of the cipher used, if supplied in the header
25
25
  :version, # [Integer] Version of the cipher used, if supplied in the header
26
- :decryption_cipher, # [SymmetricEncryption::Cipher] Cipher matching the header, or SymmetricEncryption.cipher(default_version)
26
+ :decryption_cipher # [SymmetricEncryption::Cipher] Cipher matching the header, or SymmetricEncryption.cipher(default_version)
27
27
  )
28
28
 
29
29
  # Generate a new Symmetric Key pair
@@ -36,9 +36,9 @@ module SymmetricEncryption
36
36
  openssl_cipher.encrypt
37
37
 
38
38
  {
39
- :key => openssl_cipher.random_key,
40
- :iv => openssl_cipher.random_iv,
41
- :cipher_name => cipher_name
39
+ key: openssl_cipher.random_key,
40
+ iv: openssl_cipher.random_iv,
41
+ cipher_name: cipher_name
42
42
  }
43
43
  end
44
44
 
@@ -42,51 +42,9 @@ module ActiveRecord #:nodoc:
42
42
  define_attribute_methods rescue nil
43
43
 
44
44
  options = params.last.is_a?(Hash) ? params.pop.dup : {}
45
- random_iv = options.delete(:random_iv) || false
46
- compress = options.delete(:compress) || false
47
- type = options.delete(:type) || :string
48
-
49
- raise "Invalid type: #{type.inspect}. Valid types: #{SymmetricEncryption::COERCION_TYPES.inspect}" unless SymmetricEncryption::COERCION_TYPES.include?(type)
50
-
51
- # For backward compatibility
52
- if options.delete(:marshal) == true
53
- warn("The :marshal option has been deprecated in favor of :type. For example: attr_encrypted name, :type => :yaml")
54
- raise "Marshal is depreacted and cannot be used in conjunction with :type, just use :type. For #{params.inspect}" if type != :string
55
- type = :yaml
56
- end
57
-
58
- options.each {|option| warn "Ignoring unknown option #{option.inspect} supplied to attr_encrypted with #{params.inspect}"}
59
-
60
- if const_defined?(:EncryptedAttributes, _search_ancestors = false)
61
- mod = const_get(:EncryptedAttributes)
62
- else
63
- mod = const_set(:EncryptedAttributes, Module.new)
64
- include mod
65
- end
66
45
 
67
46
  params.each do |attribute|
68
- # Generate unencrypted attribute with getter and setter
69
- mod.module_eval(<<-UNENCRYPTED, __FILE__, __LINE__ + 1)
70
- # Returns the decrypted value for the encrypted attribute
71
- # The decrypted value is cached and is only decrypted if the encrypted value has changed
72
- # If this method is not called, then the encrypted value is never decrypted
73
- def #{attribute}
74
- if @stored_encrypted_#{attribute} != self.encrypted_#{attribute}
75
- @#{attribute} = ::SymmetricEncryption.decrypt(self.encrypted_#{attribute},version=nil,:#{type}).freeze
76
- @stored_encrypted_#{attribute} = self.encrypted_#{attribute}
77
- end
78
- @#{attribute}
79
- end
80
-
81
- # Set the un-encrypted attribute
82
- # Also updates the encrypted field with the encrypted value
83
- def #{attribute}=(value)
84
- v = SymmetricEncryption::coerce(value, :#{type})
85
- self.encrypted_#{attribute} = @stored_encrypted_#{attribute} = ::SymmetricEncryption.encrypt(v,#{random_iv},#{compress},:#{type})
86
- @#{attribute} = v.freeze
87
- end
88
- UNENCRYPTED
89
-
47
+ SymmetricEncryption::Generator.generate_decrypted_accessors(self, attribute, "encrypted_#{attribute}", options)
90
48
  encrypted_attributes[attribute.to_sym] = "encrypted_#{attribute}".to_sym
91
49
  end
92
50
  end
@@ -100,7 +58,7 @@ module ActiveRecord #:nodoc:
100
58
  # attr_encrypted :email
101
59
  # end
102
60
  #
103
- # User.encrypted_attributes # { :email => :encrypted_email }
61
+ # User.encrypted_attributes => { email: encrypted_email }
104
62
  def encrypted_attributes
105
63
  @encrypted_attributes ||= superclass.respond_to?(:encrypted_attributes) ? superclass.encrypted_attributes.dup : {}
106
64
  end
@@ -180,8 +138,10 @@ module ActiveRecord #:nodoc:
180
138
  method_missing_without_attr_encrypted(method, *args, &block)
181
139
  end
182
140
 
183
- alias_method_chain :method_missing, :attr_encrypted
184
-
141
+ # Dynamic finders dropped in Rails 4.1
142
+ if ActiveRecord::VERSION::STRING.to_f < 4.1
143
+ alias_method_chain :method_missing, :attr_encrypted
144
+ end
185
145
  end
186
146
  end
187
147
  end