DEV: Refactor managed_authenticator into its own file
This commit is contained in:
parent
b3124f90d2
commit
f44a2cd7bb
|
@ -6,4 +6,5 @@ en:
|
|||
openid_connect_client_secret: "OpenID Connect client secret"
|
||||
openid_connect_authorize_scope: "The scopes sent to the authorize endpoint. This must include 'openid'."
|
||||
openid_connect_token_scope: "The scopes sent when requesting the token endpoint. The official specification does not require this."
|
||||
openid_connect_error_redirects: "If the callback error_reason contains the first parameter, the user will be redirected to the URL in the second parameter"
|
||||
openid_connect_error_redirects: "If the callback error_reason contains the first parameter, the user will be redirected to the URL in the second parameter"
|
||||
openid_connect_allow_association_change: "Allow users to disconnect and reconnect their Discourse accounts from the OpenID Connect provider"
|
|
@ -7,6 +7,8 @@ plugins:
|
|||
default: ""
|
||||
openid_connect_client_secret:
|
||||
default: ""
|
||||
openid_connect_allow_association_change:
|
||||
default: false
|
||||
openid_connect_authorize_scope:
|
||||
default: "openid"
|
||||
openid_connect_token_scope:
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
class Auth::ManagedAuthenticator < Auth::Authenticator
|
||||
def description_for_user(user)
|
||||
info = UserAssociatedAccount.find_by(provider_name: name, user_id: user.id).info
|
||||
info["name"] || info["email"] || info["nickname"] || ""
|
||||
end
|
||||
|
||||
# These three methods are designed to be overriden by child classes
|
||||
def match_by_email
|
||||
true
|
||||
end
|
||||
|
||||
def can_revoke?
|
||||
true
|
||||
end
|
||||
|
||||
def can_connect_existing_user?
|
||||
true
|
||||
end
|
||||
|
||||
def revoke(user, skip_remote: false)
|
||||
association = UserAssociatedAccount.find_by(provider_name: name, user_id: user.id)
|
||||
raise Discourse::NotFound if association.nil?
|
||||
association.destroy!
|
||||
true
|
||||
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
|
||||
|
||||
# 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
|
||||
end
|
||||
|
||||
# Matching an account by email
|
||||
if match_by_email && association.nil? && (user = User.find_by_email(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))
|
||||
end
|
||||
|
||||
# Update all the metadata in the association:
|
||||
if association
|
||||
association.update!(
|
||||
info: auth_token[:info],
|
||||
credentials: auth_token[:credentials],
|
||||
extra: auth_token[:extra]
|
||||
)
|
||||
end
|
||||
|
||||
result.email_valid = true
|
||||
|
||||
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))
|
||||
end
|
||||
end
|
56
plugin.rb
56
plugin.rb
|
@ -6,53 +6,7 @@
|
|||
|
||||
require_relative "lib/omniauth_open_id_connect"
|
||||
require_relative 'app/models/user_associated_account'
|
||||
|
||||
class Auth::ManagedAuthenticator < Auth::Authenticator
|
||||
def match_by_email
|
||||
true
|
||||
end
|
||||
|
||||
def after_authenticate(auth_token)
|
||||
# puts "after authenticate ", auth_token.to_json
|
||||
result = Auth::Result.new
|
||||
|
||||
result.extra_data = {
|
||||
provider: auth_token[:provider],
|
||||
uid: auth_token[:uid],
|
||||
info: auth_token[:info],
|
||||
extra: auth_token[:extra],
|
||||
credentials: auth_token[:credentials]
|
||||
}
|
||||
|
||||
info = auth_token[:info]
|
||||
result.email = email = info[:email]
|
||||
result.name = name = "#{info[:first_name]} #{info[:last_name]}"
|
||||
result.username = info[:nickname]
|
||||
|
||||
association = UserAssociatedAccount.find_by(provider_name: auth_token[:provider], provider_uid: auth_token[:uid])
|
||||
|
||||
if match_by_email && association.nil? && (user = User.find_by_email(email)) && !UserAssociatedAccount.exists?(user: user, provider_name: auth_token[:provider])
|
||||
association = UserAssociatedAccount.create!(user: user, provider_name: auth_token[:provider], provider_uid: auth_token[:uid], info: auth_token[:info], credentials: auth_token[:credentials], extra: auth_token[:extra])
|
||||
end
|
||||
|
||||
result.user = association&.user
|
||||
result.email_valid = true
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def after_create_account(user, auth)
|
||||
data = auth[:extra_data]
|
||||
association = UserAssociatedAccount.create!(
|
||||
user: user,
|
||||
provider_name: data[:provider],
|
||||
provider_uid: data[:uid],
|
||||
info: data[:info],
|
||||
credentials: data[:credentials],
|
||||
extra: data[:extra]
|
||||
)
|
||||
end
|
||||
end
|
||||
require_relative "lib/managed_authenticator"
|
||||
|
||||
class OpenIDConnectAuthenticator < Auth::ManagedAuthenticator
|
||||
|
||||
|
@ -60,6 +14,14 @@ class OpenIDConnectAuthenticator < Auth::ManagedAuthenticator
|
|||
'oidc'
|
||||
end
|
||||
|
||||
def can_revoke?
|
||||
SiteSetting.openid_connect_allow_association_change
|
||||
end
|
||||
|
||||
def can_connect_existing_user?
|
||||
SiteSetting.openid_connect_allow_association_change
|
||||
end
|
||||
|
||||
def enabled?
|
||||
SiteSetting.openid_connect_enabled
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue