DEV: better error message when "becoming" an inactive user (#32689)

In development mode, when 'DISCOURSE_DEV_ALLOW_ANON_TO_IMPERSONATE' is
enabled, and going to /session/:username/become, we will now show an
error message when trying to impersonate an inactive user.

This was not obvious why trying to impersonate a user wasn't working
locally because I would hit the URL and be redirected back to the index
without any error and without being logged in.
This commit is contained in:
Régis Hanol
2025-05-13 11:10:12 +02:00
committed by GitHub
parent 32ba12a408
commit 70a0cc4d7a
2 changed files with 42 additions and 15 deletions

View File

@ -110,19 +110,22 @@ class SessionController < ApplicationController
raise Discourse::ReadOnly if @readonly_mode raise Discourse::ReadOnly if @readonly_mode
if ENV["DISCOURSE_DEV_ALLOW_ANON_TO_IMPERSONATE"] != "1" if ENV["DISCOURSE_DEV_ALLOW_ANON_TO_IMPERSONATE"] != "1"
render(content_type: "text/plain", inline: <<~TEXT) return render plain: <<~TEXT, status: 403
To enable impersonating any user without typing passwords set the following ENV var To enable impersonating any user without typing passwords set the following ENV var
export DISCOURSE_DEV_ALLOW_ANON_TO_IMPERSONATE=1 export DISCOURSE_DEV_ALLOW_ANON_TO_IMPERSONATE=1
You can do that in your bashrc of bash profile file or the script you use to launch the web server You can do that in your bashrc of bash profile file or the script you use to launch the web server
TEXT TEXT
return
end end
user = User.find_by_username(params[:session_id]) user = User.find_by_username(params[:session_id])
raise "User #{params[:session_id]} not found" if user.blank?
if user.blank?
return render plain: "User #{params[:session_id]} not found", status: 403
elsif !user.active?
return render plain: "User #{params[:session_id]} is not active", status: 403
end
log_on_user(user) log_on_user(user)

View File

@ -522,20 +522,44 @@ RSpec.describe SessionController do
describe "#become" do describe "#become" do
let!(:user) { Fabricate(:user) } let!(:user) { Fabricate(:user) }
it "does not work when in production mode" do describe "when in production mode" do
Rails.env.stubs(:production?).returns(true) before { Rails.env.stubs(:production?).returns(true) }
get "/session/#{user.username}/become.json"
it "does not work" do
get "/session/#{user.username}/become"
expect(response.status).to eq(403) expect(response.status).to eq(403)
expect(response.parsed_body["error_type"]).to eq("invalid_access") expect(session[:current_user_id]).to be_blank
end
end
describe "when in development mode" do
before { Rails.env.stubs(:development?).returns(true) }
it "works" do
get "/session/#{user.username}/become"
expect(response).to be_redirect
expect(session[:current_user_id]).to eq(user.id)
end
it "raises an error if the user is not found" do
get "/session/invalid_user/become"
expect(response.status).to eq(403)
expect(response.body).to include("User invalid_user not found")
expect(session[:current_user_id]).to be_blank expect(session[:current_user_id]).to be_blank
end end
it "works in development mode" do it "raises an error if the user is not active" do
Rails.env.stubs(:development?).returns(true) user.update!(active: false)
get "/session/#{user.username}/become.json"
expect(response).to be_redirect get "/session/#{user.username}/become"
expect(session[:current_user_id]).to eq(user.id)
expect(response.status).to eq(403)
expect(response.body).to include("User #{user.username} is not active")
expect(session[:current_user_id]).to be_blank
end
end end
end end