Redact membership events if the user requested erasure upon deactivating (#17076)
Fixes #15355 by redacting all membership events before leaving rooms.
This commit is contained in:
parent
2e92b718d5
commit
47773232b0
|
@ -0,0 +1 @@
|
||||||
|
Redact membership events if the user requested erasure upon deactivating.
|
|
@ -261,11 +261,22 @@ class DeactivateAccountHandler:
|
||||||
user = UserID.from_string(user_id)
|
user = UserID.from_string(user_id)
|
||||||
|
|
||||||
rooms_for_user = await self.store.get_rooms_for_user(user_id)
|
rooms_for_user = await self.store.get_rooms_for_user(user_id)
|
||||||
|
requester = create_requester(user, authenticated_entity=self._server_name)
|
||||||
|
should_erase = await self.store.is_user_erased(user_id)
|
||||||
|
|
||||||
for room_id in rooms_for_user:
|
for room_id in rooms_for_user:
|
||||||
logger.info("User parter parting %r from %r", user_id, room_id)
|
logger.info("User parter parting %r from %r", user_id, room_id)
|
||||||
try:
|
try:
|
||||||
|
# Before parting the user, redact all membership events if requested
|
||||||
|
if should_erase:
|
||||||
|
event_ids = await self.store.get_membership_event_ids_for_user(
|
||||||
|
user_id, room_id
|
||||||
|
)
|
||||||
|
for event_id in event_ids:
|
||||||
|
await self.store.expire_event(event_id)
|
||||||
|
|
||||||
await self._room_member_handler.update_membership(
|
await self._room_member_handler.update_membership(
|
||||||
create_requester(user, authenticated_entity=self._server_name),
|
requester,
|
||||||
user,
|
user,
|
||||||
room_id,
|
room_id,
|
||||||
"leave",
|
"leave",
|
||||||
|
|
|
@ -1234,6 +1234,28 @@ class RoomMemberWorkerStore(EventsWorkerStore, CacheInvalidationWorkerStore):
|
||||||
|
|
||||||
return set(room_ids)
|
return set(room_ids)
|
||||||
|
|
||||||
|
async def get_membership_event_ids_for_user(
|
||||||
|
self, user_id: str, room_id: str
|
||||||
|
) -> Set[str]:
|
||||||
|
"""Get all event_ids for the given user and room.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_id: The user ID to get the event IDs for.
|
||||||
|
room_id: The room ID to look up events for.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Set of event IDs
|
||||||
|
"""
|
||||||
|
|
||||||
|
event_ids = await self.db_pool.simple_select_onecol(
|
||||||
|
table="room_memberships",
|
||||||
|
keyvalues={"user_id": user_id, "room_id": room_id},
|
||||||
|
retcol="event_id",
|
||||||
|
desc="get_membership_event_ids_for_user",
|
||||||
|
)
|
||||||
|
|
||||||
|
return set(event_ids)
|
||||||
|
|
||||||
@cached(max_entries=5000)
|
@cached(max_entries=5000)
|
||||||
async def _get_membership_from_event_id(
|
async def _get_membership_from_event_id(
|
||||||
self, member_event_id: str
|
self, member_event_id: str
|
||||||
|
|
|
@ -424,3 +424,40 @@ class DeactivateAccountTestCase(HomeserverTestCase):
|
||||||
self._store.get_knocked_at_rooms_for_local_user(self.user)
|
self._store.get_knocked_at_rooms_for_local_user(self.user)
|
||||||
)
|
)
|
||||||
self.assertEqual(len(after_deactivate_knocks), 0)
|
self.assertEqual(len(after_deactivate_knocks), 0)
|
||||||
|
|
||||||
|
def test_membership_is_redacted_upon_deactivation(self) -> None:
|
||||||
|
"""
|
||||||
|
Tests that room membership events are redacted if erasure is requested.
|
||||||
|
"""
|
||||||
|
# Create a room
|
||||||
|
room_id = self.helper.create_room_as(
|
||||||
|
self.user,
|
||||||
|
is_public=True,
|
||||||
|
tok=self.token,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Change the displayname
|
||||||
|
membership_event, _ = self.get_success(
|
||||||
|
self.handler.update_membership(
|
||||||
|
requester=create_requester(self.user),
|
||||||
|
target=UserID.from_string(self.user),
|
||||||
|
room_id=room_id,
|
||||||
|
action=Membership.JOIN,
|
||||||
|
content={"displayname": "Hello World!"},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Deactivate the account
|
||||||
|
self._deactivate_my_account()
|
||||||
|
|
||||||
|
# Get the all membership event IDs
|
||||||
|
membership_event_ids = self.get_success(
|
||||||
|
self._store.get_membership_event_ids_for_user(self.user, room_id=room_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get the events incl. JSON
|
||||||
|
events = self.get_success(self._store.get_events_as_list(membership_event_ids))
|
||||||
|
|
||||||
|
# Validate that there is no displayname in any of the events
|
||||||
|
for event in events:
|
||||||
|
self.assertTrue("displayname" not in event.content)
|
||||||
|
|
Loading…
Reference in New Issue