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]
|
if session[:user]
|
||||||
self.current_user = User.where(:id => session[:user]).where("status IN ('active', 'confirmed', 'suspended')").first
|
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.delete(:user)
|
||||||
session_expires_automatically
|
session_expires_automatically
|
||||||
|
|
||||||
|
@ -42,6 +46,8 @@ class ApplicationController < ActionController::Base
|
||||||
elsif session[:token]
|
elsif session[:token]
|
||||||
session[:user] = current_user.id if self.current_user = User.authenticate(:token => session[:token])
|
session[:user] = current_user.id if self.current_user = User.authenticate(:token => session[:token])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
session[:fingerprint] = current_user.fingerprint if current_user && session[:fingerprint].nil?
|
||||||
rescue StandardError => e
|
rescue StandardError => e
|
||||||
logger.info("Exception authorizing user: #{e}")
|
logger.info("Exception authorizing user: #{e}")
|
||||||
reset_session
|
reset_session
|
||||||
|
|
|
@ -183,6 +183,7 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
if current_user.save
|
if current_user.save
|
||||||
token.destroy
|
token.destroy
|
||||||
|
session[:fingerprint] = current_user.fingerprint
|
||||||
flash[:notice] = t "users.reset_password.flash changed"
|
flash[:notice] = t "users.reset_password.flash changed"
|
||||||
successful_login(current_user)
|
successful_login(current_user)
|
||||||
end
|
end
|
||||||
|
@ -323,6 +324,7 @@ class UsersController < ApplicationController
|
||||||
token.destroy
|
token.destroy
|
||||||
|
|
||||||
session[:user] = user.id
|
session[:user] = user.id
|
||||||
|
session[:fingerprint] = user.fingerprint
|
||||||
|
|
||||||
redirect_to referer || welcome_path
|
redirect_to referer || welcome_path
|
||||||
end
|
end
|
||||||
|
@ -368,6 +370,7 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
current_user.tokens.delete_all
|
current_user.tokens.delete_all
|
||||||
session[:user] = current_user.id
|
session[:user] = current_user.id
|
||||||
|
session[:fingerprint] = current_user.fingerprint
|
||||||
redirect_to :action => "account", :display_name => current_user.display_name
|
redirect_to :action => "account", :display_name => current_user.display_name
|
||||||
elsif token
|
elsif token
|
||||||
flash[:error] = t "users.confirm_email.failure"
|
flash[:error] = t "users.confirm_email.failure"
|
||||||
|
@ -552,6 +555,7 @@ class UsersController < ApplicationController
|
||||||
# process a successful login
|
# process a successful login
|
||||||
def successful_login(user, referer = nil)
|
def successful_login(user, referer = nil)
|
||||||
session[:user] = user.id
|
session[:user] = user.id
|
||||||
|
session[:fingerprint] = user.fingerprint
|
||||||
session_expires_after 28.days if session[:remember_me]
|
session_expires_after 28.days if session[:remember_me]
|
||||||
|
|
||||||
target = referer || session[:referer] || url_for(:controller => :site, :action => :index)
|
target = referer || session[:referer] || url_for(:controller => :site, :action => :index)
|
||||||
|
@ -642,6 +646,8 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
if user.save
|
if user.save
|
||||||
|
session[:fingerprint] = user.fingerprint
|
||||||
|
|
||||||
set_locale(true)
|
set_locale(true)
|
||||||
|
|
||||||
if user.new_email.blank? || user.new_email == user.email
|
if user.new_email.blank? || user.new_email == user.email
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
class User < ApplicationRecord
|
class User < ApplicationRecord
|
||||||
|
require "digest"
|
||||||
require "xml/libxml"
|
require "xml/libxml"
|
||||||
|
|
||||||
has_many :traces, -> { where(:visible => true) }
|
has_many :traces, -> { where(:visible => true) }
|
||||||
|
@ -306,6 +307,13 @@ class User < ApplicationRecord
|
||||||
ClientApplication.find_by(:key => application_key).access_token_for_user(self)
|
ClientApplication.find_by(:key => application_key).access_token_for_user(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fingerprint
|
||||||
|
digest = Digest::SHA256.new
|
||||||
|
digest.update(email)
|
||||||
|
digest.update(pass_crypt)
|
||||||
|
digest.hexdigest
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_defaults
|
def set_defaults
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue