From 35577ad5bf41fd8925614b292af03b6377ced81c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janko=20Marohni=C4=87?= Date: Wed, 7 Feb 2024 00:34:32 +0100 Subject: [PATCH] Fix routes with path format not working in front of http_basic_auth If a request was made to /my_data.xml with `Accept: */*`, and there was http basic authentication in front in the Rodauth middleware, the requested format wouldn't get selected when it came to processing the controller action. This is because rodauth-rails would infer formats from the `Accept` header as soon as it instantiated the controller (which would happen when logging the user in from Authorization header), preventing Rails from inferring the format from the URL path. We fix that by only doing this before handling Rodauth endpoints, leaving requests to Rails endpoints untouched. Fixes #272 --- lib/rodauth/rails/feature/render.rb | 7 +++---- test/integration/render_test.rb | 15 +++++++++++++++ test/rails_app/app/controllers/test_controller.rb | 7 +++++++ test/rails_app/app/misc/rodauth_app.rb | 3 +++ test/rails_app/app/misc/rodauth_main.rb | 2 +- test/rails_app/config/routes.rb | 1 + 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/rodauth/rails/feature/render.rb b/lib/rodauth/rails/feature/render.rb index 71e343ef..4cf9d928 100644 --- a/lib/rodauth/rails/feature/render.rb +++ b/lib/rodauth/rails/feature/render.rb @@ -46,10 +46,9 @@ def rails_render(*args) end # Only look up template formats that the current request is accepting. - def _rails_controller_instance - controller = super - controller.formats = rails_request.formats.map(&:ref).compact - controller + def before_rodauth + super + rails_controller_instance.formats = rails_request.formats.map(&:ref).compact end # Not all Rodauth actions are Turbo-compatible (some form submissions diff --git a/test/integration/render_test.rb b/test/integration/render_test.rb index 8c9bff64..6a582615 100644 --- a/test/integration/render_test.rb +++ b/test/integration/render_test.rb @@ -100,4 +100,19 @@ class RenderTest < IntegrationTest assert_equal %(), page.html end if defined?(::Turbo) + + test "path format is preserved with basic auth" do + Account.create!(email: "user@example.com", password: "secret123", status: "verified") + page.driver.browser.basic_authorize "user@example.com", "secret123" + + page.driver.browser.get "/basic_auth", {}, { "HTTP_ACCEPT" => "*/*" } + assert_equal "Basic Auth", page.html + assert_equal "text/plain; charset=utf-8", page.response_headers["Content-Type"] + + page.driver.browser.get "/basic_auth.json", {}, { "HTTP_ACCEPT" => "*/*" } + assert_equal "{\"message\":\"Basic Auth\"}", page.html + assert_equal "application/json; charset=utf-8", page.response_headers["Content-Type"] + + page.driver.browser.header "Authorization", nil + end end diff --git a/test/rails_app/app/controllers/test_controller.rb b/test/rails_app/app/controllers/test_controller.rb index e196180d..33c23663 100644 --- a/test/rails_app/app/controllers/test_controller.rb +++ b/test/rails_app/app/controllers/test_controller.rb @@ -13,6 +13,13 @@ def auth2 render :template end + def basic_auth + respond_to do |format| + format.text { render plain: "Basic Auth" } + format.json { render json: { message: "Basic Auth" } } + end + end + def secondary rodauth(:admin).require_authentication diff --git a/test/rails_app/app/misc/rodauth_app.rb b/test/rails_app/app/misc/rodauth_app.rb index 0e2285a1..27b64ba4 100644 --- a/test/rails_app/app/misc/rodauth_app.rb +++ b/test/rails_app/app/misc/rodauth_app.rb @@ -33,5 +33,8 @@ class RodauthApp < Rodauth::Rails::App if r.path == rails_routes.auth1_path rodauth.require_account end + if r.path.start_with?(rails_routes.basic_auth_path) + rodauth.require_http_basic_auth + end end end diff --git a/test/rails_app/app/misc/rodauth_main.rb b/test/rails_app/app/misc/rodauth_main.rb index 1eb7d361..59783561 100644 --- a/test/rails_app/app/misc/rodauth_main.rb +++ b/test/rails_app/app/misc/rodauth_main.rb @@ -1,7 +1,7 @@ class RodauthMain < Rodauth::Rails::Auth configure do enable :create_account, :verify_account, :verify_account_grace_period, - :login, :remember, :logout, :active_sessions, + :login, :remember, :logout, :active_sessions, :http_basic_auth, :reset_password, :change_password, :change_password_notify, :change_login, :verify_login_change, :close_account, :lockout, :recovery_codes, :internal_request, diff --git a/test/rails_app/config/routes.rb b/test/rails_app/config/routes.rb index 367f079e..fbc72cab 100644 --- a/test/rails_app/config/routes.rb +++ b/test/rails_app/config/routes.rb @@ -4,6 +4,7 @@ controller :test do get :auth1 get :auth2 + get :basic_auth get :secondary get :auth_json get :sign_in