Skip to content

Commit

Permalink
Add bcrypt cheesy login strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
zmack committed Dec 2, 2009
1 parent 3b5a56b commit 498481c
Show file tree
Hide file tree
Showing 10 changed files with 165 additions and 22 deletions.
2 changes: 2 additions & 0 deletions bootstrap.rb
Expand Up @@ -4,6 +4,8 @@
require 'sass'
require 'dm-core'
require 'dm-timestamps'
require 'dm-validations'
require 'bcrypt'
require 'warden'

#Really, how the fuck would you do this another way ? =/
Expand Down
2 changes: 1 addition & 1 deletion config.ru
Expand Up @@ -4,7 +4,7 @@ require 'wmnizr.rb'
use Rack::Session::Cookie

use Warden::Manager do |manager|
manager.default_strategies :password, :pickle
manager.default_strategies :bcrypt_password
manager.failure_app = Wmnizr
end

Expand Down
25 changes: 25 additions & 0 deletions lib/authentication_helpers.rb
@@ -0,0 +1,25 @@
module AuthenticationHelpers
def require_authentication
redirect '/login' unless logged_in?
end

def current_user
warden_handler.user
end

def authenticate_user!
warden_handler.authenticate!
end

def logout_user!
warden_handler.logout
end

def logged_in?
!warden_handler.nil? && warden_handler.authenticated?
end

def warden_handler
request.env['warden']
end
end
16 changes: 4 additions & 12 deletions lib/warden_strategies.rb
@@ -1,29 +1,21 @@
class Warden::Serializers::Session
def serialize(user)
p "----------------"
p user
p user.id
user.nil? ? nil : user.id
end

def deserialize(id)
p "==============#{id}"
id.nil? ? nil : User.get(id)
end
end

Warden::Strategies.add(:pickle) do
Warden::Strategies.add(:bcrypt_password) do
def valid?
p params.inspect
p params['login']
params["login"] || params["password"]
params["login"] && params["password"]
end

def authenticate!
p params.inspect
p params['email']
u = User.first
p u
u = User.find_by_login_and_password(params["login"], params["password"])

u.nil? ? fail!("Could not log in") : success!(u)
end
end
22 changes: 21 additions & 1 deletion models/user.rb
Expand Up @@ -3,5 +3,25 @@ class User

property :id, Serial
property :login, String
property :crypted_password, String
property :crypted_password, String, :length => 60

validates_is_unique :login

def self.find_by_login_and_password(login, password)
user = self.first :conditions => { :login => login }
user if user.nil? || self.is_valid_password(user.crypted_password, password)
end

def password=(value)
self.crypted_password = User.crypt(value)
end

private
def self.crypt(value)
BCrypt::Password.create(value, :cost => 10)
end

def self.is_valid_password(hash, password)
BCrypt::Password.new(hash) == password
end
end
1 change: 0 additions & 1 deletion test/test_hosts.rb
Expand Up @@ -15,7 +15,6 @@ def before

def test_stuff_happens
get '/', {}, { 'SERVER_NAME' => 'localhost' }
p last_response
end

end
67 changes: 67 additions & 0 deletions test/test_login.rb
@@ -0,0 +1,67 @@
require File.expand_path(File.join(File.dirname(__FILE__), "test_bootstrap.rb"))
require File.expand_path(File.join(File.dirname(__FILE__), '..', "wmnizr.rb"))
require 'rack/test'

::Wmnizr.use Rack::Session::Cookie

::Wmnizr.use Warden::Manager do |manager|
manager.default_strategies :bcrypt_password
manager.failure_app = ::Wmnizr
end

class TestHosts < WmnizrTest
include Rack::Test::Methods

def app
::Wmnizr
end

def before
@user = User.create(:login => 'fanel', :password => 'pitulice')
@post = Post.create
end

def test_redirected_to_login_when_requesting_admin_bits
get '/admin'
assert_equal 302, last_response.status

