Skip to content

Instantly share code, notes, and snippets.

@nthj
Created June 6, 2011 04:15
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nthj/1009737 to your computer and use it in GitHub Desktop.
Save nthj/1009737 to your computer and use it in GitHub Desktop.
Password value object for MongoMapper documents
# In a MongoMapper::Document,
# simply add
# key :password, Password
# your password will be automatically hashed,
# and you can compare plain-text passwords with the user's hashed password, ruby style:
# User.first.password == '1234'
# => true
#
# Also, prevents passwords from being leaked onto the console or error messages:
# User.first.password
# => ********
class Password < String
class Invalid < Exception; end
class << self
def from_mongo value
new value.to_s
end
def hash password
Digest::SHA256::hexdigest password
end
end
def eql? password
if hashed?
self.class.hash(password) == to_s
else
password == to_s
end if password
end
alias :== :eql?
def hash!
replace self.class.hash self unless hashed? if present?
end
def hashed?
length == 64
end
def inspect
'********'
end
end
describe Password do
it "should be saved as hashes" do
User.create :password => '******'
User.last.password.length.should eql 64
end
it "should be comparable to plain-text strings" do
User.create :password => '******'
User.last.password.eql?('******').should be_true
end
it "should ignore short passwords" do
User.create(:password => '*').valid?.should be_false
end
it "should ignore long passwords" do
User.create(
:password => '****************************************************************'
).valid?.should be_false
end
it "should not re-hash passwords when updating" do
User.create :password => '******'
p = User.last.password
User.last.save
User.last.password.to_s.should eql p
end
it "should be able to compare confirmations when not yet hashed" do
u = User.create
u.password = u.password_confirmation = '******'
u.password.eql?(u.password_confirmation).should be_true
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment