mirror of
https://github.com/discourse/discourse.git
synced 2025-05-30 15:28:37 +08:00
REFACTOR: Migrate GoogleOAuth2Authenticator to use ManagedAuthenticator (#7120)
https://meta.discourse.org/t/future-social-authentication-improvements/94691/3
This commit is contained in:
@ -1,5 +1,4 @@
|
||||
class Auth::GoogleOAuth2Authenticator < Auth::Authenticator
|
||||
|
||||
class Auth::GoogleOAuth2Authenticator < Auth::ManagedAuthenticator
|
||||
def name
|
||||
"google_oauth2"
|
||||
end
|
||||
@ -8,77 +7,10 @@ class Auth::GoogleOAuth2Authenticator < Auth::Authenticator
|
||||
SiteSetting.enable_google_oauth2_logins
|
||||
end
|
||||
|
||||
def description_for_user(user)
|
||||
info = GoogleUserInfo.find_by(user_id: user.id)
|
||||
info&.email || info&.name || ""
|
||||
end
|
||||
|
||||
def can_revoke?
|
||||
true
|
||||
end
|
||||
|
||||
def revoke(user, skip_remote: false)
|
||||
info = GoogleUserInfo.find_by(user_id: user.id)
|
||||
raise Discourse::NotFound if info.nil?
|
||||
|
||||
# We get a temporary token from google upon login but do not need it, and do not store it.
|
||||
# Therefore we do not have any way to revoke the token automatically on google's end
|
||||
|
||||
info.destroy!
|
||||
true
|
||||
end
|
||||
|
||||
def can_connect_existing_user?
|
||||
true
|
||||
end
|
||||
|
||||
def after_authenticate(auth_hash, existing_account: nil)
|
||||
session_info = parse_hash(auth_hash)
|
||||
google_hash = session_info[:google]
|
||||
|
||||
result = ::Auth::Result.new
|
||||
result.email = session_info[:email]
|
||||
result.email_valid = session_info[:email_valid]
|
||||
result.name = session_info[:name]
|
||||
|
||||
result.extra_data = google_hash
|
||||
|
||||
user_info = ::GoogleUserInfo.find_by(google_user_id: google_hash[:google_user_id])
|
||||
|
||||
if existing_account && (user_info.nil? || existing_account.id != user_info.user_id)
|
||||
user_info.destroy! if user_info
|
||||
result.user = existing_account
|
||||
user_info = GoogleUserInfo.create!({ user_id: result.user.id }.merge(google_hash))
|
||||
else
|
||||
result.user = user_info&.user
|
||||
end
|
||||
|
||||
if !result.user && !result.email.blank? && result.email_valid
|
||||
result.user = User.find_by_email(result.email)
|
||||
if result.user
|
||||
# we've matched an existing user to this login attempt...
|
||||
if result.user.google_user_info && result.user.google_user_info.google_user_id != google_hash[:google_user_id]
|
||||
# but the user has changed the google account used to log in...
|
||||
if result.user.google_user_info.email != google_hash[:email]
|
||||
# the user changed their email, go ahead and scrub the old record
|
||||
result.user.google_user_info.destroy!
|
||||
else
|
||||
# same email address but different account? likely a takeover scenario
|
||||
result.failed = true
|
||||
result.failed_reason = I18n.t('errors.conflicting_google_user_id')
|
||||
return result
|
||||
end
|
||||
end
|
||||
::GoogleUserInfo.create({ user_id: result.user.id }.merge(google_hash))
|
||||
end
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def after_create_account(user, auth)
|
||||
data = auth[:extra_data]
|
||||
GoogleUserInfo.create({ user_id: user.id }.merge(data))
|
||||
def primary_email_verified?(auth_token)
|
||||
# note, emails that come back from google via omniauth are always valid
|
||||
# this protects against future regressions
|
||||
auth_token[:extra][:raw_info][:email_verified]
|
||||
end
|
||||
|
||||
def register_middleware(omniauth)
|
||||
@ -95,37 +27,8 @@ class Auth::GoogleOAuth2Authenticator < Auth::Authenticator
|
||||
if (google_oauth2_prompt = SiteSetting.google_oauth2_prompt).present?
|
||||
strategy.options[:prompt] = google_oauth2_prompt.gsub("|", " ")
|
||||
end
|
||||
},
|
||||
skip_jwt: true
|
||||
}
|
||||
}
|
||||
# jwt encoding is causing auth to fail in quite a few conditions
|
||||
# skipping
|
||||
omniauth.provider :google_oauth2, options
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def parse_hash(hash)
|
||||
extra = hash[:extra][:raw_info]
|
||||
|
||||
h = {}
|
||||
|
||||
h[:email] = hash[:info][:email]
|
||||
h[:name] = hash[:info][:name]
|
||||
h[:email_valid] = extra[:email_verified]
|
||||
|
||||
h[:google] = {
|
||||
google_user_id: hash[:uid] || extra[:sub],
|
||||
email: extra[:email],
|
||||
first_name: extra[:given_name],
|
||||
last_name: extra[:family_name],
|
||||
gender: extra[:gender],
|
||||
name: extra[:name],
|
||||
link: extra[:hd],
|
||||
profile_link: extra[:profile],
|
||||
picture: extra[:picture]
|
||||
}
|
||||
|
||||
h
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user