@@ -204,6 +204,7 class ApplicationController < ActionController::Base | |||||
204 | def check_password_change |
|
204 | def check_password_change | |
205 | if session[:pwd] |
|
205 | if session[:pwd] | |
206 | if User.current.must_change_password? |
|
206 | if User.current.must_change_password? | |
|
207 | flash[:error] = l(:error_password_expired) | |||
207 | redirect_to my_password_path |
|
208 | redirect_to my_password_path | |
208 | else |
|
209 | else | |
209 | session.delete(:pwd) |
|
210 | session.delete(:pwd) |
@@ -323,8 +323,19 class User < Principal | |||||
323 | return auth_source.allow_password_changes? |
|
323 | return auth_source.allow_password_changes? | |
324 | end |
|
324 | end | |
325 |
|
325 | |||
|
326 | def password_expired? | |||
|
327 | changed_on = self.passwd_changed_on || Time.at(0) | |||
|
328 | period = Setting.password_max_age.to_i | |||
|
329 | ||||
|
330 | if period.zero? | |||
|
331 | false | |||
|
332 | else | |||
|
333 | changed_on < period.days.ago | |||
|
334 | end | |||
|
335 | end | |||
|
336 | ||||
326 | def must_change_password? |
|
337 | def must_change_password? | |
327 | must_change_passwd? && change_password_allowed? |
|
338 | (must_change_passwd? || password_expired?) && change_password_allowed? | |
328 | end |
|
339 | end | |
329 |
|
340 | |||
330 | def generate_password? |
|
341 | def generate_password? |
@@ -17,7 +17,7 | |||||
17 | <%= submit_tag l(:button_apply) %> |
|
17 | <%= submit_tag l(:button_apply) %> | |
18 | <% end %> |
|
18 | <% end %> | |
19 |
|
19 | |||
20 | <% unless @user.must_change_passwd? %> |
|
20 | <% unless @user.must_change_passwd? || @user.password_expired? %> | |
21 | <% content_for :sidebar do %> |
|
21 | <% content_for :sidebar do %> | |
22 | <%= render :partial => 'sidebar' %> |
|
22 | <%= render :partial => 'sidebar' %> | |
23 | <% end %> |
|
23 | <% end %> |
@@ -14,6 +14,10 | |||||
14 |
|
14 | |||
15 | <p><%= setting_text_field :password_min_length, :size => 6 %></p> |
|
15 | <p><%= setting_text_field :password_min_length, :size => 6 %></p> | |
16 |
|
16 | |||
|
17 | <p> | |||
|
18 | <%= setting_select :password_max_age, [[l(:label_disabled), 0]] + [7, 30, 60, 90, 180, 365].collect{|days| [l('datetime.distance_in_words.x_days', :count => days), days.to_s]} %> | |||
|
19 | </p> | |||
|
20 | ||||
17 | <p><%= setting_check_box :lost_password, :label => :label_password_lost %></p> |
|
21 | <p><%= setting_check_box :lost_password, :label => :label_password_lost %></p> | |
18 |
|
22 | |||
19 | <p><%= setting_text_field :max_additional_emails, :size => 6 %></p> |
|
23 | <p><%= setting_text_field :max_additional_emails, :size => 6 %></p> |
@@ -1026,6 +1026,7 de: | |||||
1026 | setting_non_working_week_days: Arbeitsfreie Tage |
|
1026 | setting_non_working_week_days: Arbeitsfreie Tage | |
1027 | setting_openid: Erlaube OpenID-Anmeldung und -Registrierung |
|
1027 | setting_openid: Erlaube OpenID-Anmeldung und -Registrierung | |
1028 | setting_password_min_length: MindestlΓ€nge des Kennworts |
|
1028 | setting_password_min_length: MindestlΓ€nge des Kennworts | |
|
1029 | setting_password_max_age: Erzwinge Passwortwechsel nach | |||
1029 | setting_per_page_options: Objekte pro Seite |
|
1030 | setting_per_page_options: Objekte pro Seite | |
1030 | setting_plain_text_mail: Nur reinen Text (kein HTML) senden |
|
1031 | setting_plain_text_mail: Nur reinen Text (kein HTML) senden | |
1031 | setting_protocol: Protokoll |
|
1032 | setting_protocol: Protokoll |
@@ -204,6 +204,7 en: | |||||
204 | error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})" |
|
204 | error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})" | |
205 | error_session_expired: "Your session has expired. Please login again." |
|
205 | error_session_expired: "Your session has expired. Please login again." | |
206 | warning_attachments_not_saved: "%{count} file(s) could not be saved." |
|
206 | warning_attachments_not_saved: "%{count} file(s) could not be saved." | |
|
207 | error_password_expired: "Your password has expired or the administrator requires you to change it." | |||
207 |
|
208 | |||
208 | mail_subject_lost_password: "Your %{value} password" |
|
209 | mail_subject_lost_password: "Your %{value} password" | |
209 | mail_body_lost_password: 'To change your password, click on the following link:' |
|
210 | mail_body_lost_password: 'To change your password, click on the following link:' | |
@@ -386,6 +387,7 en: | |||||
386 | setting_file_max_size_displayed: Maximum size of text files displayed inline |
|
387 | setting_file_max_size_displayed: Maximum size of text files displayed inline | |
387 | setting_repository_log_display_limit: Maximum number of revisions displayed on file log |
|
388 | setting_repository_log_display_limit: Maximum number of revisions displayed on file log | |
388 | setting_openid: Allow OpenID login and registration |
|
389 | setting_openid: Allow OpenID login and registration | |
|
390 | setting_password_max_age: Require password change after | |||
389 | setting_password_min_length: Minimum password length |
|
391 | setting_password_min_length: Minimum password length | |
390 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
392 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project | |
391 | setting_default_projects_modules: Default enabled modules for new projects |
|
393 | setting_default_projects_modules: Default enabled modules for new projects |
@@ -224,6 +224,7 fr: | |||||
224 | error_attachment_too_big: Ce fichier ne peut pas Γͺtre attachΓ© car il excΓ¨de la taille maximale autorisΓ©e (%{max_size}) |
|
224 | error_attachment_too_big: Ce fichier ne peut pas Γͺtre attachΓ© car il excΓ¨de la taille maximale autorisΓ©e (%{max_size}) | |
225 | error_session_expired: "Votre session a expirΓ©. Veuillez vous reconnecter." |
|
225 | error_session_expired: "Votre session a expirΓ©. Veuillez vous reconnecter." | |
226 | warning_attachments_not_saved: "%{count} fichier(s) n'ont pas pu Γͺtre sauvegardΓ©s." |
|
226 | warning_attachments_not_saved: "%{count} fichier(s) n'ont pas pu Γͺtre sauvegardΓ©s." | |
|
227 | error_password_expired: "Votre mot de passe a expirΓ© ou nΓ©cessite d'Γͺtre changΓ©." | |||
227 |
|
228 | |||
228 | mail_subject_lost_password: "Votre mot de passe %{value}" |
|
229 | mail_subject_lost_password: "Votre mot de passe %{value}" | |
229 | mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :' |
|
230 | mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :' | |
@@ -406,6 +407,7 fr: | |||||
406 | setting_file_max_size_displayed: Taille maximum des fichiers texte affichΓ©s en ligne |
|
407 | setting_file_max_size_displayed: Taille maximum des fichiers texte affichΓ©s en ligne | |
407 | setting_repository_log_display_limit: "Nombre maximum de rΓ©visions affichΓ©es sur l'historique d'un fichier" |
|
408 | setting_repository_log_display_limit: "Nombre maximum de rΓ©visions affichΓ©es sur l'historique d'un fichier" | |
408 | setting_openid: "Autoriser l'authentification et l'enregistrement OpenID" |
|
409 | setting_openid: "Autoriser l'authentification et l'enregistrement OpenID" | |
|
410 | setting_password_max_age: Expiration des mots de passe après | |||
409 | setting_password_min_length: Longueur minimum des mots de passe |
|
411 | setting_password_min_length: Longueur minimum des mots de passe | |
410 | setting_new_project_user_role_id: RΓ΄le donnΓ© Γ un utilisateur non-administrateur qui crΓ©e un projet |
|
412 | setting_new_project_user_role_id: RΓ΄le donnΓ© Γ un utilisateur non-administrateur qui crΓ©e un projet | |
411 | setting_default_projects_modules: Modules activΓ©s par dΓ©faut pour les nouveaux projets |
|
413 | setting_default_projects_modules: Modules activΓ©s par dΓ©faut pour les nouveaux projets |
@@ -36,6 +36,10 unsubscribe: | |||||
36 | password_min_length: |
|
36 | password_min_length: | |
37 | format: int |
|
37 | format: int | |
38 | default: 8 |
|
38 | default: 8 | |
|
39 | # Maximum password age in days | |||
|
40 | password_max_age: | |||
|
41 | format: int | |||
|
42 | default: 0 | |||
39 | # Maximum number of additional email addresses per user |
|
43 | # Maximum number of additional email addresses per user | |
40 | max_additional_emails: |
|
44 | max_additional_emails: | |
41 | format: int |
|
45 | format: int |
@@ -150,6 +150,40 class AccountTest < Redmine::IntegrationTest | |||||
150 | assert_equal false, User.find_by_login('jsmith').must_change_passwd? |
|
150 | assert_equal false, User.find_by_login('jsmith').must_change_passwd? | |
151 | end |
|
151 | end | |
152 |
|
152 | |||
|
153 | def test_user_with_expired_password_should_be_forced_to_change_its_password | |||
|
154 | User.find_by_login('jsmith').update_attribute :passwd_changed_on, 14.days.ago | |||
|
155 | ||||
|
156 | with_settings :password_max_age => 7 do | |||
|
157 | post '/login', :username => 'jsmith', :password => 'jsmith' | |||
|
158 | assert_redirected_to '/my/page' | |||
|
159 | follow_redirect! | |||
|
160 | assert_redirected_to '/my/password' | |||
|
161 | ||||
|
162 | get '/issues' | |||
|
163 | assert_redirected_to '/my/password' | |||
|
164 | end | |||
|
165 | end | |||
|
166 | ||||
|
167 | def test_user_with_expired_password_should_be_able_to_change_its_password | |||
|
168 | User.find_by_login('jsmith').update_attribute :passwd_changed_on, 14.days.ago | |||
|
169 | ||||
|
170 | with_settings :password_max_age => 7 do | |||
|
171 | post '/login', :username => 'jsmith', :password => 'jsmith' | |||
|
172 | assert_redirected_to '/my/page' | |||
|
173 | follow_redirect! | |||
|
174 | assert_redirected_to '/my/password' | |||
|
175 | follow_redirect! | |||
|
176 | assert_response :success | |||
|
177 | post '/my/password', :password => 'jsmith', :new_password => 'newpassword', :new_password_confirmation => 'newpassword' | |||
|
178 | assert_redirected_to '/my/account' | |||
|
179 | follow_redirect! | |||
|
180 | assert_response :success | |||
|
181 | ||||
|
182 | assert_equal false, User.find_by_login('jsmith').must_change_passwd? | |||
|
183 | end | |||
|
184 | ||||
|
185 | end | |||
|
186 | ||||
153 | def test_register_with_automatic_activation |
|
187 | def test_register_with_automatic_activation | |
154 | Setting.self_registration = '3' |
|
188 | Setting.self_registration = '3' | |
155 |
|
189 |
General Comments 0
You need to be logged in to leave comments.
Login now