##// END OF EJS Templates
Code cleanup....
Jean-Philippe Lang -
r9763:c11f5a23fee2
parent child
Show More
@@ -1,291 +1,295
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class AccountController < ApplicationController
19 19 helper :custom_fields
20 20 include CustomFieldsHelper
21 21
22 22 # prevents login action to be filtered by check_if_login_required application scope filter
23 23 skip_before_filter :check_if_login_required
24 24
25 25 # Login request and validation
26 26 def login
27 27 if request.get?
28 28 logout_user
29 29 else
30 30 authenticate_user
31 31 end
32 32 rescue AuthSourceException => e
33 33 logger.error "An error occured when authenticating #{params[:username]}: #{e.message}"
34 34 render_error :message => e.message
35 35 end
36 36
37 37 # Log out current user and redirect to welcome page
38 38 def logout
39 39 logout_user
40 40 redirect_to home_url
41 41 end
42 42
43 43 # Lets user choose a new password
44 44 def lost_password
45 45 redirect_to(home_url) && return unless Setting.lost_password?
46 46 if params[:token]
47 47 @token = Token.find_by_action_and_value("recovery", params[:token].to_s)
48 48 if @token.nil? || @token.expired?
49 49 redirect_to home_url
50 50 return
51 51 end
52 52 @user = @token.user
53 unless @user && @user.active?
54 redirect_to home_url
55 return
56 end
53 57 if request.post?
54 58 @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
55 59 if @user.save
56 60 @token.destroy
57 61 flash[:notice] = l(:notice_account_password_updated)
58 62 redirect_to signin_path
59 63 return
60 64 end
61 65 end
62 66 render :template => "account/password_recovery"
63 67 return
64 68 else
65 69 if request.post?
66 70 user = User.find_by_mail(params[:mail].to_s)
67 71 # user not found or not active
68 72 unless user && user.active?
69 73 flash.now[:error] = l(:notice_account_unknown_email)
70 74 return
71 75 end
72 76 # user cannot change its password
73 77 unless user.change_password_allowed?
74 78 flash.now[:error] = l(:notice_can_t_change_password)
75 79 return
76 80 end
77 81 # create a new token for password recovery
78 82 token = Token.new(:user => user, :action => "recovery")
79 83 if token.save
80 84 Mailer.lost_password(token).deliver
81 85 flash[:notice] = l(:notice_account_lost_email_sent)
82 86 redirect_to signin_path
83 87 return
84 88 end
85 89 end
86 90 end
87 91 end
88 92
89 93 # User self-registration
90 94 def register
91 95 redirect_to(home_url) && return unless Setting.self_registration? || session[:auth_source_registration]
92 96 if request.get?
93 97 session[:auth_source_registration] = nil
94 98 @user = User.new(:language => Setting.default_language)
95 99 else
96 100 user_params = params[:user] || {}
97 101 @user = User.new
98 102 @user.safe_attributes = user_params
99 103 @user.admin = false
100 104 @user.register
101 105 if session[:auth_source_registration]
102 106 @user.activate
103 107 @user.login = session[:auth_source_registration][:login]
104 108 @user.auth_source_id = session[:auth_source_registration][:auth_source_id]
105 109 if @user.save
106 110 session[:auth_source_registration] = nil
107 111 self.logged_user = @user
108 112 flash[:notice] = l(:notice_account_activated)
109 113 redirect_to :controller => 'my', :action => 'account'
110 114 end
111 115 else
112 116 @user.login = params[:user][:login]
113 117 unless user_params[:identity_url].present? && user_params[:password].blank? && user_params[:password_confirmation].blank?
114 118 @user.password, @user.password_confirmation = user_params[:password], user_params[:password_confirmation]
115 119 end
116 120
117 121 case Setting.self_registration
118 122 when '1'
119 123 register_by_email_activation(@user)
120 124 when '3'
121 125 register_automatically(@user)
122 126 else
123 127 register_manually_by_administrator(@user)
124 128 end
125 129 end
126 130 end
127 131 end
128 132
129 133 # Token based account activation
130 134 def activate
131 135 redirect_to(home_url) && return unless Setting.self_registration? && params[:token]
132 136 token = Token.find_by_action_and_value('register', params[:token])
133 137 redirect_to(home_url) && return unless token and !token.expired?
134 138 user = token.user
135 139 redirect_to(home_url) && return unless user.registered?
136 140 user.activate
137 141 if user.save
138 142 token.destroy
139 143 flash[:notice] = l(:notice_account_activated)
140 144 end
141 145 redirect_to signin_path
142 146 end
143 147
144 148 private
145 149
146 150 def authenticate_user
147 151 if Setting.openid? && using_open_id?
148 152 open_id_authenticate(params[:openid_url])
149 153 else
150 154 password_authentication
151 155 end
152 156 end
153 157
154 158 def password_authentication
155 159 user = User.try_to_login(params[:username], params[:password])
156 160
157 161 if user.nil?
158 162 invalid_credentials
159 163 elsif user.new_record?
160 164 onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
161 165 else
162 166 # Valid user
163 167 successful_authentication(user)
164 168 end
165 169 end
166 170
167 171 def open_id_authenticate(openid_url)
168 172 authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => signin_url, :method => :post) do |result, identity_url, registration|
169 173 if result.successful?
170 174 user = User.find_or_initialize_by_identity_url(identity_url)
171 175 if user.new_record?
172 176 # Self-registration off
173 177 redirect_to(home_url) && return unless Setting.self_registration?
174 178
175 179 # Create on the fly
176 180 user.login = registration['nickname'] unless registration['nickname'].nil?
177 181 user.mail = registration['email'] unless registration['email'].nil?
178 182 user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
179 183 user.random_password
180 184 user.register
181 185
182 186 case Setting.self_registration
183 187 when '1'
184 188 register_by_email_activation(user) do
185 189 onthefly_creation_failed(user)
186 190 end
187 191 when '3'
188 192 register_automatically(user) do
189 193 onthefly_creation_failed(user)
190 194 end
191 195 else
192 196 register_manually_by_administrator(user) do
193 197 onthefly_creation_failed(user)
194 198 end
195 199 end
196 200 else
197 201 # Existing record
198 202 if user.active?
199 203 successful_authentication(user)
200 204 else
201 205 account_pending
202 206 end
203 207 end
204 208 end
205 209 end
206 210 end
207 211
208 212 def successful_authentication(user)
209 213 # Valid user
210 214 self.logged_user = user
211 215 # generate a key and set cookie if autologin
212 216 if params[:autologin] && Setting.autologin?
213 217 set_autologin_cookie(user)
214 218 end
215 219 call_hook(:controller_account_success_authentication_after, {:user => user })
216 220 redirect_back_or_default :controller => 'my', :action => 'page'
217 221 end
218 222
219 223 def set_autologin_cookie(user)
220 224 token = Token.create(:user => user, :action => 'autologin')
221 225 cookie_name = Redmine::Configuration['autologin_cookie_name'] || 'autologin'
222 226 cookie_options = {
223 227 :value => token.value,
224 228 :expires => 1.year.from_now,
225 229 :path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
226 230 :secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
227 231 :httponly => true
228 232 }
229 233 cookies[cookie_name] = cookie_options
230 234 end
231 235
232 236 # Onthefly creation failed, display the registration form to fill/fix attributes
233 237 def onthefly_creation_failed(user, auth_source_options = { })
234 238 @user = user
235 239 session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
236 240 render register_path
237 241 end
238 242
239 243 def invalid_credentials
240 244 logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
241 245 flash.now[:error] = l(:notice_account_invalid_creditentials)
242 246 end
243 247
244 248 # Register a user for email activation.
245 249 #
246 250 # Pass a block for behavior when a user fails to save
247 251 def register_by_email_activation(user, &block)
248 252 token = Token.new(:user => user, :action => "register")
249 253 if user.save and token.save
250 254 Mailer.register(token).deliver
251 255 flash[:notice] = l(:notice_account_register_done)
252 256 redirect_to signin_path
253 257 else
254 258 yield if block_given?
255 259 end
256 260 end
257 261
258 262 # Automatically register a user
259 263 #
260 264 # Pass a block for behavior when a user fails to save
261 265 def register_automatically(user, &block)
262 266 # Automatic activation
263 267 user.activate
264 268 user.last_login_on = Time.now
265 269 if user.save
266 270 self.logged_user = user
267 271 flash[:notice] = l(:notice_account_activated)
268 272 redirect_to :controller => 'my', :action => 'account'
269 273 else
270 274 yield if block_given?
271 275 end
272 276 end
273 277
274 278 # Manual activation by the administrator
275 279 #
276 280 # Pass a block for behavior when a user fails to save
277 281 def register_manually_by_administrator(user, &block)
278 282 if user.save
279 283 # Sends an email to the administrators
280 284 Mailer.account_activation_request(user).deliver
281 285 account_pending
282 286 else
283 287 yield if block_given?
284 288 end
285 289 end
286 290
287 291 def account_pending
288 292 flash[:notice] = l(:notice_account_pending)
289 293 redirect_to signin_path
290 294 end
291 295 end
@@ -1,189 +1,243
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'account_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class AccountController; def rescue_action(e) raise e end; end
23 23
24 24 class AccountControllerTest < ActionController::TestCase
25 25 fixtures :users, :roles
26 26
27 27 def setup
28 28 @controller = AccountController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_login_should_redirect_to_back_url_param
35 35 # request.uri is "test.host" in test environment
36 36 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.host%2Fissues%2Fshow%2F1'
37 37 assert_redirected_to '/issues/show/1'
38 38 end
39 39
40 40 def test_login_should_not_redirect_to_another_host
41 41 post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http%3A%2F%2Ftest.foo%2Ffake'
42 42 assert_redirected_to '/my/page'
43 43 end
44 44
45 45 def test_login_with_wrong_password
46 46 post :login, :username => 'admin', :password => 'bad'
47 47 assert_response :success
48 48 assert_template 'login'
49 49 assert_tag 'div',
50 50 :attributes => { :class => "flash error" },
51 51 :content => /Invalid user or password/
52 52 end
53 53
54 54 def test_login_should_rescue_auth_source_exception
55 55 source = AuthSource.create!(:name => 'Test')
56 56 User.find(2).update_attribute :auth_source_id, source.id
57 57 AuthSource.any_instance.stubs(:authenticate).raises(AuthSourceException.new("Something wrong"))
58 58
59 59 post :login, :username => 'jsmith', :password => 'jsmith'
60 60 assert_response 500
61 61 assert_error_tag :content => /Something wrong/
62 62 end
63 63
64 64 def test_login_should_reset_session
65 65 @controller.expects(:reset_session).once
66 66
67 67 post :login, :username => 'jsmith', :password => 'jsmith'
68 68 assert_response 302
69 69 end
70 70
71 71 def test_logout
72 72 @request.session[:user_id] = 2
73 73 get :logout
74 74 assert_redirected_to '/'
75 75 assert_nil @request.session[:user_id]
76 76 end
77 77
78 78 def test_logout_should_reset_session
79 79 @controller.expects(:reset_session).once
80 80
81 81 @request.session[:user_id] = 2
82 82 get :logout
83 83 assert_response 302
84 84 end
85 85
86 86 def test_get_register_with_registration_on
87 87 with_settings :self_registration => '3' do
88 88 get :register
89 89 assert_response :success
90 90 assert_template 'register'
91 91 assert_not_nil assigns(:user)
92 92
93 93 assert_tag 'input', :attributes => {:name => 'user[password]'}
94 94 assert_tag 'input', :attributes => {:name => 'user[password_confirmation]'}
95 95 end
96 96 end
97 97
98 98 def test_get_register_with_registration_off_should_redirect
99 99 with_settings :self_registration => '0' do
100 100 get :register
101 101 assert_redirected_to '/'
102 102 end
103 103 end
104 104
105 105 # See integration/account_test.rb for the full test
106 106 def test_post_register_with_registration_on
107 107 with_settings :self_registration => '3' do
108 108 assert_difference 'User.count' do
109 109 post :register, :user => {
110 110 :login => 'register',
111 111 :password => 'test',
112 112 :password_confirmation => 'test',
113 113 :firstname => 'John',
114 114 :lastname => 'Doe',
115 115 :mail => 'register@example.com'
116 116 }
117 117 assert_redirected_to '/my/account'
118 118 end
119 119 user = User.first(:order => 'id DESC')
120 120 assert_equal 'register', user.login
121 121 assert_equal 'John', user.firstname
122 122 assert_equal 'Doe', user.lastname
123 123 assert_equal 'register@example.com', user.mail
124 124 assert user.check_password?('test')
125 125 assert user.active?
126 126 end
127 127 end
128 128
129 129 def test_post_register_with_registration_off_should_redirect
130 130 with_settings :self_registration => '0' do
131 131 assert_no_difference 'User.count' do
132 132 post :register, :user => {
133 133 :login => 'register',
134 134 :password => 'test',
135 135 :password_confirmation => 'test',
136 136 :firstname => 'John',
137 137 :lastname => 'Doe',
138 138 :mail => 'register@example.com'
139 139 }
140 140 assert_redirected_to '/'
141 141 end
142 142 end
143 143 end
144 144
145 145 def test_get_lost_password_should_display_lost_password_form
146 146 get :lost_password
147 147 assert_response :success
148 148 assert_select 'input[name=mail]'
149 149 end
150 150
151 151 def test_lost_password_for_active_user_should_create_a_token
152 152 Token.delete_all
153 153 ActionMailer::Base.deliveries.clear
154 154 assert_difference 'ActionMailer::Base.deliveries.size' do
155 155 assert_difference 'Token.count' do
156 156 with_settings :host_name => 'mydomain.foo', :protocol => 'http' do
157 157 post :lost_password, :mail => 'JSmith@somenet.foo'
158 158 assert_redirected_to '/login'
159 159 end
160 160 end
161 161 end
162 162
163 163 token = Token.order('id DESC').first
164 164 assert_equal User.find(2), token.user
165 165 assert_equal 'recovery', token.action
166 166
167 167 assert_select_email do
168 168 assert_select "a[href=?]", "http://mydomain.foo/account/lost_password?token=#{token.value}"
169 169 end
170 170 end
171 171
172 172 def test_lost_password_for_unknown_user_should_fail
173 173 Token.delete_all
174 174 assert_no_difference 'Token.count' do
175 175 post :lost_password, :mail => 'invalid@somenet.foo'
176 176 assert_response :success
177 177 end
178 178 end
179 179
180 180 def test_lost_password_for_non_active_user_should_fail
181 181 Token.delete_all
182 182 assert User.find(2).lock!
183 183
184 184 assert_no_difference 'Token.count' do
185 185 post :lost_password, :mail => 'JSmith@somenet.foo'
186 186 assert_response :success
187 187 end
188 188 end
189
190 def test_get_lost_password_with_token_should_display_the_password_recovery_form
191 user = User.find(2)
192 token = Token.create!(:action => 'recovery', :user => user)
193
194 get :lost_password, :token => token.value
195 assert_response :success
196 assert_template 'password_recovery'
197
198 assert_select 'input[type=hidden][name=token][value=?]', token.value
199 end
200
201 def test_get_lost_password_with_invalid_token_should_redirect
202 get :lost_password, :token => "abcdef"
203 assert_redirected_to '/'
204 end
205
206 def test_post_lost_password_with_token_should_change_the_user_password
207 user = User.find(2)
208 token = Token.create!(:action => 'recovery', :user => user)
209
210 post :lost_password, :token => token.value, :new_password => 'newpass', :new_password_confirmation => 'newpass'
211 assert_redirected_to '/login'
212 user.reload
213 assert user.check_password?('newpass')
214 assert_nil Token.find_by_id(token.id), "Token was not deleted"
215 end
216
217 def test_post_lost_password_with_token_for_non_active_user_should_fail
218 user = User.find(2)
219 token = Token.create!(:action => 'recovery', :user => user)
220 user.lock!
221
222 post :lost_password, :token => token.value, :new_password => 'newpass', :new_password_confirmation => 'newpass'
223 assert_redirected_to '/'
224 assert ! user.check_password?('newpass')
225 end
226
227 def test_post_lost_password_with_token_and_password_confirmation_failure_should_redisplay_the_form
228 user = User.find(2)
229 token = Token.create!(:action => 'recovery', :user => user)
230
231 post :lost_password, :token => token.value, :new_password => 'newpass', :new_password_confirmation => 'wrongpass'
232 assert_response :success
233 assert_template 'password_recovery'
234 assert_not_nil Token.find_by_id(token.id), "Token was deleted"
235
236 assert_select 'input[type=hidden][name=token][value=?]', token.value
237 end
238
239 def test_post_lost_password_with_invalid_token_should_redirect
240 post :lost_password, :token => "abcdef", :new_password => 'newpass', :new_password_confirmation => 'newpass'
241 assert_redirected_to '/'
242 end
189 243 end
General Comments 0
You need to be logged in to leave comments. Login now