FIX: URL encode username and first letter in avatar URL

FIX: URL encode username and first letter in avatar URL

And it adds specs as a follow-up to aadb7da7

diff --git a/app/models/user.rb b/app/models/user.rb
index 0b11dfe..1c6d9ad 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -752,8 +752,8 @@ class User < ActiveRecord::Base
       url = SiteSetting.external_system_avatars_url.dup
       url = "#{Discourse::base_uri}#{url}" unless url =~ /^https?:\/\//
       url.gsub! "{color}", letter_avatar_color(normalized_username)
-      url.gsub! "{username}", username
-      url.gsub! "{first_letter}", normalized_username.grapheme_clusters.first
+      url.gsub! "{username}", CGI.escape(username)
+      url.gsub! "{first_letter}", CGI.escape(normalized_username.grapheme_clusters.first)
       url.gsub! "{hostname}", Discourse.current_hostname
       url
     else
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index efc241a..7dd33bf 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -2103,5 +2103,25 @@ describe User do
         expect(User.username_exists?("foo")).to eq(false)
       end
     end
+
+    describe ".system_avatar_template" do
+      context "with external system avatars enabled" do
+        before { SiteSetting.external_system_avatars_enabled = true }
+
+        it "uses the normalized username" do
+          expect(User.system_avatar_template("Lo\u0308we")).to match(%r|/letter_avatar_proxy/v\d/letter/l/71e660/{size}.png|)
+          expect(User.system_avatar_template("L\u00F6wE")).to match(%r|/letter_avatar_proxy/v\d/letter/l/71e660/{size}.png|)
+        end
+
+        it "uses the first grapheme cluster and URL encodes it" do
+          expect(User.system_avatar_template("बहुत")).to match(%r|/letter_avatar_proxy/v\d/letter/%E0%A4%AC/ea5d25/{size}.png|)
+        end
+
+        it "substitues {username} with the URL encoded username" do
+          SiteSetting.external_system_avatars_url = "https://{hostname}/{username}.png"
+          expect(User.system_avatar_template("बहुत")).to eq("https://#{Discourse.current_hostname}/%E0%A4%AC%E0%A4%B9%E0%A5%81%E0%A4%A4.png")
+        end
+      end
+    end
   end
 end

GitHub sha: 7a27c93c

1 Like