To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / app / controllers / account_controller.rb @ 1592:72d9219f2f19

History | View | Annotate | Download (11.4 KB)

1
# Redmine - project management software
2
# Copyright (C) 2006-2014  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, :check_password_change
24

    
25
  # Overrides ApplicationController#verify_authenticity_token to disable
26
  # token verification on openid callbacks
27
  def verify_authenticity_token
28
    unless using_open_id?
29
      super
30
    end
31
  end
32

    
33
  # Login request and validation
34
  def login
35
    if request.get?
36
      if User.current.logged?
37
        redirect_back_or_default home_url, :referer => true
38
      end
39
    else
40
      authenticate_user
41
    end
42
  rescue AuthSource::AuthSourceException => e
43
    logger.error "An error occured when authenticating #{params[:username]}: #{e.message}"
44
    render_error :message => e.message
45
  end
46

    
47
  # Log out current user and redirect to welcome page
48
  def logout
49
    if User.current.anonymous?
50
      redirect_to home_url
51
    elsif request.post?
52
      logout_user
53
      redirect_to home_url
54
    end
55
    # display the logout form
56
  end
57

    
58
  # Lets user choose a new password
59
  def lost_password
60
    (redirect_to(home_url); return) unless Setting.lost_password?
61
    if params[:token]
62
      @token = Token.find_token("recovery", params[:token].to_s)
63
      if @token.nil? || @token.expired?
64
        redirect_to home_url
65
        return
66
      end
67
      @user = @token.user
68
      unless @user && @user.active?
69
        redirect_to home_url
70
        return
71
      end
72
      if request.post?
73
        @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
74
        if @user.save
75
          @token.destroy
76
          flash[:notice] = l(:notice_account_password_updated)
77
          redirect_to signin_path
78
          return
79
        end
80
      end
81
      render :template => "account/password_recovery"
82
      return
83
    else
84
      if request.post?
85
        user = User.find_by_mail(params[:mail].to_s)
86
        # user not found
87
        unless user
88
          flash.now[:error] = l(:notice_account_unknown_email)
89
          return
90
        end
91
        unless user.active?
92
          handle_inactive_user(user, lost_password_path)
93
          return
94
        end
95
        # user cannot change its password
96
        unless user.change_password_allowed?
97
          flash.now[:error] = l(:notice_can_t_change_password)
98
          return
99
        end
100
        # create a new token for password recovery
101
        token = Token.new(:user => user, :action => "recovery")
102
        if token.save
103
          Mailer.lost_password(token).deliver
104
          flash[:notice] = l(:notice_account_lost_email_sent)
105
          redirect_to signin_path
106
          return
107
        end
108
      end
109
    end
110
  end
111

    
112
  # User self-registration
113
  def register
114
    (redirect_to(home_url); return) unless Setting.self_registration? || session[:auth_source_registration]
115

    
116
    if request.get?
117
      session[:auth_source_registration] = nil
118
      @user = User.new(:language => Setting.default_language)
119

    
120
      @ssamr_user_details = SsamrUserDetail.new
121

    
122
    else
123
      user_params = params[:user] || {}
124
      @user = User.new
125
      @user.safe_attributes = user_params
126
      @user.admin = false
127
                  
128
      @user.register
129
      
130
      if session[:auth_source_registration]
131
        @user.activate
132
        @user.login = session[:auth_source_registration][:login]
133
        @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
134
        if @user.save
135
          session[:auth_source_registration] = nil
136
          self.logged_user = @user
137
          flash[:notice] = l(:notice_account_activated)
138
          redirect_to my_account_path
139
        end
140
      else
141
        @user.login = params[:user][:login]
142
        unless user_params[:identity_url].present? && user_params[:password].blank? && user_params[:password_confirmation].blank?
143
          @user.password, @user.password_confirmation = user_params[:password], user_params[:password_confirmation]
144
        end
145

    
146
        @ssamr_user_details = SsamrUserDetail.new(params[:ssamr_user_details])
147

    
148
        # associates the 2 objects
149
        @user.ssamr_user_detail = @ssamr_user_details
150
        @selected_institution_id = params[:ssamr_user_details][:institution_id].to_i
151

    
152
        
153
        case Setting.self_registration
154
        when '1'
155
          register_by_email_activation(@user)
156
        when '3'
157
          register_automatically(@user)
158
        else
159
          register_manually_by_administrator(@user)
160
        end
161
      end
162
    end
163
  end
164

    
165
  # Token based account activation
166
  def activate
167
    (redirect_to(home_url); return) unless Setting.self_registration? && params[:token].present?
168
    token = Token.find_token('register', params[:token].to_s)
169
    (redirect_to(home_url); return) unless token and !token.expired?
170
    user = token.user
171
    (redirect_to(home_url); return) unless user.registered?
172
    user.activate
173
    if user.save
174
      token.destroy
175
      flash[:notice] = l(:notice_account_activated)
176
    end
177
    redirect_to signin_path
178
  end
179

    
180
  # Sends a new account activation email
181
  def activation_email
182
    if session[:registered_user_id] && Setting.self_registration == '1'
183
      user_id = session.delete(:registered_user_id).to_i
184
      user = User.find_by_id(user_id)
185
      if user && user.registered?
186
        register_by_email_activation(user)
