Skip to content

Instantly share code, notes, and snippets.

@durango
Created July 18, 2011 16:47
Show Gist options
  • Save durango/1090042 to your computer and use it in GitHub Desktop.
Save durango/1090042 to your computer and use it in GitHub Desktop.
require 'bcrypt'
require 'securerandom'
class User
include DataMapper::Resource
include BCrypt
property :id, Serial
property :email, String, :required => true, :index => :login, :unique => true, :format => :email_address
property :password_hash, Text, :required => true, :index => :login, :writer => :protected
property :password_salt, Text, :required => true, :writer => :protected
property :authToken, Text
property :name, String, :unique => true, :required => true, :length => 3..30, :message => "Your name must not be blank and at least 3 characters."
property :created_at, DateTime, :default => proc { DateTime.now }
property :forgotten, String, :length => 32, :writer => :protected
attr_accessor :password, :password_confirmation, :password_needed,
:_csrf, :password_reset, :pid, :gender, :main_name, :char_name,
validates_presence_of :password_confirmation, :password, :if => :password_needed?
validates_length_of :password, :min => 6, :max => 255, :if => :password_needed?
validates_confirmation_of :password, :if => :password_needed?
validates_presence_of :char_name, :if => :new?, :message => "Character name must not be blank"
validates_length_of :char_name, :min => 3, :max => 30, :message => "Character name must be between 3 and 30 characters."
has n, :player, :model => 'Player'
before :valid?, :make_password
def make_password
if new?
self.email.to_s.downcase unless self.email.nil?
self.password_salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
self.password_hash = BCrypt::Password.create(password + self.password_salt)
self.char_name = name
end
end
def crypted_pass
pass = attribute_get(:password_hash)
return nil if pass.nil?
BCrypt::Password.new(pass)
end
alias_method :crypted_password, :crypted_pass
def forgotten_token
token = SecureRandom.hex(16)
self.forgotten = token
save
token
end
def new_account?
new?
end
def password_needed?
new? or password_reset
end
def reset_password(password, confirmation)
self.password_reset = true
self.password = password
self.password_confirmation = confirmation
self.forgotten = nil
self.save
end
def authenticate(password)
pepper = attribute_get(:password_salt)
crypted_pass == (password + pepper)
end
def self.authenticate(username, password)
u = first(:email => username.to_s.downcase)
if u && u.authenticate(password)
u
else
nil
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment