Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions lib/attr_encrypted.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def self.extended(base) # :nodoc:
include InstanceMethods
attr_writer :attr_encrypted_options
@attr_encrypted_options, @encrypted_attributes = {}, {}
@attr_encrypted_semaphore = Mutex.new
end
end

Expand Down Expand Up @@ -289,6 +290,10 @@ def encrypted_attributes
@encrypted_attributes ||= superclass.encrypted_attributes.dup
end

def attr_encrypted_semaphore
@attr_encrypted_semaphore ||= superclass.attr_encrypted_semaphore
end

# Forwards calls to :encrypt_#{attribute} or :decrypt_#{attribute} to the corresponding encrypt or decrypt method
# if attribute was configured with attr_encrypted
#
Expand Down Expand Up @@ -324,9 +329,11 @@ module InstanceMethods
# @user = User.new('some-secret-key')
# @user.decrypt(:email, 'SOME_ENCRYPTED_EMAIL_STRING')
def decrypt(attribute, encrypted_value)
encrypted_attributes[attribute.to_sym][:operation] = :decrypting
encrypted_attributes[attribute.to_sym][:value_present] = self.class.not_empty?(encrypted_value)
self.class.decrypt(attribute, encrypted_value, evaluated_attr_encrypted_options_for(attribute))
attr_encrypted_semaphore.synchronize do
encrypted_attributes[attribute.to_sym][:operation] = :decrypting
encrypted_attributes[attribute.to_sym][:value_present] = self.class.not_empty?(encrypted_value)
self.class.decrypt(attribute, encrypted_value, evaluated_attr_encrypted_options_for(attribute))
end
end

# Encrypts a value for the attribute specified using options evaluated in the current object's scope
Expand All @@ -345,9 +352,11 @@ def decrypt(attribute, encrypted_value)
# @user = User.new('some-secret-key')
# @user.encrypt(:email, 'test@example.com')
def encrypt(attribute, value)
encrypted_attributes[attribute.to_sym][:operation] = :encrypting
encrypted_attributes[attribute.to_sym][:value_present] = self.class.not_empty?(value)
self.class.encrypt(attribute, value, evaluated_attr_encrypted_options_for(attribute))
attr_encrypted_semaphore.synchronize do
encrypted_attributes[attribute.to_sym][:operation] = :encrypting
encrypted_attributes[attribute.to_sym][:value_present] = self.class.not_empty?(value)
self.class.encrypt(attribute, value, evaluated_attr_encrypted_options_for(attribute))
end
end

# Copies the class level hash of encrypted attributes with virtual attribute names as keys
Expand All @@ -359,6 +368,13 @@ def encrypted_attributes

protected

def attr_encrypted_semaphore
return @attr_encrypted_semaphore unless @attr_encrypted_semaphore.nil?
self.class.attr_encrypted_semaphore.synchronize do
@attr_encrypted_semaphore ||= Mutex.new
end
end

# Returns attr_encrypted options evaluated in the current object's scope for the attribute specified
def evaluated_attr_encrypted_options_for(attribute)
evaluated_options = Hash.new
Expand Down