Invalidate existing sessions when changing email or password
As we don't have any way to actually find the active sessions for an account we instead store a fingerprint in the session, and refuse to use any session with a different fingerprint.
This commit is contained in:
parent
c694c78c9a
commit
7db541d697
3 changed files with 21 additions and 1 deletions
|
@ -23,7 +23,11 @@ class ApplicationController < ActionController::Base
|
|||
if session[:user]
|
||||
self.current_user = User.where(:id => session[:user]).where("status IN ('active', 'confirmed', 'suspended')").first
|
||||
|
||||
if current_user.status == "suspended"
|
||||
if session[:fingerprint] &&
|
||||
session[:fingerprint] != current_user.fingerprint
|
||||
reset_session
|
||||
self.current_user = nil
|
||||
elsif current_user.status == "suspended"
|
||||
session.delete(:user)
|
||||
session_expires_automatically
|
||||
|
||||
|
@ -42,6 +46,8 @@ class ApplicationController < ActionController::Base
|
|||
elsif session[:token]
|
||||
session[:user] = current_user.id if self.current_user = User.authenticate(:token => session[:token])
|
||||
end
|
||||
|
||||
session[:fingerprint] = current_user.fingerprint if current_user && session[:fingerprint].nil?
|
||||
rescue StandardError => e
|
||||
logger.info("Exception authorizing user: #{e}")
|
||||
reset_session
|
||||
|
|
|
@ -183,6 +183,7 @@ class UsersController < ApplicationController
|
|||
|
||||
if current_user.save
|
||||
token.destroy
|
||||
session[:fingerprint] = current_user.fingerprint
|
||||
flash[:notice] = t "users.reset_password.flash changed"
|
||||
successful_login(current_user)
|
||||
end
|
||||
|
@ -323,6 +324,7 @@ class UsersController < ApplicationController
|
|||
token.destroy
|
||||
|
||||
session[:user] = user.id
|
||||
session[:fingerprint] = user.fingerprint
|
||||
|
||||
redirect_to referer || welcome_path
|
||||
end
|
||||
|
@ -368,6 +370,7 @@ class UsersController < ApplicationController
|
|||
end
|
||||
current_user.tokens.delete_all
|
||||
session[:user] = current_user.id
|
||||
session[:fingerprint] = current_user.fingerprint
|
||||
redirect_to :action => "account", :display_name => current_user.display_name
|
||||
elsif token
|
||||
flash[:error] = t "users.confirm_email.failure"
|
||||
|
@ -552,6 +555,7 @@ class UsersController < ApplicationController
|
|||
# process a successful login
|
||||
def successful_login(user, referer = nil)
|
||||
session[:user] = user.id
|
||||
session[:fingerprint] = user.fingerprint
|
||||
session_expires_after 28.days if session[:remember_me]
|
||||
|
||||
target = referer || session[:referer] || url_for(:controller => :site, :action => :index)
|
||||
|
@ -642,6 +646,8 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
if user.save
|
||||
session[:fingerprint] = user.fingerprint
|
||||
|
||||
set_locale(true)
|
||||
|
||||
if user.new_email.blank? || user.new_email == user.email
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#
|
||||
|
||||
class User < ApplicationRecord
|
||||
require "digest"
|
||||
require "xml/libxml"
|
||||
|
||||
has_many :traces, -> { where(:visible => true) }
|
||||
|
@ -306,6 +307,13 @@ class User < ApplicationRecord
|
|||
ClientApplication.find_by(:key => application_key).access_token_for_user(self)
|
||||
end
|
||||
|
||||
def fingerprint
|
||||
digest = Digest::SHA256.new
|
||||
digest.update(email)
|
||||
digest.update(pass_crypt)
|
||||
digest.hexdigest
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_defaults
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue