mirror of
https://github.com/discourse/discourse.git
synced 2025-02-20 11:38:47 +08:00
Add a distributed mutex around user creation via SSO.
* When two SSO requests containing the same email in the payload are sent at the same time, it would sometimes result in two users being created but one without an email record. Investigations points to ActiveRecord not generating the right statements but we have no figured out the reproduction steps yet. We should review this after upgrading to Rails 5.2.
This commit is contained in:
parent
7ff78cc013
commit
6e46f81123
|
@ -156,49 +156,53 @@ class DiscourseSingleSignOn < SingleSignOn
|
|||
end
|
||||
|
||||
def match_email_or_create_user(ip_address)
|
||||
unless user = User.find_by_email(email)
|
||||
try_name = name.presence
|
||||
try_username = username.presence
|
||||
# Use a mutex here to counter SSO requests that are sent at the same time w
|
||||
# the same email payload
|
||||
DistributedMutex.synchronize("discourse_single_sign_on_#{email}") do
|
||||
unless user = User.find_by_email(email)
|
||||
try_name = name.presence
|
||||
try_username = username.presence
|
||||
|
||||
user_params = {
|
||||
primary_email: UserEmail.new(email: email, primary: true),
|
||||
name: try_name || User.suggest_name(try_username || email),
|
||||
username: UserNameSuggester.suggest(try_username || try_name || email),
|
||||
ip_address: ip_address
|
||||
}
|
||||
user_params = {
|
||||
primary_email: UserEmail.new(email: email, primary: true),
|
||||
name: try_name || User.suggest_name(try_username || email),
|
||||
username: UserNameSuggester.suggest(try_username || try_name || email),
|
||||
ip_address: ip_address
|
||||
}
|
||||
|
||||
user = User.create!(user_params)
|
||||
user = User.create!(user_params)
|
||||
|
||||
if SiteSetting.verbose_sso_logging
|
||||
Rails.logger.warn("Verbose SSO log: New User (user_id: #{user.id}) Params: #{user_params} User Params: #{user.attributes} User Errors: #{user.errors.full_messages} Email: #{user.primary_email.attributes} Email Error: #{user.primary_email.errors.full_messages}")
|
||||
if SiteSetting.verbose_sso_logging
|
||||
Rails.logger.warn("Verbose SSO log: New User (user_id: #{user.id}) Params: #{user_params} User Params: #{user.attributes} User Errors: #{user.errors.full_messages} Email: #{user.primary_email.attributes} Email Error: #{user.primary_email.errors.full_messages}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if user
|
||||
if sso_record = user.single_sign_on_record
|
||||
sso_record.last_payload = unsigned_payload
|
||||
sso_record.external_id = external_id
|
||||
else
|
||||
if avatar_url.present?
|
||||
Jobs.enqueue(:download_avatar_from_url,
|
||||
url: avatar_url,
|
||||
user_id: user.id,
|
||||
override_gravatar: SiteSetting.sso_overrides_avatar
|
||||
if user
|
||||
if sso_record = user.single_sign_on_record
|
||||
sso_record.last_payload = unsigned_payload
|
||||
sso_record.external_id = external_id
|
||||
else
|
||||
if avatar_url.present?
|
||||
Jobs.enqueue(:download_avatar_from_url,
|
||||
url: avatar_url,
|
||||
user_id: user.id,
|
||||
override_gravatar: SiteSetting.sso_overrides_avatar
|
||||
)
|
||||
end
|
||||
|
||||
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
|
||||
)
|
||||
end
|
||||
|
||||
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
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
user
|
||||
user
|
||||
end
|
||||
end
|
||||
|
||||
def change_external_attributes_and_override(sso_record, user)
|
||||
|
|
Loading…
Reference in New Issue
Block a user