aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorAssain <assainjaleel20@gmail.com>2017-08-14 19:16:58 +0530
committerAssain <assainjaleel20@gmail.com>2017-08-20 23:07:56 +0530
commit5f37e16ab5fb36555175379ad96b2da3c3b31a0b (patch)
tree9105e2146ecbb50a2ab9e347434a94f1ac6206e7 /actionpack
parent57585b6f3b8ef1703970c858ba6297e6427be0bd (diff)
downloadrails-5f37e16ab5fb36555175379ad96b2da3c3b31a0b.tar.gz
rails-5f37e16ab5fb36555175379ad96b2da3c3b31a0b.tar.bz2
rails-5f37e16ab5fb36555175379ad96b2da3c3b31a0b.zip
freshen :expires option with duration support and add expiry metadata to cookies
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb18
-rw-r--r--actionpack/test/dispatch/cookies_test.rb32
-rw-r--r--actionpack/test/dispatch/session/cookie_store_test.rb9
3 files changed, 54 insertions, 5 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index 5a55ee13ee..c0913715ac 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -360,7 +360,11 @@ module ActionDispatch
@cookies.map { |k, v| "#{escape(k)}=#{escape(v)}" }.join "; "
end
- def handle_options(options) #:nodoc:
+ def handle_options(options) # :nodoc:
+ if options[:expires].respond_to?(:from_now)
+ options[:expires] = options[:expires].from_now
+ end
+
options[:path] ||= "/"
if options[:domain] == :all || options[:domain] == "all"
@@ -488,6 +492,14 @@ module ActionDispatch
def request; @parent_jar.request; end
private
+ def expiry_options(options)
+ if options[:expires].respond_to?(:from_now)
+ { expires_in: options[:expires] }
+ else
+ { expires_at: options[:expires] }
+ end
+ end
+
def parse(name, data); data; end
def commit(options); end
end
@@ -569,7 +581,7 @@ module ActionDispatch
end
def commit(options)
- options[:value] = @verifier.generate(serialize(options[:value]))
+ options[:value] = @verifier.generate(serialize(options[:value]), expiry_options(options))
raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE
end
@@ -609,7 +621,7 @@ module ActionDispatch
end
def commit(options)
- options[:value] = @encryptor.encrypt_and_sign(serialize(options[:value]))
+ options[:value] = @encryptor.encrypt_and_sign(serialize(options[:value]), expiry_options(options))
raise CookieOverflow if options[:value].bytesize > MAX_COOKIE_SIZE
end
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index a551fb00a8..cb225c0f62 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -278,6 +278,11 @@ class CookiesTest < ActionController::TestCase
def encrypted_cookie
cookies.encrypted["foo"]
end
+
+ def cookie_expires_in_two_hours
+ cookies[:user_name] = { value: "assain", expires: 2.hours }
+ head :ok
+ end
end
tests TestController
@@ -1235,6 +1240,33 @@ class CookiesTest < ActionController::TestCase
assert_equal "bar", @controller.encrypted_cookie
end
+ def test_signed_cookie_with_expires_set_relatively
+ cookies.signed[:user_name] = { value: "assain", expires: 2.hours }
+
+ travel 1.hour
+ assert_equal "assain", cookies.signed[:user_name]
+
+ travel 2.hours
+ assert_nil cookies.signed[:user_name]
+ end
+
+ def test_encrypted_cookie_with_expires_set_relatively
+ cookies.encrypted[:user_name] = { value: "assain", expires: 2.hours }
+
+ travel 1.hour
+ assert_equal "assain", cookies.encrypted[:user_name]
+
+ travel 2.hours
+ assert_nil cookies.encrypted[:user_name]
+ end
+
+ def test_vanilla_cookie_with_expires_set_relatively
+ travel_to Time.utc(2017, 8, 15) do
+ get :cookie_expires_in_two_hours
+ assert_cookie_header "user_name=assain; path=/; expires=Tue, 15 Aug 2017 02:00:00 -0000"
+ end
+ end
+
private
def assert_cookie_header(expected)
header = @response.headers["Set-Cookie"]
diff --git a/actionpack/test/dispatch/session/cookie_store_test.rb b/actionpack/test/dispatch/session/cookie_store_test.rb
index 26a63c9f7d..6517cf4c99 100644
--- a/actionpack/test/dispatch/session/cookie_store_test.rb
+++ b/actionpack/test/dispatch/session/cookie_store_test.rb
@@ -26,6 +26,11 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
render plain: Rack::Utils.escape(Verifier.generate(session.to_hash))
end
+ def set_session_value_expires_in_five_hours
+ session[:foo] = "bar"
+ render plain: Rack::Utils.escape(Verifier.generate(session.to_hash, expires_in: 5.hours))
+ end
+
def get_session_value
render plain: "foo: #{session[:foo].inspect}"
end
@@ -283,7 +288,7 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
cookies[SessionKey] = SignedBar
- get "/set_session_value"
+ get "/set_session_value_expires_in_five_hours"
assert_response :success
cookie_body = response.body
@@ -299,7 +304,7 @@ class CookieStoreTest < ActionDispatch::IntegrationTest
get "/no_session_access"
assert_response :success
- assert_equal "_myapp_session=#{cookie_body}; path=/; expires=#{expected_expiry}; HttpOnly",
+ assert_equal "_myapp_session=#{cookies[SessionKey]}; path=/; expires=#{expected_expiry}; HttpOnly",
headers["Set-Cookie"]
end
end