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--guides/source/engines.md2
-rw-r--r--guides/source/plugins.md4
-rw-r--r--railties/test/application/middleware/cookies_test.rb64
-rw-r--r--railties/test/application/middleware/session_test.rb2
6 files changed, 42 insertions, 46 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/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/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)'