symmetric-encryption 3.4.0 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
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