提交 b3ae51c9 编写于 作者: G Greg Ose

Add serializer option to cookie store and use Rails 4 Hash flash

Backport for Rails 4 flash hash based on https://github.com/envato/rails_4_session_flash_backport
上级 1e6e438f
2.3.14.github43
2.3.14.github44
......@@ -56,11 +56,33 @@ def [](k)
end
class FlashHash < Hash
def self.from_session_value(value)
flash = case value
when FlashHash # Rails 2.3
value
when Hash # Rails 4.0
flashes = value['flashes'] || {}
discard = value['discard']
used = Hash[flashes.keys.map{|k| [k, discard.include?(k)] }]
new_from_values(flashes, used)
else
new
end
flash
end
def initialize #:nodoc:
super
@used = {}
end
def to_session_value
return nil if empty?
rails_3_discard_list = @used.map{|k,v| k if v}.compact
{'discard' => rails_3_discard_list, 'flashes' => Hash[to_a]}
end
def []=(k, v) #:nodoc:
keep(k)
super
......@@ -126,8 +148,7 @@ def sweep #:nodoc:
end
def store(session, key = "flash")
return if self.empty?
session[key] = self
session[key] = to_session_value
end
private
......@@ -143,6 +164,15 @@ def use(k=nil, v=true)
keys.each{ |key| use(key, v) }
end
end
def self.new_from_values(flashes, used)
new.tap do |flash_hash|
flashes.each do |k, v|
flash_hash[k] = v
end
flash_hash.instance_variable_set("@used", used)
end
end
end
module InstanceMethods #:nodoc:
......@@ -168,11 +198,11 @@ def redirect_to_with_flash(options = {}, response_status_and_flash = {}) #:doc:
if notice = response_status_and_flash.delete(:notice)
flash[:notice] = notice
end
if other_flashes = response_status_and_flash.delete(:flash)
flash.update(other_flashes)
end
redirect_to_without_flash(options, response_status_and_flash)
end
......@@ -181,19 +211,19 @@ def redirect_to_with_flash(options = {}, response_status_and_flash = {}) #:doc:
# to put a new one.
def flash #:doc:
if !defined?(@_flash)
@_flash = session["flash"] || FlashHash.new
@_flash = Flash::FlashHash.from_session_value(session["flash"])
@_flash.sweep
end
@_flash
end
# Convenience accessor for flash[:alert]
def alert
flash[:alert]
end
# Convenience accessor for flash[:alert]=
def alert=(message)
flash[:alert] = message
......@@ -203,7 +233,7 @@ def alert=(message)
def notice
flash[:notice]
end
# Convenience accessor for flash[:notice]=
def notice=(message)
flash[:notice] = message
......
......@@ -2,7 +2,7 @@
module ActionController
module Session
class AbstractStore
class AbstractStore
ENV_SESSION_KEY = 'rack.session'.freeze
ENV_SESSION_OPTIONS_KEY = 'rack.session.options'.freeze
......@@ -55,17 +55,17 @@ def session_id
def [](key)
load_for_read!
super
super(key.to_s) || super(key)
end
def has_key?(key)
load_for_read!
super
super(key.to_s) || super(key)
end
def []=(key, value)
load_for_write!
super
super(key.to_s, value)
end
def clear
......@@ -87,7 +87,9 @@ def update(hash)
def delete(key)
load_for_write!
super
value = super(key)
string_value = super(key.to_s)
value || string_value
end
def data
......@@ -119,7 +121,7 @@ def destroy
end
private
def load_for_read!
load! if !loaded? && exists?
end
......@@ -183,7 +185,7 @@ def call(env)
request = ActionController::Request.new(env)
return response if (options[:secure] && !request.ssl?)
session_data.send(:load!) if session_data.is_a?(AbstractStore::SessionHash) && !session_data.loaded?
sid = options[:id] || generate_sid
......@@ -205,12 +207,12 @@ def call(env)
end
private
def prepare!(env)
env[ENV_SESSION_KEY] = SessionHash.new(self, env)
env[ENV_SESSION_OPTIONS_KEY] = OptionsHash.new(self, env, @default_options)
end
def generate_sid
ActiveSupport::SecureRandom.hex(16)
end
......@@ -222,7 +224,7 @@ def load_session(env)
[sid, session]
end
end
def extract_session_id(env)
stale_session_check! do
request = Rack::Request.new(env)
......@@ -235,7 +237,7 @@ def extract_session_id(env)
def current_session_id(env)
env[ENV_SESSION_OPTIONS_KEY][:id]
end
def exists?(env)
current_session_id(env).present?
end
......@@ -247,11 +249,11 @@ def get_session(env, sid)
def set_session(env, sid, session_data)
raise '#set_session needs to be implemented.'
end
def destroy(env)
raise '#destroy needs to be implemented.'
end
module SessionUtils
private
def stale_session_check!
......
......@@ -86,7 +86,8 @@ def initialize(app, options = {})
@secret = options.delete(:secret).freeze
@digest = options.delete(:digest) || 'SHA1'
@verifier = verifier_for(@secret, @digest)
@serializer = options.delete(:serializer) || Marshal
@verifier = verifier_for(@secret, @digest, @serializer)
@default_options = DEFAULT_OPTIONS.merge(options).freeze
......@@ -138,13 +139,13 @@ def prepare!(env)
def load_session(env)
data = unpacked_cookie_data(env)
data = persistent_session_id!(data)
[data[:session_id], data]
[data["session_id"] || data[:session_id], data]
end
def extract_session_id(env)
if data = unpacked_cookie_data(env)
persistent_session_id!(data) unless data.empty?
data[:session_id]
data["session_id"] || data[:session_id]
else
nil
end
......@@ -214,9 +215,9 @@ def ensure_secret_secure(secret)
end
end
def verifier_for(secret, digest)
def verifier_for(secret, digest, serializer)
key = secret.respond_to?(:call) ? secret.call : secret
ActiveSupport::MessageVerifier.new(key, digest: digest)
ActiveSupport::MessageVerifier.new(key, digest: digest, serializer: serializer)
end
def generate_sid
......@@ -232,12 +233,12 @@ def persistent_session_id!(data)
end
def inject_persistent_session_id(data)
requires_session_id?(data) ? { :session_id => generate_sid } : {}
requires_session_id?(data) ? { "session_id" => generate_sid } : {}
end
def requires_session_id?(data)
if data
data.respond_to?(:key?) && !data.key?(:session_id)
data.respond_to?(:key?) && !(data.key?("session_id") || data.key?(:session_id))
else
true
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册