187
        return
188
      end
189
    end
190
    redirect_to(home_url)
191
  end
192

    
193
  private
194

    
195
  def authenticate_user
196
    if Setting.openid? && using_open_id?
197
      open_id_authenticate(params[:openid_url])
198
    else
199
      password_authentication
200
    end
201
  end
202

    
203
  def password_authentication
204
    user = User.try_to_login(params[:username], params[:password], false)
205

    
206
    if user.nil?
207
      invalid_credentials
208
    elsif user.new_record?
209
      onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
210
    else
211
      # Valid user
212
      if user.active?
213
        successful_authentication(user)
214
      else
215
        handle_inactive_user(user)
216
      end
217
    end
218
  end
219

    
220
  def open_id_authenticate(openid_url)
221
    back_url = signin_url(:autologin => params[:autologin])
222
    authenticate_with_open_id(
223
          openid_url, :required => [:nickname, :fullname, :email],
224
          :return_to => back_url, :method => :post
225
    ) do |result, identity_url, registration|
226
      if result.successful?
227
        user = User.find_or_initialize_by_identity_url(identity_url)
228
        if user.new_record?
229
          # Self-registration off
230
          (redirect_to(home_url); return) unless Setting.self_registration?
231
          # Create on the fly
232
          user.login = registration['nickname'] unless registration['nickname'].nil?
233
          user.mail = registration['email'] unless registration['email'].nil?
234
          user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
235
          user.random_password
236
          user.register
237
          case Setting.self_registration
238
          when '1'
239
            register_by_email_activation(user) do
240
              onthefly_creation_failed(user)
241
            end
242
          when '3'
243
            register_automatically(user) do
244
              onthefly_creation_failed(user)
245
            end
246
          else
247
            register_manually_by_administrator(user) do
248
              onthefly_creation_failed(user)
249
            end
250
          end
251
        else
252
          # Existing record
253
          if user.active?
254
            successful_authentication(user)
255
          else
256
            handle_inactive_user(user)
257
          end
258
        end
259
      end
260
    end
261
  end
262

    
263
  def successful_authentication(user)
264
    logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}"
265
    # Valid user
266
    self.logged_user = user
267
    # generate a key and set cookie if autologin
268
    if params[:autologin] && Setting.autologin?
269
      set_autologin_cookie(user)
270
    end
271
    call_hook(:controller_account_success_authentication_after, {:user => user })
272
    redirect_back_or_default my_page_path
273
  end
274

    
275
  def set_autologin_cookie(user)
276
    token = Token.create(:user => user, :action => 'autologin')
277
    cookie_options = {
278
      :value => token.value,
279
      :expires => 1.year.from_now,
280
      :path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
281
      :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
282
      :httponly => true
283
    }
284
    cookies[autologin_cookie_name] = cookie_options
285
  end
286

    
287
  # Onthefly creation failed, display the registration form to fill/fix attributes
288
  def onthefly_creation_failed(user, auth_source_options = { })
289
    @user = user
290
    session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
291
    render :action => 'register'
292
  end
293

    
294
  def invalid_credentials
295
    logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
296
    flash.now[:error] = l(:notice_account_invalid_creditentials)
297
  end
298

    
299
  # Register a user for email activation.
300
  #
301
  # Pass a block for behavior when a user fails to save
302
  def register_by_email_activation(user, &block)
303
    token = Token.new(:user => user, :action => "register")
304
    if user.save and token.save
305
      Mailer.register(token).deliver
306
      flash[:notice] = l(:notice_account_register_done, :email => user.mail)
307
      redirect_to signin_path
308
    else
309
      yield if block_given?
310
    end
311
  end
312

    
313
  # Automatically register a user
314
  #
315
  # Pass a block for behavior when a user fails to save
316
  def register_automatically(user, &block)
317
    # Automatic activation
318
    user.activate
319
    user.last_login_on = Time.now
320
    if user.save
321
      self.logged_user = user
322
      flash[:notice] = l(:notice_account_activated)
323
      redirect_to my_account_path
324
    else
325
      yield if block_given?
326
    end
327
  end
328

    
329
  # Manual activation by the administrator
330
  #
331
  # Pass a block for behavior when a user fails to save
332
  def register_manually_by_administrator(user, &block)
333
    if user.save
334

    
335
       @ssamr_user_details.save!
336

    
337
      # Sends an email to the administrators
338
      Mailer.account_activation_request(user).deliver
339
      account_pending(user)
340
    else
341
      yield if block_given?
342
    end
343
  end
344

    
345
  def handle_inactive_user(user, redirect_path=signin_path)
346
    if user.registered?
347
      account_pending(user, redirect_path)
348
    else
349
      account_locked(user, redirect_path)
350
    end
351
  end
352

    
353
  def account_pending(user, redirect_path=signin_path)
354
    if Setting.self_registration == '1'
355
      flash[:error] = l(:notice_account_not_activated_yet, :url => activation_email_path)
356
      session[:registered_user_id] = user.id
357
    else
358
      flash[:error] = l(:notice_account_pending)
359
    end
360
    redirect_to redirect_path
361
  end
362

    
363
  def account_locked(user, redirect_path=signin_path)
364
    flash[:error] = l(:notice_account_locked)
365
    redirect_to redirect_path
366
  end
367
end