mirror of
https://github.com/meineerde/redmine.git
synced 2025-12-31 04:39:40 +00:00
Expire other sessions on password change (#17796).
Contributed by Jan Schulz-Hofen. git-svn-id: http://svn.redmine.org/redmine/trunk@13412 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
e632a79d59
commit
b519aba63e
@ -49,7 +49,7 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
end
|
||||
|
||||
before_filter :session_expiration, :user_setup, :check_if_login_required, :check_password_change, :set_localization
|
||||
before_filter :session_expiration, :user_setup, :force_logout_if_password_changed, :check_if_login_required, :check_password_change, :set_localization
|
||||
|
||||
rescue_from ::Unauthorized, :with => :deny_access
|
||||
rescue_from ::ActionView::MissingTemplate, :with => :missing_template
|
||||
@ -145,6 +145,18 @@ class ApplicationController < ActionController::Base
|
||||
user
|
||||
end
|
||||
|
||||
def force_logout_if_password_changed
|
||||
passwd_changed_on = User.current.passwd_changed_on || Time.at(0)
|
||||
# Make sure we force logout only for web browser sessions, not API calls
|
||||
# if the password was changed after the session creation.
|
||||
if session[:user_id] && passwd_changed_on.utc.to_i > session[:ctime].to_i
|
||||
reset_session
|
||||
set_localization
|
||||
flash[:error] = l(:error_session_expired)
|
||||
redirect_to signin_url
|
||||
end
|
||||
end
|
||||
|
||||
def autologin_cookie_name
|
||||
Redmine::Configuration['autologin_cookie_name'].presence || 'autologin'
|
||||
end
|
||||
|
||||
@ -100,6 +100,9 @@ class MyController < ApplicationController
|
||||
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
@user.must_change_passwd = false
|
||||
if @user.save
|
||||
# Reset the session creation time to not log out this session on next
|
||||
# request due to ApplicationController#force_logout_if_password_changed
|
||||
session[:ctime] = Time.now.utc.to_i
|
||||
flash[:notice] = l(:notice_account_password_updated)
|
||||
redirect_to my_account_path
|
||||
end
|
||||
|
||||
@ -279,6 +279,7 @@ class User < Principal
|
||||
def salt_password(clear_password)
|
||||
self.salt = User.generate_salt
|
||||
self.hashed_password = User.hash_password("#{salt}#{User.hash_password clear_password}")
|
||||
self.passwd_changed_on = Time.now
|
||||
end
|
||||
|
||||
# Does the backend storage allow this user to change their password?
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
class AddPasswordChangedAtToUser < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :passwd_changed_on, :datetime
|
||||
end
|
||||
end
|
||||
@ -185,6 +185,18 @@ class MyControllerTest < ActionController::TestCase
|
||||
assert User.try_to_login('jsmith', 'secret123')
|
||||
end
|
||||
|
||||
def test_change_password_kills_other_sessions
|
||||
@request.session[:ctime] = (Time.now - 30.minutes).utc.to_i
|
||||
|
||||
jsmith = User.find(2)
|
||||
jsmith.passwd_changed_on = Time.now
|
||||
jsmith.save!
|
||||
|
||||
get 'account'
|
||||
assert_response 302
|
||||
assert flash[:error].match(/Your session has expired/)
|
||||
end
|
||||
|
||||
def test_change_password_should_redirect_if_user_cannot_change_its_password
|
||||
User.find(2).update_attribute(:auth_source_id, 1)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user