Skip to content

Commit

Permalink
ensures original options are reinitialized even if there is in error …
Browse files Browse the repository at this point in the history
…encrypting/decrypting
  • Loading branch information
nate committed Apr 26, 2010
1 parent 2f57559 commit 8f4be41
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
35 changes: 21 additions & 14 deletions lib/attr_encrypted.rb
@@ -1,5 +1,6 @@
require 'eigenclass'
require 'encryptor'
require 'ruby-debug'

module AttrEncrypted
def self.extended(base)
Expand Down Expand Up @@ -177,26 +178,32 @@ def attr_encrypted(*attrs)
end

define_method "#{attribute}" do
value = instance_variable_get("@#{attribute}")
encrypted_value = send(encrypted_attribute_name.to_sym)
original_options = [:key, :if, :unless].inject({}) do |hash, option|
hash[option] = options[option]
options[option] = self.class.send :evaluate_attr_encrypted_option, options[option], self
hash
begin
value = instance_variable_get("@#{attribute}")
encrypted_value = send(encrypted_attribute_name.to_sym)
original_options = [:key, :if, :unless].inject({}) do |hash, option|
hash[option] = options[option]
options[option] = self.class.send :evaluate_attr_encrypted_option, options[option], self
hash
end
value = instance_variable_set("@#{attribute}", self.class.send("decrypt_#{attribute}".to_sym, encrypted_value)) if value.nil? && !encrypted_value.nil?
ensure
options.merge!(original_options)
end
value = instance_variable_set("@#{attribute}", self.class.send("decrypt_#{attribute}".to_sym, encrypted_value)) if value.nil? && !encrypted_value.nil?
options.merge!(original_options)
value
end

define_method "#{attribute}=" do |value|
original_options = [:key, :if, :unless].inject({}) do |hash, option|
hash[option] = options[option]
options[option] = self.class.send :evaluate_attr_encrypted_option, options[option], self
hash
begin
original_options = [:key, :if, :unless].inject({}) do |hash, option|
hash[option] = options[option]
options[option] = self.class.send :evaluate_attr_encrypted_option, options[option], self
hash
end
send("#{encrypted_attribute_name}=".to_sym, self.class.send("encrypt_#{attribute}".to_sym, value))
ensure
options.merge!(original_options)
end
send("#{encrypted_attribute_name}=".to_sym, self.class.send("encrypt_#{attribute}".to_sym, value))
options.merge!(original_options)
instance_variable_set("@#{attribute}", value)
end
end
Expand Down
20 changes: 20 additions & 0 deletions test/attr_encrypted_test.rb
@@ -1,4 +1,5 @@
require File.dirname(__FILE__) + '/test_helper'
require 'mocha'

class SillyEncryptor
def self.silly_encrypt(options)
Expand All @@ -24,13 +25,16 @@ class User
attr_encrypted :with_false_if, :key => 'secret key', :if => false
attr_encrypted :with_true_unless, :key => 'secret key', :unless => true
attr_encrypted :with_false_unless, :key => 'secret key', :unless => false
attr_encrypted :with_if_changed, :key => 'secret key', :if => :should_encrypt

attr_encryptor :aliased, :key => 'secret_key'

attr_accessor :salt
attr_accessor :should_encrypt

def initialize
self.salt = Time.now.to_i.to_s
self.should_encrypt = true
end
end

Expand Down Expand Up @@ -249,4 +253,20 @@ def test_should_work_with_aliased_attr_encryptor
assert User.encrypted_attributes.include?('aliased')
end

def test_should_always_reset_options
@user = User.new
@user.with_if_changed = "encrypt_stuff"
@user.stubs(:instance_variable_get).returns(nil)
@user.stubs(:instance_variable_set).raises("BadStuff")
assert_raise RuntimeError do
@user.with_if_changed
end

@user = User.new
@user.should_encrypt = false
@user.with_if_changed = "not_encrypted_stuff"
assert_equal "not_encrypted_stuff", @user.with_if_changed
assert_equal "not_encrypted_stuff", @user.encrypted_with_if_changed
end

end

0 comments on commit 8f4be41

Please sign in to comment.