mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 05:33:44 +08:00
DEV: Allow ManagedAuthenticator classes to match by username (#18517)
This commit is contained in:
parent
a10a81244c
commit
36f7fbebdc
|
@ -24,6 +24,11 @@ class Auth::ManagedAuthenticator < Auth::Authenticator
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Depending on the authenticator, this could be insecure, so it's disabled by default
|
||||||
|
def match_by_username
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
def primary_email_verified?(auth_token)
|
def primary_email_verified?(auth_token)
|
||||||
# Omniauth providers should only provide verified emails in the :info hash.
|
# Omniauth providers should only provide verified emails in the :info hash.
|
||||||
# This method allows additional checks to be added
|
# This method allows additional checks to be added
|
||||||
|
@ -67,6 +72,16 @@ class Auth::ManagedAuthenticator < Auth::Authenticator
|
||||||
association.user = user
|
association.user = user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Matching an account by username
|
||||||
|
if match_by_username &&
|
||||||
|
association.user.nil? &&
|
||||||
|
SiteSetting.username_change_period.zero? &&
|
||||||
|
(user = find_user_by_username(auth_token))
|
||||||
|
|
||||||
|
UserAssociatedAccount.where(user: user, provider_name: auth_token[:provider]).destroy_all # Destroy existing associations for the new user
|
||||||
|
association.user = user
|
||||||
|
end
|
||||||
|
|
||||||
# Update all the metadata in the association:
|
# Update all the metadata in the association:
|
||||||
association.info = auth_token[:info] || {}
|
association.info = auth_token[:info] || {}
|
||||||
association.credentials = auth_token[:credentials] || {}
|
association.credentials = auth_token[:credentials] || {}
|
||||||
|
@ -122,6 +137,13 @@ class Auth::ManagedAuthenticator < Auth::Authenticator
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_user_by_username(auth_token)
|
||||||
|
username = auth_token.dig(:info, :nickname)
|
||||||
|
if username
|
||||||
|
User.find_by_username(username)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def retrieve_avatar(user, url)
|
def retrieve_avatar(user, url)
|
||||||
return unless user && url
|
return unless user && url
|
||||||
return if user.user_avatar.try(:custom_upload_id).present?
|
return if user.user_avatar.try(:custom_upload_id).present?
|
||||||
|
|
|
@ -254,6 +254,78 @@ RSpec.describe Auth::ManagedAuthenticator do
|
||||||
expect(user.user_profile.location).to eq("DiscourseVille")
|
expect(user.user_profile.location).to eq("DiscourseVille")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'match by username' do
|
||||||
|
let(:user_match_authenticator) {
|
||||||
|
Class.new(described_class) do
|
||||||
|
def name
|
||||||
|
"myauth"
|
||||||
|
end
|
||||||
|
def match_by_email
|
||||||
|
false
|
||||||
|
end
|
||||||
|
def match_by_username
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end.new
|
||||||
|
}
|
||||||
|
|
||||||
|
it 'works normally' do
|
||||||
|
SiteSetting.username_change_period = 0
|
||||||
|
user = Fabricate(:user)
|
||||||
|
result = user_match_authenticator.after_authenticate(hash.deep_merge(info: { nickname: user.username }))
|
||||||
|
expect(result.user.id).to eq(user.id)
|
||||||
|
expect(UserAssociatedAccount.find_by(provider_name: 'myauth', provider_uid: "1234").user_id).to eq(user.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works if there is already an association with the target account' do
|
||||||
|
SiteSetting.username_change_period = 0
|
||||||
|
user = Fabricate(:user, username: "IAmGroot")
|
||||||
|
result = user_match_authenticator.after_authenticate(hash)
|
||||||
|
expect(result.user.id).to eq(user.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'works if the username is different case' do
|
||||||
|
SiteSetting.username_change_period = 0
|
||||||
|
user = Fabricate(:user, username: "IAMGROOT")
|
||||||
|
result = user_match_authenticator.after_authenticate(hash)
|
||||||
|
expect(result.user.id).to eq(user.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not match if username_change_period isn\'t 0' do
|
||||||
|
SiteSetting.username_change_period = 3
|
||||||
|
user = Fabricate(:user, username: "IAmGroot")
|
||||||
|
result = user_match_authenticator.after_authenticate(hash)
|
||||||
|
expect(result.user).to eq(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not match if default match_by_username not overriden' do
|
||||||
|
SiteSetting.username_change_period = 0
|
||||||
|
authenticator = Class.new(described_class) do
|
||||||
|
def name
|
||||||
|
"myauth"
|
||||||
|
end
|
||||||
|
end.new
|
||||||
|
user = Fabricate(:user, username: "IAmGroot")
|
||||||
|
result = authenticator.after_authenticate(hash)
|
||||||
|
expect(result.user).to eq(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not match if match_by_username is false' do
|
||||||
|
SiteSetting.username_change_period = 0
|
||||||
|
authenticator = Class.new(described_class) do
|
||||||
|
def name
|
||||||
|
"myauth"
|
||||||
|
end
|
||||||
|
def match_by_username
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end.new
|
||||||
|
user = Fabricate(:user, username: "IAmGroot")
|
||||||
|
result = authenticator.after_authenticate(hash)
|
||||||
|
expect(result.user).to eq(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'description_for_user' do
|
describe 'description_for_user' do
|
||||||
|
|
Loading…
Reference in New Issue
Block a user