mirror of
https://github.com/discourse/discourse.git
synced 2025-05-29 01:31:35 +08:00
FIX: Use database to persist metadata during social registration (#6750)
Previously was using the cookie_store, which is limited to 4kb. This caused issues for providers sending large volumes of metadata about a user.
This commit is contained in:
@ -26,77 +26,56 @@ class Auth::ManagedAuthenticator < Auth::Authenticator
|
||||
end
|
||||
|
||||
def after_authenticate(auth_token, existing_account: nil)
|
||||
result = Auth::Result.new
|
||||
|
||||
# Store all the metadata for later, in case the `after_create_account` hook is used
|
||||
result.extra_data = {
|
||||
provider: auth_token[:provider],
|
||||
uid: auth_token[:uid],
|
||||
info: auth_token[:info],
|
||||
extra: auth_token[:extra],
|
||||
credentials: auth_token[:credentials]
|
||||
}
|
||||
|
||||
# Build the Auth::Result object
|
||||
info = auth_token[:info]
|
||||
result.email = email = info[:email]
|
||||
result.name = name = "#{info[:first_name]} #{info[:last_name]}"
|
||||
result.username = info[:nickname]
|
||||
|
||||
# Try and find an association for this account
|
||||
association = UserAssociatedAccount.find_by(provider_name: auth_token[:provider], provider_uid: auth_token[:uid])
|
||||
result.user = association&.user
|
||||
association = UserAssociatedAccount.find_or_initialize_by(provider_name: auth_token[:provider], provider_uid: auth_token[:uid])
|
||||
|
||||
# Reconnecting to existing account
|
||||
if can_connect_existing_user? && existing_account && (association.nil? || existing_account.id != association.user_id)
|
||||
association.destroy! if association
|
||||
association = nil
|
||||
result.user = existing_account
|
||||
if can_connect_existing_user? && existing_account && (association.user.nil? || existing_account.id != association.user_id)
|
||||
association.user = existing_account
|
||||
end
|
||||
|
||||
# Matching an account by email
|
||||
if match_by_email && association.nil? && result.user.nil? && (user = User.find_by_email(email))
|
||||
if match_by_email && association.user.nil? && (user = User.find_by_email(auth_token.dig(:info, :email)))
|
||||
UserAssociatedAccount.where(user: user, provider_name: auth_token[:provider]).destroy_all # Destroy existing associations for the new user
|
||||
result.user = user
|
||||
end
|
||||
|
||||
# Add the association to the database if it doesn't already exist
|
||||
if association.nil? && result.user
|
||||
association = create_association!(result.extra_data.merge(user: result.user))
|
||||
association.user = user
|
||||
end
|
||||
|
||||
# Update all the metadata in the association:
|
||||
if association
|
||||
association.update!(
|
||||
info: auth_token[:info] || {},
|
||||
credentials: auth_token[:credentials] || {},
|
||||
extra: auth_token[:extra] || {}
|
||||
)
|
||||
retrieve_avatar(result.user, auth_token.dig(:info, :image))
|
||||
retrieve_profile(result.user, auth_token[:info])
|
||||
end
|
||||
association.info = auth_token[:info] || {}
|
||||
association.credentials = auth_token[:credentials] || {}
|
||||
association.extra = auth_token[:extra] || {}
|
||||
|
||||
# Save to the DB. Do this even if we don't have a user - it might be linked up later in after_create_account
|
||||
association.save!
|
||||
|
||||
# Update avatar/profile
|
||||
retrieve_avatar(association.user, association.info["image"])
|
||||
retrieve_profile(association.user, association.info)
|
||||
|
||||
# Build the Auth::Result object
|
||||
result = Auth::Result.new
|
||||
info = auth_token[:info]
|
||||
result.email = info[:email]
|
||||
result.name = "#{info[:first_name]} #{info[:last_name]}"
|
||||
result.username = info[:nickname]
|
||||
result.email_valid = true if result.email
|
||||
result.extra_data = {
|
||||
provider: auth_token[:provider],
|
||||
uid: auth_token[:uid]
|
||||
}
|
||||
result.user = association.user
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def create_association!(hash)
|
||||
association = UserAssociatedAccount.create!(
|
||||
user: hash[:user],
|
||||
provider_name: hash[:provider],
|
||||
provider_uid: hash[:uid],
|
||||
info: hash[:info] || {},
|
||||
credentials: hash[:credentials] || {},
|
||||
extra: hash[:extra] || {}
|
||||
)
|
||||
end
|
||||
|
||||
def after_create_account(user, auth)
|
||||
data = auth[:extra_data]
|
||||
create_association!(data.merge(user: user))
|
||||
retrieve_avatar(user, data.dig(:info, :image))
|
||||
retrieve_profile(user, data[:info])
|
||||
auth_token = auth[:extra_data]
|
||||
association = UserAssociatedAccount.find_or_initialize_by(provider_name: auth_token[:provider], provider_uid: auth_token[:uid])
|
||||
association.user = user
|
||||
association.save!
|
||||
|
||||
retrieve_avatar(user, association.info["image"])
|
||||
retrieve_profile(user, association.info)
|
||||
end
|
||||
|
||||
def retrieve_avatar(user, url)
|
||||
@ -108,8 +87,8 @@ class Auth::ManagedAuthenticator < Auth::Authenticator
|
||||
def retrieve_profile(user, info)
|
||||
return unless user
|
||||
|
||||
bio = info[:description]
|
||||
location = info[:location]
|
||||
bio = info["description"]
|
||||
location = info["location"]
|
||||
|
||||
if bio || location
|
||||
profile = user.user_profile
|
||||
|
Reference in New Issue
Block a user