File: app/controllers/account_controller.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  class: AccountController#18
includes
  CustomFieldsHelper   
inherits from
  ApplicationController   
has properties
method: login #26
method: logout #38
method: lost_password #44
method: register #81
method: activate #118
method: logout_user #134
method: authenticate_user #142
method: password_authentication #150
method: open_id_authenticate / 1 #163
method: successful_authentication / 1 #204
method: set_autologin_cookie / 1 #215
method: onthefly_creation_failed / 2 #229
method: invalid_credentials #235
method: register_by_email_activation / 2 #243
method: register_automatically / 2 #257
method: register_manually_by_administrator / 2 #273
method: account_pending #283

Class Hierarchy

Code

   1  # Redmine - project management software
   2  # Copyright (C) 2006-2011  Jean-Philippe Lang
   3  #
   4  # This program is free software; you can redistribute it and/or
   5  # modify it under the terms of the GNU General Public License
   6  # as published by the Free Software Foundation; either version 2
   7  # of the License, or (at your option) any later version.
   8  #
   9  # This program is distributed in the hope that it will be useful,
  10  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  # GNU General Public License for more details.
  13  #
  14  # You should have received a copy of the GNU General Public License
  15  # along with this program; if not, write to the Free Software
  16  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  17 
  18  class AccountController < ApplicationController
  19    helper :custom_fields
  20    include CustomFieldsHelper
  21 
  22    # prevents login action to be filtered by check_if_login_required application scope filter
  23    skip_before_filter :check_if_login_required
  24 
  25    # Login request and validation
  26    def login
  27      if request.get?
  28        logout_user
  29      else
  30        authenticate_user
  31      end
  32    rescue AuthSourceException => e
  33      logger.error "An error occured when authenticating #{params[:username]}: #{e.message}"
  34      render_error :message => e.message
  35    end
  36 
  37    # Log out current user and redirect to welcome page
  38    def logout
  39      logout_user
  40      redirect_to home_url
  41    end
  42 
  43    # Enable user to choose a new password
  44    def lost_password
  45      redirect_to(home_url) && return unless Setting.lost_password?
  46      if params[:token]
  47        @token = Token.find_by_action_and_value("recovery", params[:token])
  48        redirect_to(home_url) && return unless @token and !@token.expired?
  49        @user = @token.user
  50        if request.post?
  51          @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
  52          if @user.save
  53            @token.destroy
  54            flash[:notice] = l(:notice_account_password_updated)
  55            redirect_to :action => 'login'
  56            return
  57          end
  58        end
  59        render :template => "account/password_recovery"
  60        return
  61      else
  62        if request.post?
  63          user = User.find_by_mail(params[:mail])
  64          # user not found in db
  65          (flash.now[:error] = l(:notice_account_unknown_email); return) unless user
  66          # user uses an external authentification
  67          (flash.now[:error] = l(:notice_can_t_change_password); return) if user.auth_source_id
  68          # create a new token for password recovery
  69          token = Token.new(:user => user, :action => "recovery")
  70          if token.save
  71            Mailer.deliver_lost_password(token)
  72            flash[:notice] = l(:notice_account_lost_email_sent)
  73            redirect_to :action => 'login'
  74            return
  75          end
  76        end
  77      end
  78    end
  79 
  80    # User self-registration
  81    def register
  82      redirect_to(home_url) && return unless Setting.self_registration? || session[:auth_source_registration]
  83      if request.get?
  84        session[:auth_source_registration] = nil
  85        @user = User.new(:language => Setting.default_language)
  86      else
  87        @user = User.new
  88        @user.safe_attributes = params[:user]
  89        @user.admin = false
  90        @user.register
  91        if session[:auth_source_registration]
  92          @user.activate
  93          @user.login = session[:auth_source_registration][:login]
  94          @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
  95          if @user.save
  96            session[:auth_source_registration] = nil
  97            self.logged_user = @user
  98            flash[:notice] = l(:notice_account_activated)
  99            redirect_to :controller => 'my', :action => 'account'
 100          end
 101        else
 102          @user.login = params[:user][:login]
 103          @user.password, @user.password_confirmation = params[:user][:password], params[:user][:password_confirmation]
 104 
 105          case Setting.self_registration
 106          when '1'
 107            register_by_email_activation(@user)
 108          when '3'
 109            register_automatically(@user)
 110          else
 111            register_manually_by_administrator(@user)
 112          end
 113        end
 114      end
 115    end
 116 
 117    # Token based account activation
 118    def activate
 119      redirect_to(home_url) && return unless Setting.self_registration? && params[:token]
 120      token = Token.find_by_action_and_value('register', params[:token])
 121      redirect_to(home_url) && return unless token and !token.expired?
 122      user = token.user
 123      redirect_to(home_url) && return unless user.registered?
 124      user.activate
 125      if user.save
 126        token.destroy
 127        flash[:notice] = l(:notice_account_activated)
 128      end
 129      redirect_to :action => 'login'
 130    end
 131 
 132    private
 133 
 134    def logout_user
 135      if User.current.logged?
 136        cookies.delete :autologin
 137        Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
 138        self.logged_user = nil
 139      end
 140    end
 141 
 142    def authenticate_user
 143      if Setting.openid? && using_open_id?
 144        open_id_authenticate(params[:openid_url])
 145      else
 146        password_authentication
 147      end
 148    end
 149 
 150    def password_authentication
 151      user = User.try_to_login(params[:username], params[:password])
 152 
 153      if user.nil?
 154        invalid_credentials
 155      elsif user.new_record?
 156        onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
 157      else
 158        # Valid user
 159        successful_authentication(user)
 160      end
 161    end
 162 
 163    def open_id_authenticate(openid_url)
 164      authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => signin_url) do |result, identity_url, registration|
 165        if result.successful?
 166          user = User.find_or_initialize_by_identity_url(identity_url)
 167          if user.new_record?
 168            # Self-registration off
 169            redirect_to(home_url) && return unless Setting.self_registration?
 170 
 171            # Create on the fly
 172            user.login = registration['nickname'] unless registration['nickname'].nil?
 173            user.mail = registration['email'] unless registration['email'].nil?
 174            user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
 175            user.random_password
 176            user.register
 177 
 178            case Setting.self_registration
 179            when '1'
 180              register_by_email_activation(user) do
 181                onthefly_creation_failed(user)
 182              end
 183            when '3'
 184              register_automatically(user) do
 185                onthefly_creation_failed(user)
 186              end
 187            else
 188              register_manually_by_administrator(user) do
 189                onthefly_creation_failed(user)
 190              end
 191            end
 192          else
 193            # Existing record
 194            if user.active?
 195              successful_authentication(user)
 196            else
 197              account_pending
 198            end
 199          end
 200        end
 201      end
 202    end
 203 
 204    def successful_authentication(user)
 205      # Valid user
 206      self.logged_user = user
 207      # generate a key and set cookie if autologin
 208      if params[:autologin] && Setting.autologin?
 209        set_autologin_cookie(user)
 210      end
 211      call_hook(:controller_account_success_authentication_after, {:user => user })
 212      redirect_back_or_default :controller => 'my', :action => 'page'
 213    end
 214 
 215    def set_autologin_cookie(user)
 216      token = Token.create(:user => user, :action => 'autologin')
 217      cookie_name = Redmine::Configuration['autologin_cookie_name'] || 'autologin'
 218      cookie_options = {
 219        :value => token.value,
 220        :expires => 1.year.from_now,
 221        :path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
 222        :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
 223        :httponly => true
 224      }
 225      cookies[cookie_name] = cookie_options
 226    end
 227 
 228    # Onthefly creation failed, display the registration form to fill/fix attributes
 229    def onthefly_creation_failed(user, auth_source_options = { })
 230      @user = user
 231      session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
 232      render :action => 'register'
 233    end
 234 
 235    def invalid_credentials
 236      logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
 237      flash.now[:error] = l(:notice_account_invalid_creditentials)
 238    end
 239 
 240    # Register a user for email activation.
 241    #
 242    # Pass a block for behavior when a user fails to save
 243    def register_by_email_activation(user, &block)
 244      token = Token.new(:user => user, :action => "register")
 245      if user.save and token.save
 246        Mailer.deliver_register(token)
 247        flash[:notice] = l(:notice_account_register_done)
 248        redirect_to :action => 'login'
 249      else
 250        yield if block_given?
 251      end
 252    end
 253 
 254    # Automatically register a user
 255    #
 256    # Pass a block for behavior when a user fails to save
 257    def register_automatically(user, &block)
 258      # Automatic activation
 259      user.activate
 260      user.last_login_on = Time.now
 261      if user.save
 262        self.logged_user = user
 263        flash[:notice] = l(:notice_account_activated)
 264        redirect_to :controller => 'my', :action => 'account'
 265      else
 266        yield if block_given?
 267      end
 268    end
 269 
 270    # Manual activation by the administrator
 271    #
 272    # Pass a block for behavior when a user fails to save
 273    def register_manually_by_administrator(user, &block)
 274      if user.save
 275        # Sends an email to the administrators
 276        Mailer.deliver_account_activation_request(user)
 277        account_pending
 278      else
 279        yield if block_given?
 280      end
 281    end
 282 
 283    def account_pending
 284      flash[:notice] = l(:notice_account_pending)
 285      redirect_to :action => 'login'
 286    end
 287  end