From e38b860374e786b8a703740942edfd11a2ad11a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Wed, 2 Nov 2022 23:24:35 +0100 Subject: [PATCH] Use the right tenant after Devise redirections This is something we had read about a long time ago, but didn't find how to reproduce the issue until now. As mentioned in the Apartment documentation: > it's important to consider that you may want to maintain the > "selected" tenant through different parts of the Rack application > stack. For example, the Devise gem adds the Warden::Manager middleware > at the end of the stack in the examples above, our > Apartment::Elevators::Subdomain middleware would come after it. > Trouble is, Apartment resets the selected tenant after the request is > finished, so some redirects (e.g. authentication) in Devise will be > run in the context of the "public" tenant. The same issue would also > effect a gem such as the better_errors gem which inserts a middleware > quite early in the Rails middleware stack. > > To resolve this issue, consider adding the Apartment middleware at a > location in the Rack stack that makes sense for your needs, e.g.: > > Rails.application.config.middleware.insert_before Warden::Manager, > Apartment::Elevators::Subdomain > > Now work done in the Warden middleware is wrapped in the > Apartment::Tenant.switch context started in the Generic elevator. --- config/initializers/apartment.rb | 2 +- spec/system/multitenancy_spec.rb | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index 3088a06c2..511699f4b 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -107,7 +107,7 @@ end # Setup a custom Tenant switching middleware. The Proc should return the name of the Tenant that # you want to switch to. -Rails.application.config.middleware.use Apartment::Elevators::Generic, ->(request) do +Rails.application.config.middleware.insert_before Warden::Manager, Apartment::Elevators::Generic, ->(request) do Tenant.resolve_host(request.host) end diff --git a/spec/system/multitenancy_spec.rb b/spec/system/multitenancy_spec.rb index dd1f25e84..45f6d473f 100644 --- a/spec/system/multitenancy_spec.rb +++ b/spec/system/multitenancy_spec.rb @@ -156,4 +156,17 @@ describe "Multitenancy", :seed_tenants do expect(page).to have_content "Invalid Email or username or password." end end + + scenario "Uses the right tenant after failing to sign in" do + with_subdomain("mars") do + visit new_user_session_path + fill_in "Email or username", with: "wrong@consul.dev" + fill_in "Password", with: "wrong" + click_button "Enter" + + expect(page).to have_content "Invalid Email or username or password" + expect(page).to have_css "html.tenant-mars" + expect(page).not_to have_css "html.tenant-public" + end + end end