Skip to content

Instantly share code, notes, and snippets.

@robcthegeek
Created November 9, 2011 21:32
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robcthegeek/1353123 to your computer and use it in GitHub Desktop.
Save robcthegeek/1353123 to your computer and use it in GitHub Desktop.
"Standard" User Model Using Mongoid/BCrypt
require 'bcrypt'
class User
include Mongoid::Document
include Mongoid::Timestamps
include BCrypt
attr_accessor :password, :password_confirmation
attr_protected :password_hash
field :email, :type => String
field :password_hash, :type => String
field :accept_terms, :type => Boolean
validates_presence_of :email, :message => "Email Address is Required."
validates_uniqueness_of :email, :message => "Email Address Already In Use. Have You Forgot Your Password?"
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i, :message => "Please Enter a Valid Email Address."
validates_acceptance_of :accept_terms, :allow_nil => false, :accept => true, :message => "Terms and Conditions Must Be Accepted."
validates_length_of :password, :minimum => 8, :message => "Password Must Be Longer Than 8 Characters."
validates_confirmation_of :password, :message => "Password Confirmation Must Match Given Password."
before_save :encrypt_password
def self.find_by_email(email)
first(conditions: { email: email })
end
def self.authenticate(email, password)
if password_correct?(email, password)
# Success!
true
else
# Failed! :(
false
end
end
def self.password_correct?(user_email, password)
user = find_by_email user_email
return if user.nil?
user_pass = Password.new(user.password_hash)
user_pass == password
end
protected
def encrypt_password
self.password_hash = Password.create(@password)
end
end
@konklone
Copy link

Thank you for posting this! This is exactly what I would like to do.

@aq1018
Copy link

aq1018 commented Jul 3, 2012

Nice! Neede this as well... Maybe make a mongoid-type-password to encapsulate all that? Just say...

@robcthegeek
Copy link
Author

Hey guys - thanks for the comments. TBH, I've not done much more with this code - kinda "write once and forget about it" (hence the need for me to write it down :)

I'll be looking at using Devise more in other projects, since you seem to get a lot of other things in it that are commonly required (e.g. social sign-in etc). There are also examples using mongoid about.

Hope this helps!

@aq1018
Copy link

aq1018 commented Jul 5, 2012

@robcthegeek

In my case, I was using sinatra + warden + your code. Devise doesn't work with sinatra and contains too much features / code that I don't need. I'm kinda of a neat freak. :p

@robcthegeek
Copy link
Author

@aq1018 ain't nothing wrong with that - me too :)

@crazyjin
Copy link

  def self.password_correct?(user_email, password)
    user = find_by_email user_email
    return if user.nil?
    user_pass = Password.new(user.password_hash)
    user_pass == password
  end

Does Password.new decrypte a hash? or it should be like this:

    user_pass_hash = Password.new(password)
    user_pass_hash == user.password_hash

@cilindrox
Copy link

@crazyjin it creates a new BCrypt object so it can be used for comparison on the next line. BCrypt overrides de '==' method so you can do

user_pass_hash == user.password_hash

Note that the opposite won't work, ie: user.password_hash == user_pass_hash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment