lib/mongo_session_store/mongo_store_base.rb
require "action_dispatch/middleware/session/abstract_store"
module ActionDispatch
module Session
class MongoStoreBase < AbstractStore
SESSION_RECORD_KEY = "rack.session.record".freeze
ENV_SESSION_OPTIONS_KEY =
if defined? Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY
Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY
else
Rack::RACK_SESSION_OPTIONS
end
def self.session_class
self::Session
end
private
def session_class
self.class.session_class
end
def find_session(req, sid)
get_session(req.env, sid)
end
def get_session(env, sid)
id, record = find_or_initialize_session(sid)
env[SESSION_RECORD_KEY] = record
[id, record.data]
end
def write_session(req, sid, session_data, options)
set_session(req.env, sid, session_data, options)
end
def set_session(env, sid, session_data, _options = {})
id, record = get_session_record(env, sid)
record.data = session_data
yield if block_given?
# Rack spec dictates that set_session should return true or false
# depending on whether or not the session was saved or not.
# However, ActionPack seems to want a session id instead.
record.save ? id : false
end
def find_or_initialize_session(id)
existing_session = (id && session_class.where(:_id => id.to_s).first)
session = existing_session if existing_session
session ||= session_class.new(:_id => generate_sid)
[session._id, session]
end
def get_session_record(env, sid)
if env[ENV_SESSION_OPTIONS_KEY][:id].nil? || !env[SESSION_RECORD_KEY]
sid, env[SESSION_RECORD_KEY] = find_or_initialize_session(sid)
end
[sid, env[SESSION_RECORD_KEY]]
end
def delete_session(req, sid, options)
destroy_session(req.env, sid, options)
end
def destroy_session(env, sid, options)
destroy(env, sid)
generate_sid unless options[:drop]
end
def destroy(env, sid)
return unless sid
_, record = get_session_record(env, sid)
record.destroy
env[SESSION_RECORD_KEY] = nil
end
end
end
end