engine/lib/locomotive/session_store.rb

57 lines
1.5 KiB
Ruby

module ActionDispatch
module Session
class MongoidStore < AbstractStore
class Session
include Mongoid::Document
include Mongoid::Timestamps
field :data, :type => String, :default => [Marshal.dump({})].pack("m*")
index :updated_at
end
# The class used for session storage.
cattr_accessor :session_class
self.session_class = Session
SESSION_RECORD_KEY = 'rack.session.record'.freeze
private
def generate_sid
BSON::ObjectId.new
end
def get_session(env, sid)
sid ||= generate_sid
session = find_session(sid)
env[SESSION_RECORD_KEY] = session
[sid, unpack(session.data)]
end
def set_session(env, sid, session_data)
record = env[SESSION_RECORD_KEY] ||= find_session(sid)
record.data = pack(session_data)
# 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 ? sid : false
end
def find_session(id)
id = BSON::ObjectId.from_string(id.to_s)
@@session_class.first(:conditions => { :_id => id }) ||
@@session_class.new(:id => id)
end
def pack(data)
[Marshal.dump(data)].pack("m*")
end
def unpack(packed)
return nil unless packed
Marshal.load(packed.unpack("m*").first)
end
end
end
end