class ActiveRecord::SessionStore::Session

The default Active Record class.

Constants

SEMAPHORE

Attributes

data[W]

Public Class Methods

data_column_name() click to toggle source

Customizable data column name. Defaults to 'data'.

# File lib/active_record/session_store/session.rb, line 14
cattr_accessor :data_column_name
data_column_size_limit() click to toggle source
# File lib/active_record/session_store/session.rb, line 21
def data_column_size_limit
  @data_column_size_limit ||= columns_hash[data_column_name].limit
end
find_by_session_id(session_id) click to toggle source

Hook to set up sessid compatibility.

# File lib/active_record/session_store/session.rb, line 26
def find_by_session_id(session_id)
  SEMAPHORE.synchronize { setup_sessid_compatibility! }
  find_by_session_id(session_id)
end
new(*) click to toggle source
Calls superclass method
# File lib/active_record/session_store/session.rb, line 57
def initialize(*)
  @data = nil
  super
end

Private Class Methods

session_id_column() click to toggle source
# File lib/active_record/session_store/session.rb, line 32
def session_id_column
  'session_id'
end
setup_sessid_compatibility!() click to toggle source

Compatibility with tables using sessid instead of session_id.

# File lib/active_record/session_store/session.rb, line 37
def setup_sessid_compatibility!
  # Reset column info since it may be stale.
  reset_column_information
  if columns_hash['sessid']
    def self.find_by_session_id(session_id)
      find_by_sessid(session_id)
    end

    define_method(:session_id)  { sessid }
    define_method(:session_id=) { |session_id| self.sessid = session_id }
  else
    class << self; remove_possible_method :find_by_session_id; end

    def self.find_by_session_id(session_id)
      where(session_id: session_id).first
    end
  end
end

Public Instance Methods

data() click to toggle source

Lazy-deserialize session state.

# File lib/active_record/session_store/session.rb, line 63
def data
  @data ||= self.class.deserialize(read_attribute(@@data_column_name)) || {}
end
loaded?() click to toggle source

Has the session been loaded yet?

# File lib/active_record/session_store/session.rb, line 70
def loaded?
  @data
end
secure!() click to toggle source

This method was introduced when addressing CVE-2019-16782 (see github.com/rack/rack/security/advisories/GHSA-hrqr-hxpp-chr3). Sessions created on version <= 1.1.3 were guessable via a timing attack. To secure sessions created on those old versions, this method can be called on all existing sessions in the database. Users will not lose their session when this is done.

# File lib/active_record/session_store/session.rb, line 80
def secure!
  session_id_column = if self.class.columns_hash['sessid']
    :sessid
  else
    :session_id
  end
  raw_session_id = read_attribute(session_id_column)
  if ActionDispatch::Session::ActiveRecordStore.private_session_id?(raw_session_id)
    # is already private, nothing to do
  else
    session_id_object = Rack::Session::SessionId.new(raw_session_id)
    update_column(session_id_column, session_id_object.private_id)
  end
end

Private Instance Methods

raise_on_session_data_overflow!() click to toggle source

Ensures that the data about to be stored in the database is not larger than the data storage column. Raises ActionController::SessionOverflowError.

# File lib/active_record/session_store/session.rb, line 106
def raise_on_session_data_overflow!
  unless loaded?
    throw :abort
  end
  limit = self.class.data_column_size_limit
  if limit and read_attribute(@@data_column_name).size > limit
    raise ActionController::SessionOverflowError
  end
end
serialize_data!() click to toggle source
# File lib/active_record/session_store/session.rb, line 96
def serialize_data!
  unless loaded?
    throw :abort
  end
  write_attribute(@@data_column_name, self.class.serialize(data))
end