mirror of
https://github.com/discourse/discourse.git
synced 2024-11-30 11:34:43 +08:00
67 lines
1.9 KiB
Ruby
67 lines
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "has_errors"
|
|
|
|
class Auth::GithubAuthenticator < Auth::ManagedAuthenticator
|
|
def name
|
|
"github"
|
|
end
|
|
|
|
def enabled?
|
|
SiteSetting.enable_github_logins
|
|
end
|
|
|
|
def after_authenticate(auth_token, existing_account: nil)
|
|
result = super
|
|
return result if result.user
|
|
# If email domain restrictions are configured,
|
|
# pick a secondary email which is allowed
|
|
all_github_emails(auth_token).each do |candidate|
|
|
next if !EmailValidator.allowed?(candidate[:email])
|
|
result.email = candidate[:email]
|
|
result.email_valid = !!candidate[:verified]
|
|
break
|
|
end
|
|
|
|
result
|
|
end
|
|
|
|
def find_user_by_email(auth_token)
|
|
# Use verified secondary emails to find a match
|
|
all_github_emails(auth_token).each do |candidate|
|
|
next if !candidate[:verified]
|
|
if user = User.find_by_email(candidate[:email])
|
|
return user
|
|
end
|
|
end
|
|
nil
|
|
end
|
|
|
|
def all_github_emails(auth_token)
|
|
emails = Array.new(auth_token[:extra][:all_emails])
|
|
primary_email = emails.find { |email| email[:primary] }
|
|
if primary_email
|
|
emails.delete(primary_email)
|
|
emails.unshift(primary_email)
|
|
end
|
|
emails
|
|
end
|
|
|
|
def register_middleware(omniauth)
|
|
omniauth.provider :github,
|
|
setup:
|
|
lambda { |env|
|
|
strategy = env["omniauth.strategy"]
|
|
strategy.options[:client_id] = SiteSetting.github_client_id
|
|
strategy.options[:client_secret] = SiteSetting.github_client_secret
|
|
},
|
|
scope: "user:email"
|
|
end
|
|
|
|
# the omniauth-github gem only picks up the primary email if it's verified:
|
|
# https://github.com/omniauth/omniauth-github/blob/0ac46b59ccdabd4cbe5be4a665df269355081915/lib/omniauth/strategies/github.rb#L58-L61
|
|
def primary_email_verified?(auth_token)
|
|
true
|
|
end
|
|
end
|