get '/admin/posts'
assert_equal 302, last_response.status

post '/admin/posts'
assert_equal 302, last_response.status

get "/admin/posts/#{@post.id}"
assert_equal 302, last_response.status

get "/admin/posts/#{@post.id}/edit"
assert_equal 302, last_response.status

post "/admin/posts/#{@post.id}"
assert_equal 302, last_response.status
end

def test_does_ok_when_logged_in
# cheesy rack session id bug down here, do investigate :3
post '/login', :login => 'fanel', :password => 'pitulice'

get '/admin'
assert_equal 200, last_response.status

get '/admin/posts'
assert_equal 200, last_response.status

post '/admin/posts', { :post => { :title => 'foo' }}
assert_equal 302, last_response.status

get "/admin/posts/#{@post.id}"
assert_equal 200, last_response.status

get "/admin/posts/#{@post.id}/edit"
assert_equal 200, last_response.status

post "/admin/posts/#{@post.id}", { :post => { :title => 'foo' }}
assert_equal 302, last_response.status
end

end
File renamed without changes.
25 changes: 25 additions & 0 deletions test/test_user.rb
@@ -0,0 +1,25 @@
require File.expand_path(File.join(File.dirname(__FILE__), "test_bootstrap.rb"))


class PostTest < WmnizrTest
def test_setting_password_sets_crypted_password
@user = User.new
assert_equal nil, @user.crypted_password
@user.password = "foobarbaz"
assert_not_equal nil, @user.crypted_password
end

def test_can_find_user_by_login_and_password
@user = User.create(:login => 'foo', :password => 'barbaz')

assert_equal nil, User.find_by_login_and_password('foo', 'boo')
assert_not_equal nil, User.find_by_login_and_password('foo', 'barbaz')
end

def test_validate_login_is_unique
@user = User.create(:login => 'foo', :password => 'barbaz')
@user = User.create(:login => 'foo', :password => 'barbaz')

assert_equal 1, User.all.count
end
end
27 changes: 20 additions & 7 deletions wmnizr.rb
Expand Up @@ -9,6 +9,7 @@ def hostname_for(hostname)
end

class Wmnizr < Sinatra::Base
helpers AuthenticationHelpers
before do
@hostname = hostname_for request.host
content_type 'text/html', :charset => 'utf-8'
Expand All @@ -19,44 +20,56 @@ class Wmnizr < Sinatra::Base
end

post '/login' do
p env['warden'].authenticate!(:pickle)
user = env['warden'].authenticate

redirect '/admin' unless user.nil?
haml :'admin/login', :layout => :'admin/layout'
end

get '/logout' do
logout_user!
redirect '/login'
end

get '/admin' do
@posts = Post.all
require_authentication

@posts = Post.all
haml :'admin/index', :layout => :'admin/layout'
end

get '/admin/posts' do
@posts = Post.all
require_authentication

@posts = Post.all
haml :'admin/posts', :layout => :'admin/layout'
end

post '/admin/posts' do
@post = Post.create params[:post]
require_authentication

@post = Post.create params[:post]
redirect "/admin/posts/#{@post.id}"
end

get '/admin/posts/:id' do
@post = Post.first :id => params[:id]
require_authentication

@post = Post.first :id => params[:id]
haml :'admin/single_post', :layout => :'admin/layout'
end

get '/admin/posts/:id/edit' do
@post = Post.first :id => params[:id]
require_authentication

@post = Post.first :id => params[:id]
haml :'admin/post_form', :layout => :'admin/layout', :locals => { :action => "/admin/posts/#{@post.id}", :post => @post }
end

post '/admin/posts/:id' do
@post = Post.first :id => params[:id]
require_authentication

@post = Post.first :id => params[:id]
@post.update(params[:post])

redirect "/admin/posts/#{@post.id}"
Expand Down

0 comments on commit 498481c

Please sign in to comment.