-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ian D. Eccles
committed
May 19, 2011
1 parent
67fad0f
commit b3a476e
Showing
9 changed files
with
176 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
-f progress | ||
-c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
require 'securely_hashed_attributes' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,32 @@ | ||
# Kind of necessary for, you know, everything else we do. | ||
require 'bcrypt' | ||
require 'active_record' | ||
|
||
module SecurelyHashedAttributes | ||
# Your code goes here... | ||
DEFAULT_ATTRIBUTE_OPTIONS = { | ||
:to => nil, | ||
:with => nil | ||
} | ||
end | ||
require 'securely_hashed_attributes/version' | ||
require 'securely_hashed_attributes/coders' | ||
|
||
# Boom, boom, add a method! | ||
class << ActiveRecord::Base | ||
def securely_hashes attrib, opts={} | ||
opts = SecurelyHashedAttributes::DEFAULT_ATTRIBUTE_OPTIONS.merge opts | ||
attrib = attrib.to_sym | ||
if opts[:to] | ||
col = opts[:to].to_sym | ||
serialize col, opts[:with] | ||
|
||
attr_reader attrib | ||
define_method :"#{attrib}=" do |val| | ||
instance_variable_set(:"@#{attrib}", val) | ||
self[col] = val | ||
end | ||
else | ||
serialize attrib, opts[:with] | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module SecurelyHashedAttributes::Coders | ||
end | ||
|
||
require 'securely_hashed_attributes/coders/bcrypt_password_column' |
18 changes: 18 additions & 0 deletions
18
lib/securely_hashed_attributes/coders/bcrypt_password_column.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
class SecurelyHashedAttributes::Coders::BCryptPasswordColumn | ||
RESCUE_ERRORS = [ArgumentError, BCrypt::Errors::InvalidHash] | ||
|
||
def self.dump(obj) | ||
BCrypt::Password.create(obj) | ||
end | ||
|
||
def self.load(bcrypt) | ||
return '' if bcrypt.nil? | ||
begin | ||
BCrypt::Password.new(bcrypt) | ||
rescue *RESCUE_ERRORS | ||
bcrypt | ||
end | ||
end | ||
|
||
SecurelyHashedAttributes::DEFAULT_ATTRIBUTE_OPTIONS[:with] = self | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
spec/securely_hashed_attributes/coders/bcrypt_password_column_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
require 'spec_helper' | ||
|
||
describe SecurelyHashedAttributes::Coders::BCryptPasswordColumn do | ||
it "should dump a string as a bcrypt password hash" do | ||
hashed = SecurelyHashedAttributes::Coders::BCryptPasswordColumn.dump('my stringzy') | ||
hashed.should be_a_kind_of(BCrypt::Password) | ||
end | ||
|
||
it "should dump a non string to bcrypt by converting it to a string" do | ||
hashed = SecurelyHashedAttributes::Coders::BCryptPasswordColumn.dump([1, 2, 3]) | ||
hashed.should be_a_kind_of(BCrypt::Password) | ||
end | ||
|
||
it "should load a bcrypt hash as a string" do | ||
hashed = SecurelyHashedAttributes::Coders::BCryptPasswordColumn.dump('my stringzy') | ||
loaded = SecurelyHashedAttributes::Coders::BCryptPasswordColumn.load(hashed) | ||
loaded.should be_a_kind_of(BCrypt::Password) | ||
loaded.should == 'my stringzy' | ||
end | ||
|
||
it "should load a nil as an empty string" do | ||
loaded = SecurelyHashedAttributes::Coders::BCryptPasswordColumn.load(nil) | ||
loaded.should_not be_a_kind_of(BCrypt::Password) | ||
loaded.should == '' | ||
end | ||
|
||
it "should load a non bcrypt hash as a plain string" do | ||
loaded = SecurelyHashedAttributes::Coders::BCryptPasswordColumn.load('sweet lameness') | ||
loaded.should_not be_a_kind_of(BCrypt::Password) | ||
loaded.should == 'sweet lameness' | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
require 'spec_helper' | ||
|
||
require 'active_record/connection_adapters/sqlite3_adapter' | ||
|
||
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") | ||
|
||
describe ActiveRecord::Base do | ||
class AlternateCoder | ||
def dump(*_); 'encoded'; end | ||
def load(*_); 'decoded'; end | ||
end | ||
|
||
let(:new_model) { | ||
HashingModel.new | ||
} | ||
|
||
with_model :hashing_model do | ||
table do |t| | ||
t.string :blathering | ||
t.string :password_hash | ||
t.string :chicken_fist_digest | ||
end | ||
|
||
model do | ||
attr_reader :stately_dutch | ||
alias :stately_dutch? :stately_dutch | ||
|
||
securely_hashes :blathering, :with => AlternateCoder | ||
securely_hashes :password, :to => :password_hash | ||
securely_hashes :chicken_fist, :to => :chicken_fist_digest | ||
|
||
def chicken_fist=(bird) | ||
@stately_dutch = true | ||
end | ||
end | ||
end | ||
|
||
before(:each) do | ||
HashingModel.delete_all | ||
end | ||
|
||
it "should create getters and setters for :password" do | ||
new_model.should respond_to(:password) | ||
new_model.should respond_to(:password=) | ||
new_model.password = 'super duper' | ||
new_model.password.should == 'super duper' | ||
end | ||
|
||
it "should serialize :password to :password_digest on save" do | ||
new_model.password = 'super duper' | ||
new_model.save | ||
old_model = HashingModel.find(new_model.id) | ||
old_model.password_hash.should_not be_empty | ||
old_model.password_hash.should be_a_kind_of(BCrypt::Password) | ||
old_model.password_hash.should == 'super duper' | ||
end | ||
|
||
it "should get clobbered by #chicken_fist=" do | ||
new_model.should_not be_stately_dutch | ||
new_model.chicken_fist = 'a string to hash' | ||
new_model.should be_stately_dutch | ||
end | ||
|
||
it "should not hash properly because of #chicken_fist=" do | ||
new_model.chicken_fist = 'a string to hash' | ||
new_model.save | ||
new_model.chicken_fist_digest.should be_empty | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
Dir[File.expand_path('support', File.dirname(__FILE__)) + "/**/*.rb"].each { |f| require f } | ||
|
||
begin | ||
require 'simplecov' | ||
SimpleCov.start do | ||
add_filter "/spec/" | ||
end | ||
rescue LoadError | ||
end | ||
|
||
require 'securely_hashed_attributes' | ||
require 'with_model' | ||
|
||
RSpec.configure do |config| | ||
config.extend WithModel | ||
end |