mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 14:38:17 +08:00
DEV: Migrate existing cookies to Rails 7 format
This patch introduces a cookies rotator as indicated in the Rails upgrade guide. This allows to migrate from the old SHA1 digest to the new SHA256 digest.
This commit is contained in:
parent
1a759fd75f
commit
66e8fe9cc6
|
@ -171,6 +171,9 @@ module Discourse
|
|||
require "middleware/discourse_public_exceptions"
|
||||
config.exceptions_app = Middleware::DiscoursePublicExceptions.new(Rails.public_path)
|
||||
|
||||
require "middleware/cookies_rotator"
|
||||
config.middleware.insert_before ActionDispatch::Cookies, Middleware::CookiesRotator
|
||||
|
||||
require "discourse_js_processor"
|
||||
require "discourse_sourcemapping_url_processor"
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ Rails.application.config.action_view.apply_stylesheet_media_default = false
|
|||
#
|
||||
# See upgrading guide for more information on how to build a rotator.
|
||||
# https://guides.rubyonrails.org/v7.0/upgrading_ruby_on_rails.html
|
||||
# Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
|
||||
Rails.application.config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
|
||||
|
||||
# Change the digest class for ActiveSupport::Digest.
|
||||
# Changing this default means that for example Etags change and
|
||||
|
|
34
lib/middleware/cookies_rotator.rb
Normal file
34
lib/middleware/cookies_rotator.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Implementing cookies rotator for Rails 7+ as a middleware because this will
|
||||
# work in single site mode AND in multisite mode without leaking anything in
|
||||
# `Rails.application.config.action_dispatch.cookies_rotations`.
|
||||
module Middleware
|
||||
class CookiesRotator
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
request = ActionDispatch::Request.new(env)
|
||||
env[
|
||||
ActionDispatch::Cookies::COOKIES_ROTATIONS
|
||||
] = ActiveSupport::Messages::RotationConfiguration.new.tap do |cookies|
|
||||
key_generator =
|
||||
ActiveSupport::KeyGenerator.new(
|
||||
request.secret_key_base,
|
||||
iterations: 1000,
|
||||
hash_digest_class: OpenSSL::Digest::SHA1,
|
||||
)
|
||||
key_len = ActiveSupport::MessageEncryptor.key_len
|
||||
|
||||
cookies.rotate(
|
||||
:encrypted,
|
||||
key_generator.generate_key(request.authenticated_encrypted_cookie_salt, key_len),
|
||||
)
|
||||
cookies.rotate(:signed, key_generator.generate_key(request.signed_cookie_salt))
|
||||
end
|
||||
@app.call(env)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,9 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe "multisite", type: %i[multisite request] do
|
||||
let!(:first_host) { get "http://test.localhost/session/csrf.json" }
|
||||
|
||||
it "works" do
|
||||
get "http://test.localhost/session/csrf.json"
|
||||
expect(response.status).to eq(200)
|
||||
expect(response).to have_http_status :ok
|
||||
cookie = CGI.escape(response.cookies["_forum_session"])
|
||||
id1 = session["session_id"]
|
||||
|
||||
|
@ -11,7 +13,7 @@ RSpec.describe "multisite", type: %i[multisite request] do
|
|||
headers: {
|
||||
"Cookie" => "_forum_session=#{cookie};",
|
||||
}
|
||||
expect(response.status).to eq(200)
|
||||
expect(response).to have_http_status :ok
|
||||
id2 = session["session_id"]
|
||||
|
||||
expect(id1).to eq(id2)
|
||||
|
@ -20,10 +22,31 @@ RSpec.describe "multisite", type: %i[multisite request] do
|
|||
headers: {
|
||||
"Cookie" => "_forum_session=#{cookie};",
|
||||
}
|
||||
expect(response.status).to eq(200)
|
||||
expect(response).to have_http_status :ok
|
||||
id3 = session["session_id"]
|
||||
|
||||
# Session cookie was rejected and rotated
|
||||
expect(id2).not_to eq(id3)
|
||||
end
|
||||
|
||||
describe "Cookies rotator" do
|
||||
let!(:rotations) { request.cookies_rotations }
|
||||
let(:second_host) { get "http://test2.localhost/session/csrf.json" }
|
||||
let(:global_rotations) { Rails.application.config.action_dispatch.cookies_rotations }
|
||||
|
||||
it "adds different rotations for different hosts" do
|
||||
first_host
|
||||
expect(request.cookies_rotations).to have_attributes signed: rotations.signed,
|
||||
encrypted: rotations.encrypted
|
||||
|
||||
second_host
|
||||
expect(request.cookies_rotations).not_to have_attributes signed: rotations.signed,
|
||||
encrypted: rotations.encrypted
|
||||
end
|
||||
|
||||
it "doesn't change global rotations" do
|
||||
second_host
|
||||
expect(global_rotations).to have_attributes signed: [], encrypted: []
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user