aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLourens Naude <lourens@methodmissing.com>2008-12-18 11:33:53 -0600
committerJoshua Peek <josh@joshpeek.com>2008-12-18 11:33:53 -0600
commit3ff6b00ee30d0961f57e3c4b64ec8ff0155aaf2d (patch)
treee8adf40ecf077c4216ee36bcf9cc20f5ef071952
parent33f76bb25a973a4707437064e2f963c521413fcb (diff)
downloadrails-3ff6b00ee30d0961f57e3c4b64ec8ff0155aaf2d.tar.gz
rails-3ff6b00ee30d0961f57e3c4b64ec8ff0155aaf2d.tar.bz2
rails-3ff6b00ee30d0961f57e3c4b64ec8ff0155aaf2d.zip
Persistent session identifier support for CookieSessionStore and API compat. with the server side stores [#1591 state:resolved]
Signed-off-by: Joshua Peek <josh@joshpeek.com>
-rw-r--r--actionpack/lib/action_controller/session/abstract_store.rb14
-rw-r--r--actionpack/lib/action_controller/session/cookie_store.rb38
-rw-r--r--actionpack/test/controller/session/cookie_store_test.rb26
3 files changed, 63 insertions, 15 deletions
diff --git a/actionpack/lib/action_controller/session/abstract_store.rb b/actionpack/lib/action_controller/session/abstract_store.rb
index c6dd865fad..7874ee5a28 100644
--- a/actionpack/lib/action_controller/session/abstract_store.rb
+++ b/actionpack/lib/action_controller/session/abstract_store.rb
@@ -21,6 +21,13 @@ module ActionController
@id
end
+ def session_id
+ ActiveSupport::Deprecation.warn(
+ "ActionController::Session::AbstractStore::SessionHash#session_id" +
+ "has been deprecated.Please use #id instead.", caller)
+ id
+ end
+
def [](key)
load! unless @loaded
super
@@ -37,6 +44,13 @@ module ActionController
h
end
+ def data
+ ActiveSupport::Deprecation.warn(
+ "ActionController::Session::AbstractStore::SessionHash#data" +
+ "has been deprecated.Please use #to_hash instead.", caller)
+ to_hash
+ end
+
private
def load!
@id, session = @by.send(:load_session, @env)
diff --git a/actionpack/lib/action_controller/session/cookie_store.rb b/actionpack/lib/action_controller/session/cookie_store.rb
index f4089bfa8b..ce3cf354fd 100644
--- a/actionpack/lib/action_controller/session/cookie_store.rb
+++ b/actionpack/lib/action_controller/session/cookie_store.rb
@@ -74,17 +74,8 @@ module ActionController
freeze
end
- class SessionHash < AbstractStore::SessionHash
- private
- def load!
- session = @by.send(:load_session, @env)
- replace(session)
- @loaded = true
- end
- end
-
def call(env)
- session_data = SessionHash.new(self, env)
+ session_data = AbstractStore::SessionHash.new(self, env)
original_value = session_data.dup
env[ENV_SESSION_KEY] = session_data
@@ -142,17 +133,18 @@ module ActionController
def load_session(env)
request = Rack::Request.new(env)
session_data = request.cookies[@key]
- unmarshal(session_data) || {}
+ data = unmarshal(session_data) || persistent_session_id!({})
+ [data[:session_id], data]
end
# Marshal a session hash into safe cookie data. Include an integrity hash.
def marshal(session)
- @verifier.generate(session)
+ @verifier.generate( persistent_session_id!(session))
end
# Unmarshal cookie data to a hash and verify its integrity.
def unmarshal(cookie)
- @verifier.verify(cookie) if cookie
+ persistent_session_id!(@verifier.verify(cookie)) if cookie
rescue ActiveSupport::MessageVerifier::InvalidSignature
nil
end
@@ -195,6 +187,26 @@ module ActionController
key = secret.respond_to?(:call) ? secret.call : secret
ActiveSupport::MessageVerifier.new(key, digest)
end
+
+ def generate_sid
+ ActiveSupport::SecureRandom.hex(16)
+ end
+
+ def persistent_session_id!(data)
+ (data ||= {}).merge!(inject_persistent_session_id(data))
+ end
+
+ def inject_persistent_session_id(data)
+ requires_session_id?(data) ? { :session_id => generate_sid } : {}
+ end
+
+ def requires_session_id?(data)
+ if data
+ data.respond_to?(:key?) && !data.key?(:session_id)
+ else
+ true
+ end
+ end
end
end
end
diff --git a/actionpack/test/controller/session/cookie_store_test.rb b/actionpack/test/controller/session/cookie_store_test.rb
index 8098059d46..ad8ff09884 100644
--- a/actionpack/test/controller/session/cookie_store_test.rb
+++ b/actionpack/test/controller/session/cookie_store_test.rb
@@ -9,6 +9,8 @@ class CookieStoreTest < ActionController::IntegrationTest
CookieStoreApp = ActionController::Session::CookieStore.new(DispatcherApp,
:key => SessionKey, :secret => SessionSecret)
+ Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1')
+
SignedBar = "BAh7BjoIZm9vIghiYXI%3D--" +
"fef868465920f415f2c0652d6910d3af288a0367"
@@ -17,9 +19,13 @@ class CookieStoreTest < ActionController::IntegrationTest
head :ok
end
+ def persistent_session_id
+ render :text => session[:session_id]
+ end
+
def set_session_value
session[:foo] = "bar"
- head :ok
+ render :text => Marshal.dump(session.to_hash)
end
def get_session_value
@@ -83,7 +89,8 @@ class CookieStoreTest < ActionController::IntegrationTest
with_test_route_set do
get '/set_session_value'
assert_response :success
- assert_equal ["_myapp_session=#{SignedBar}; path=/"],
+ session_payload = Verifier.generate( Marshal.load(response.body) )
+ assert_equal ["_myapp_session=#{session_payload}; path=/"],
headers['Set-Cookie']
end
end
@@ -132,6 +139,21 @@ class CookieStoreTest < ActionController::IntegrationTest
end
end
+ def test_persistent_session_id
+ with_test_route_set do
+ cookies[SessionKey] = SignedBar
+ get '/persistent_session_id'
+ assert_response :success
+ assert_equal response.body.size, 32
+ session_id = response.body
+ get '/persistent_session_id'
+ assert_equal session_id, response.body
+ reset!
+ get '/persistent_session_id'
+ assert_not_equal session_id, response.body
+ end
+ end
+
private
def with_test_route_set
with_routing do |set|