mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
add option to override user attributes from SSO payload
add an external_username attribute for username from SSO payload repair the field name in SingleSignOnRecord migration move setting of external_username for sso to controller add settings toggle to override username/email from SSO payload fix changing of external username after override toggle complete tests and logic for sso override add some extra context to username override option add external_email and external_name to single sign on record add setting for name override from SSO payload complete override with stored external_email and external_name add missing checks to tests remove an unneeded describe block break up a monster method for single sign on fixes for sso attribute override after failed tests
This commit is contained in:
@@ -39,31 +39,19 @@ class DiscourseSingleSignOn < SingleSignOn
|
||||
"SSO_NONCE_#{nonce}"
|
||||
end
|
||||
|
||||
|
||||
def lookup_or_create_user
|
||||
sso_record = SingleSignOnRecord.where(external_id: external_id).first
|
||||
if sso_record && sso_record.user
|
||||
|
||||
if sso_record && user = sso_record.user
|
||||
sso_record.last_payload = unsigned_payload
|
||||
sso_record.save
|
||||
else
|
||||
user = User.where(email: Email.downcase(email)).first
|
||||
|
||||
user_params = {
|
||||
email: email,
|
||||
name: User.suggest_name(name || username || email),
|
||||
username: UserNameSuggester.suggest(username || name || email),
|
||||
}
|
||||
|
||||
if user || user = User.create(user_params)
|
||||
if sso_record = user.single_sign_on_record
|
||||
sso_record.last_payload = unsigned_payload
|
||||
sso_record.external_id = external_id
|
||||
sso_record.save!
|
||||
else
|
||||
sso_record = user.create_single_sign_on_record(last_payload: unsigned_payload,
|
||||
external_id: external_id)
|
||||
end
|
||||
end
|
||||
user = match_email_or_create_user
|
||||
sso_record = user.single_sign_on_record
|
||||
end
|
||||
|
||||
# if the user isn't new or it's attached to the SSO record we might be overriding username or email
|
||||
unless user.new_record?
|
||||
change_external_attributes_and_override(sso_record, user)
|
||||
end
|
||||
|
||||
if sso_record && (user = sso_record.user) && !user.active
|
||||
@@ -71,8 +59,62 @@ class DiscourseSingleSignOn < SingleSignOn
|
||||
user.save
|
||||
user.enqueue_welcome_message('welcome_user')
|
||||
end
|
||||
|
||||
# optionally save the user and sso_record if they have changed
|
||||
user.save!
|
||||
sso_record.save!
|
||||
|
||||
sso_record && sso_record.user
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def match_email_or_create_user
|
||||
user = User.where(email: Email.downcase(email)).first
|
||||
|
||||
user_params = {
|
||||
email: email,
|
||||
name: User.suggest_name(name || username || email),
|
||||
username: UserNameSuggester.suggest(username || name || email),
|
||||
}
|
||||
|
||||
if user || user = User.create(user_params)
|
||||
if sso_record = user.single_sign_on_record
|
||||
sso_record.last_payload = unsigned_payload
|
||||
sso_record.external_id = external_id
|
||||
else
|
||||
sso_record = user.create_single_sign_on_record(last_payload: unsigned_payload,
|
||||
external_id: external_id,
|
||||
external_username: username,
|
||||
external_email: email,
|
||||
external_name: name)
|
||||
end
|
||||
end
|
||||
|
||||
user
|
||||
end
|
||||
|
||||
def change_external_attributes_and_override(sso_record, user)
|
||||
if SiteSetting.sso_overrides_email && email != sso_record.external_email
|
||||
# set the user's email to whatever came in the payload
|
||||
user.email = email
|
||||
end
|
||||
|
||||
if SiteSetting.sso_overrides_username && username != sso_record.external_username && user.username != username
|
||||
# we have an external username change, and the user's current username doesn't match
|
||||
# run it through the UserNameSuggester to override it
|
||||
user.username = UserNameSuggester.suggest(username || name || email)
|
||||
end
|
||||
|
||||
if SiteSetting.sso_overrides_name && name != sso_record.external_name && user.name != name
|
||||
# we have an external name change, and the user's current name doesn't match
|
||||
# run it through the name suggester to override it
|
||||
user.name = User.suggest_name(name || username || email)
|
||||
end
|
||||
|
||||
# change external attributes for sso record
|
||||
sso_record.external_username = username
|
||||
sso_record.external_email = email
|
||||
sso_record.external_name = name
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user