FIX: crawler view with unicode usernames (#27051)

When "unicode_usernames" is enabled, calling the "user_path" helper with a username containing some non ASCII character will break due to the route constraint we have on username.

This fixes the issue by always encoding the username before passing it to the "user_path" helper.

Internal ref - t/127547
This commit is contained in:
Régis Hanol 2024-05-16 17:11:24 +02:00 committed by GitHub
parent 02469d5795
commit 0e9451e93f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 19 additions and 11 deletions

View File

@ -78,7 +78,10 @@ class GroupMessage
begin begin
h = { base_url: Discourse.base_url }.merge(@opts[:message_params] || {}) h = { base_url: Discourse.base_url }.merge(@opts[:message_params] || {})
if @opts[:user] if @opts[:user]
h.merge!(username: @opts[:user].username, user_url: user_path(@opts[:user].username)) h.merge!(
username: @opts[:user].username,
user_url: user_path(@opts[:user].encoded_username(lower: true)),
)
end end
h h
end end

View File

@ -14,8 +14,8 @@
<div class='admins-list' itemscope itemtype='http://schema.org/ItemList'> <div class='admins-list' itemscope itemtype='http://schema.org/ItemList'>
<% @about.admins.each do |user| %> <% @about.admins.each do |user| %>
<div itemprop='itemListElement' itemscope itemtype='http://schema.org/ListItem'> <div itemprop='itemListElement' itemscope itemtype='http://schema.org/ListItem'>
<meta itemprop='url' content='<%= user_path(user.username_lower) %>'> <meta itemprop='url' content='<%= user_path(user.encoded_username(lower: true)) %>'>
<a href='<%= user_path(user.username_lower) %>' itemprop='item'> <a href='<%= user_path(user.encoded_username(lower: true)) %>' itemprop='item'>
<span itemprop='image'> <span itemprop='image'>
<img width="45" height="45" class="avatar" src="<%= user.small_avatar_url %>"> <img width="45" height="45" class="avatar" src="<%= user.small_avatar_url %>">
</span> </span>
@ -35,8 +35,8 @@
<div class='moderators-list' itemscope itemtype='http://schema.org/ItemList'> <div class='moderators-list' itemscope itemtype='http://schema.org/ItemList'>
<% @about.moderators.each do |user| %> <% @about.moderators.each do |user| %>
<div itemprop='itemListElement' itemscope itemtype='http://schema.org/ListItem'> <div itemprop='itemListElement' itemscope itemtype='http://schema.org/ListItem'>
<meta itemprop='url' content='<%= user_path(user.username_lower) %>'> <meta itemprop='url' content='<%= user_path(user.encoded_username(lower: true)) %>'>
<a href='<%= user_path(user.username_lower) %>' itemprop='item'> <a href='<%= user_path(user.encoded_username(lower: true)) %>' itemprop='item'>
<span itemprop='image'> <span itemprop='image'>
<img width="45" height="45" class="avatar" src="<%= user.small_avatar_url %>"> <img width="45" height="45" class="avatar" src="<%= user.small_avatar_url %>">
</span> </span>

View File

@ -38,6 +38,14 @@ RSpec.describe AboutController do
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.body).to include("/u/anadminuser") expect(response.body).to include("/u/anadminuser")
end end
it "supports unicode usernames" do
SiteSetting.unicode_usernames = true
Fabricate(:admin, username: "martínez")
get "/about", headers: { "HTTP_USER_AGENT" => "Googlebot" }
expect(response.status).to eq(200)
expect(response.body).to include("/u/mart%25C3%25ADnez")
end
end end
it "serializes stats when 'Guardian#can_see_about_stats?' is true" do it "serializes stats when 'Guardian#can_see_about_stats?' is true" do

View File

@ -7,8 +7,8 @@ RSpec.describe GroupMessage do
let(:moderators_group) { Group[:moderators].name } let(:moderators_group) { Group[:moderators].name }
let!(:admin) { Fabricate.build(:admin, id: 999) } fab!(:admin)
let!(:user) { Fabricate.build(:user, id: 111) } fab!(:user)
before { Discourse.stubs(:system_user).returns(admin) } before { Discourse.stubs(:system_user).returns(admin) }
@ -57,11 +57,10 @@ RSpec.describe GroupMessage do
end end
describe "message_params" do describe "message_params" do
let(:user) { Fabricate.build(:user, id: 123_123) }
shared_examples "common message params for group messages" do shared_examples "common message params for group messages" do
it "returns the correct params" do it "returns the correct params" do
expect(message_params[:username]).to eq(user.username) expect(message_params[:username]).to eq(user.username)
expect(message_params[:user_url]).to be_present expect(message_params[:user_url]).to eq("/u/#{user.username}")
end end
end end
@ -87,8 +86,6 @@ RSpec.describe GroupMessage do
GroupMessage.new(moderators_group, :user_automatically_silenced, user: user) GroupMessage.new(moderators_group, :user_automatically_silenced, user: user)
end end
let(:user) { Fabricate.build(:user, id: 123_123) }
before do before do
PostCreator.stubs(:create).returns(stub_everything) PostCreator.stubs(:create).returns(stub_everything)
group_message.stubs(:sent_recently_key).returns("the_key") group_message.stubs(:sent_recently_key).returns("the_key")