From 274a3aa64cb903c52a41d1767cac0bc3eae44172 Mon Sep 17 00:00:00 2001 From: Trevor Turk Date: Thu, 28 Mar 2013 14:35:48 -0500 Subject: Allow transparent upgrading of legacy signed cookies to encrypted cookies; Automatically configure cookie-based sessions to use the best cookie jar given the app's config --- railties/lib/rails/application.rb | 13 +++-- .../config/initializers/session_store.rb.tt | 2 +- .../test/application/middleware/session_test.rb | 68 +++++++++++++++++++--- railties/test/generators/app_generator_test.rb | 2 +- 4 files changed, 69 insertions(+), 16 deletions(-) (limited to 'railties') diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 563905e8b3..455ceed5f8 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -1,4 +1,5 @@ require 'fileutils' +require 'active_support/core_ext/object/blank' # FIXME remove DummyKeyGenerator and this require in 4.1 require 'active_support/key_generator' require 'rails/engine' @@ -122,7 +123,8 @@ module Rails # # * "action_dispatch.parameter_filter" => config.filter_parameters # * "action_dispatch.redirect_filter" => config.filter_redirect - # * "action_dispatch.secret_token" => config.secret_token, + # * "action_dispatch.secret_token" => config.secret_token + # * "action_dispatch.secret_key_base" => config.secret_key_base # * "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions # * "action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local # * "action_dispatch.logger" => Rails.logger @@ -135,13 +137,12 @@ module Rails # def env_config @app_env_config ||= begin - if config.secret_key_base.nil? - ActiveSupport::Deprecation.warn "You didn't set config.secret_key_base in config/initializers/secret_token.rb file. " + - "This should be used instead of the old deprecated config.secret_token in order to use the new EncryptedCookieStore. " + - "To convert safely to the encrypted store (without losing existing cookies and sessions), see http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#action-pack" + if config.secret_key_base.blank? + ActiveSupport::Deprecation.warn "You didn't set config.secret_key_base. " + + "Read the upgrade documentation to learn more about this new config option." if config.secret_token.blank? - raise "You must set config.secret_key_base in your app's config" + raise "You must set config.secret_key_base in your app's config." end end diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt index df07de9922..4a099a4ce2 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt @@ -1,3 +1,3 @@ # Be sure to restart your server when you modify this file. -<%= app_const %>.config.session_store :encrypted_cookie_store, key: <%= "'_#{app_name}_session'" %> +<%= app_const %>.config.session_store :cookie_store, key: <%= "'_#{app_name}_session'" %> diff --git a/railties/test/application/middleware/session_test.rb b/railties/test/application/middleware/session_test.rb index a5fdfbf887..8cb0dfeb63 100644 --- a/railties/test/application/middleware/session_test.rb +++ b/railties/test/application/middleware/session_test.rb @@ -157,10 +157,6 @@ module ApplicationTests end RUBY - add_to_config <<-RUBY - config.session_store :encrypted_cookie_store, key: '_myapp_session' - RUBY - require "#{app_path}/config/environment" get '/foo/write_session' @@ -178,7 +174,7 @@ module ApplicationTests assert_equal 1, encryptor.decrypt_and_verify(last_response.body)['foo'] end - test "session using upgrade signature to encryption cookie store works the same way as encrypted cookie store" do + test "session upgrading signature to encryption cookie store works the same way as encrypted cookie store" do app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do get ':controller(/:action)' @@ -208,7 +204,6 @@ module ApplicationTests add_to_config <<-RUBY config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" - config.session_store :upgrade_signature_to_encryption_cookie_store, key: '_myapp_session' RUBY require "#{app_path}/config/environment" @@ -228,7 +223,7 @@ module ApplicationTests assert_equal 1, encryptor.decrypt_and_verify(last_response.body)['foo'] end - test "session using upgrade signature to encryption cookie store upgrades session to encrypted mode" do + test "session upgrading signature to encryption cookie store upgrades session to encrypted mode" do app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do get ':controller(/:action)' @@ -264,7 +259,6 @@ module ApplicationTests add_to_config <<-RUBY config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" - config.session_store :upgrade_signature_to_encryption_cookie_store, key: '_myapp_session' RUBY require "#{app_path}/config/environment" @@ -287,5 +281,63 @@ module ApplicationTests get '/foo/read_raw_cookie' assert_equal 2, encryptor.decrypt_and_verify(last_response.body)['foo'] end + + test "session upgrading legacy signed cookies to new signed cookies" do + app_file 'config/routes.rb', <<-RUBY + AppTemplate::Application.routes.draw do + get ':controller(/:action)' + end + RUBY + + controller :foo, <<-RUBY + class FooController < ActionController::Base + def write_raw_session + # {"session_id"=>"1965d95720fffc123941bdfb7d2e6870", "foo"=>1} + cookies[:_myapp_session] = "BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTE5NjVkOTU3MjBmZmZjMTIzOTQxYmRmYjdkMmU2ODcwBjsAVEkiCGZvbwY7AEZpBg==--315fb9931921a87ae7421aec96382f0294119749" + render nothing: true + end + + def write_session + session[:foo] = session[:foo] + 1 + render nothing: true + end + + def read_session + render text: session[:foo] + end + + def read_signed_cookie + render text: cookies.signed[:_myapp_session]['foo'] + end + + def read_raw_cookie + render text: cookies[:_myapp_session] + end + end + RUBY + + add_to_config <<-RUBY + config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" + config.secret_key_base = nil + RUBY + + require "#{app_path}/config/environment" + + get '/foo/write_raw_session' + get '/foo/read_session' + assert_equal '1', last_response.body + + get '/foo/write_session' + get '/foo/read_session' + assert_equal '2', last_response.body + + get '/foo/read_signed_cookie' + assert_equal '2', last_response.body + + verifier = ActiveSupport::MessageVerifier.new(app.config.secret_token) + + get '/foo/read_raw_cookie' + assert_equal 2, verifier.verify(last_response.body)['foo'] + end end end diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index b813a7f6bb..5c9c3297a4 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -341,7 +341,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_new_hash_style run_generator [destination_root] assert_file "config/initializers/session_store.rb" do |file| - assert_match(/config.session_store :encrypted_cookie_store, key: '_.+_session'/, file) + assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file) end end -- cgit v1.2.3