def check_password_change
if session[:pwd]
if User.current.must_change_password?
+ flash[:error] = l(:error_password_expired)
redirect_to my_password_path
else
session.delete(:pwd)
return auth_source.allow_password_changes?
end
+ def password_expired?
+ changed_on = self.passwd_changed_on || Time.at(0)
+ period = Setting.password_max_age.to_i
+
+ if period.zero?
+ false
+ else
+ changed_on < period.days.ago
+ end
+ end
+
def must_change_password?
- must_change_passwd? && change_password_allowed?
+ (must_change_passwd? || password_expired?) && change_password_allowed?
end
def generate_password?
<%= submit_tag l(:button_apply) %>
<% end %>
-<% unless @user.must_change_passwd? %>
+<% unless @user.must_change_passwd? || @user.password_expired? %>
<% content_for :sidebar do %>
<%= render :partial => 'sidebar' %>
<% end %>
<p><%= setting_text_field :password_min_length, :size => 6 %></p>
+<p>
+ <%= 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]} %>
+</p>
+
<p><%= setting_check_box :lost_password, :label => :label_password_lost %></p>
<p><%= setting_text_field :max_additional_emails, :size => 6 %></p>
setting_non_working_week_days: Arbeitsfreie Tage
setting_openid: Erlaube OpenID-Anmeldung und -Registrierung
setting_password_min_length: Mindestlänge des Kennworts
+ setting_password_max_age: Erzwinge Passwortwechsel nach
setting_per_page_options: Objekte pro Seite
setting_plain_text_mail: Nur reinen Text (kein HTML) senden
setting_protocol: Protokoll
error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})"
error_session_expired: "Your session has expired. Please login again."
warning_attachments_not_saved: "%{count} file(s) could not be saved."
+ error_password_expired: "Your password has expired or the administrator requires you to change it."
mail_subject_lost_password: "Your %{value} password"
mail_body_lost_password: 'To change your password, click on the following link:'
setting_file_max_size_displayed: Maximum size of text files displayed inline
setting_repository_log_display_limit: Maximum number of revisions displayed on file log
setting_openid: Allow OpenID login and registration
+ setting_password_max_age: Require password change after
setting_password_min_length: Minimum password length
setting_new_project_user_role_id: Role given to a non-admin user who creates a project
setting_default_projects_modules: Default enabled modules for new projects
error_attachment_too_big: Ce fichier ne peut pas être attaché car il excède la taille maximale autorisée (%{max_size})
error_session_expired: "Votre session a expiré. Veuillez vous reconnecter."
warning_attachments_not_saved: "%{count} fichier(s) n'ont pas pu être sauvegardés."
+ error_password_expired: "Votre mot de passe a expiré ou nécessite d'être changé."
mail_subject_lost_password: "Votre mot de passe %{value}"
mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :'
setting_file_max_size_displayed: Taille maximum des fichiers texte affichés en ligne
setting_repository_log_display_limit: "Nombre maximum de révisions affichées sur l'historique d'un fichier"
setting_openid: "Autoriser l'authentification et l'enregistrement OpenID"
+ setting_password_max_age: Expiration des mots de passe après
setting_password_min_length: Longueur minimum des mots de passe
setting_new_project_user_role_id: Rôle donné à un utilisateur non-administrateur qui crée un projet
setting_default_projects_modules: Modules activés par défaut pour les nouveaux projets
password_min_length:
format: int
default: 8
+# Maximum password age in days
+password_max_age:
+ format: int
+ default: 0
# Maximum number of additional email addresses per user
max_additional_emails:
format: int
assert_equal false, User.find_by_login('jsmith').must_change_passwd?
end
+ def test_user_with_expired_password_should_be_forced_to_change_its_password
+ User.find_by_login('jsmith').update_attribute :passwd_changed_on, 14.days.ago
+
+ with_settings :password_max_age => 7 do
+ post '/login', :username => 'jsmith', :password => 'jsmith'
+ assert_redirected_to '/my/page'
+ follow_redirect!
+ assert_redirected_to '/my/password'
+
+ get '/issues'
+ assert_redirected_to '/my/password'
+ end
+ end
+
+ def test_user_with_expired_password_should_be_able_to_change_its_password
+ User.find_by_login('jsmith').update_attribute :passwd_changed_on, 14.days.ago
+
+ with_settings :password_max_age => 7 do
+ post '/login', :username => 'jsmith', :password => 'jsmith'
+ assert_redirected_to '/my/page'
+ follow_redirect!
+ assert_redirected_to '/my/password'
+ follow_redirect!
+ assert_response :success
+ post '/my/password', :password => 'jsmith', :new_password => 'newpassword', :new_password_confirmation => 'newpassword'
+ assert_redirected_to '/my/account'
+ follow_redirect!
+ assert_response :success
+
+ assert_equal false, User.find_by_login('jsmith').must_change_passwd?
+ end
+
+ end
+
def test_register_with_automatic_activation
Setting.self_registration = '3'