Permalink
Browse files

Optionally allow disabling of Lock#ensure_required_columns.

  • Loading branch information...
1 parent 746530e commit 850bd70fa6b855a7b11ae2b3b7f45fb7de2c2800 Jason Whittle committed Jan 12, 2011
Showing with 50 additions and 23 deletions.
  1. +9 −8 lib/strongbox.rb
  2. +16 −15 lib/strongbox/lock.rb
  3. +25 −0 test/missing_attributes_test.rb
View
17 lib/strongbox.rb
@@ -11,26 +11,27 @@ module Strongbox
RSA_SSLV23_PADDING = OpenSSL::PKey::RSA::SSLV23_PADDING
RSA_NO_PADDING = OpenSSL::PKey::RSA::NO_PADDING
RSA_PKCS1_OAEP_PADDING = OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING
-
+
class << self
# Provides for setting the default options for Strongbox
def options
@options ||= {
:base64 => false,
:symmetric => :always,
:padding => RSA_PKCS1_PADDING,
- :symmetric_cipher => 'aes-256-cbc'
+ :symmetric_cipher => 'aes-256-cbc',
+ :ensure_required_columns => true
}
end
-
+
def included base #:nodoc:
base.extend ClassMethods
end
end
class StrongboxError < StandardError #:nodoc:
end
-
+
module ClassMethods
# +encrypt_with_public_key+ gives the class it is called on an attribute that
# when assigned is automatically encrypted using a public key. This allows the
@@ -49,18 +50,18 @@ def encrypt_with_public_key(name, options = {})
lock_options[name] = options.symbolize_keys.reverse_merge Strongbox.options
-
+
define_method name do
lock_for(name)
end
-
+
define_method "#{name}=" do | plaintext |
lock_for(name).encrypt plaintext
end
-
+
end
end
-
+
module InstanceMethods
def lock_for name
@_locks ||= {}
View
31 lib/strongbox/lock.rb
@@ -1,17 +1,17 @@
module Strongbox
- # The Lock class encrypts and decrypts the protected attribute. It
+ # The Lock class encrypts and decrypts the protected attribute. It
# automatically encrypts the data when set and decrypts it when the private
# key password is provided.
class Lock
-
+
def initialize name, instance, options = {}
@name = name
@instance = instance
-
+
@size = nil
-
+
options = Strongbox.options.merge(options)
-
+
@base64 = options[:base64]
@public_key = options[:public_key] || options[:key_pair]
@private_key = options[:private_key] || options[:key_pair]
@@ -20,10 +20,11 @@ def initialize name, instance, options = {}
@symmetric_cipher = options[:symmetric_cipher]
@symmetric_key = options[:symmetric_key] || "#{name}_key"
@symmetric_iv = options[:symmetric_iv] || "#{name}_iv"
+ @ensure_required_columns = options[:ensure_required_columns]
end
-
+
def encrypt plaintext
- ensure_required_columns
+ ensure_required_columns if @ensure_required_columns
unless @public_key
raise StrongboxError.new("#{@instance.class} model does not have public key_file")
end
@@ -55,22 +56,22 @@ def encrypt plaintext
@instance[@name] = ciphertext
end
end
-
+
# Given the private key password decrypts the attribute. Will raise
# OpenSSL::PKey::RSAError if the password is wrong.
-
+
def decrypt password = nil
# Given a private key and a nil password OpenSSL::PKey::RSA.new() will
# *prompt* for a password, we default to an empty string to avoid that.
ciphertext = @instance[@name]
return nil if ciphertext.nil?
return "" if ciphertext.empty?
-
+
return "*encrypted*" if password.nil?
unless @private_key
raise StrongboxError.new("#{@instance.class} model does not have private key_file")
end
-
+
if ciphertext
ciphertext = Base64.decode64(ciphertext) if @base64
private_key = get_rsa_key(@private_key,password)
@@ -94,20 +95,20 @@ def decrypt password = nil
nil
end
end
-
+
def to_s
decrypt
end
-
+
# Needed for validations
def blank?
@instance[@name].blank?
end
-
+
def nil?
@instance[@name].nil?
end
-
+
def size
@size
end
View
25 test/missing_attributes_test.rb
@@ -49,4 +49,29 @@ class MissingAttribuesTest < Test::Unit::TestCase
rebuild_model
end
end
+
+ context 'A Class with a secured field without a matching database column told not to check columns' do
+ setup do
+ ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
+ table.string :in_the_clear
+ end
+ rebuild_class {}
+ end
+
+ should 'not raise' do
+ assert_nothing_raised do
+ Dummy.class_eval do
+ encrypt_with_public_key(:secret,
+ :key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
+ :ensure_required_columns => false)
+ end
+ @dummy = Dummy.new
+ @dummy.secret = 'Shhhh'
+ end
+ end
+
+ teardown do
+ rebuild_model
+ end
+ end
end

0 comments on commit 850bd70

Please sign in to comment.