annotate app/controllers/account_controller.rb @ 8:0c83d98252d9 yuya

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