From cb0fbbeac8c36ca01329c623d29bf75daa994840 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Tue, 10 Dec 2013 09:38:27 -0500 Subject: [PATCH 1/7] Add config/tokens.yml template --- railties/lib/rails/generators/rails/app/app_generator.rb | 1 + .../generators/rails/app/templates/config/tokens.yml | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100644 railties/lib/rails/generators/rails/app/templates/config/tokens.yml diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 87556bd609..2c4911cadc 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -78,6 +78,7 @@ module Rails template "routes.rb" template "application.rb" template "environment.rb" + template "tokens.yml" directory "environments" directory "initializers" diff --git a/railties/lib/rails/generators/rails/app/templates/config/tokens.yml b/railties/lib/rails/generators/rails/app/templates/config/tokens.yml new file mode 100644 index 0000000000..3ce5de1dc9 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/config/tokens.yml @@ -0,0 +1,8 @@ +development: + secret_key_base: <%= app_secret %> + +test: + secret_key_base: <%= app_secret %> + +production: + secret_key_base: <%= app_secret %> From 0f4d235c1606ccec30e8fd0aeb4b88a061ee83fe Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Tue, 10 Dec 2013 10:03:40 -0500 Subject: [PATCH 2/7] Remove secret_token.rb --- .../templates/config/initializers/secret_token.rb.tt | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt deleted file mode 100644 index f3cc6098a3..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt +++ /dev/null @@ -1,12 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Your secret key is used for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! - -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -# You can use `rake secret` to generate a secure secret key. - -# Make sure your secret_key_base is kept private -# if you're sharing your code publicly. -Rails.application.config.secret_key_base = '<%= app_secret %>' From 3eaa29840b92813f37adcc41d3d8c08d976480a4 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Tue, 10 Dec 2013 10:04:07 -0500 Subject: [PATCH 3/7] Load secret_key_base from tokens.yml, fallback to config.secret_key_base --- railties/lib/rails/application.rb | 34 +++++++++++++++---- .../lib/rails/application/configuration.rb | 1 + railties/test/abstract_unit.rb | 2 +- .../test/application/configuration_test.rb | 26 ++++++++++++-- railties/test/isolation/abstract_unit.rb | 3 +- 5 files changed, 54 insertions(+), 12 deletions(-) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index e45bfaf6fc..20e90737b0 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -1,4 +1,5 @@ require 'fileutils' +require 'active_support/core_ext/hash/keys' require 'active_support/core_ext/object/blank' require 'active_support/key_generator' require 'active_support/message_verifier' @@ -104,7 +105,7 @@ module Rails delegate :default_url_options, :default_url_options=, to: :routes INITIAL_VARIABLES = [:config, :railties, :routes_reloader, :reloaders, - :routes, :helpers, :app_env_config] # :nodoc: + :routes, :helpers, :app_env_config, :secrets] # :nodoc: def initialize(initial_variable_values = {}, &block) super() @@ -151,8 +152,8 @@ module Rails # number of iterations selected based on consultation with the google security # team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220 @caching_key_generator ||= begin - if config.secret_key_base - key_generator = ActiveSupport::KeyGenerator.new(config.secret_key_base, iterations: 1000) + if secrets.secret_key_base + key_generator = ActiveSupport::KeyGenerator.new(secrets.secret_key_base, iterations: 1000) ActiveSupport::CachingKeyGenerator.new(key_generator) else ActiveSupport::LegacyKeyGenerator.new(config.secret_token) @@ -195,7 +196,7 @@ 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_key_base" => config.secret_key_base, + "action_dispatch.secret_key_base" => secrets.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, @@ -300,6 +301,27 @@ module Rails @config = configuration end + def secrets #:nodoc: + @secrets ||= begin + secrets = ActiveSupport::OrderedOptions.new + yaml = config.paths["config/tokens"].first + if File.exist?(yaml) + require "erb" + env_secrets = YAML.load(ERB.new(IO.read(yaml)).result)[Rails.env] + secrets.merge!(env_secrets.symbolize_keys) if env_secrets + end + + # Fallback to config.secret_key_base if secrets.secret_key_base isn't set + secrets.secret_key_base ||= config.secret_key_base + + secrets + end + end + + def secrets=(secrets) #:nodoc: + @secrets = secrets + end + def to_app #:nodoc: self end @@ -391,8 +413,8 @@ module Rails end def validate_secret_key_config! #:nodoc: - if config.secret_key_base.blank? && config.secret_token.blank? - raise "You must set config.secret_key_base in your app's config." + if secrets.secret_key_base.blank? && config.secret_token.blank? + raise "You must set secret_key_base in your app's config" end end end diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index dd0b9c6d70..f835ccceaa 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -76,6 +76,7 @@ module Rails @paths ||= begin paths = super paths.add "config/database", with: "config/database.yml" + paths.add "config/tokens", with: "config/tokens.yml" paths.add "config/environment", with: "config/environment.rb" paths.add "lib/templates" paths.add "log", with: "log/#{Rails.env}.log" diff --git a/railties/test/abstract_unit.rb b/railties/test/abstract_unit.rb index 643cc6b0ee..ade08d3f5a 100644 --- a/railties/test/abstract_unit.rb +++ b/railties/test/abstract_unit.rb @@ -14,6 +14,6 @@ require 'rails/all' module TestApp class Application < Rails::Application config.root = File.dirname(__FILE__) - config.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33' + secrets.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33' end end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index b3fbceb0dc..1f3127b069 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -250,7 +250,7 @@ module ApplicationTests test "Use key_generator when secret_key_base is set" do make_basic_app do |app| - app.config.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33' + app.secrets.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33' app.config.session_store :disabled end @@ -270,7 +270,7 @@ module ApplicationTests test "application verifier can be used in the entire application" do make_basic_app do |app| - app.config.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33' + app.secrets.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33' app.config.session_store :disabled end @@ -285,7 +285,7 @@ module ApplicationTests test "application verifier can build different verifiers" do make_basic_app do |app| - app.config.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33' + app.secrets.secret_key_base = 'b3c631c314c0bbca50c1b2843150fe33' app.config.session_store :disabled end @@ -303,6 +303,26 @@ module ApplicationTests assert_not_equal default_verifier.object_id, text_verifier.object_id end + test "secrets.secret_key_base is used when config/tokens.yml is present" do + app_file 'config/tokens.yml', <<-YAML + development: + secret_key_base: 3b7cd727ee24e8444053437c36cc66c3 + YAML + + require "#{app_path}/config/environment" + assert_equal '3b7cd727ee24e8444053437c36cc66c3', app.secrets.secret_key_base + end + + test "secret_key_base is copied from config to secrets when not set" do + remove_file "config/tokens.yml" + app_file 'config/initializers/secret_token.rb', <<-RUBY + Rails.application.config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c3" + RUBY + + require "#{app_path}/config/environment" + assert_equal '3b7cd727ee24e8444053437c36cc66c3', app.secrets.secret_key_base + end + test "protect from forgery is the default in a new app" do make_basic_app diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index 913e2b5e29..362c2c510a 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -119,7 +119,6 @@ module TestHelpers add_to_config <<-RUBY config.eager_load = false - config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4" config.session_store :cookie_store, key: "_myapp_session" config.active_support.deprecation = :log config.action_controller.allow_forgery_protection = false @@ -139,7 +138,7 @@ module TestHelpers app = Class.new(Rails::Application) app.config.eager_load = false - app.config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4" + app.secrets.secret_key_base = "3b7cd727ee24e8444053437c36cc66c4" app.config.session_store :cookie_store, key: "_myapp_session" app.config.active_support.deprecation = :log From 404314779263e120ce0da5ae62f09c19114476d7 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Thu, 12 Dec 2013 11:07:31 -0500 Subject: [PATCH 4/7] Replace config.secret_key_base with secrets.secret_key_base in test --- railties/test/application/middleware/session_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/railties/test/application/middleware/session_test.rb b/railties/test/application/middleware/session_test.rb index 14a56176f5..31a64c2f5a 100644 --- a/railties/test/application/middleware/session_test.rb +++ b/railties/test/application/middleware/session_test.rb @@ -318,7 +318,7 @@ module ApplicationTests add_to_config <<-RUBY config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" - config.secret_key_base = nil + secrets.secret_key_base = nil RUBY require "#{app_path}/config/environment" From 39fd0be7660e2f666328af85c705c3df5a8ac09e Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Thu, 12 Dec 2013 11:39:15 -0500 Subject: [PATCH 5/7] Add test for custom tokens stored in config/tokens.yml --- railties/test/application/configuration_test.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 1f3127b069..6554e0e08a 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -323,6 +323,19 @@ module ApplicationTests assert_equal '3b7cd727ee24e8444053437c36cc66c3', app.secrets.secret_key_base end + test "custom secrets saved in config/tokens.yml are loaded in app secrets" do + app_file 'config/tokens.yml', <<-YAML + development: + secret_key_base: 3b7cd727ee24e8444053437c36cc66c3 + aws_access_key_id: myamazonaccesskeyid + aws_secret_access_key: myamazonsecretaccesskey + YAML + + require "#{app_path}/config/environment" + assert_equal 'myamazonaccesskeyid', app.secrets.aws_access_key_id + assert_equal 'myamazonsecretaccesskey', app.secrets.aws_secret_access_key + end + test "protect from forgery is the default in a new app" do make_basic_app From bb7537bc872e0a724fa97468e5899de0c70c1fc1 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Thu, 12 Dec 2013 14:58:53 -0500 Subject: [PATCH 6/7] Rename tokens.yml to secrets.yml --- railties/lib/rails/application.rb | 2 +- railties/lib/rails/application/configuration.rb | 2 +- railties/lib/rails/generators/rails/app/app_generator.rb | 2 +- .../rails/app/templates/config/{tokens.yml => secrets.yml} | 0 railties/test/application/configuration_test.rb | 6 +++--- 5 files changed, 6 insertions(+), 6 deletions(-) rename railties/lib/rails/generators/rails/app/templates/config/{tokens.yml => secrets.yml} (100%) diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 20e90737b0..06acb4c877 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -304,7 +304,7 @@ module Rails def secrets #:nodoc: @secrets ||= begin secrets = ActiveSupport::OrderedOptions.new - yaml = config.paths["config/tokens"].first + yaml = config.paths["config/secrets"].first if File.exist?(yaml) require "erb" env_secrets = YAML.load(ERB.new(IO.read(yaml)).result)[Rails.env] diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb index f835ccceaa..9975bb8596 100644 --- a/railties/lib/rails/application/configuration.rb +++ b/railties/lib/rails/application/configuration.rb @@ -76,7 +76,7 @@ module Rails @paths ||= begin paths = super paths.add "config/database", with: "config/database.yml" - paths.add "config/tokens", with: "config/tokens.yml" + paths.add "config/secrets", with: "config/secrets.yml" paths.add "config/environment", with: "config/environment.rb" paths.add "lib/templates" paths.add "log", with: "log/#{Rails.env}.log" diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 2c4911cadc..e12ee3c713 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -78,7 +78,7 @@ module Rails template "routes.rb" template "application.rb" template "environment.rb" - template "tokens.yml" + template "secrets.yml" directory "environments" directory "initializers" diff --git a/railties/lib/rails/generators/rails/app/templates/config/tokens.yml b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml similarity index 100% rename from railties/lib/rails/generators/rails/app/templates/config/tokens.yml rename to railties/lib/rails/generators/rails/app/templates/config/secrets.yml diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 6554e0e08a..e024ec8cef 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -304,7 +304,7 @@ module ApplicationTests end test "secrets.secret_key_base is used when config/tokens.yml is present" do - app_file 'config/tokens.yml', <<-YAML + app_file 'config/secrets.yml', <<-YAML development: secret_key_base: 3b7cd727ee24e8444053437c36cc66c3 YAML @@ -314,7 +314,7 @@ module ApplicationTests end test "secret_key_base is copied from config to secrets when not set" do - remove_file "config/tokens.yml" + remove_file "config/secrets.yml" app_file 'config/initializers/secret_token.rb', <<-RUBY Rails.application.config.secret_key_base = "3b7cd727ee24e8444053437c36cc66c3" RUBY @@ -324,7 +324,7 @@ module ApplicationTests end test "custom secrets saved in config/tokens.yml are loaded in app secrets" do - app_file 'config/tokens.yml', <<-YAML + app_file 'config/secrets.yml', <<-YAML development: secret_key_base: 3b7cd727ee24e8444053437c36cc66c3 aws_access_key_id: myamazonaccesskeyid From c1f4bc262884668217060d3a74ebafbf60bc44b3 Mon Sep 17 00:00:00 2001 From: Guillermo Iguaran Date: Fri, 13 Dec 2013 12:47:37 -0500 Subject: [PATCH 7/7] Add comment about secret_key_base in secrets.yml --- .../rails/app/templates/config/secrets.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml index 3ce5de1dc9..50c1d1d8c7 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml @@ -1,3 +1,15 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rake secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + development: secret_key_base: <%= app_secret %>