From c09f345cff283c12eb069a89f87021b566c8cb06 Mon Sep 17 00:00:00 2001
From: Matt Palmer <mpalmer@hezmatt.org>
Date: Mon, 28 Sep 2015 21:41:57 +1000
Subject: [PATCH] Proxy letter avatars by default

On sites that don't otherwise configure an avatar fallback, Discourse will
now tell the client to get its letter avatars from a location which nginx
proxies to the centralised `avatars.discourse.org` service.  This alleviates
privacy concerns, whilst still providing some degree of performance benefit
(no need for every site to delay avatar response by 300ms for image
rendering).

It is still possible to gain the benefits of global image caching and the
lower latency of requesting directly from a CDN, by explicitly changing the
`external_system_avatars_url` site setting to
`https://avatars.discourse.org/letter/{first_letter}/{color}/{size}.png`.
---
 app/models/user.rb       | 1 +
 config/nginx.sample.conf | 5 +++++
 config/site_settings.yml | 4 ++--
 spec/models/user_spec.rb | 2 +-
 4 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/app/models/user.rb b/app/models/user.rb
index cca5693bb..8f42ac3c7 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -475,6 +475,7 @@ class User < ActiveRecord::Base
       url.gsub! "{color}", letter_avatar_color(username.downcase)
       url.gsub! "{username}", username
       url.gsub! "{first_letter}", username[0].downcase
+      url.gsub! "{hostname}", RailsMultisite::ConnectionManagement.current_hostname
       url
     else
       "#{Discourse.base_uri}/letter_avatar/#{username.downcase}/{size}/#{LetterAvatar.version}.png"
diff --git a/config/nginx.sample.conf b/config/nginx.sample.conf
index 6e846f2a9..fa29fe8c8 100644
--- a/config/nginx.sample.conf
+++ b/config/nginx.sample.conf
@@ -192,6 +192,11 @@ server {
       break;
     }
 
+    location /letter_avatar_proxy {
+      rewrite /letter_avatar_proxy/(.*)$ /$1 break;
+      proxy_pass https://avatars.discourse.org;
+    }
+
     # this means every file in public is tried first
     try_files $uri @discourse;
   }
diff --git a/config/site_settings.yml b/config/site_settings.yml
index 149713872..81453913b 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -593,9 +593,9 @@ files:
     client: true
     shadowed_by_global: true
   external_system_avatars_url:
-    default: "https://avatars.discourse.org/v2/letter/{first_letter}/{color}/{size}.png"
+    default: "//{hostname}/letter_avatar_proxy/v2/letter/{first_letter}/{color}/{size}.png"
     client: true
-    regex: '^https?:\/\/.+[^\/]'
+    regex: '^((https?:)?\/)?\/.+[^\/]'
   default_opengraph_image_url: ''
 
 trust:
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 2f3fbfd27..1a6f028b2 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -912,7 +912,7 @@ describe User do
       expect(user.small_avatar_url).to eq("//test.localhost/letter_avatar/sam/45/#{LetterAvatar.version}.png")
 
       SiteSetting.external_system_avatars_enabled = true
-      expect(user.small_avatar_url).to eq("https://avatars.discourse.org/v2/letter/s/5f9b8f/45.png")
+      expect(user.small_avatar_url).to eq("//test.localhost/letter_avatar_proxy/v2/letter/s/5f9b8f/45.png")
     end
 
   end