FEATURE: Allow /u/by-external to work for all managed authenticators (#11168)

Previously, `/u/by-external/{id}` would only work for 'Discourse SSO' systems. This commit adds a new 'provider' parameter to the URL: `/u/by-external/{provider}/{id}`

This is compatible with all auth methods which have migrated to the 'ManagedAuthenticator' pattern. That includes all core providers, and also popular plugins such as discourse-oauth2-basic and discourse-openid-connect.

The new route is admin-only, since some authenticators use sensitive information like email addresses as the external id.
This commit is contained in:
David Taylor
2020-11-10 10:41:46 +00:00
committed by GitHub
parent ffc3da35a6
commit a7adf30357
4 changed files with 46 additions and 1 deletions

View File

@ -502,7 +502,14 @@ class ApplicationController < ActionController::Base
result.find_by(find_opts)
elsif params[:external_id]
external_id = params[:external_id].chomp('.json')
SingleSignOnRecord.find_by(external_id: external_id).try(:user)
if provider_name = params[:external_provider]
raise Discourse::InvalidAccess unless guardian.is_admin? # external_id might be something sensitive
provider = Discourse.enabled_authenticators.find { |a| a.name == provider_name }
raise Discourse::NotFound if !provider&.is_managed? # Only managed authenticators use UserAssociatedAccount
UserAssociatedAccount.find_by(provider_name: provider_name, provider_uid: external_id)&.user
else
SingleSignOnRecord.find_by(external_id: external_id).try(:user)
end
end
raise Discourse::NotFound if user.blank?