Permalink
Browse files

Working example application

  • Loading branch information...
1 parent 2765e95 commit a0748f5b15da023344f1c51a5d41426f634f8cc0 @HP committed Jan 25, 2010
View
@@ -0,0 +1,19 @@
+# RailsWarden example using Mongoid
+created by: http://github.com/HP
+
+User Model based on [Clearance](http://github.com/thoughtbot/clearance/).
+Example Application based on [Authlogic Example App](http://github.com/binarylogic/authlogic_example).
+
+[RailsWarden](http://github.com/hassox/rails_warden) provides a wrapper to [Warden](http://github.com/hassox/warden): Warden provides a mechanism for authentication in Rack based Ruby applications. It’s made with multiple applications sharing within the same rack instance in mind.
+
+Helper Methods defined by RailsWarden:
+- Access Warden: `warden`
+- Check if user is logged in: `logged_in?`, `authenticated?`
+- Access logged in user: `current_user`, `user`
+- Set logged in user: `current_user=`, `user=`
+
+Controller Methods:
+- Authenticate: `authenticate`
+- Authenticate with error/redirect: `authenticate!`
+- Log out: `logout`
+
@@ -6,5 +6,22 @@ class ApplicationController < ActionController::Base
protect_from_forgery # See ActionController::RequestForgeryProtection for details
# Scrub sensitive parameters from your log
- # filter_parameter_logging :password
+ filter_parameter_logging :password, :password_confirmation
+
+ private
+ def require_user
+ unless current_user
+ flash[:notice] = "You must be logged in to access that page"
+ redirect_to new_user_session_url
+ return false
+ end
+ end
+
+ def require_no_user
+ if current_user
+ flash[:notice] = "You must be logged out to access that page"
+ redirect_to account_url
+ return false
+ end
+ end
end
@@ -0,0 +1,30 @@
+class UserSessionsController < ApplicationController
+ before_filter :require_no_user, :only => [:new, :create]
+ before_filter :require_user, :only => :destroy
+
+ def new
+ end
+
+ def create
+ authenticate!
+
+ if logged_in?
+ flash[:notice] = "Login successful!"
+ redirect_to account_url
+ end
+ end
+
+ def destroy
+ logout
+
+ flash[:notice] = "Logout successful!"
+ redirect_to root_url
+ end
+
+ def unauthenticated
+ flash[:error] = "Incorrect email/password combination"
+
+ redirect_to new_user_session_url
+ return false
+ end
+end
@@ -0,0 +1,44 @@
+class UsersController < ApplicationController
+ before_filter :require_no_user, :only => [:new, :create]
+ before_filter :require_user, :only => [:show, :destroy]
+
+ def show
+ @user = current_user
+ end
+
+ def new
+ @user = User.new
+ end
+
+ def create
+ @user = User.new(params[:user])
+ if @user.save
+ flash[:notice] = "Account registered!"
+ redirect_to account_url
+ else
+ render :action => :new
+ end
+ end
+
+ def edit
+ @user = current_user
+ end
+
+ def update
+ @user = current_user
+ if @user.update_attributes(params[:user])
+ flash[:notice] = "Account updated!"
+ redirect_to account_url
+ else
+ render :action => :edit
+ end
+ end
+
+ def destroy
+ current_user.destroy
+ logout
+ flash[:notice] = "Account removed!"
+ redirect_to root_url
+ end
+
+end
View
@@ -0,0 +1,58 @@
+# Lifted from Clearance::User
+
+class User
+ include Mongoid::Document
+ include Mongoid::Timestamps
+
+ field :name, :type => String
+ field :email, :type => String
+ field :encrypted_password, :type => String
+ field :password_salt, :type => String
+
+ validates_presence_of :email, :name
+ validates_uniqueness_of :email
+ validates_format_of :email, :with => %r{.+@.+\..+}
+
+ validates_presence_of :password, :if => :password_required?
+ validates_confirmation_of :password, :if => :password_required?
+
+ before_save :initialize_salt, :encrypt_password
+
+ attr_accessor :password, :password_confirmation
+
+ class << self
+ def authenticate(email, password)
+ return nil unless user = criteria.where(:email => email).first
+ return user if user.authenticated?(password)
+ end
+ end
+
+ def authenticated?(password)
+ encrypted_password == encrypt(password)
+ end
+
+ protected
+
+ def encrypt_password
+ self.encrypted_password = encrypt(password)
+ end
+
+ def generate_hash(string)
+ Digest::SHA1.hexdigest(string)
+ end
+
+ def initialize_salt
+ if new_record?
+ self.password_salt = generate_hash("--#{Time.now.utc}--#{password}--")
+ end
+ end
+
+ def encrypt(string)
+ generate_hash("--#{password_salt}--#{string}--")
+ end
+
+ def password_required?
+ encrypted_password.blank? || !password.blank?
+ end
+
+end
@@ -8,6 +8,14 @@
</head>
<body>
<div id="container">
+ <% if !current_user %>
+ <%= link_to "Register", new_account_path %> |
+ <%= link_to "Log In", new_user_session_path %>
+ <% else %>
+ <%= link_to "My Account", account_path %> |
+ <%= link_to "Logout", user_session_path, :method => :delete, :confirm => "Are you sure you want to logout?" %>
+ <% end %>
+
<%- flash.each do |name, msg| -%>
<%= content_tag :div, msg, :id => "flash_#{name}" %>
<%- end -%>
@@ -0,0 +1,13 @@
+<% title 'Log in' %>
+
+<% form_tag '/session' do %>
+ <p>
+ <label for="email">Email</label><br/>
+ <input type="text" name="email" value="" id="email">
+ </p>
+ <p>
+ <label for="password">Password</label><br/>
+ <input type="password" name="password" value="" id="password">
+ </p>
+ <p><input type="submit" name="commit" value="Log in" ></p>
+<% end %>
@@ -0,0 +1,24 @@
+<% title "Edit your account" %>
+
+<% form_for @user, :url => account_path do |f| %>
+ <%= f.error_messages %>
+
+ <p>
+ <%= f.label :name, "Name" %><br />
+ <%= f.text_field :name %>
+ </p>
+ <p>
+ <%= f.label :email, "Email" %><br />
+ <%= f.text_field :email %>
+ </p>
+ <p>
+ <%= f.label :password, "Password" %><br />
+ <%= f.password_field :password %>
+ </p>
+ <p>
+ <%= f.label :password_confirmation, "Password Confirmation" %><br />
+ <%= f.password_field :password_confirmation %>
+ </p>
+
+ <p><%= f.submit "Save" %></p>
+<% end %>
@@ -0,0 +1,24 @@
+<% title "Create account" %>
+
+<% form_for @user, :url => account_path do |f| %>
+ <%= f.error_messages %>
+
+ <p>
+ <%= f.label :name, "Name" %><br />
+ <%= f.text_field :name %>
+ </p>
+ <p>
+ <%= f.label :email, "Email" %><br />
+ <%= f.text_field :email %>
+ </p>
+ <p>
+ <%= f.label :password, "Password" %><br />
+ <%= f.password_field :password %>
+ </p>
+ <p>
+ <%= f.label :password_confirmation, "Password Confirmation" %><br />
+ <%= f.password_field :password_confirmation %>
+ </p>
+
+ <p><%= f.submit "Register" %></p>
+<% end %>
@@ -0,0 +1,7 @@
+<% title "Your account" %>
+
+<p>Name: <%= @user.name %></p>
+
+<p>Email: <%= @user.email %></p>
+
+<p><%= link_to "Edit account", edit_account_path %> or <%= link_to "delete account", account_path, :method => :delete, :confirm => "Are you sure you want to destroy your account?" %></p>
View
@@ -20,6 +20,7 @@
# config.gem "sqlite3-ruby", :lib => "sqlite3"
# config.gem "aws-s3", :lib => "aws/s3"
config.gem "mongoid"
+ config.gem "rails_warden"
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named
@@ -0,0 +1,28 @@
+Rails.configuration.middleware.use RailsWarden::Manager do |manager|
+ manager.default_strategies :password
+ manager.failure_app = UserSessionsController
+end
+
+class Warden::SessionSerializer
+ def serialize(user)
+ user.id
+ end
+
+ def deserialize(key)
+ User.criteria.id(key).first
+ end
+end
+
+## Declare your strategies here
+Warden::Strategies.add(:password) do
+
+ def valid?
+ params[:email] || params[:password]
+ end
+
+ def authenticate!
+ u = User.authenticate(params[:email], params[:password])
+ u.nil? ? fail!("Could not log in") : success!(u)
+ end
+
+end
View
@@ -1,43 +1,6 @@
ActionController::Routing::Routes.draw do |map|
- # The priority is based upon order of creation: first created -> highest priority.
-
- # Sample of regular route:
- # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
- # Keep in mind you can assign values other than :controller and :action
-
- # Sample of named route:
- # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
- # This route can be invoked with purchase_url(:id => product.id)
-
- # Sample resource route (maps HTTP verbs to controller actions automatically):
- # map.resources :products
-
- # Sample resource route with options:
- # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
-
- # Sample resource route with sub-resources:
- # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
-
- # Sample resource route with more complex sub-resources
- # map.resources :products do |products|
- # products.resources :comments
- # products.resources :sales, :collection => { :recent => :get }
- # end
-
- # Sample resource route within a namespace:
- # map.namespace :admin do |admin|
- # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
- # admin.resources :products
- # end
-
- # You can have the root of your site routed with map.root -- just remember to delete public/index.html.
- # map.root :controller => "welcome"
-
- # See how all your routes lay out with "rake routes"
-
- # Install the default routes as the lowest priority.
- # Note: These default routes make all actions in every controller accessible via GET requests. You should
- # consider removing or commenting them out if you're using named routes and resources.
- map.connect ':controller/:action/:id'
- map.connect ':controller/:action/:id.:format'
+ map.resource :account, :controller => "users"
+ map.resources :users
+ map.resource :user_session, :as => "session"
+ map.root :controller => "user_sessions", :action => "new"
end
View
No changes.

0 comments on commit a0748f5

Please sign in to comment.