aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_dispatch/middleware/cookies.rb5
-rw-r--r--activerecord/lib/active_record/reflection.rb11
-rw-r--r--activesupport/test/message_encryptor_test.rb2
-rw-r--r--guides/source/engines.md2
-rw-r--r--guides/source/plugins.md4
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb6
-rw-r--r--railties/lib/rails/generators/rails/master_key/master_key_generator.rb26
-rw-r--r--railties/test/application/middleware/cookies_test.rb64
-rw-r--r--railties/test/application/middleware/session_test.rb2
-rw-r--r--railties/test/generators/app_generator_test.rb7
10 files changed, 65 insertions, 64 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb
index baffe200bc..0213987c99 100644
--- a/actionpack/lib/action_dispatch/middleware/cookies.rb
+++ b/actionpack/lib/action_dispatch/middleware/cookies.rb
@@ -608,10 +608,11 @@ module ActionDispatch
end
if upgrade_legacy_hmac_aes_cbc_cookies?
- secret = request.key_generator.generate_key(request.encrypted_cookie_salt)
+ legacy_cipher = "aes-256-cbc"
+ secret = request.key_generator.generate_key(request.encrypted_cookie_salt, ActiveSupport::MessageEncryptor.key_len(legacy_cipher))
sign_secret = request.key_generator.generate_key(request.encrypted_signed_cookie_salt)
- @encryptor.rotate secret, sign_secret, cipher: "aes-256-cbc", digest: digest, serializer: SERIALIZER
+ @encryptor.rotate(secret, sign_secret, cipher: legacy_cipher, digest: digest, serializer: SERIALIZER)
end
if upgrade_legacy_signed_cookies?
diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb
index 82ab2415e1..032df925bf 100644
--- a/activerecord/lib/active_record/reflection.rb
+++ b/activerecord/lib/active_record/reflection.rb
@@ -425,7 +425,6 @@ module ActiveRecord
def initialize(name, scope, options, active_record)
super
- @automatic_inverse_of = nil
@type = options[:as] && (options[:foreign_type] || "#{options[:as]}_type")
@foreign_type = options[:foreign_type] || "#{name}_type"
@constructable = calculate_constructable(macro, options)
@@ -609,12 +608,14 @@ module ActiveRecord
# If it cannot find a suitable inverse association name, it returns
# +nil+.
def inverse_name
- options.fetch(:inverse_of) do
- @automatic_inverse_of ||= automatic_inverse_of
+ unless defined?(@inverse_name)
+ @inverse_name = options.fetch(:inverse_of) { automatic_inverse_of }
end
+
+ @inverse_name
end
- # returns either false or the inverse association name that it finds.
+ # returns either +nil+ or the inverse association name that it finds.
def automatic_inverse_of
if can_find_inverse_of_automatically?(self)
inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_record.name.demodulize).to_sym
@@ -631,8 +632,6 @@ module ActiveRecord
return inverse_name
end
end
-
- false
end
# Checks if the inverse reflection that is returned from the
diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb
index 8fde3928dc..9edf07f762 100644
--- a/activesupport/test/message_encryptor_test.rb
+++ b/activesupport/test/message_encryptor_test.rb
@@ -201,7 +201,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase
end
def secrets
- @secrets ||= Hash.new { |h,k| h[k] = SecureRandom.random_bytes(32) }
+ @secrets ||= Hash.new { |h, k| h[k] = SecureRandom.random_bytes(32) }
end
def munge(base64_string)
diff --git a/guides/source/engines.md b/guides/source/engines.md
index c7331b6ca4..343c224a7c 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -1322,7 +1322,7 @@ engine.
Assets within an engine work in an identical way to a full application. Because
the engine class inherits from `Rails::Engine`, the application will know to
-look up assets in the engine's 'app/assets' and 'lib/assets' directories.
+look up assets in the engine's `app/assets` and `lib/assets` directories.
Like all of the other components of an engine, the assets should be namespaced.
This means that if you have an asset called `style.css`, it should be placed at
diff --git a/guides/source/plugins.md b/guides/source/plugins.md
index b3a7f544f5..5048444cb2 100644
--- a/guides/source/plugins.md
+++ b/guides/source/plugins.md
@@ -359,7 +359,7 @@ When you run `bin/test`, you should see the tests all pass:
### Add an Instance Method
-This plugin will add a method named 'squawk' to any Active Record object that calls 'acts_as_yaffle'. The 'squawk'
+This plugin will add a method named 'squawk' to any Active Record object that calls `acts_as_yaffle`. The 'squawk'
method will simply set the value of one of the fields in the database.
To start out, write a failing test that shows the behavior you'd like:
@@ -392,7 +392,7 @@ end
```
Run the test to make sure the last two tests fail with an error that contains "NoMethodError: undefined method `squawk'",
-then update 'acts_as_yaffle.rb' to look like this:
+then update `acts_as_yaffle.rb` to look like this:
```ruby
# yaffle/lib/yaffle/acts_as_yaffle.rb
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index ac82ff6633..23fdf03b05 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -69,7 +69,7 @@ module Rails
def version_control
if !options[:skip_git] && !options[:pretend]
- run "git init"
+ run "git init", capture: options[:quiet]
end
end
@@ -164,7 +164,7 @@ module Rails
require_relative "../master_key/master_key_generator"
after_bundle do
- Rails::Generators::MasterKeyGenerator.new.add_master_key_file
+ Rails::Generators::MasterKeyGenerator.new([], quiet: options[:quiet]).add_master_key_file
end
end
@@ -174,7 +174,7 @@ module Rails
require_relative "../credentials/credentials_generator"
after_bundle do
- Rails::Generators::CredentialsGenerator.new.add_credentials_file_silently
+ Rails::Generators::CredentialsGenerator.new([], quiet: options[:quiet]).add_credentials_file_silently
end
end
diff --git a/railties/lib/rails/generators/rails/master_key/master_key_generator.rb b/railties/lib/rails/generators/rails/master_key/master_key_generator.rb
index e49d3b39e0..395687974a 100644
--- a/railties/lib/rails/generators/rails/master_key/master_key_generator.rb
+++ b/railties/lib/rails/generators/rails/master_key/master_key_generator.rb
@@ -13,15 +13,15 @@ module Rails
unless MASTER_KEY_PATH.exist?
key = ActiveSupport::EncryptedFile.generate_key
- say "Adding #{MASTER_KEY_PATH} to store the master encryption key: #{key}"
- say ""
- say "Save this in a password manager your team can access."
- say ""
- say "If you lose the key, no one, including you, can access anything encrypted with it."
+ log "Adding #{MASTER_KEY_PATH} to store the master encryption key: #{key}"
+ log ""
+ log "Save this in a password manager your team can access."
+ log ""
+ log "If you lose the key, no one, including you, can access anything encrypted with it."
- say ""
+ log ""
create_file MASTER_KEY_PATH, key
- say ""
+ log ""
ignore_master_key_file
end
@@ -31,15 +31,15 @@ module Rails
def ignore_master_key_file
if File.exist?(".gitignore")
unless File.read(".gitignore").include?(key_ignore)
- say "Ignoring #{MASTER_KEY_PATH} so it won't end up in Git history:"
- say ""
+ log "Ignoring #{MASTER_KEY_PATH} so it won't end up in Git history:"
+ log ""
append_to_file ".gitignore", key_ignore
- say ""
+ log ""
end
else
- say "IMPORTANT: Don't commit #{MASTER_KEY_PATH}. Add this to your ignore file:"
- say key_ignore, :on_green
- say ""
+ log "IMPORTANT: Don't commit #{MASTER_KEY_PATH}. Add this to your ignore file:"
+ log key_ignore, :on_green
+ log ""
end
end
diff --git a/railties/test/application/middleware/cookies_test.rb b/railties/test/application/middleware/cookies_test.rb
index 092f7a1099..ecb4ee3446 100644
--- a/railties/test/application/middleware/cookies_test.rb
+++ b/railties/test/application/middleware/cookies_test.rb
@@ -52,14 +52,6 @@ module ApplicationTests
end
test "signed cookies with SHA512 digest and rotated out SHA256 and SHA1 digests" do
- skip "@kaspth will fix this"
-
- key_gen_sha1 = ActiveSupport::KeyGenerator.new("legacy sha1 secret", iterations: 1000)
- key_gen_sha256 = ActiveSupport::KeyGenerator.new("legacy sha256 secret", iterations: 1000)
-
- verifer_sha1 = ActiveSupport::MessageVerifier.new(key_gen_sha1.generate_key("sha1 salt"), digest: :SHA1)
- verifer_sha256 = ActiveSupport::MessageVerifier.new(key_gen_sha256.generate_key("sha256 salt"), digest: :SHA256)
-
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
get ':controller(/:action)'
@@ -72,12 +64,12 @@ module ApplicationTests
protect_from_forgery with: :null_session
def write_raw_cookie_sha1
- cookies[:signed_cookie] = "#{verifer_sha1.generate("signed cookie")}"
+ cookies[:signed_cookie] = TestVerifiers.sha1.generate("signed cookie")
head :ok
end
def write_raw_cookie_sha256
- cookies[:signed_cookie] = "#{verifer_sha256.generate("signed cookie")}"
+ cookies[:signed_cookie] = TestVerifiers.sha256.generate("signed cookie")
head :ok
end
@@ -92,44 +84,43 @@ module ApplicationTests
RUBY
add_to_config <<-RUBY
- config.action_dispatch.cookies_rotations.rotate :signed,
- digest: "SHA1", secret: "legacy sha1 secret", salt: "sha1 salt"
+ sha1_secret = Rails.application.key_generator.generate_key("sha1")
+ sha256_secret = Rails.application.key_generator.generate_key("sha256")
- config.action_dispatch.cookies_rotations.rotate :signed,
- digest: "SHA256", secret: "legacy sha256 secret", salt: "sha256 salt"
+ ::TestVerifiers = Class.new do
+ class_attribute :sha1, default: ActiveSupport::MessageVerifier.new(sha1_secret, digest: "SHA1")
+ class_attribute :sha256, default: ActiveSupport::MessageVerifier.new(sha256_secret, digest: "SHA256")
+ end
config.action_dispatch.signed_cookie_digest = "SHA512"
config.action_dispatch.signed_cookie_salt = "sha512 salt"
+
+ config.action_dispatch.cookies_rotations.tap do |cookies|
+ cookies.rotate :signed, sha1_secret, digest: "SHA1"
+ cookies.rotate :signed, sha256_secret, digest: "SHA256"
+ end
RUBY
require "#{app_path}/config/environment"
- verifer_sha512 = ActiveSupport::MessageVerifier.new(app.key_generator.generate_key("sha512 salt"), digest: :SHA512)
+ verifier_sha512 = ActiveSupport::MessageVerifier.new(app.key_generator.generate_key("sha512 salt"), digest: :SHA512)
get "/foo/write_raw_cookie_sha1"
get "/foo/read_signed"
assert_equal "signed cookie".inspect, last_response.body
get "/foo/read_raw_cookie"
- assert_equal "signed cookie", verifer_sha512.verify(last_response.body)
+ assert_equal "signed cookie", verifier_sha512.verify(last_response.body)
get "/foo/write_raw_cookie_sha256"
get "/foo/read_signed"
assert_equal "signed cookie".inspect, last_response.body
get "/foo/read_raw_cookie"
- assert_equal "signed cookie", verifer_sha512.verify(last_response.body)
+ assert_equal "signed cookie", verifier_sha512.verify(last_response.body)
end
- test "encrypted cookies with multiple rotated out ciphers" do
- skip "@kaspth will fix this"
-
- key_gen_one = ActiveSupport::KeyGenerator.new("legacy secret one", iterations: 1000)
- key_gen_two = ActiveSupport::KeyGenerator.new("legacy secret two", iterations: 1000)
-
- encryptor_one = ActiveSupport::MessageEncryptor.new(key_gen_one.generate_key("salt one", 32), cipher: "aes-256-gcm")
- encryptor_two = ActiveSupport::MessageEncryptor.new(key_gen_two.generate_key("salt two", 32), cipher: "aes-256-gcm")
-
+ test "encrypted cookies rotating multiple encryption keys" do
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
get ':controller(/:action)'
@@ -142,12 +133,12 @@ module ApplicationTests
protect_from_forgery with: :null_session
def write_raw_cookie_one
- cookies[:encrypted_cookie] = "#{encryptor_one.encrypt_and_sign("encrypted cookie")}"
+ cookies[:encrypted_cookie] = TestEncryptors.first_gcm.encrypt_and_sign("encrypted cookie")
head :ok
end
def write_raw_cookie_two
- cookies[:encrypted_cookie] = "#{encryptor_two.encrypt_and_sign("encrypted cookie")}"
+ cookies[:encrypted_cookie] = TestEncryptors.second_gcm.encrypt_and_sign("encrypted cookie")
head :ok
end
@@ -162,15 +153,22 @@ module ApplicationTests
RUBY
add_to_config <<-RUBY
+ first_secret = Rails.application.key_generator.generate_key("first", 32)
+ second_secret = Rails.application.key_generator.generate_key("second", 32)
+
+ ::TestEncryptors = Class.new do
+ class_attribute :first_gcm, default: ActiveSupport::MessageEncryptor.new(first_secret, cipher: "aes-256-gcm")
+ class_attribute :second_gcm, default: ActiveSupport::MessageEncryptor.new(second_secret, cipher: "aes-256-gcm")
+ end
+
config.action_dispatch.use_authenticated_cookie_encryption = true
config.action_dispatch.encrypted_cookie_cipher = "aes-256-gcm"
config.action_dispatch.authenticated_encrypted_cookie_salt = "salt"
- config.action_dispatch.cookies_rotations.rotate :encrypted,
- cipher: "aes-256-gcm", secret: "legacy secret one", salt: "salt one"
-
- config.action_dispatch.cookies_rotations.rotate :encrypted,
- cipher: "aes-256-gcm", secret: "legacy secret two", salt: "salt two"
+ config.action_dispatch.cookies_rotations.tap do |cookies|
+ cookies.rotate :encrypted, first_secret
+ cookies.rotate :encrypted, second_secret
+ end
RUBY
require "#{app_path}/config/environment"
diff --git a/railties/test/application/middleware/session_test.rb b/railties/test/application/middleware/session_test.rb
index 36d1bf5bf2..a17988235a 100644
--- a/railties/test/application/middleware/session_test.rb
+++ b/railties/test/application/middleware/session_test.rb
@@ -301,8 +301,6 @@ module ApplicationTests
end
test "session upgrading from AES-CBC-HMAC encryption to AES-GCM encryption" do
- skip "@kaspth will fix this"
-
app_file "config/routes.rb", <<-RUBY
Rails.application.routes.draw do
get ':controller(/:action)'
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 904e2a5c84..20f593f25c 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -560,6 +560,11 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_no_match(/run git init/, output)
end
+ def test_quiet_option
+ output = run_generator [File.join(destination_root, "myapp"), "--quiet"]
+ assert_empty output
+ end
+
def test_application_name_with_spaces
path = File.join(destination_root, "foo bar")
@@ -737,7 +742,7 @@ class AppGeneratorTest < Rails::Generators::TestCase
sequence = ["git init", "install", "exec spring binstub --all", "echo ran after_bundle"]
@sequence_step ||= 0
- ensure_bundler_first = -> command do
+ ensure_bundler_first = -> command, options = nil do
assert_equal sequence[@sequence_step], command, "commands should be called in sequence #{sequence}"
@sequence_step += 1
end