FIX: download SSO avatars in a background job to prevent hangs when avatars are huge

This commit is contained in:
Régis Hanol 2016-10-24 19:55:30 +02:00
parent e79465a965
commit 750338954c
2 changed files with 76 additions and 61 deletions

View File

@ -119,13 +119,15 @@ class DiscourseSingleSignOn < SingleSignOn
sso_record.last_payload = unsigned_payload
sso_record.external_id = external_id
else
UserAvatar.import_url_for_user(avatar_url, user) if avatar_url.present?
user.create_single_sign_on_record(last_payload: unsigned_payload,
Jobs.enqueue(:download_avatar_from_url, url: avatar_url, user_id: user.id) if avatar_url.present?
user.create_single_sign_on_record(
last_payload: unsigned_payload,
external_id: external_id,
external_username: username,
external_email: email,
external_name: name,
external_avatar_url: avatar_url)
external_avatar_url: avatar_url
)
end
end
@ -148,11 +150,10 @@ class DiscourseSingleSignOn < SingleSignOn
avatar_missing = user.uploaded_avatar_id.nil? || !Upload.exists?(user.uploaded_avatar_id)
if (avatar_missing || avatar_force_update || SiteSetting.sso_overrides_avatar) && avatar_url.present?
avatar_changed = sso_record.external_avatar_url != avatar_url
if avatar_force_update || avatar_changed || avatar_missing
UserAvatar.import_url_for_user(avatar_url, user)
Jobs.enqueue(:download_avatar_from_url, url: avatar_url, user_id: user.id)
end
end

View File

@ -1,4 +1,5 @@
require "rails_helper"
require 'sidekiq/testing'
describe DiscourseSingleSignOn do
before do
@ -279,7 +280,7 @@ describe DiscourseSingleSignOn do
it "correctly handles provided avatar_urls" do
Sidekiq::Testing.inline! do
sso = DiscourseSingleSignOn.new
sso.external_id = 666
sso.email = "sam@sam.com"
@ -289,6 +290,7 @@ describe DiscourseSingleSignOn do
FileHelper.stubs(:download).returns(file_from_fixtures("logo.png"))
user = sso.lookup_or_create_user(ip_address)
user.reload
avatar_id = user.uploaded_avatar_id
# initial creation ...
@ -299,6 +301,7 @@ describe DiscourseSingleSignOn do
Upload.destroy(old_id)
user = sso.lookup_or_create_user(ip_address)
user.reload
avatar_id = user.uploaded_avatar_id
expect(avatar_id).to_not eq(nil)
@ -307,6 +310,7 @@ describe DiscourseSingleSignOn do
FileHelper.stubs(:download) { raise "should not be called" }
sso.avatar_url = "https://some.new/avatar.png"
user = sso.lookup_or_create_user(ip_address)
user.reload
# avatar updated but no override specified ...
expect(user.uploaded_avatar_id).to eq(avatar_id)
@ -314,6 +318,7 @@ describe DiscourseSingleSignOn do
sso.avatar_force_update = true
FileHelper.stubs(:download).returns(file_from_fixtures("logo-dev.png"))
user = sso.lookup_or_create_user(ip_address)
user.reload
# we better have a new avatar
expect(user.uploaded_avatar_id).not_to eq(avatar_id)
@ -324,15 +329,18 @@ describe DiscourseSingleSignOn do
sso.avatar_force_update = true
FileHelper.stubs(:download) { raise "not found" }
user = sso.lookup_or_create_user(ip_address)
user.reload
# we better have the same avatar
expect(user.uploaded_avatar_id).to eq(avatar_id)
end
end
end
context 'when sso_overrides_avatar is enabled' do
let!(:sso_record) { Fabricate(:single_sign_on_record, external_avatar_url: "http://example.com/an_image.png") }
let!(:sso) {
sso = DiscourseSingleSignOn.new
sso.username = "test"
@ -341,6 +349,7 @@ describe DiscourseSingleSignOn do
sso.external_id = sso_record.external_id
sso
}
let(:logo) { file_from_fixtures("logo.png") }
before do
@ -348,16 +357,19 @@ describe DiscourseSingleSignOn do
end
it "deal with no avatar url passed for an existing user with an avatar" do
Sidekiq::Testing.inline! do
# Deliberately not setting avatar_url so it should not update
sso_record.user.update_columns(uploaded_avatar_id: -1)
user = sso.lookup_or_create_user(ip_address)
user.reload
expect(user).to_not be_nil
expect(user.uploaded_avatar_id).to eq(-1)
end
end
it "deal with no avatar_force_update passed as a boolean" do
Sidekiq::Testing.inline! do
FileHelper.stubs(:download).returns(logo)
sso_record.user.update_columns(uploaded_avatar_id: -1)
@ -366,9 +378,11 @@ describe DiscourseSingleSignOn do
sso.avatar_force_update = false
user = sso.lookup_or_create_user(ip_address)
user.reload
expect(user).to_not be_nil
expect(user.uploaded_avatar_id).to_not eq(-1)
end
end
end
end