@@ -204,6 +204,7 class ApplicationController < ActionController::Base | |||
|
204 | 204 | def check_password_change |
|
205 | 205 | if session[:pwd] |
|
206 | 206 | if User.current.must_change_password? |
|
207 | flash[:error] = l(:error_password_expired) | |
|
207 | 208 | redirect_to my_password_path |
|
208 | 209 | else |
|
209 | 210 | session.delete(:pwd) |
@@ -323,8 +323,19 class User < Principal | |||
|
323 | 323 | return auth_source.allow_password_changes? |
|
324 | 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 | 337 | def must_change_password? |
|
327 | must_change_passwd? && change_password_allowed? | |
|
338 | (must_change_passwd? || password_expired?) && change_password_allowed? | |
|
328 | 339 | end |
|
329 | 340 | |
|
330 | 341 | def generate_password? |
@@ -17,7 +17,7 | |||
|
17 | 17 | <%= submit_tag l(:button_apply) %> |
|
18 | 18 | <% end %> |
|
19 | 19 | |
|
20 | <% unless @user.must_change_passwd? %> | |
|
20 | <% unless @user.must_change_passwd? || @user.password_expired? %> | |
|
21 | 21 | <% content_for :sidebar do %> |
|
22 | 22 | <%= render :partial => 'sidebar' %> |
|
23 | 23 | <% end %> |
@@ -14,6 +14,10 | |||
|
14 | 14 | |
|
15 | 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 | 21 | <p><%= setting_check_box :lost_password, :label => :label_password_lost %></p> |
|
18 | 22 | |
|
19 | 23 | <p><%= setting_text_field :max_additional_emails, :size => 6 %></p> |
@@ -1026,6 +1026,7 de: | |||
|
1026 | 1026 | setting_non_working_week_days: Arbeitsfreie Tage |
|
1027 | 1027 | setting_openid: Erlaube OpenID-Anmeldung und -Registrierung |
|
1028 | 1028 | setting_password_min_length: Mindestlänge des Kennworts |
|
1029 | setting_password_max_age: Erzwinge Passwortwechsel nach | |
|
1029 | 1030 | setting_per_page_options: Objekte pro Seite |
|
1030 | 1031 | setting_plain_text_mail: Nur reinen Text (kein HTML) senden |
|
1031 | 1032 | setting_protocol: Protokoll |
@@ -204,6 +204,7 en: | |||
|
204 | 204 | error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})" |
|
205 | 205 | error_session_expired: "Your session has expired. Please login again." |
|
206 | 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 | 209 | mail_subject_lost_password: "Your %{value} password" |
|
209 | 210 | mail_body_lost_password: 'To change your password, click on the following link:' |
@@ -386,6 +387,7 en: | |||
|
386 | 387 | setting_file_max_size_displayed: Maximum size of text files displayed inline |
|
387 | 388 | setting_repository_log_display_limit: Maximum number of revisions displayed on file log |
|
388 | 389 | setting_openid: Allow OpenID login and registration |
|
390 | setting_password_max_age: Require password change after | |
|
389 | 391 | setting_password_min_length: Minimum password length |
|
390 | 392 | setting_new_project_user_role_id: Role given to a non-admin user who creates a project |
|
391 | 393 | setting_default_projects_modules: Default enabled modules for new projects |
@@ -224,6 +224,7 fr: | |||
|
224 | 224 | error_attachment_too_big: Ce fichier ne peut pas être attaché car il excède la taille maximale autorisée (%{max_size}) |
|
225 | 225 | error_session_expired: "Votre session a expiré. Veuillez vous reconnecter." |
|
226 | 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 | 229 | mail_subject_lost_password: "Votre mot de passe %{value}" |
|
229 | 230 | mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :' |
@@ -406,6 +407,7 fr: | |||
|
406 | 407 | setting_file_max_size_displayed: Taille maximum des fichiers texte affichés en ligne |
|
407 | 408 | setting_repository_log_display_limit: "Nombre maximum de révisions affichées sur l'historique d'un fichier" |
|
408 | 409 | setting_openid: "Autoriser l'authentification et l'enregistrement OpenID" |
|
410 | setting_password_max_age: Expiration des mots de passe après | |
|
409 | 411 | setting_password_min_length: Longueur minimum des mots de passe |
|
410 | 412 | setting_new_project_user_role_id: Rôle donné à un utilisateur non-administrateur qui crée un projet |
|
411 | 413 | setting_default_projects_modules: Modules activés par défaut pour les nouveaux projets |
@@ -36,6 +36,10 unsubscribe: | |||
|
36 | 36 | password_min_length: |
|
37 | 37 | format: int |
|
38 | 38 | default: 8 |
|
39 | # Maximum password age in days | |
|
40 | password_max_age: | |
|
41 | format: int | |
|
42 | default: 0 | |
|
39 | 43 | # Maximum number of additional email addresses per user |
|
40 | 44 | max_additional_emails: |
|
41 | 45 | format: int |
@@ -150,6 +150,40 class AccountTest < Redmine::IntegrationTest | |||
|
150 | 150 | assert_equal false, User.find_by_login('jsmith').must_change_passwd? |
|
151 | 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 | 187 | def test_register_with_automatic_activation |
|
154 | 188 | Setting.self_registration = '3' |
|
155 | 189 |
General Comments 0
You need to be logged in to leave comments.
Login now