Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use semaphore when encrypting/decrypting values (#1) #345

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
1 change: 0 additions & 1 deletion attr_encrypted.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ Gem::Specification.new do |s|
s.homepage = 'http://github.com/attr-encrypted/attr_encrypted'
s.license = 'MIT'

s.has_rdoc = false
s.rdoc_options = ['--line-numbers', '--inline-source', '--main', 'README.rdoc']

s.require_paths = ['lib']
Expand Down
28 changes: 22 additions & 6 deletions lib/attr_encrypted.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,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 @@ -291,6 +292,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 @@ -326,9 +331,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 @@ -347,9 +354,11 @@ def decrypt(attribute, encrypted_value)
# @user = User.new('some-secret-key')
# @user.encrypt(:email, '[email protected]')
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 @@ -365,6 +374,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