mirror of
https://github.com/element-hq/synapse.git
synced 2026-08-28 19:28:17 +00:00
Recreate user profile on account reactivation (#19902)
Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com>
This commit is contained in:
co-authored by
Andrew Morgan
parent
5f89ff2b31
commit
963e486a70
@@ -0,0 +1,2 @@
|
||||
Fix a bug introduced in Synapse v1.150.0 where reactivating a deactivated and erased user did not restore their profile, breaking login, name changes, and invitations.
|
||||
Contributed by @m4us1ne.
|
||||
@@ -349,6 +349,9 @@ class DeactivateAccountHandler:
|
||||
# Ensure the user is not marked as erased.
|
||||
await self.store.mark_user_not_erased(user_id)
|
||||
|
||||
# The profile row is deleted on erasure, so recreate it if missing.
|
||||
await self.store.create_profile(user)
|
||||
|
||||
# Mark the user as active.
|
||||
await self.store.set_user_deactivated_status(user_id, False)
|
||||
|
||||
|
||||
@@ -293,15 +293,17 @@ class ProfileWorkerStore(SQLBaseStore):
|
||||
|
||||
async def create_profile(self, user_id: UserID) -> None:
|
||||
"""
|
||||
Create a blank profile for a user.
|
||||
Create a blank profile for a user, if one does not already exist.
|
||||
|
||||
Args:
|
||||
user_id: The user to create the profile for.
|
||||
"""
|
||||
user_localpart = user_id.localpart
|
||||
await self.db_pool.simple_insert(
|
||||
await self.db_pool.simple_upsert(
|
||||
table="profiles",
|
||||
values={"user_id": user_localpart, "full_user_id": user_id.to_string()},
|
||||
keyvalues={"full_user_id": user_id.to_string()},
|
||||
values={},
|
||||
insertion_values={"user_id": user_localpart},
|
||||
desc="create_profile",
|
||||
)
|
||||
|
||||
|
||||
@@ -483,3 +483,70 @@ class DeactivateAccountTestCase(HomeserverTestCase):
|
||||
|
||||
# Validate that the created room is forgotten
|
||||
self.assertTrue(room_id in forgotten_rooms)
|
||||
|
||||
def _get_profile_row(self) -> str | None:
|
||||
"""Return the `user_id` of `self.user`'s `profiles` row, or None if absent."""
|
||||
return self.get_success(
|
||||
self._store.db_pool.simple_select_one_onecol(
|
||||
table="profiles",
|
||||
keyvalues={"full_user_id": self.user},
|
||||
retcol="user_id",
|
||||
allow_none=True,
|
||||
desc="_get_profile_row",
|
||||
)
|
||||
)
|
||||
|
||||
def test_reactivation_recreates_profile(self) -> None:
|
||||
"""
|
||||
Tests that reactivating an erased user recreates their profile row, so
|
||||
that subsequent profile operations work.
|
||||
"""
|
||||
self.assertIsNotNone(self._get_profile_row())
|
||||
|
||||
# Erasure deletes the whole profiles row.
|
||||
self._deactivate_my_account()
|
||||
self.assertIsNone(self._get_profile_row())
|
||||
|
||||
# Reactivating recreates a blank profile row.
|
||||
deactivate_handler = self.hs.get_deactivate_account_handler()
|
||||
self.get_success(deactivate_handler.activate_account(self.user))
|
||||
self.assertIsNotNone(self._get_profile_row())
|
||||
|
||||
# Setting a display name now works again.
|
||||
user = UserID.from_string(self.user)
|
||||
self.get_success(
|
||||
self.hs.get_profile_handler().set_displayname(
|
||||
user, create_requester(user), "Reactivated", by_admin=True
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
self.get_success(self._store.get_profile_displayname(user)),
|
||||
"Reactivated",
|
||||
)
|
||||
|
||||
def test_reactivation_without_erasure_keeps_profile(self) -> None:
|
||||
"""
|
||||
Reactivating a user whose profile row still exists leaves it untouched.
|
||||
"""
|
||||
user = UserID.from_string(self.user)
|
||||
self.get_success(
|
||||
self.hs.get_profile_handler().set_displayname(
|
||||
user, create_requester(user), "Original", by_admin=True
|
||||
)
|
||||
)
|
||||
|
||||
# Deactivate without erasure, so the profile row is left intact.
|
||||
deactivate_handler = self.hs.get_deactivate_account_handler()
|
||||
self.get_success(
|
||||
deactivate_handler.deactivate_account(
|
||||
self.user, erase_data=False, requester=create_requester(user)
|
||||
)
|
||||
)
|
||||
self.assertIsNotNone(self._get_profile_row())
|
||||
|
||||
# Reactivating must not raise despite the existing profile row.
|
||||
self.get_success(deactivate_handler.activate_account(self.user))
|
||||
self.assertEqual(
|
||||
self.get_success(self._store.get_profile_displayname(user)),
|
||||
"Original",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user