diff .svn/pristine/a7/a757b81e7f3e085496f4684df875891a66fc60e7.svn-base @ 1298:4f746d8966dd redmine_2.3_integration

Merge from redmine-2.3 branch to create new branch redmine-2.3-integration
author Chris Cannam
date Fri, 14 Jun 2013 09:28:30 +0100
parents 622f24f53b42
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.svn/pristine/a7/a757b81e7f3e085496f4684df875891a66fc60e7.svn-base	Fri Jun 14 09:28:30 2013 +0100
@@ -0,0 +1,304 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+class AccountController < ApplicationController
+  helper :custom_fields
+  include CustomFieldsHelper
+
+  # prevents login action to be filtered by check_if_login_required application scope filter
+  skip_before_filter :check_if_login_required
+
+  # Login request and validation
+  def login
+    if request.get?
+      if User.current.logged?
+        redirect_to home_url
+      end
+    else
+      authenticate_user
+    end
+  rescue AuthSourceException => e
+    logger.error "An error occured when authenticating #{params[:username]}: #{e.message}"
+    render_error :message => e.message
+  end
+
+  # Log out current user and redirect to welcome page
+  def logout
+    if User.current.anonymous?
+      redirect_to home_url
+    elsif request.post?
+      logout_user
+      redirect_to home_url
+    end
+    # display the logout form
+  end
+
+  # Lets user choose a new password
+  def lost_password
+    (redirect_to(home_url); return) unless Setting.lost_password?
+    if params[:token]
+      @token = Token.find_token("recovery", params[:token].to_s)
+      if @token.nil? || @token.expired?
+        redirect_to home_url
+        return
+      end
+      @user = @token.user
+      unless @user && @user.active?
+        redirect_to home_url
+        return
+      end
+      if request.post?
+        @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
+        if @user.save
+          @token.destroy
+          flash[:notice] = l(:notice_account_password_updated)
+          redirect_to signin_path
+          return
+        end
+      end
+      render :template => "account/password_recovery"
+      return
+    else
+      if request.post?
+        user = User.find_by_mail(params[:mail].to_s)
+        # user not found or not active
+        unless user && user.active?
+          flash.now[:error] = l(:notice_account_unknown_email)
+          return
+        end
+        # user cannot change its password
+        unless user.change_password_allowed?
+          flash.now[:error] = l(:notice_can_t_change_password)
+          return
+        end
+        # create a new token for password recovery
+        token = Token.new(:user => user, :action => "recovery")
+        if token.save
+          Mailer.lost_password(token).deliver
+          flash[:notice] = l(:notice_account_lost_email_sent)
+          redirect_to signin_path
+          return
+        end
+      end
+    end
+  end
+
+  # User self-registration
+  def register
+    (redirect_to(home_url); return) unless Setting.self_registration? || session[:auth_source_registration]
+    if request.get?
+      session[:auth_source_registration] = nil
+      @user = User.new(:language => current_language.to_s)
+    else
+      user_params = params[:user] || {}
+      @user = User.new
+      @user.safe_attributes = user_params
+      @user.admin = false
+      @user.register
+      if session[:auth_source_registration]
+        @user.activate
+        @user.login = session[:auth_source_registration][:login]
+        @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
+        if @user.save
+          session[:auth_source_registration] = nil
+          self.logged_user = @user
+          flash[:notice] = l(:notice_account_activated)
+          redirect_to my_account_path
+        end
+      else
+        @user.login = params[:user][:login]
+        unless user_params[:identity_url].present? && user_params[:password].blank? && user_params[:password_confirmation].blank?
+          @user.password, @user.password_confirmation = user_params[:password], user_params[:password_confirmation]
+        end
+
+        case Setting.self_registration
+        when '1'
+          register_by_email_activation(@user)
+        when '3'
+          register_automatically(@user)
+        else
+          register_manually_by_administrator(@user)
+        end
+      end
+    end
+  end
+
+  # Token based account activation
+  def activate
+    (redirect_to(home_url); return) unless Setting.self_registration? && params[:token].present?
+    token = Token.find_token('register', params[:token].to_s)
+    (redirect_to(home_url); return) unless token and !token.expired?
+    user = token.user
+    (redirect_to(home_url); return) unless user.registered?
+    user.activate
+    if user.save
+      token.destroy
+      flash[:notice] = l(:notice_account_activated)
+    end
+    redirect_to signin_path
+  end
+
+  private
+
+  def authenticate_user
+    if Setting.openid? && using_open_id?
+      open_id_authenticate(params[:openid_url])
+    else
+      password_authentication
+    end
+  end
+
+  def password_authentication
+    user = User.try_to_login(params[:username], params[:password])
+
+    if user.nil?
+      invalid_credentials
+    elsif user.new_record?
+      onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
+    else
+      # Valid user
+      successful_authentication(user)
+    end
+  end
+
+  def open_id_authenticate(openid_url)
+    back_url = signin_url(:autologin => params[:autologin])
+
+    authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => back_url, :method => :post) do |result, identity_url, registration|
+      if result.successful?
+        user = User.find_or_initialize_by_identity_url(identity_url)
+        if user.new_record?
+          # Self-registration off
+          (redirect_to(home_url); return) unless Setting.self_registration?
+
+          # Create on the fly
+          user.login = registration['nickname'] unless registration['nickname'].nil?
+          user.mail = registration['email'] unless registration['email'].nil?
+          user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
+          user.random_password
+          user.register
+
+          case Setting.self_registration
+          when '1'
+            register_by_email_activation(user) do
+              onthefly_creation_failed(user)
+            end
+          when '3'
+            register_automatically(user) do
+              onthefly_creation_failed(user)
+            end
+          else
+            register_manually_by_administrator(user) do
+              onthefly_creation_failed(user)
+            end
+          end
+        else
+          # Existing record
+          if user.active?
+            successful_authentication(user)
+          else
+            account_pending
+          end
+        end
+      end
+    end
+  end
+
+  def successful_authentication(user)
+    logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}"
+    # Valid user
+    self.logged_user = user
+    # generate a key and set cookie if autologin
+    if params[:autologin] && Setting.autologin?
+      set_autologin_cookie(user)
+    end
+    call_hook(:controller_account_success_authentication_after, {:user => user })
+    redirect_back_or_default my_page_path
+  end
+
+  def set_autologin_cookie(user)
+    token = Token.create(:user => user, :action => 'autologin')
+    cookie_options = {
+      :value => token.value,
+      :expires => 1.year.from_now,
+      :path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
+      :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
+      :httponly => true
+    }
+    cookies[autologin_cookie_name] = cookie_options
+  end
+
+  # Onthefly creation failed, display the registration form to fill/fix attributes
+  def onthefly_creation_failed(user, auth_source_options = { })
+    @user = user
+    session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
+    render :action => 'register'
+  end
+
+  def invalid_credentials
+    logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
+    flash.now[:error] = l(:notice_account_invalid_creditentials)
+  end
+
+  # Register a user for email activation.
+  #
+  # Pass a block for behavior when a user fails to save
+  def register_by_email_activation(user, &block)
+    token = Token.new(:user => user, :action => "register")
+    if user.save and token.save
+      Mailer.register(token).deliver
+      flash[:notice] = l(:notice_account_register_done)
+      redirect_to signin_path
+    else
+      yield if block_given?
+    end
+  end
+
+  # Automatically register a user
+  #
+  # Pass a block for behavior when a user fails to save
+  def register_automatically(user, &block)
+    # Automatic activation
+    user.activate
+    user.last_login_on = Time.now
+    if user.save
+      self.logged_user = user
+      flash[:notice] = l(:notice_account_activated)
+      redirect_to my_account_path
+    else
+      yield if block_given?
+    end
+  end
+
+  # Manual activation by the administrator
+  #
+  # Pass a block for behavior when a user fails to save
+  def register_manually_by_administrator(user, &block)
+    if user.save
+      # Sends an email to the administrators
+      Mailer.account_activation_request(user).deliver
+      account_pending
+    else
+      yield if block_given?
+    end
+  end
+
+  def account_pending
+    flash[:notice] = l(:notice_account_pending)
+    redirect_to signin_path
+  end
+end