mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 15:48:43 -05:00
FEATURE: Import facebook avatars when logging in via facebook
FIX: warning about popup dimensions when using facebook login Rules are: - On account creation we always import - If you already have an avatar uploaded, nothing is changed - If you have no avatar uploaded, we upload from facebook on login - If you have no avatar uploaded, we select facebook unless gravatar already selected This also fixes SSO issues where on account creation accounts had missing avatar uploads
This commit is contained in:
parent
72f9369966
commit
5b3cd3fac9
6 changed files with 83 additions and 7 deletions
|
@ -130,7 +130,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
if(customLogin){
|
if(customLogin){
|
||||||
customLogin();
|
customLogin();
|
||||||
} else {
|
} else {
|
||||||
const authUrl = loginMethod.get('customUrl') || Discourse.getURL("/auth/" + name);
|
let authUrl = loginMethod.get('customUrl') || Discourse.getURL("/auth/" + name);
|
||||||
if (loginMethod.get("fullScreenLogin")) {
|
if (loginMethod.get("fullScreenLogin")) {
|
||||||
document.cookie = "fsl=true";
|
document.cookie = "fsl=true";
|
||||||
window.location = authUrl;
|
window.location = authUrl;
|
||||||
|
@ -141,6 +141,11 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
|
|
||||||
const height = loginMethod.get("frameHeight") || 400;
|
const height = loginMethod.get("frameHeight") || 400;
|
||||||
const width = loginMethod.get("frameWidth") || 800;
|
const width = loginMethod.get("frameWidth") || 800;
|
||||||
|
|
||||||
|
if (loginMethod.get("displayPopup")) {
|
||||||
|
authUrl = authUrl + "?display=popup";
|
||||||
|
}
|
||||||
|
|
||||||
const w = window.open(authUrl, "_blank",
|
const w = window.open(authUrl, "_blank",
|
||||||
"menubar=no,status=no,height=" + height + ",width=" + width + ",left=" + left + ",top=" + top);
|
"menubar=no,status=no,height=" + height + ",width=" + width + ",left=" + left + ",top=" + top);
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
|
@ -34,7 +34,9 @@ export function findAll(siteSettings, capabilities, isMobileDevice) {
|
||||||
params.frameWidth = 850;
|
params.frameWidth = 850;
|
||||||
params.frameHeight = 500;
|
params.frameHeight = 500;
|
||||||
} else if (name === "facebook") {
|
} else if (name === "facebook") {
|
||||||
params.frameHeight = 450;
|
params.frameWidth= 580;
|
||||||
|
params.frameHeight = 400;
|
||||||
|
params.displayPopup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
params.siteSettings = siteSettings;
|
params.siteSettings = siteSettings;
|
||||||
|
|
|
@ -60,23 +60,33 @@ class UserAvatar < ActiveRecord::Base
|
||||||
"#{upload_id}_#{OptimizedImage::VERSION}"
|
"#{upload_id}_#{OptimizedImage::VERSION}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.import_url_for_user(avatar_url, user)
|
def self.import_url_for_user(avatar_url, user, options=nil)
|
||||||
tempfile = FileHelper.download(avatar_url, SiteSetting.max_image_size_kb.kilobytes, "sso-avatar", true)
|
tempfile = FileHelper.download(avatar_url, SiteSetting.max_image_size_kb.kilobytes, "sso-avatar", true)
|
||||||
|
|
||||||
ext = FastImage.type(tempfile).to_s
|
ext = FastImage.type(tempfile).to_s
|
||||||
tempfile.rewind
|
tempfile.rewind
|
||||||
|
|
||||||
upload = Upload.create_for(user.id, tempfile, "external-avatar." + ext, File.size(tempfile.path), origin: avatar_url, image_type: "avatar")
|
upload = Upload.create_for(user.id, tempfile, "external-avatar." + ext, File.size(tempfile.path), origin: avatar_url, image_type: "avatar")
|
||||||
user.uploaded_avatar_id = upload.id
|
|
||||||
|
|
||||||
unless user.user_avatar
|
unless user.user_avatar
|
||||||
user.build_user_avatar
|
user.create_user_avatar
|
||||||
end
|
end
|
||||||
|
|
||||||
if !user.user_avatar.contains_upload?(upload.id)
|
if !user.user_avatar.contains_upload?(upload.id)
|
||||||
user.user_avatar.custom_upload_id = upload.id
|
user.user_avatar.update_columns(custom_upload_id: upload.id)
|
||||||
|
|
||||||
|
override_gravatar = !options || options[:override_gravatar]
|
||||||
|
|
||||||
|
if user.uploaded_avatar_id.nil? ||
|
||||||
|
!user.user_avatar.contains_upload?(user.uploaded_avatar_id) ||
|
||||||
|
override_gravatar
|
||||||
|
user.update_columns(uploaded_avatar_id: upload.id)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
rescue => e
|
rescue => e
|
||||||
|
p e
|
||||||
# skip saving, we are not connected to the net
|
# skip saving, we are not connected to the net
|
||||||
Rails.logger.warn "#{e}: Failed to download external avatar: #{avatar_url}, user id #{ user.id }"
|
Rails.logger.warn "#{e}: Failed to download external avatar: #{avatar_url}, user id #{ user.id }"
|
||||||
ensure
|
ensure
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddAvatarUrlToFacebookInfo < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :facebook_user_infos, :avatar_url, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -24,6 +24,17 @@ class Auth::FacebookAuthenticator < Auth::Authenticator
|
||||||
FacebookUserInfo.create({user_id: result.user.id}.merge(facebook_hash))
|
FacebookUserInfo.create({user_id: result.user.id}.merge(facebook_hash))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if user_info
|
||||||
|
user_info.update_columns(facebook_hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
user = result.user
|
||||||
|
if user && (!user.user_avatar || user.user_avatar.custom_upload_id.nil?)
|
||||||
|
if (avatar_url = facebook_hash[:avatar_url]).present?
|
||||||
|
UserAvatar.import_url_for_user(avatar_url, user, override_gravatar: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if email.blank?
|
if email.blank?
|
||||||
UserHistory.create(
|
UserHistory.create(
|
||||||
action: UserHistory.actions[:facebook_no_email],
|
action: UserHistory.actions[:facebook_no_email],
|
||||||
|
@ -37,14 +48,24 @@ class Auth::FacebookAuthenticator < Auth::Authenticator
|
||||||
def after_create_account(user, auth)
|
def after_create_account(user, auth)
|
||||||
data = auth[:extra_data]
|
data = auth[:extra_data]
|
||||||
FacebookUserInfo.create({user_id: user.id}.merge(data))
|
FacebookUserInfo.create({user_id: user.id}.merge(data))
|
||||||
|
|
||||||
|
|
||||||
|
if (avatar_url = data[:avatar_url]).present?
|
||||||
|
UserAvatar.import_url_for_user(avatar_url, user)
|
||||||
|
user.save
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def register_middleware(omniauth)
|
def register_middleware(omniauth)
|
||||||
|
|
||||||
omniauth.provider :facebook,
|
omniauth.provider :facebook,
|
||||||
:setup => lambda { |env|
|
:setup => lambda { |env|
|
||||||
strategy = env["omniauth.strategy"]
|
strategy = env["omniauth.strategy"]
|
||||||
strategy.options[:client_id] = SiteSetting.facebook_app_id
|
strategy.options[:client_id] = SiteSetting.facebook_app_id
|
||||||
strategy.options[:client_secret] = SiteSetting.facebook_app_secret
|
strategy.options[:client_secret] = SiteSetting.facebook_app_secret
|
||||||
|
strategy.options[:info_fields] = 'gender,email,name,bio,first_name,link,last_name'
|
||||||
},
|
},
|
||||||
:scope => "email"
|
:scope => "email"
|
||||||
end
|
end
|
||||||
|
@ -54,6 +75,8 @@ class Auth::FacebookAuthenticator < Auth::Authenticator
|
||||||
def parse_auth_token(auth_token)
|
def parse_auth_token(auth_token)
|
||||||
|
|
||||||
raw_info = auth_token["extra"]["raw_info"]
|
raw_info = auth_token["extra"]["raw_info"]
|
||||||
|
info = auth_token["info"]
|
||||||
|
|
||||||
email = auth_token["info"][:email]
|
email = auth_token["info"][:email]
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -65,7 +88,8 @@ class Auth::FacebookAuthenticator < Auth::Authenticator
|
||||||
last_name: raw_info["last_name"],
|
last_name: raw_info["last_name"],
|
||||||
email: email,
|
email: email,
|
||||||
gender: raw_info["gender"],
|
gender: raw_info["gender"],
|
||||||
name: raw_info["name"]
|
name: raw_info["name"],
|
||||||
|
avatar_url: info["image"]
|
||||||
},
|
},
|
||||||
email: email,
|
email: email,
|
||||||
email_valid: true
|
email_valid: true
|
||||||
|
|
|
@ -17,4 +17,34 @@ describe UserAvatar do
|
||||||
temp.unlink
|
temp.unlink
|
||||||
expect(avatar.gravatar_upload).not_to eq(nil)
|
expect(avatar.gravatar_upload).not_to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context '#import_url_for_user' do
|
||||||
|
|
||||||
|
it 'creates user_avatar record if missing' do
|
||||||
|
user = Fabricate(:user)
|
||||||
|
user.user_avatar.destroy
|
||||||
|
user.reload
|
||||||
|
|
||||||
|
|
||||||
|
FileHelper.stubs(:download).returns(file_from_fixtures("logo.png"))
|
||||||
|
|
||||||
|
UserAvatar.import_url_for_user("logo.png", user)
|
||||||
|
user.reload
|
||||||
|
|
||||||
|
expect(user.uploaded_avatar_id).not_to eq(nil)
|
||||||
|
expect(user.user_avatar.custom_upload_id).to eq(user.uploaded_avatar_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can leave gravatar alone' do
|
||||||
|
user = Fabricate(:user, uploaded_avatar_id: 1)
|
||||||
|
user.user_avatar.update_columns(gravatar_upload_id: 1)
|
||||||
|
|
||||||
|
FileHelper.stubs(:download).returns(file_from_fixtures("logo.png"))
|
||||||
|
UserAvatar.import_url_for_user("logo.png", user, override_gravatar: false)
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.uploaded_avatar_id).to eq(1)
|
||||||
|
expect(user.user_avatar.custom_upload_id).not_to eq(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue