@@ -75,11 +75,15 class AccountController < ApplicationController | |||||
75 | else |
|
75 | else | |
76 | if request.post? |
|
76 | if request.post? | |
77 | user = User.find_by_mail(params[:mail].to_s) |
|
77 | user = User.find_by_mail(params[:mail].to_s) | |
78 |
# user not found |
|
78 | # user not found | |
79 |
unless user |
|
79 | unless user | |
80 | flash.now[:error] = l(:notice_account_unknown_email) |
|
80 | flash.now[:error] = l(:notice_account_unknown_email) | |
81 | return |
|
81 | return | |
82 | end |
|
82 | end | |
|
83 | unless user.active? | |||
|
84 | handle_inactive_user(user, lost_password_path) | |||
|
85 | return | |||
|
86 | end | |||
83 | # user cannot change its password |
|
87 | # user cannot change its password | |
84 | unless user.change_password_allowed? |
|
88 | unless user.change_password_allowed? | |
85 | flash.now[:error] = l(:notice_can_t_change_password) |
|
89 | flash.now[:error] = l(:notice_can_t_change_password) | |
@@ -152,6 +156,19 class AccountController < ApplicationController | |||||
152 | redirect_to signin_path |
|
156 | redirect_to signin_path | |
153 | end |
|
157 | end | |
154 |
|
158 | |||
|
159 | # Sends a new account activation email | |||
|
160 | def activation_email | |||
|
161 | if session[:registered_user_id] && Setting.self_registration == '1' | |||
|
162 | user_id = session.delete(:registered_user_id).to_i | |||
|
163 | user = User.find_by_id(user_id) | |||
|
164 | if user && user.registered? | |||
|
165 | register_by_email_activation(user) | |||
|
166 | return | |||
|
167 | end | |||
|
168 | end | |||
|
169 | redirect_to(home_url) | |||
|
170 | end | |||
|
171 | ||||
155 | private |
|
172 | private | |
156 |
|
173 | |||
157 | def authenticate_user |
|
174 | def authenticate_user | |
@@ -163,7 +180,7 class AccountController < ApplicationController | |||||
163 | end |
|
180 | end | |
164 |
|
181 | |||
165 | def password_authentication |
|
182 | def password_authentication | |
166 | user = User.try_to_login(params[:username], params[:password]) |
|
183 | user = User.try_to_login(params[:username], params[:password], false) | |
167 |
|
184 | |||
168 | if user.nil? |
|
185 | if user.nil? | |
169 | invalid_credentials |
|
186 | invalid_credentials | |
@@ -171,7 +188,11 class AccountController < ApplicationController | |||||
171 | onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id }) |
|
188 | onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id }) | |
172 | else |
|
189 | else | |
173 | # Valid user |
|
190 | # Valid user | |
174 | successful_authentication(user) |
|
191 | if user.active? | |
|
192 | successful_authentication(user) | |||
|
193 | else | |||
|
194 | handle_inactive_user(user) | |||
|
195 | end | |||
175 | end |
|
196 | end | |
176 | end |
|
197 | end | |
177 |
|
198 | |||
@@ -211,7 +232,7 class AccountController < ApplicationController | |||||
211 | if user.active? |
|
232 | if user.active? | |
212 | successful_authentication(user) |
|
233 | successful_authentication(user) | |
213 | else |
|
234 | else | |
214 | account_pending |
|
235 | handle_inactive_user(user) | |
215 | end |
|
236 | end | |
216 | end |
|
237 | end | |
217 | end |
|
238 | end | |
@@ -291,14 +312,32 class AccountController < ApplicationController | |||||
291 | if user.save |
|
312 | if user.save | |
292 | # Sends an email to the administrators |
|
313 | # Sends an email to the administrators | |
293 | Mailer.account_activation_request(user).deliver |
|
314 | Mailer.account_activation_request(user).deliver | |
294 | account_pending |
|
315 | account_pending(user) | |
295 | else |
|
316 | else | |
296 | yield if block_given? |
|
317 | yield if block_given? | |
297 | end |
|
318 | end | |
298 | end |
|
319 | end | |
299 |
|
320 | |||
300 | def account_pending |
|
321 | def handle_inactive_user(user, redirect_path=signin_path) | |
301 | flash[:notice] = l(:notice_account_pending) |
|
322 | if user.registered? | |
302 | redirect_to signin_path |
|
323 | account_pending(user, redirect_path) | |
|
324 | else | |||
|
325 | account_locked(user, redirect_path) | |||
|
326 | end | |||
|
327 | end | |||
|
328 | ||||
|
329 | def account_pending(user, redirect_path=signin_path) | |||
|
330 | if Setting.self_registration == '1' | |||
|
331 | flash[:error] = l(:notice_account_not_activated_yet, :url => activation_email_path) | |||
|
332 | session[:registered_user_id] = user.id | |||
|
333 | else | |||
|
334 | flash[:error] = l(:notice_account_pending) | |||
|
335 | end | |||
|
336 | redirect_to redirect_path | |||
|
337 | end | |||
|
338 | ||||
|
339 | def account_locked(user, redirect_path=signin_path) | |||
|
340 | flash[:error] = l(:notice_account_locked) | |||
|
341 | redirect_to redirect_path | |||
303 | end |
|
342 | end | |
304 | end |
|
343 | end |
@@ -157,7 +157,7 class User < Principal | |||||
157 | end |
|
157 | end | |
158 |
|
158 | |||
159 | # Returns the user that matches provided login and password, or nil |
|
159 | # Returns the user that matches provided login and password, or nil | |
160 | def self.try_to_login(login, password) |
|
160 | def self.try_to_login(login, password, active_only=true) | |
161 | login = login.to_s |
|
161 | login = login.to_s | |
162 | password = password.to_s |
|
162 | password = password.to_s | |
163 |
|
163 | |||
@@ -166,8 +166,8 class User < Principal | |||||
166 | user = find_by_login(login) |
|
166 | user = find_by_login(login) | |
167 | if user |
|
167 | if user | |
168 | # user is already in local database |
|
168 | # user is already in local database | |
169 | return nil unless user.active? |
|
|||
170 | return nil unless user.check_password?(password) |
|
169 | return nil unless user.check_password?(password) | |
|
170 | return nil if !user.active? && active_only | |||
171 | else |
|
171 | else | |
172 | # user is not yet registered, try to authenticate with available sources |
|
172 | # user is not yet registered, try to authenticate with available sources | |
173 | attrs = AuthSource.authenticate(login, password) |
|
173 | attrs = AuthSource.authenticate(login, password) | |
@@ -181,7 +181,7 class User < Principal | |||||
181 | end |
|
181 | end | |
182 | end |
|
182 | end | |
183 | end |
|
183 | end | |
184 | user.update_column(:last_login_on, Time.now) if user && !user.new_record? |
|
184 | user.update_column(:last_login_on, Time.now) if user && !user.new_record? && user.active? | |
185 | user |
|
185 | user | |
186 | rescue => text |
|
186 | rescue => text | |
187 | raise text |
|
187 | raise text |
@@ -150,6 +150,8 en: | |||||
150 | notice_account_wrong_password: Wrong password |
|
150 | notice_account_wrong_password: Wrong password | |
151 | notice_account_register_done: Account was successfully created. To activate your account, click on the link that was emailed to you. |
|
151 | notice_account_register_done: Account was successfully created. To activate your account, click on the link that was emailed to you. | |
152 | notice_account_unknown_email: Unknown user. |
|
152 | notice_account_unknown_email: Unknown user. | |
|
153 | notice_account_not_activated_yet: You haven't activated your account yet. If you want to receive a new activation email, please <a href="%{url}">click this link</a>. | |||
|
154 | notice_account_locked: Your account is locked. | |||
153 | notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password. |
|
155 | notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password. | |
154 | notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you. |
|
156 | notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you. | |
155 | notice_account_activated: Your account has been activated. You can now log in. |
|
157 | notice_account_activated: Your account has been activated. You can now log in. |
@@ -167,6 +167,8 fr: | |||||
167 | notice_account_wrong_password: Mot de passe incorrect |
|
167 | notice_account_wrong_password: Mot de passe incorrect | |
168 | notice_account_register_done: Un message contenant les instructions pour activer votre compte vous a Γ©tΓ© envoyΓ©. |
|
168 | notice_account_register_done: Un message contenant les instructions pour activer votre compte vous a Γ©tΓ© envoyΓ©. | |
169 | notice_account_unknown_email: Aucun compte ne correspond Γ cette adresse. |
|
169 | notice_account_unknown_email: Aucun compte ne correspond Γ cette adresse. | |
|
170 | notice_account_not_activated_yet: Vous n'avez pas encore activΓ© votre compte. Si vous voulez recevoir un nouveau message d'activation, veuillez <a href="%{url}">cliquer sur ce lien</a>. | |||
|
171 | notice_account_locked: Votre compte est verrouillΓ©. | |||
170 | notice_can_t_change_password: Ce compte utilise une authentification externe. Impossible de changer le mot de passe. |
|
172 | notice_can_t_change_password: Ce compte utilise une authentification externe. Impossible de changer le mot de passe. | |
171 | notice_account_lost_email_sent: Un message contenant les instructions pour choisir un nouveau mot de passe vous a Γ©tΓ© envoyΓ©. |
|
173 | notice_account_lost_email_sent: Un message contenant les instructions pour choisir un nouveau mot de passe vous a Γ©tΓ© envoyΓ©. | |
172 | notice_account_activated: Votre compte a Γ©tΓ© activΓ©. Vous pouvez Γ prΓ©sent vous connecter. |
|
174 | notice_account_activated: Votre compte a Γ©tΓ© activΓ©. Vous pouvez Γ prΓ©sent vous connecter. |
@@ -23,6 +23,7 RedmineApp::Application.routes.draw do | |||||
23 | match 'account/register', :to => 'account#register', :via => [:get, :post], :as => 'register' |
|
23 | match 'account/register', :to => 'account#register', :via => [:get, :post], :as => 'register' | |
24 | match 'account/lost_password', :to => 'account#lost_password', :via => [:get, :post], :as => 'lost_password' |
|
24 | match 'account/lost_password', :to => 'account#lost_password', :via => [:get, :post], :as => 'lost_password' | |
25 | match 'account/activate', :to => 'account#activate', :via => :get |
|
25 | match 'account/activate', :to => 'account#activate', :via => :get | |
|
26 | get 'account/activation_email', :to => 'account#activation_email', :as => 'activation_email' | |||
26 |
|
27 | |||
27 | match '/news/preview', :controller => 'previews', :action => 'news', :as => 'preview_news', :via => [:get, :post, :put] |
|
28 | match '/news/preview', :controller => 'previews', :action => 'news', :as => 'preview_news', :via => [:get, :post, :put] | |
28 | match '/issues/preview/new/:project_id', :to => 'previews#issue', :as => 'preview_new_issue', :via => [:get, :post, :put] |
|
29 | match '/issues/preview/new/:project_id', :to => 'previews#issue', :as => 'preview_new_issue', :via => [:get, :post, :put] |
@@ -63,6 +63,36 class AccountControllerTest < ActionController::TestCase | |||||
63 | assert_select 'input[name=password][value]', 0 |
|
63 | assert_select 'input[name=password][value]', 0 | |
64 | end |
|
64 | end | |
65 |
|
65 | |||
|
66 | def test_login_with_locked_account_should_fail | |||
|
67 | User.find(2).update_attribute :status, User::STATUS_LOCKED | |||
|
68 | ||||
|
69 | post :login, :username => 'jsmith', :password => 'jsmith' | |||
|
70 | assert_redirected_to '/login' | |||
|
71 | assert_include 'locked', flash[:error] | |||
|
72 | assert_nil @request.session[:user_id] | |||
|
73 | end | |||
|
74 | ||||
|
75 | def test_login_as_registered_user_with_manual_activation_should_inform_user | |||
|
76 | User.find(2).update_attribute :status, User::STATUS_REGISTERED | |||
|
77 | ||||
|
78 | with_settings :self_registration => '2', :default_language => 'en' do | |||
|
79 | post :login, :username => 'jsmith', :password => 'jsmith' | |||
|
80 | assert_redirected_to '/login' | |||
|
81 | assert_include 'pending administrator approval', flash[:error] | |||
|
82 | end | |||
|
83 | end | |||
|
84 | ||||
|
85 | def test_login_as_registered_user_with_email_activation_should_propose_new_activation_email | |||
|
86 | User.find(2).update_attribute :status, User::STATUS_REGISTERED | |||
|
87 | ||||
|
88 | with_settings :self_registration => '1', :default_language => 'en' do | |||
|
89 | post :login, :username => 'jsmith', :password => 'jsmith' | |||
|
90 | assert_redirected_to '/login' | |||
|
91 | assert_equal 2, @request.session[:registered_user_id] | |||
|
92 | assert_include 'new activation email', flash[:error] | |||
|
93 | end | |||
|
94 | end | |||
|
95 | ||||
66 | def test_login_should_rescue_auth_source_exception |
|
96 | def test_login_should_rescue_auth_source_exception | |
67 | source = AuthSource.create!(:name => 'Test') |
|
97 | source = AuthSource.create!(:name => 'Test') | |
68 | User.find(2).update_attribute :auth_source_id, source.id |
|
98 | User.find(2).update_attribute :auth_source_id, source.id | |
@@ -217,7 +247,7 class AccountControllerTest < ActionController::TestCase | |||||
217 |
|
247 | |||
218 | assert_no_difference 'Token.count' do |
|
248 | assert_no_difference 'Token.count' do | |
219 | post :lost_password, :mail => 'JSmith@somenet.foo' |
|
249 | post :lost_password, :mail => 'JSmith@somenet.foo' | |
220 | assert_response :success |
|
250 | assert_redirected_to '/account/lost_password' | |
221 | end |
|
251 | end | |
222 | end |
|
252 | end | |
223 |
|
253 | |||
@@ -274,4 +304,16 class AccountControllerTest < ActionController::TestCase | |||||
274 | post :lost_password, :token => "abcdef", :new_password => 'newpass', :new_password_confirmation => 'newpass' |
|
304 | post :lost_password, :token => "abcdef", :new_password => 'newpass', :new_password_confirmation => 'newpass' | |
275 | assert_redirected_to '/' |
|
305 | assert_redirected_to '/' | |
276 | end |
|
306 | end | |
|
307 | ||||
|
308 | def test_activation_email_should_send_an_activation_email | |||
|
309 | User.find(2).update_attribute :status, User::STATUS_REGISTERED | |||
|
310 | @request.session[:registered_user_id] = 2 | |||
|
311 | ||||
|
312 | with_settings :self_registration => '1' do | |||
|
313 | assert_difference 'ActionMailer::Base.deliveries.size' do | |||
|
314 | get :activation_email | |||
|
315 | assert_redirected_to '/login' | |||
|
316 | end | |||
|
317 | end | |||
|
318 | end | |||
277 | end |
|
319 | end |
@@ -221,4 +221,49 class AccountTest < ActionController::IntegrationTest | |||||
221 | assert_equal 66, user.auth_source_id |
|
221 | assert_equal 66, user.auth_source_id | |
222 | assert user.hashed_password.blank? |
|
222 | assert user.hashed_password.blank? | |
223 | end |
|
223 | end | |
|
224 | ||||
|
225 | def test_registered_user_should_be_able_to_get_a_new_activation_email | |||
|
226 | Token.delete_all | |||
|
227 | ||||
|
228 | with_settings :self_registration => '1', :default_language => 'en' do | |||
|
229 | # register a new account | |||
|
230 | assert_difference 'User.count' do | |||
|
231 | assert_difference 'Token.count' do | |||
|
232 | post 'account/register', | |||
|
233 | :user => {:login => "newuser", :language => "en", | |||
|
234 | :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar", | |||
|
235 | :password => "newpass123", :password_confirmation => "newpass123"} | |||
|
236 | end | |||
|
237 | end | |||
|
238 | user = User.order('id desc').first | |||
|
239 | assert_equal User::STATUS_REGISTERED, user.status | |||
|
240 | reset! | |||
|
241 | ||||
|
242 | # try to use "lost password" | |||
|
243 | assert_no_difference 'ActionMailer::Base.deliveries.size' do | |||
|
244 | post '/account/lost_password', :mail => 'newuser@foo.bar' | |||
|
245 | end | |||
|
246 | assert_redirected_to '/account/lost_password' | |||
|
247 | follow_redirect! | |||
|
248 | assert_response :success | |||
|
249 | assert_select 'div.flash', :text => /new activation email/ | |||
|
250 | assert_select 'div.flash a[href=/account/activation_email]' | |||
|
251 | ||||
|
252 | # request a new action activation email | |||
|
253 | assert_difference 'ActionMailer::Base.deliveries.size' do | |||
|
254 | get '/account/activation_email' | |||
|
255 | end | |||
|
256 | assert_redirected_to '/login' | |||
|
257 | token = Token.order('id desc').first | |||
|
258 | activation_path = "/account/activate?token=#{token.value}" | |||
|
259 | assert_include activation_path, mail_body(ActionMailer::Base.deliveries.last) | |||
|
260 | ||||
|
261 | # activate the account | |||
|
262 | get activation_path | |||
|
263 | assert_redirected_to '/login' | |||
|
264 | ||||
|
265 | post '/login', :username => 'newuser', :password => 'newpass123' | |||
|
266 | assert_redirected_to '/my/page' | |||
|
267 | end | |||
|
268 | end | |||
224 | end |
|
269 | end |
General Comments 0
You need to be logged in to leave comments.
Login now