From e40f865c45d29a2615a9c2bd0d84f55b08580270 Mon Sep 17 00:00:00 2001 From: benni Date: Wed, 11 May 2011 13:38:46 +0200 Subject: [PATCH] Refactored login module. Implemented standard sessions controller. --- app/controllers/application_controller.rb | 47 +--- app/controllers/login_controller.rb | 49 +--- app/controllers/sessions_controller.rb | 24 ++ app/helpers/application_helper.rb | 2 +- app/helpers/sessions_helper.rb | 2 + app/models/user.rb | 9 + app/views/layouts/login.haml | 2 + app/views/login/forgot_password.html.haml | 2 - .../login.haml => sessions/new.html.haml} | 12 +- config/routes.rb | 20 +- public/index.html | 239 ------------------ test/functional/sessions_controller_test.rb | 9 + test/unit/helpers/sessions_helper_test.rb | 4 + 13 files changed, 89 insertions(+), 332 deletions(-) create mode 100644 app/controllers/sessions_controller.rb create mode 100644 app/helpers/sessions_helper.rb rename app/views/{login/login.haml => sessions/new.html.haml} (69%) delete mode 100644 public/index.html create mode 100644 test/functional/sessions_controller_test.rb create mode 100644 test/unit/helpers/sessions_helper_test.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 06307475..5cebad4c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,12 +1,10 @@ class ApplicationController < ActionController::Base - filter_parameter_logging :password, :password_confirmation # do not log passwort parameters + protect_from_forgery before_filter :select_foodcoop, :authenticate, :store_controller after_filter :remove_controller - - # sends a mail, when an error occurs - # see plugins/exception_notification - include ExceptionNotifiable + + helper_method :current_user # Returns the controller handling the current request. def self.current @@ -25,46 +23,27 @@ class ApplicationController < ActionController::Base protected def current_user - begin - # check if there is a valid session and return the logged-in user (its object) - if session[:user] and session[:foodcoop] - # for shared-host installations. check if the cookie-subdomain fits to request. - return User.current_user = User.find(session[:user]) if session[:foodcoop] == Foodsoft.env - end - rescue - reset_session - flash[:error]= _("An error has occurred. Please login again.") - redirect_to :controller => 'login' + # check if there is a valid session and return the logged-in user (its object) + if session[:user_id] and params[:foodcoop] + # for shared-host installations. check if the cookie-subdomain fits to request. + @current_user ||= User.find(session[:user_id]) if params[:foodcoop] == Foodsoft.env end end - - def current_user=(user) - session[:user], session[:foodcoop] = user.id, Foodsoft.env - end - - def return_to - session['return_to'] - end - - def return_to=(uri) - session['return_to'] = uri - end def deny_access self.return_to = request.request_uri - redirect_to :controller => '/login', :action => 'denied' - return false + redirect_to login_url, :alert => 'Access denied!' end private def authenticate(role = 'any') # Attempt to retrieve authenticated user from controller instance or session... - if !(user = current_user) + if !current_user # No user at all: redirect to login page. - self.return_to = request.request_uri - redirect_to :controller => '/login' - return false + session[:user_id] = nil + session['return_to'] = request.fullpath + redirect_to login_url, :alert => 'Authentication required!' else # We have an authenticated user, now check role... # Roles gets the user through his memberships. @@ -78,7 +57,7 @@ class ApplicationController < ActionController::Base else false # any unknown role will always fail end if hasRole - @current_user = user + current_user else deny_access end diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb index e68876d0..10dafa58 100644 --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -2,47 +2,8 @@ class LoginController < ApplicationController skip_before_filter :authenticate # no authentication since this is the login page before_filter :validate_token, :only => [:password, :update_password] - verify :method => :post, :only => [:login, :reset_password, :new], :redirect_to => { :action => :index } - - # Redirects to the login action. - def index - render :action => 'login' - end - - # Logout the current user and deletes the session - def logout - self.return_to = nil - current_user = nil - reset_session - flash[:notice] = "Abgemeldet" - render :action => 'login' - end - - # Displays a "denied due to insufficient privileges" message and provides the login form. - def denied - flash[:error] = "Du bist nicht berechtigt diese Seite zu besuchen. Bitte als berechtige Benutzerin anmelden oder zurück gehen." - render :action => 'login' - end - - # Login to the foodsoft. - def login - user = User.find_by_nick(params[:login][:user]) - if user && user.has_password(params[:login][:password]) - # Set last_login to Now() - user.update_attribute(:last_login, Time.now) - self.current_user = user - if (redirect = return_to) - self.return_to = nil - redirect_to redirect - else - redirect_to root_path - end - else - current_user = nil - flash[:error] = "Tschuldige, die Anmeldung war nicht erfolgreich. Bitte erneut versuchen." - end - end - + verify :method => :post, :only => [:reset_password], :redirect_to => { :action => 'forgot_password' } + # Display the form to enter an email address requesting a token to set a new password. def forgot_password end @@ -57,8 +18,7 @@ class LoginController < ApplicationController logger.debug("Sent password reset email to #{user.email}.") end end - flash[:notice] = "Wenn Deine E-Mail hier registiert ist bekommst Du jetzt eine Nachricht mit einem Passwort-Zurücksetzen-Link." - render :action => 'login' + redirect_to login_url, :notice => "Wenn Deine E-Mail hier registiert ist bekommst Du jetzt eine Nachricht mit einem Passwort-Zurücksetzen-Link." end # Set a new password with a token from the password reminder email. @@ -74,8 +34,7 @@ class LoginController < ApplicationController @user.reset_password_token = nil @user.reset_password_expires = nil @user.save - flash[:notice] = "Dein Passwort wurde aktualisiert. Du kannst Dich jetzt anmelden." - render :action => 'login' + redirect_to login_url, :notice => "Dein Passwort wurde aktualisiert. Du kannst Dich jetzt anmelden." else render :action => 'password' end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 00000000..00ac595b --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,24 @@ +class SessionsController < ApplicationController + + skip_before_filter :authenticate + layout 'login' + + def new + end + + def create + user = User.authenticate(params[:nick], params[:password]) + if user + session[:user_id] = user.id + redirect_to session['return_to'] || root_url, :notice => "Logged in!" + else + flash.now.alert = "Invalid email or password" + render "new" + end + end + + def destroy + session[:user_id] = nil + redirect_to login_url, :notice => "Logged out!" + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5ea4120c..a22543ba 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -108,7 +108,7 @@ module ApplicationHelper # to set a title for both the h1-tag and the title in the header def title(page_title, show_title = true) - @content_for_title = page_title.to_s + content_for(:title) { page_title.to_s } @show_title = show_title end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb new file mode 100644 index 00000000..309f8b2e --- /dev/null +++ b/app/helpers/sessions_helper.rb @@ -0,0 +1,2 @@ +module SessionsHelper +end diff --git a/app/models/user.rb b/app/models/user.rb index 81b80e9f..2675d0e8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -176,6 +176,15 @@ class User < ActiveRecord::Base self.groups.find(:all, :conditions => {:type => ""}) end + def self.authenticate(nick, password) + user = find_by_nick(nick) + if user && user.has_password(password) + user + else + nil + end + end + end # == Schema Information diff --git a/app/views/layouts/login.haml b/app/views/layouts/login.haml index 1e1d771a..787ece3c 100644 --- a/app/views/layouts/login.haml +++ b/app/views/layouts/login.haml @@ -10,6 +10,8 @@ #login - if yield(:title) %h1= yield(:title) + - flash.each do |name, msg| + = content_tag :div, msg, :class => "flash #{name}" = yield #meta Foodcoop diff --git a/app/views/login/forgot_password.html.haml b/app/views/login/forgot_password.html.haml index 0578df73..4515a8d5 100644 --- a/app/views/login/forgot_password.html.haml +++ b/app/views/login/forgot_password.html.haml @@ -1,6 +1,4 @@ - title "Passwort vergessen?" -- if flash[:error] - %p{:style => "color: red"}= flash[:error] %p Kein Problem, Du kannst dir einfach ein neues Passwort zulegen. %p diff --git a/app/views/login/login.haml b/app/views/sessions/new.html.haml similarity index 69% rename from app/views/login/login.haml rename to app/views/sessions/new.html.haml index a57cee72..597d991f 100644 --- a/app/views/login/login.haml +++ b/app/views/sessions/new.html.haml @@ -15,19 +15,15 @@ bitte abschalten. #login-form.edit_form(style="width:25em;display:none") - - form_tag :action => 'login' do - - if flash[:notice] - %div.notice= flash[:notice] - - if flash[:error] - %div.error= flash[:error] + = form_tag sessions_path do %p %label{:for => 'user'} Benutzerin %br/ - = text_field 'login', 'user' + = text_field_tag 'nick' %p %label{:for => 'password'} Passwort %br/ - = password_field 'login', 'password' + = password_field_tag 'password' = submit_tag "Anmelden" | - = link_to "Passwort vergessen?", :action => 'forgot_password' \ No newline at end of file + = link_to "Passwort vergessen?", :controller => 'login', :action => 'forgot_password' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 270f48e0..ccc7e8ce 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,20 +1,29 @@ Foodsoft::Application.routes.draw do + get "sessions/new" + # Use routing filter to select foodcoop config and datbase # filter :foodcoop + root :to => redirect("/#{Foodsoft.env}") + scope '/:foodcoop', :defaults => { :foodcoop => Foodsoft.env } do # Root path root :to => 'home#index' + ########### Sessions + + match '/login' => 'sessions#new', :as => 'login' + match '/logout' => 'sessions#destroy', :as => 'logout' + resources :sessions, :only => [:new, :create, :destroy] + ########### User specific - match '/login' => 'login#index', :as => 'login' - match '/logout' => 'login#logout', :as => 'logout' match '/home/profile' => 'home#profile', :as => 'my_profile' match '/home/ordergroup' => 'home#ordergroup', :as => 'my_ordergroup' + ############ Wiki resources :pages do @@ -141,5 +150,10 @@ Foodsoft::Application.routes.draw do end end end - end + + ############## The rest + + match '/:controller(/:action(/:id))' + + end # End of /:foodcoop scope end diff --git a/public/index.html b/public/index.html deleted file mode 100644 index 75d5edd0..00000000 --- a/public/index.html +++ /dev/null @@ -1,239 +0,0 @@ - - - - Ruby on Rails: Welcome aboard - - - - -
- - -
- - - - -
-

Getting started

-

Here’s how to get rolling:

- -
    -
  1. -

    Use rails generate to create your models and controllers

    -

    To see all available options, run it without parameters.

    -
  2. - -
  3. -

    Set up a default route and remove or rename this file

    -

    Routes are set up in config/routes.rb.

    -
  4. - -
  5. -

    Create your database

    -

    Run rake db:migrate to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

    -
  6. -
-
-
- - -
- - diff --git a/test/functional/sessions_controller_test.rb b/test/functional/sessions_controller_test.rb new file mode 100644 index 00000000..75db9687 --- /dev/null +++ b/test/functional/sessions_controller_test.rb @@ -0,0 +1,9 @@ +require 'test_helper' + +class SessionsControllerTest < ActionController::TestCase + test "should get new" do + get :new + assert_response :success + end + +end diff --git a/test/unit/helpers/sessions_helper_test.rb b/test/unit/helpers/sessions_helper_test.rb new file mode 100644 index 00000000..7d44e096 --- /dev/null +++ b/test/unit/helpers/sessions_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class SessionsHelperTest < ActionView::TestCase +end