FEATURE: Merge user associated accounts, favouring the target user upon conflict (#26645)
This commit is contained in:
parent
bbe62d88d2
commit
1fea2bf1c5
|
@ -18,6 +18,7 @@ class UserMerger
|
|||
merge_user_visits
|
||||
update_site_settings
|
||||
merge_user_attributes
|
||||
merge_user_associated_accounts
|
||||
|
||||
DiscourseEvent.trigger(:merging_users, @source_user, @target_user)
|
||||
update_user_stats
|
||||
|
@ -294,6 +295,29 @@ class UserMerger
|
|||
SQL
|
||||
end
|
||||
|
||||
def merge_user_associated_accounts
|
||||
if @acting_user
|
||||
::MessageBus.publish "/merge_user",
|
||||
{
|
||||
message:
|
||||
I18n.t("admin.user.merge_user.merging_user_associated_accounts"),
|
||||
},
|
||||
user_ids: [@acting_user.id]
|
||||
end
|
||||
|
||||
UserAssociatedAccount.where(user_id: @source_user.id).update_all(<<~SQL)
|
||||
user_id = CASE
|
||||
WHEN EXISTS (
|
||||
SELECT 1
|
||||
FROM user_associated_accounts AS conflicts
|
||||
WHERE (conflicts.user_id = #{@target_user.id} AND conflicts.provider_name = user_associated_accounts.provider_name)
|
||||
)
|
||||
THEN NULL
|
||||
ELSE #{@target_user.id}
|
||||
END
|
||||
SQL
|
||||
end
|
||||
|
||||
def update_user_ids
|
||||
if @acting_user
|
||||
::MessageBus.publish "/merge_user",
|
||||
|
|
|
@ -2931,6 +2931,7 @@ en:
|
|||
updating_site_settings: "Updating site settings…"
|
||||
updating_user_stats: "Updating user stats…"
|
||||
merging_user_attributes: "Merging user attributes…"
|
||||
merging_user_associated_accounts: "Merging user associated accounts…"
|
||||
updating_user_ids: "Updating user ids…"
|
||||
deleting_source_user: "Deleting source user…"
|
||||
user:
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:user_associated_account) do
|
||||
provider_name "meecrosof"
|
||||
provider_uid { sequence(:key) { |i| "#{i + 1}" } }
|
||||
user
|
||||
info { |attrs| { name: attrs[:user].username, email: attrs[:user].email } }
|
||||
end
|
|
@ -1084,6 +1084,44 @@ RSpec.describe UserMerger do
|
|||
end
|
||||
end
|
||||
|
||||
context "with user associated accounts (UAAs)" do
|
||||
context "when only merging account has UAAs" do
|
||||
it "transfers the source user UAA to the target" do
|
||||
source_uaa = Fabricate(:user_associated_account, user: source_user)
|
||||
|
||||
merge_users!
|
||||
|
||||
expect(source_uaa.reload.user).to eq(target_user)
|
||||
end
|
||||
end
|
||||
|
||||
context "when both accounts have UAAs" do
|
||||
context "when both accounts' UAAs have different provider_names" do
|
||||
it "transfers the source user UAA to the target and keeps both" do
|
||||
source_uaa = Fabricate(:user_associated_account, user: source_user, provider_name: "x")
|
||||
target_uaa = Fabricate(:user_associated_account, user: target_user, provider_name: "y")
|
||||
|
||||
merge_users!
|
||||
|
||||
expect(target_uaa.reload.user).to eq(target_user)
|
||||
expect(source_uaa.reload.user).to eq(target_user)
|
||||
end
|
||||
end
|
||||
|
||||
context "when both accounts' UAAs have same provider_names" do
|
||||
it "keeps only the target UAA" do
|
||||
source_uaa = Fabricate(:user_associated_account, user: source_user, provider_name: "x")
|
||||
target_uaa = Fabricate(:user_associated_account, user: target_user, provider_name: "x")
|
||||
|
||||
merge_users!
|
||||
|
||||
expect(target_uaa.reload.user).to eq(target_user)
|
||||
expect(source_uaa.reload.user).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "updates users" do
|
||||
walter.update!(approved_by: source_user)
|
||||
upload = Fabricate(:upload)
|
||||
|
|
Loading…
Reference in New Issue