attr_encrypted 1.1.2 → 1.2.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.
@@ -12,7 +12,6 @@ It works with ANY class, however, you get a few extra features when you're using
12
12
 
13
13
  == Usage
14
14
 
15
-
16
15
  === Basic
17
16
 
18
17
  Encrypting attributes has never been easier:
@@ -38,7 +37,7 @@ Encrypting attributes has never been easier:
38
37
  @user = User.load
39
38
  @user.ssn # decrypts :encrypted_ssn and returns '123-45-6789'
40
39
 
41
- The <tt>attr_encrypted</tt> method is also aliased as <tt>attr_encryptor</tt> to conform to Ruby's <tt>attr_</tt> naming conventions. I know that I should have called this project <tt>attr_encryptor</tt> but it was too late when I realized it ='(.
40
+ The <tt>attr_encrypted</tt> method is also aliased as <tt>attr_encryptor</tt> to conform to Ruby's <tt>attr_</tt> naming conventions. I should have called this project <tt>attr_encryptor</tt> but it was too late when I realized it ='(.
42
41
 
43
42
 
44
43
  === Specifying the encrypted attribute name
@@ -246,6 +245,8 @@ You may want to encrypt objects other than strings (e.g. hashes, arrays, etc). I
246
245
  attr_encrypted :credentials, :key => 'some secret key', :marshal => true
247
246
  end
248
247
 
248
+ You may also optionally specify <tt>:marshaler</tt>, <tt>:dump_method</tt>, and <tt>:load_method</tt> if you want to use something other than the default <tt>Marshal</tt> object.
249
+
249
250
 
250
251
  === Encrypt/decrypt attribute methods
251
252
 
@@ -297,12 +298,5 @@ Just like the default options for <tt>ActiveRecord</tt>, the <tt>:encode</tt> op
297
298
  * Make your feature addition or bug fix.
298
299
  * Add tests for it. This is important so I don't break it in a
299
300
  future version unintentionally.
300
- * Commit, do not mess with rakefile, version, or history.
301
- (if you want to have your own version, that is fine but
302
- bump version in a commit by itself I can ignore when I pull)
303
- * Send me a pull request. Bonus points for topic branches.
304
-
305
-
306
- == Contact
307
-
308
- Problems, comments, and suggestions all welcome: shuber@huberry.com
301
+ * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
302
+ * Send me a pull request. Bonus points for topic branches.
@@ -1,26 +1,162 @@
1
- require 'eigenclass'
2
1
  require 'encryptor'
3
2
 
3
+ # Adds attr_accessors that encrypt and decrypt an object's attributes
4
4
  module AttrEncrypted
5
- def self.extended(base)
6
- base.attr_encrypted_options = {}
7
- base.instance_variable_set('@encrypted_attributes', {})
5
+ autoload :Version, 'attr_encrypted/version'
6
+
7
+ def self.extended(base) # :nodoc:
8
+ base.class_eval do
9
+ include InstanceMethods
10
+ attr_writer :attr_encrypted_options
11
+ @attr_encrypted_options, @encrypted_attributes = {}, {}
12
+ end
8
13
  end
9
-
10
- # Default options to use with calls to <tt>attr_encrypted</tt>.
14
+
15
+ # Generates attr_accessors that encrypt and decrypt attributes transparently
16
+ #
17
+ # Options (any other options you specify are passed to the encryptor's encrypt and decrypt methods)
18
+ #
19
+ # :attribute => The name of the referenced encrypted attribute. For example
20
+ # <tt>attr_accessor :email, :attribute => :ee</tt> would generate an
21
+ # attribute named 'ee' to store the encrypted email. This is useful when defining
22
+ # one attribute to encrypt at a time or when the :prefix and :suffix options
23
+ # aren't enough. Defaults to nil.
24
+ #
25
+ # :prefix => A prefix used to generate the name of the referenced encrypted attributes.
26
+ # For example <tt>attr_accessor :email, :password, :prefix => 'crypted_'</tt> would
27
+ # generate attributes named 'crypted_email' and 'crypted_password' to store the
28
+ # encrypted email and password. Defaults to 'encrypted_'.
29
+ #
30
+ # :suffix => A suffix used to generate the name of the referenced encrypted attributes.
31
+ # For example <tt>attr_accessor :email, :password, :prefix => '', :suffix => '_encrypted'</tt>
32
+ # would generate attributes named 'email_encrypted' and 'password_encrypted' to store the
33
+ # encrypted email. Defaults to ''.
34
+ #
35
+ # :key => The encryption key. This option may not be required if you're using a custom encryptor. If you pass
36
+ # a symbol representing an instance method then the :key option will be replaced with the result of the
37
+ # method before being passed to the encryptor. Objects that respond to :call are evaluated as well (including procs).
38
+ # Any other key types will be passed directly to the encryptor.
39
+ #
40
+ # :encode => If set to true, attributes will be encoded as well as encrypted. This is useful if you're
41
+ # planning on storing the encrypted attributes in a database. The default encoding is 'm' (base64),
42
+ # however this can be overwritten by setting the :encode option to some other encoding string instead of
43
+ # just 'true'. See http://www.ruby-doc.org/core/classes/Array.html#M002245 for more encoding directives.
44
+ # Defaults to false unless you're using it with ActiveRecord, DataMapper, or Sequel.
45
+ #
46
+ # :default_encoding => Defaults to 'm' (base64).
47
+ #
48
+ # :marshal => If set to true, attributes will be marshaled as well as encrypted. This is useful if you're planning
49
+ # on encrypting something other than a string. Defaults to false unless you're using it with ActiveRecord
50
+ # or DataMapper.
51
+ #
52
+ # :marshaler => The object to use for marshaling. Defaults to Marshal.
53
+ #
54
+ # :dump_method => The dump method name to call on the <tt>:marshaler</tt> object to. Defaults to 'dump'.
55
+ #
56
+ # :load_method => The load method name to call on the <tt>:marshaler</tt> object. Defaults to 'load'.
11
57
  #
12
- # It will inherit existing options from its parent class
58
+ # :encryptor => The object to use for encrypting. Defaults to Encryptor.
59
+ #
60
+ # :encrypt_method => The encrypt method name to call on the <tt>:encryptor</tt> object. Defaults to 'encrypt'.
61
+ #
62
+ # :decrypt_method => The decrypt method name to call on the <tt>:encryptor</tt> object. Defaults to 'decrypt'.
63
+ #
64
+ # :if => Attributes are only encrypted if this option evaluates to true. If you pass a symbol representing an instance
65
+ # method then the result of the method will be evaluated. Any objects that respond to <tt>:call</tt> are evaluated as well.
66
+ # Defaults to true.
67
+ #
68
+ # :unless => Attributes are only encrypted if this option evaluates to false. If you pass a symbol representing an instance
69
+ # method then the result of the method will be evaluated. Any objects that respond to <tt>:call</tt> are evaluated as well.
70
+ # Defaults to false.
71
+ #
72
+ # You can specify your own default options
73
+ #
74
+ # class User
75
+ # # now all attributes will be encoded and marshaled by default
76
+ # attr_encrypted_options.merge!(:encode => true, :marshal => true, :some_other_option => true)
77
+ # attr_encrypted :configuration, :key => 'my secret key'
78
+ # end
79
+ #
80
+ #
81
+ # Example
82
+ #
83
+ # class User
84
+ # attr_encrypted :email, :credit_card, :key => 'some secret key'
85
+ # attr_encrypted :configuration, :key => 'some other secret key', :marshal => true
86
+ # end
87
+ #
88
+ # @user = User.new
89
+ # @user.encrypted_email # returns nil
90
+ # @user.email = 'test@example.com'
91
+ # @user.encrypted_email # returns the encrypted version of 'test@example.com'
92
+ #
93
+ # @user.configuration = { :time_zone => 'UTC' }
94
+ # @user.encrypted_configuration # returns the encrypted version of configuration
95
+ #
96
+ # See README for more examples
97
+ def attr_encrypted(*attributes)
98
+ options = {
99
+ :prefix => 'encrypted_',
100
+ :suffix => '',
101
+ :if => true,
102
+ :unless => false,
103
+ :encode => false,
104
+ :default_encoding => 'm',
105
+ :marshal => false,
106
+ :marshaler => Marshal,
107
+ :dump_method => 'dump',
108
+ :load_method => 'load',
109
+ :encryptor => Encryptor,
110
+ :encrypt_method => 'encrypt',
111
+ :decrypt_method => 'decrypt'
112
+ }.merge!(attr_encrypted_options).merge!(attributes.last.is_a?(Hash) ? attributes.pop : {})
113
+
114
+ options[:encode] = options[:default_encoding] if options[:encode] == true
115
+
116
+ attributes.each do |attribute|
117
+ encrypted_attribute_name = (options[:attribute] ? options[:attribute] : [options[:prefix], attribute, options[:suffix]].join).to_sym
118
+
119
+ instance_methods_as_symbols = instance_methods.collect { |method| method.to_sym }
120
+ attr_reader encrypted_attribute_name unless instance_methods_as_symbols.include?(encrypted_attribute_name)
121
+ attr_writer encrypted_attribute_name unless instance_methods_as_symbols.include?(:"#{encrypted_attribute_name}=")
122
+
123
+ define_method(attribute) do
124
+ instance_variable_get("@#{attribute}") || instance_variable_set("@#{attribute}", decrypt(attribute, send(encrypted_attribute_name)))
125
+ end
126
+
127
+ define_method("#{attribute}=") do |value|
128
+ send("#{encrypted_attribute_name}=", encrypt(attribute, value))
129
+ instance_variable_set("@#{attribute}", value)
130
+ end
131
+
132
+ encrypted_attributes[attribute.to_sym] = options.merge!(:attribute => encrypted_attribute_name)
133
+ end
134
+ end
135
+ alias_method :attr_encryptor, :attr_encrypted
136
+
137
+ # Default options to use with calls to <tt>attr_encrypted</tt>
138
+ #
139
+ # It will inherit existing options from its superclass
13
140
  def attr_encrypted_options
14
- @attr_encrypted_options ||= superclass.attr_encrypted_options.nil? ? {} : superclass.attr_encrypted_options.dup
141
+ @attr_encrypted_options ||= superclass.attr_encrypted_options.dup
15
142
  end
16
-
17
- # Sets default options to use with calls to <tt>attr_encrypted</tt>.
18
- def attr_encrypted_options=(options)
19
- @attr_encrypted_options = options
143
+
144
+ # Checks if an attribute is configured with <tt>attr_encrypted</tt>
145
+ #
146
+ # Example
147
+ #
148
+ # class User
149
+ # attr_accessor :name
150
+ # attr_encrypted :email
151
+ # end
152
+ #
153
+ # User.attr_encrypted?(:name) # false
154
+ # User.attr_encrypted?(:email) # true
155
+ def attr_encrypted?(attribute)
156
+ encrypted_attributes.has_key?(attribute.to_sym)
20
157
  end
21
-
22
- # Contains a hash of encrypted attributes with virtual attribute names as keys and real attribute
23
- # names as values
158
+
159
+ # Decrypts a value for the attribute specified
24
160
  #
25
161
  # Example
26
162
  #
@@ -28,201 +164,133 @@ module AttrEncrypted
28
164
  # attr_encrypted :email
29
165
  # end
30
166
  #
31
- # User.encrypted_attributes # { 'email' => 'encrypted_email' }
32
- def encrypted_attributes
33
- @encrypted_attributes ||= superclass.encrypted_attributes.nil? ? {} : superclass.encrypted_attributes.dup
167
+ # email = User.decrypt(:email, 'SOME_ENCRYPTED_EMAIL_STRING')
168
+ def decrypt(attribute, encrypted_value, options = {})
169
+ options = encrypted_attributes[attribute.to_sym].merge(options)
170
+ if options[:if] && !options[:unless] && !encrypted_value.nil? && !(encrypted_value.is_a?(String) && encrypted_value.empty?)
171
+ encrypted_value = encrypted_value.unpack(options[:encode]).first if options[:encode]
172
+ value = options[:encryptor].send(options[:decrypt_method], options.merge!(:value => encrypted_value))
173
+ value = options[:marshaler].send(options[:load_method], value) if options[:marshal]
174
+ value
175
+ else
176
+ encrypted_value
177
+ end
34
178
  end
35
-
36
- # Checks if an attribute has been configured to be encrypted
179
+
180
+ # Encrypts a value for the attribute specified
37
181
  #
38
182
  # Example
39
183
  #
40
184
  # class User
41
- # attr_accessor :name
42
185
  # attr_encrypted :email
43
186
  # end
44
187
  #
45
- # User.attr_encrypted?(:name) # false
46
- # User.attr_encrypted?(:email) # true
47
- def attr_encrypted?(attribute)
48
- encrypted_attributes.keys.include?(attribute.to_s)
188
+ # encrypted_email = User.encrypt(:email, 'test@example.com')
189
+ def encrypt(attribute, value, options = {})
190
+ options = encrypted_attributes[attribute.to_sym].merge(options)
191
+ if options[:if] && !options[:unless] && !value.nil? && !(value.is_a?(String) && value.empty?)
192
+ value = options[:marshaler].send(options[:dump_method], value) if options[:marshal]
193
+ encrypted_value = options[:encryptor].send(options[:encrypt_method], options.merge!(:value => value))
194
+ encrypted_value = [encrypted_value].pack(options[:encode]) if options[:encode]
195
+ encrypted_value
196
+ else
197
+ value
198
+ end
49
199
  end
50
-
51
- protected
52
-
53
- # Generates attr_accessors that encrypt and decrypt attributes transparently
54
- #
55
- # Options (any other options you specify are passed to the encryptor's encrypt and decrypt methods)
56
- #
57
- # :attribute => The name of the referenced encrypted attribute. For example
58
- # <tt>attr_accessor :email, :attribute => :ee</tt> would generate an
59
- # attribute named 'ee' to store the encrypted email. This is useful when defining
60
- # one attribute to encrypt at a time or when the :prefix and :suffix options
61
- # aren't enough. Defaults to nil.
62
- #
63
- # :prefix => A prefix used to generate the name of the referenced encrypted attributes.
64
- # For example <tt>attr_accessor :email, :password, :prefix => 'crypted_'</tt> would
65
- # generate attributes named 'crypted_email' and 'crypted_password' to store the
66
- # encrypted email and password. Defaults to 'encrypted_'.
67
- #
68
- # :suffix => A suffix used to generate the name of the referenced encrypted attributes.
69
- # For example <tt>attr_accessor :email, :password, :prefix => '', :suffix => '_encrypted'</tt>
70
- # would generate attributes named 'email_encrypted' and 'password_encrypted' to store the
71
- # encrypted email. Defaults to ''.
72
- #
73
- # :key => The encryption key. This option may not be required if you're using a custom encryptor. If you pass
74
- # a symbol representing an instance method then the :key option will be replaced with the result of the
75
- # method before being passed to the encryptor. Objects that respond to :call are evaluated as well (including procs).
76
- # Any other key types will be passed directly to the encryptor.
77
- #
78
- # :encode => If set to true, attributes will be encoded as well as encrypted. This is useful if you're
79
- # planning on storing the encrypted attributes in a database. The default encoding is 'm*' (base64),
80
- # however this can be overwritten by setting the :encode option to some other encoding string instead of
81
- # just 'true'. See http://www.ruby-doc.org/core/classes/Array.html#M002245 for more encoding directives.
82
- # Defaults to false unless you're using it with ActiveRecord or DataMapper.
83
- #
84
- # :marshal => If set to true, attributes will be marshaled as well as encrypted. This is useful if you're planning
85
- # on encrypting something other than a string. Defaults to false unless you're using it with ActiveRecord
86
- # or DataMapper.
87
- #
88
- # :encryptor => The object to use for encrypting. Defaults to Encryptor.
89
- #
90
- # :encrypt_method => The encrypt method name to call on the <tt>:encryptor</tt> object. Defaults to :encrypt.
91
- #
92
- # :decrypt_method => The decrypt method name to call on the <tt>:encryptor</tt> object. Defaults to :decrypt.
93
- #
94
- # :if => Attributes are only encrypted if this option evaluates to true. If you pass a symbol representing an instance
95
- # method then the result of the method will be evaluated. Any objects that respond to :call are evaluated as well.
96
- # Defaults to true.
200
+
201
+ # Contains a hash of encrypted attributes with virtual attribute names as keys
202
+ # and their corresponding options as values
203
+ #
204
+ # Example
205
+ #
206
+ # class User
207
+ # attr_encrypted :email, :key => 'my secret key'
208
+ # end
209
+ #
210
+ # User.encrypted_attributes # { :email => { :attribute => 'encrypted_email', :key => 'my secret key' } }
211
+ def encrypted_attributes
212
+ @encrypted_attributes ||= superclass.encrypted_attributes.dup
213
+ end
214
+
215
+ # Forwards calls to :encrypt_#{attribute} or :decrypt_#{attribute} to the corresponding encrypt or decrypt method
216
+ # if attribute was configured with attr_encrypted
217
+ #
218
+ # Example
219
+ #
220
+ # class User
221
+ # attr_encrypted :email, :key => 'my secret key'
222
+ # end
223
+ #
224
+ # User.encrypt_email('SOME_ENCRYPTED_EMAIL_STRING')
225
+ def method_missing(method, *arguments, &block)
226
+ if method.to_s =~ /^((en|de)crypt)_(.+)$/ && attr_encrypted?($3)
227
+ send($1, $3, *arguments)
228
+ else
229
+ super
230
+ end
231
+ end
232
+
233
+ module InstanceMethods
234
+ # Decrypts a value for the attribute specified using options evaluated in the current object's scope
97
235
  #
98
- # :unless => Attributes are only encrypted if this option evaluates to false. If you pass a symbol representing an instance
99
- # method then the result of the method will be evaluated. Any objects that respond to :call are evaluated as well.
100
- # Defaults to false.
236
+ # Example
101
237
  #
102
- # You can specify your own default options
238
+ # class User
239
+ # attr_accessor :secret_key
240
+ # attr_encrypted :email, :key => :secret_key
103
241
  #
104
- # class User
105
- # # now all attributes will be encoded and marshaled by default
106
- # attr_encrypted_options.merge!(:encode => true, :marshal => true, :some_other_option => true)
107
- # attr_encrypted :configuration
108
- # end
242
+ # def initialize(secret_key)
243
+ # self.secret_key = secret_key
244
+ # end
245
+ # end
109
246
  #
247
+ # @user = User.new('some-secret-key')
248
+ # @user.decrypt(:email, 'SOME_ENCRYPTED_EMAIL_STRING')
249
+ def decrypt(attribute, encrypted_value)
250
+ self.class.decrypt(attribute, encrypted_value, evaluated_attr_encrypted_options_for(attribute))
251
+ end
252
+
253
+ # Encrypts a value for the attribute specified using options evaluated in the current object's scope
110
254
  #
111
255
  # Example
112
256
  #
113
- # class User
114
- # attr_encrypted :email, :credit_card, :key => 'some secret key'
115
- # attr_encrypted :configuration, :key => 'some other secret key', :marshal => true
116
- # end
117
- #
118
- # @user = User.new
119
- # @user.encrypted_email # returns nil
120
- # @user.email = 'test@example.com'
121
- # @user.encrypted_email # returns the encrypted version of 'test@example.com'
257
+ # class User
258
+ # attr_accessor :secret_key
259
+ # attr_encrypted :email, :key => :secret_key
122
260
  #
123
- # @user.configuration = { :time_zone => 'UTC' }
124
- # @user.encrypted_configuration # returns the encrypted version of configuration
261
+ # def initialize(secret_key)
262
+ # self.secret_key = secret_key
263
+ # end
264
+ # end
125
265
  #
126
- # See README for more examples
127
- def attr_encrypted(*attrs)
128
- options = {
129
- :prefix => 'encrypted_',
130
- :suffix => '',
131
- :encryptor => Encryptor,
132
- :encrypt_method => :encrypt,
133
- :decrypt_method => :decrypt,
134
- :encode => false,
135
- :marshal => false,
136
- :if => true,
137
- :unless => false
138
- }.merge(attr_encrypted_options).merge(attrs.last.is_a?(Hash) ? attrs.pop : {})
139
- options[:encode] = 'm*' if options[:encode] == true
140
-
141
- attrs.each do |attribute|
142
- encrypted_attribute_name = options[:attribute].nil? ? options[:prefix].to_s + attribute.to_s + options[:suffix].to_s : options[:attribute].to_s
143
-
144
- encrypted_attributes[attribute.to_s] = encrypted_attribute_name
145
-
146
- attr_reader encrypted_attribute_name.to_sym unless instance_methods.include?(encrypted_attribute_name)
147
- attr_writer encrypted_attribute_name.to_sym unless instance_methods.include?("#{encrypted_attribute_name}=")
148
-
149
- define_class_method "encrypt_#{attribute}" do |value|
150
- if options[:if] && !options[:unless]
151
- if value.nil? || (value.is_a?(String) && value.empty?)
152
- encrypted_value = value
153
- else
154
- value = Marshal.dump(value) if options[:marshal]
155
- encrypted_value = options[:encryptor].send options[:encrypt_method], options.merge(:value => value)
156
- encrypted_value = [encrypted_value].pack(options[:encode]) if options[:encode]
157
- end
158
- encrypted_value
159
- else
160
- value
161
- end
162
- end
163
-
164
- define_class_method "decrypt_#{attribute}" do |encrypted_value|
165
- if options[:if] && !options[:unless]
166
- if encrypted_value.nil? || (encrypted_value.is_a?(String) && encrypted_value.empty?)
167
- decrypted_value = encrypted_value
168
- else
169
- encrypted_value = encrypted_value.unpack(options[:encode]).to_s if options[:encode]
170
- decrypted_value = options[:encryptor].send(options[:decrypt_method], options.merge(:value => encrypted_value))
171
- decrypted_value = Marshal.load(decrypted_value) if options[:marshal]
172
- end
173
- decrypted_value
174
- else
175
- encrypted_value
176
- end
177
- end
178
-
179
- define_method "#{attribute}" do
180
- begin
181
- value = instance_variable_get("@#{attribute}")
182
- encrypted_value = send(encrypted_attribute_name.to_sym)
183
- original_options = [:key, :if, :unless].inject({}) do |hash, option|
184
- hash[option] = options[option]
185
- options[option] = self.class.send :evaluate_attr_encrypted_option, options[option], self
186
- hash
187
- end
188
- value = instance_variable_set("@#{attribute}", self.class.send("decrypt_#{attribute}".to_sym, encrypted_value)) if value.nil? && !encrypted_value.nil?
189
- ensure
190
- options.merge!(original_options)
191
- end
192
- value
193
- end
194
-
195
- define_method "#{attribute}=" do |value|
196
- begin
197
- original_options = [:key, :if, :unless].inject({}) do |hash, option|
198
- hash[option] = options[option]
199
- options[option] = self.class.send :evaluate_attr_encrypted_option, options[option], self
200
- hash
201
- end
202
- send("#{encrypted_attribute_name}=".to_sym, self.class.send("encrypt_#{attribute}".to_sym, value))
203
- ensure
204
- options.merge!(original_options)
205
- end
206
- instance_variable_set("@#{attribute}", value)
207
- end
208
- end
266
+ # @user = User.new('some-secret-key')
267
+ # @user.encrypt(:email, 'test@example.com')
268
+ def encrypt(attribute, value)
269
+ self.class.encrypt(attribute, value, evaluated_attr_encrypted_options_for(attribute))
209
270
  end
210
- alias_method :attr_encryptor, :attr_encrypted
211
-
212
- # Evaluates an option specified as a symbol representing an instance method or a proc
213
- #
214
- # If the option is not a symbol or proc then the original option is returned
215
- def evaluate_attr_encrypted_option(option, object)
216
- if option.is_a?(Symbol) && object.respond_to?(option)
217
- object.send(option)
218
- elsif option.respond_to?(:call)
219
- option.call(object)
220
- else
221
- option
271
+
272
+ protected
273
+
274
+ # Returns attr_encrypted options evaluated in the current object's scope for the attribute specified
275
+ def evaluated_attr_encrypted_options_for(attribute)
276
+ self.class.encrypted_attributes[attribute.to_sym].inject({}) { |hash, (option, value)| hash.merge!(option => evaluate_attr_encrypted_option(value)) }
222
277
  end
223
- end
278
+
279
+ # Evaluates symbol (method reference) or proc (responds to call) options
280
+ #
281
+ # If the option is not a symbol or proc then the original option is returned
282
+ def evaluate_attr_encrypted_option(option)
283
+ if option.is_a?(Symbol) && respond_to?(option)
284
+ send(option)
285
+ elsif option.respond_to?(:call)
286
+ option.call(self)
287
+ else
288
+ option
289
+ end
290
+ end
291
+ end
224
292
  end
225
293
 
226
294
  Object.extend AttrEncrypted
227
295
 
228
- Dir[File.join(File.dirname(__FILE__), 'attr_encrypted', 'adapters', '*.rb')].each { |file| require file }
296
+ Dir[File.join(File.dirname(__FILE__), 'attr_encrypted', 'adapters', '*.rb')].each { |adapter| require adapter }