diff options
Diffstat (limited to 'actionpack/test/dispatch/cookies_test.rb')
-rw-r--r-- | actionpack/test/dispatch/cookies_test.rb | 239 |
1 files changed, 222 insertions, 17 deletions
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb index 347b3b3b5a..91ac13e7c6 100644 --- a/actionpack/test/dispatch/cookies_test.rb +++ b/actionpack/test/dispatch/cookies_test.rb @@ -1,5 +1,15 @@ require 'abstract_unit' +begin + require 'openssl' + OpenSSL::PKCS5 +rescue LoadError, NameError + $stderr.puts "Skipping KeyGenerator test: broken OpenSSL install" +else + +require 'active_support/key_generator' +require 'active_support/message_verifier' + class CookiesTest < ActionController::TestCase class TestController < ActionController::Base def authenticate @@ -65,6 +75,26 @@ class CookiesTest < ActionController::TestCase head :ok end + def get_signed_cookie + cookies.signed[:user_id] + head :ok + end + + def set_encrypted_cookie + cookies.encrypted[:foo] = 'bar' + head :ok + end + + def get_encrypted_cookie + cookies.encrypted[:foo] + head :ok + end + + def set_invalid_encrypted_cookie + cookies[:invalid_cookie] = 'invalid--9170e00a57cfc27083363b5c75b835e477bd90cf' + head :ok + end + def raise_data_overflow cookies.signed[:foo] = 'bye!' * 1024 head :ok @@ -146,10 +176,43 @@ class CookiesTest < ActionController::TestCase def setup super - @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.key_generator"] = ActiveSupport::KeyGenerator.new("b3c631c314c0bbca50c1b2843150fe33") + @request.env["action_dispatch.signed_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.encrypted_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.encrypted_signed_cookie_salt"] = "b3c631c314c0bbca50c1b2843150fe33" @request.host = "www.nextangle.com" end + def test_fetch + x = Object.new + assert_not request.cookie_jar.key?('zzzzzz') + assert_equal x, request.cookie_jar.fetch('zzzzzz', x) + assert_not request.cookie_jar.key?('zzzzzz') + end + + def test_fetch_exists + x = Object.new + request.cookie_jar['foo'] = 'bar' + assert_equal 'bar', request.cookie_jar.fetch('foo', x) + end + + def test_fetch_block + x = Object.new + assert_not request.cookie_jar.key?('zzzzzz') + assert_equal x, request.cookie_jar.fetch('zzzzzz') { x } + end + + def test_key_is_to_s + request.cookie_jar['foo'] = 'bar' + assert_equal 'bar', request.cookie_jar.fetch(:foo) + end + + def test_fetch_type_error + assert_raises(KeyError) do + request.cookie_jar.fetch(:omglolwut) + end + end + def test_each request.cookie_jar['foo'] = :bar list = [] @@ -201,13 +264,13 @@ class CookiesTest < ActionController::TestCase def test_setting_cookie_for_fourteen_days get :authenticate_for_fourteen_days - assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT" + assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000" assert_equal({"user_name" => "david"}, @response.cookies) end def test_setting_cookie_for_fourteen_days_with_symbols get :authenticate_for_fourteen_days_with_symbols - assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT" + assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000" assert_equal({"user_name" => "david"}, @response.cookies) end @@ -240,7 +303,7 @@ class CookiesTest < ActionController::TestCase def test_multiple_cookies get :set_multiple_cookies assert_equal 2, @response.cookies.size - assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT\nlogin=XJ-122; path=/" + assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000\nlogin=XJ-122; path=/" assert_equal({"login" => "XJ-122", "user_name" => "david"}, @response.cookies) end @@ -251,14 +314,14 @@ class CookiesTest < ActionController::TestCase def test_expiring_cookie request.cookies[:user_name] = 'Joe' get :logout - assert_cookie_header "user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT" + assert_cookie_header "user_name=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000" assert_equal({"user_name" => nil}, @response.cookies) end def test_delete_cookie_with_path request.cookies[:user_name] = 'Joe' get :delete_cookie_with_path - assert_cookie_header "user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT" + assert_cookie_header "user_name=; path=/beaten; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000" end def test_delete_unexisting_cookie @@ -285,12 +348,17 @@ class CookiesTest < ActionController::TestCase assert response.headers["Set-Cookie"] =~ /user_name=david/ end - def test_permanent_cookie + def test_set_permanent_cookie get :set_permanent_cookie assert_match(/Jamie/, @response.headers["Set-Cookie"]) assert_match(%r(#{20.years.from_now.utc.year}), @response.headers["Set-Cookie"]) end + def test_read_permanent_cookie + get :set_permanent_cookie + assert_equal 'Jamie', @controller.send(:cookies).permanent[:user_name] + end + def test_signed_cookie get :set_signed_cookie assert_equal 45, @controller.send(:cookies).signed[:user_id] @@ -301,6 +369,26 @@ class CookiesTest < ActionController::TestCase assert_nil @controller.send(:cookies).signed[:non_existant_attribute] end + def test_encrypted_cookie + get :set_encrypted_cookie + cookies = @controller.send :cookies + assert_not_equal 'bar', cookies[:foo] + assert_raises TypeError do + cookies.signed[:foo] + end + assert_equal 'bar', cookies.encrypted[:foo] + end + + def test_accessing_nonexistant_encrypted_cookie_should_not_raise_invalid_message + get :set_encrypted_cookie + assert_nil @controller.send(:cookies).encrypted[:non_existant_attribute] + end + + def test_setting_invalid_encrypted_cookie_should_return_nil_when_accessing_it + get :set_invalid_encrypted_cookie + assert_nil @controller.send(:cookies).encrypted[:invalid_cookie] + end + def test_permanent_signed_cookie get :set_permanent_signed_cookie assert_match(%r(#{20.years.from_now.utc.year}), @response.headers["Set-Cookie"]) @@ -310,7 +398,7 @@ class CookiesTest < ActionController::TestCase def test_delete_and_set_cookie request.cookies[:user_name] = 'Joe' get :delete_and_set_cookie - assert_cookie_header "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT" + assert_cookie_header "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 -0000" assert_equal({"user_name" => "david"}, @response.cookies) end @@ -329,33 +417,148 @@ class CookiesTest < ActionController::TestCase def test_raises_argument_error_if_missing_secret assert_raise(ArgumentError, nil.inspect) { - @request.env["action_dispatch.secret_token"] = nil + @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new(nil) get :set_signed_cookie } assert_raise(ArgumentError, ''.inspect) { - @request.env["action_dispatch.secret_token"] = "" + @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new("") get :set_signed_cookie } end def test_raises_argument_error_if_secret_is_probably_insecure assert_raise(ArgumentError, "password".inspect) { - @request.env["action_dispatch.secret_token"] = "password" + @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new("password") get :set_signed_cookie } assert_raise(ArgumentError, "secret".inspect) { - @request.env["action_dispatch.secret_token"] = "secret" + @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new("secret") get :set_signed_cookie } assert_raise(ArgumentError, "12345678901234567890123456789".inspect) { - @request.env["action_dispatch.secret_token"] = "12345678901234567890123456789" + @request.env["action_dispatch.key_generator"] = ActiveSupport::LegacyKeyGenerator.new("12345678901234567890123456789") get :set_signed_cookie } end + def test_signed_uses_signed_cookie_jar_if_only_secret_token_is_set + @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.secret_key_base"] = nil + get :set_signed_cookie + assert_kind_of ActionDispatch::Cookies::SignedCookieJar, cookies.signed + end + + def test_signed_uses_signed_cookie_jar_if_only_secret_key_base_is_set + @request.env["action_dispatch.secret_token"] = nil + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + get :set_signed_cookie + assert_kind_of ActionDispatch::Cookies::SignedCookieJar, cookies.signed + end + + def test_signed_uses_upgrade_legacy_signed_cookie_jar_if_both_secret_token_and_secret_key_base_are_set + @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + get :set_signed_cookie + assert_kind_of ActionDispatch::Cookies::UpgradeLegacySignedCookieJar, cookies.signed + end + + def test_signed_or_encrypted_uses_signed_cookie_jar_if_only_secret_token_is_set + @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.secret_key_base"] = nil + get :get_encrypted_cookie + assert_kind_of ActionDispatch::Cookies::SignedCookieJar, cookies.signed_or_encrypted + end + + def test_signed_or_encrypted_uses_encrypted_cookie_jar_if_only_secret_key_base_is_set + @request.env["action_dispatch.secret_token"] = nil + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + get :get_encrypted_cookie + assert_kind_of ActionDispatch::Cookies::EncryptedCookieJar, cookies.signed_or_encrypted + end + + def test_signed_or_encrypted_uses_upgrade_legacy_encrypted_cookie_jar_if_both_secret_token_and_secret_key_base_are_set + @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + get :get_encrypted_cookie + assert_kind_of ActionDispatch::Cookies::UpgradeLegacyEncryptedCookieJar, cookies.signed_or_encrypted + end + + def test_encrypted_uses_encrypted_cookie_jar_if_only_secret_key_base_is_set + @request.env["action_dispatch.secret_token"] = nil + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + get :get_encrypted_cookie + assert_kind_of ActionDispatch::Cookies::EncryptedCookieJar, cookies.encrypted + end + + def test_encrypted_uses_upgrade_legacy_encrypted_cookie_jar_if_both_secret_token_and_secret_key_base_are_set + @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + get :get_encrypted_cookie + assert_kind_of ActionDispatch::Cookies::UpgradeLegacyEncryptedCookieJar, cookies.encrypted + end + + def test_legacy_signed_cookie_is_read_and_transparently_upgraded_by_signed_cookie_jar_if_both_secret_token_and_secret_key_base_are_set + @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + + legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate(45) + + @request.headers["Cookie"] = "user_id=#{legacy_value}" + get :get_signed_cookie + + assert_equal 45, @controller.send(:cookies).signed[:user_id] + + key_generator = @request.env["action_dispatch.key_generator"] + secret = key_generator.generate_key(@request.env["action_dispatch.signed_cookie_salt"]) + verifier = ActiveSupport::MessageVerifier.new(secret) + assert_equal 45, verifier.verify(@response.cookies["user_id"]) + end + + def test_legacy_signed_cookie_is_read_and_transparently_encrypted_by_encrypted_cookie_jar_if_both_secret_token_and_secret_key_base_are_set + @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + @request.env["action_dispatch.encrypted_cookie_salt"] = "4433796b79d99a7735553e316522acee" + @request.env["action_dispatch.encrypted_signed_cookie_salt"] = "00646eb40062e1b1deff205a27cd30f9" + + legacy_value = ActiveSupport::MessageVerifier.new("b3c631c314c0bbca50c1b2843150fe33").generate('bar') + + @request.headers["Cookie"] = "foo=#{legacy_value}" + get :get_encrypted_cookie + + assert_equal 'bar', @controller.send(:cookies).encrypted[:foo] + + key_generator = @request.env["action_dispatch.key_generator"] + secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_cookie_salt"]) + sign_secret = key_generator.generate_key(@request.env["action_dispatch.encrypted_signed_cookie_salt"]) + encryptor = ActiveSupport::MessageEncryptor.new(secret, sign_secret) + assert_equal 'bar', encryptor.decrypt_and_verify(@response.cookies["foo"]) + end + + def test_legacy_signed_cookie_is_treated_as_nil_by_signed_cookie_jar_if_tampered + @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + + @request.headers["Cookie"] = "user_id=45" + get :get_signed_cookie + + assert_equal nil, @controller.send(:cookies).signed[:user_id] + assert_equal nil, @response.cookies["user_id"] + end + + def test_legacy_signed_cookie_is_treated_as_nil_by_encrypted_cookie_jar_if_tampered + @request.env["action_dispatch.secret_token"] = "b3c631c314c0bbca50c1b2843150fe33" + @request.env["action_dispatch.secret_key_base"] = "c3b95688f35581fad38df788add315ff" + + @request.headers["Cookie"] = "foo=baz" + get :get_encrypted_cookie + + assert_equal nil, @controller.send(:cookies).encrypted[:foo] + assert_equal nil, @response.cookies["foo"] + end + def test_cookie_with_all_domain_option get :set_cookie_with_domain assert_response :success @@ -415,7 +618,7 @@ class CookiesTest < ActionController::TestCase request.cookies[:user_name] = 'Joe' get :delete_cookie_with_domain assert_response :success - assert_cookie_header "user_name=; domain=.nextangle.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT" + assert_cookie_header "user_name=; domain=.nextangle.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000" end def test_cookie_with_all_domain_option_and_tld_length @@ -442,7 +645,7 @@ class CookiesTest < ActionController::TestCase request.cookies[:user_name] = 'Joe' get :delete_cookie_with_domain_and_tld assert_response :success - assert_cookie_header "user_name=; domain=.nextangle.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT" + assert_cookie_header "user_name=; domain=.nextangle.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000" end def test_cookie_with_several_preset_domains_using_one_of_these_domains @@ -471,7 +674,7 @@ class CookiesTest < ActionController::TestCase request.cookies[:user_name] = 'Joe' get :delete_cookie_with_domains assert_response :success - assert_cookie_header "user_name=; domain=example2.com; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT" + assert_cookie_header "user_name=; domain=example2.com; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000" end def test_deletings_cookie_with_several_preset_domains_using_other_domain @@ -479,7 +682,7 @@ class CookiesTest < ActionController::TestCase request.cookies[:user_name] = 'Joe' get :delete_cookie_with_domains assert_response :success - assert_cookie_header "user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT" + assert_cookie_header "user_name=; path=/; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000" end def test_cookies_hash_is_indifferent_access @@ -604,3 +807,5 @@ class CookiesTest < ActionController::TestCase end end end + +end |