Merge pull request #4412 from matrix-org/anoa/dm_room_upgrade
Migrate direct message and tag state on room upgrade
This commit is contained in:
commit
88f4df85ca
5 changed files with 83 additions and 18 deletions
1
changelog.d/4412.bugfix
Normal file
1
changelog.d/4412.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Copy over whether a room is a direct message and any associated room tags on room upgrade.
|
|
@ -125,7 +125,7 @@ class RoomCreationHandler(BaseHandler):
|
||||||
)
|
)
|
||||||
yield self.auth.check_from_context(tombstone_event, tombstone_context)
|
yield self.auth.check_from_context(tombstone_event, tombstone_context)
|
||||||
|
|
||||||
yield self.clone_exiting_room(
|
yield self.clone_existing_room(
|
||||||
requester,
|
requester,
|
||||||
old_room_id=old_room_id,
|
old_room_id=old_room_id,
|
||||||
new_room_id=new_room_id,
|
new_room_id=new_room_id,
|
||||||
|
@ -230,7 +230,7 @@ class RoomCreationHandler(BaseHandler):
|
||||||
)
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def clone_exiting_room(
|
def clone_existing_room(
|
||||||
self, requester, old_room_id, new_room_id, new_room_version,
|
self, requester, old_room_id, new_room_id, new_room_version,
|
||||||
tombstone_event_id,
|
tombstone_event_id,
|
||||||
):
|
):
|
||||||
|
@ -262,6 +262,7 @@ class RoomCreationHandler(BaseHandler):
|
||||||
|
|
||||||
initial_state = dict()
|
initial_state = dict()
|
||||||
|
|
||||||
|
# Replicate relevant room events
|
||||||
types_to_copy = (
|
types_to_copy = (
|
||||||
(EventTypes.JoinRules, ""),
|
(EventTypes.JoinRules, ""),
|
||||||
(EventTypes.Name, ""),
|
(EventTypes.Name, ""),
|
||||||
|
|
|
@ -63,7 +63,7 @@ class RoomMemberHandler(object):
|
||||||
self.directory_handler = hs.get_handlers().directory_handler
|
self.directory_handler = hs.get_handlers().directory_handler
|
||||||
self.registration_handler = hs.get_handlers().registration_handler
|
self.registration_handler = hs.get_handlers().registration_handler
|
||||||
self.profile_handler = hs.get_profile_handler()
|
self.profile_handler = hs.get_profile_handler()
|
||||||
self.event_creation_hander = hs.get_event_creation_handler()
|
self.event_creation_handler = hs.get_event_creation_handler()
|
||||||
|
|
||||||
self.member_linearizer = Linearizer(name="member")
|
self.member_linearizer = Linearizer(name="member")
|
||||||
|
|
||||||
|
@ -161,6 +161,8 @@ class RoomMemberHandler(object):
|
||||||
ratelimit=True,
|
ratelimit=True,
|
||||||
content=None,
|
content=None,
|
||||||
):
|
):
|
||||||
|
user_id = target.to_string()
|
||||||
|
|
||||||
if content is None:
|
if content is None:
|
||||||
content = {}
|
content = {}
|
||||||
|
|
||||||
|
@ -168,14 +170,14 @@ class RoomMemberHandler(object):
|
||||||
if requester.is_guest:
|
if requester.is_guest:
|
||||||
content["kind"] = "guest"
|
content["kind"] = "guest"
|
||||||
|
|
||||||
event, context = yield self.event_creation_hander.create_event(
|
event, context = yield self.event_creation_handler.create_event(
|
||||||
requester,
|
requester,
|
||||||
{
|
{
|
||||||
"type": EventTypes.Member,
|
"type": EventTypes.Member,
|
||||||
"content": content,
|
"content": content,
|
||||||
"room_id": room_id,
|
"room_id": room_id,
|
||||||
"sender": requester.user.to_string(),
|
"sender": requester.user.to_string(),
|
||||||
"state_key": target.to_string(),
|
"state_key": user_id,
|
||||||
|
|
||||||
# For backwards compatibility:
|
# For backwards compatibility:
|
||||||
"membership": membership,
|
"membership": membership,
|
||||||
|
@ -186,14 +188,14 @@ class RoomMemberHandler(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check if this event matches the previous membership event for the user.
|
# Check if this event matches the previous membership event for the user.
|
||||||
duplicate = yield self.event_creation_hander.deduplicate_state_event(
|
duplicate = yield self.event_creation_handler.deduplicate_state_event(
|
||||||
event, context,
|
event, context,
|
||||||
)
|
)
|
||||||
if duplicate is not None:
|
if duplicate is not None:
|
||||||
# Discard the new event since this membership change is a no-op.
|
# Discard the new event since this membership change is a no-op.
|
||||||
defer.returnValue(duplicate)
|
defer.returnValue(duplicate)
|
||||||
|
|
||||||
yield self.event_creation_hander.handle_new_client_event(
|
yield self.event_creation_handler.handle_new_client_event(
|
||||||
requester,
|
requester,
|
||||||
event,
|
event,
|
||||||
context,
|
context,
|
||||||
|
@ -204,12 +206,12 @@ class RoomMemberHandler(object):
|
||||||
prev_state_ids = yield context.get_prev_state_ids(self.store)
|
prev_state_ids = yield context.get_prev_state_ids(self.store)
|
||||||
|
|
||||||
prev_member_event_id = prev_state_ids.get(
|
prev_member_event_id = prev_state_ids.get(
|
||||||
(EventTypes.Member, target.to_string()),
|
(EventTypes.Member, user_id),
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
|
||||||
if event.membership == Membership.JOIN:
|
if event.membership == Membership.JOIN:
|
||||||
# Only fire user_joined_room if the user has acutally joined the
|
# Only fire user_joined_room if the user has actually joined the
|
||||||
# room. Don't bother if the user is just changing their profile
|
# room. Don't bother if the user is just changing their profile
|
||||||
# info.
|
# info.
|
||||||
newly_joined = True
|
newly_joined = True
|
||||||
|
@ -218,6 +220,18 @@ class RoomMemberHandler(object):
|
||||||
newly_joined = prev_member_event.membership != Membership.JOIN
|
newly_joined = prev_member_event.membership != Membership.JOIN
|
||||||
if newly_joined:
|
if newly_joined:
|
||||||
yield self._user_joined_room(target, room_id)
|
yield self._user_joined_room(target, room_id)
|
||||||
|
|
||||||
|
# Copy over direct message status and room tags if this is a join
|
||||||
|
# on an upgraded room
|
||||||
|
|
||||||
|
# Check if this is an upgraded room
|
||||||
|
predecessor = yield self.store.get_room_predecessor(room_id)
|
||||||
|
|
||||||
|
if predecessor:
|
||||||
|
# It is an upgraded room. Copy over old tags
|
||||||
|
self.copy_room_tags_and_direct_to_room(
|
||||||
|
predecessor["room_id"], room_id, user_id,
|
||||||
|
)
|
||||||
elif event.membership == Membership.LEAVE:
|
elif event.membership == Membership.LEAVE:
|
||||||
if prev_member_event_id:
|
if prev_member_event_id:
|
||||||
prev_member_event = yield self.store.get_event(prev_member_event_id)
|
prev_member_event = yield self.store.get_event(prev_member_event_id)
|
||||||
|
@ -226,6 +240,55 @@ class RoomMemberHandler(object):
|
||||||
|
|
||||||
defer.returnValue(event)
|
defer.returnValue(event)
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def copy_room_tags_and_direct_to_room(
|
||||||
|
self,
|
||||||
|
old_room_id,
|
||||||
|
new_room_id,
|
||||||
|
user_id,
|
||||||
|
):
|
||||||
|
"""Copies the tags and direct room state from one room to another.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
old_room_id (str)
|
||||||
|
new_room_id (str)
|
||||||
|
user_id (str)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Deferred[None]
|
||||||
|
"""
|
||||||
|
# Retrieve user account data for predecessor room
|
||||||
|
user_account_data, _ = yield self.store.get_account_data_for_user(
|
||||||
|
user_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Copy direct message state if applicable
|
||||||
|
direct_rooms = user_account_data.get("m.direct", {})
|
||||||
|
|
||||||
|
# Check which key this room is under
|
||||||
|
if isinstance(direct_rooms, dict):
|
||||||
|
for key, room_id_list in direct_rooms.items():
|
||||||
|
if old_room_id in room_id_list and new_room_id not in room_id_list:
|
||||||
|
# Add new room_id to this key
|
||||||
|
direct_rooms[key].append(new_room_id)
|
||||||
|
|
||||||
|
# Save back to user's m.direct account data
|
||||||
|
yield self.store.add_account_data_for_user(
|
||||||
|
user_id, "m.direct", direct_rooms,
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
|
# Copy room tags if applicable
|
||||||
|
room_tags = yield self.store.get_tags_for_room(
|
||||||
|
user_id, old_room_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Copy each room tag to the new room
|
||||||
|
for tag, tag_content in room_tags.items():
|
||||||
|
yield self.store.add_tag_to_room(
|
||||||
|
user_id, new_room_id, tag, tag_content
|
||||||
|
)
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def update_membership(
|
def update_membership(
|
||||||
self,
|
self,
|
||||||
|
@ -493,7 +556,7 @@ class RoomMemberHandler(object):
|
||||||
else:
|
else:
|
||||||
requester = synapse.types.create_requester(target_user)
|
requester = synapse.types.create_requester(target_user)
|
||||||
|
|
||||||
prev_event = yield self.event_creation_hander.deduplicate_state_event(
|
prev_event = yield self.event_creation_handler.deduplicate_state_event(
|
||||||
event, context,
|
event, context,
|
||||||
)
|
)
|
||||||
if prev_event is not None:
|
if prev_event is not None:
|
||||||
|
@ -513,7 +576,7 @@ class RoomMemberHandler(object):
|
||||||
if is_blocked:
|
if is_blocked:
|
||||||
raise SynapseError(403, "This room has been blocked on this server")
|
raise SynapseError(403, "This room has been blocked on this server")
|
||||||
|
|
||||||
yield self.event_creation_hander.handle_new_client_event(
|
yield self.event_creation_handler.handle_new_client_event(
|
||||||
requester,
|
requester,
|
||||||
event,
|
event,
|
||||||
context,
|
context,
|
||||||
|
@ -527,7 +590,7 @@ class RoomMemberHandler(object):
|
||||||
)
|
)
|
||||||
|
|
||||||
if event.membership == Membership.JOIN:
|
if event.membership == Membership.JOIN:
|
||||||
# Only fire user_joined_room if the user has acutally joined the
|
# Only fire user_joined_room if the user has actually joined the
|
||||||
# room. Don't bother if the user is just changing their profile
|
# room. Don't bother if the user is just changing their profile
|
||||||
# info.
|
# info.
|
||||||
newly_joined = True
|
newly_joined = True
|
||||||
|
@ -755,7 +818,7 @@ class RoomMemberHandler(object):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
yield self.event_creation_hander.create_and_send_nonmember_event(
|
yield self.event_creation_handler.create_and_send_nonmember_event(
|
||||||
requester,
|
requester,
|
||||||
{
|
{
|
||||||
"type": EventTypes.ThirdPartyInvite,
|
"type": EventTypes.ThirdPartyInvite,
|
||||||
|
|
|
@ -89,7 +89,7 @@ class RoomStateEventRestServlet(ClientV1RestServlet):
|
||||||
def __init__(self, hs):
|
def __init__(self, hs):
|
||||||
super(RoomStateEventRestServlet, self).__init__(hs)
|
super(RoomStateEventRestServlet, self).__init__(hs)
|
||||||
self.handlers = hs.get_handlers()
|
self.handlers = hs.get_handlers()
|
||||||
self.event_creation_hander = hs.get_event_creation_handler()
|
self.event_creation_handler = hs.get_event_creation_handler()
|
||||||
self.room_member_handler = hs.get_room_member_handler()
|
self.room_member_handler = hs.get_room_member_handler()
|
||||||
self.message_handler = hs.get_message_handler()
|
self.message_handler = hs.get_message_handler()
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ class RoomStateEventRestServlet(ClientV1RestServlet):
|
||||||
content=content,
|
content=content,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
event = yield self.event_creation_hander.create_and_send_nonmember_event(
|
event = yield self.event_creation_handler.create_and_send_nonmember_event(
|
||||||
requester,
|
requester,
|
||||||
event_dict,
|
event_dict,
|
||||||
txn_id=txn_id,
|
txn_id=txn_id,
|
||||||
|
@ -189,7 +189,7 @@ class RoomSendEventRestServlet(ClientV1RestServlet):
|
||||||
|
|
||||||
def __init__(self, hs):
|
def __init__(self, hs):
|
||||||
super(RoomSendEventRestServlet, self).__init__(hs)
|
super(RoomSendEventRestServlet, self).__init__(hs)
|
||||||
self.event_creation_hander = hs.get_event_creation_handler()
|
self.event_creation_handler = hs.get_event_creation_handler()
|
||||||
|
|
||||||
def register(self, http_server):
|
def register(self, http_server):
|
||||||
# /rooms/$roomid/send/$event_type[/$txn_id]
|
# /rooms/$roomid/send/$event_type[/$txn_id]
|
||||||
|
@ -211,7 +211,7 @@ class RoomSendEventRestServlet(ClientV1RestServlet):
|
||||||
if b'ts' in request.args and requester.app_service:
|
if b'ts' in request.args and requester.app_service:
|
||||||
event_dict['origin_server_ts'] = parse_integer(request, "ts", 0)
|
event_dict['origin_server_ts'] = parse_integer(request, "ts", 0)
|
||||||
|
|
||||||
event = yield self.event_creation_hander.create_and_send_nonmember_event(
|
event = yield self.event_creation_handler.create_and_send_nonmember_event(
|
||||||
requester,
|
requester,
|
||||||
event_dict,
|
event_dict,
|
||||||
txn_id=txn_id,
|
txn_id=txn_id,
|
||||||
|
|
|
@ -240,7 +240,7 @@ class BackgroundUpdateStore(SQLBaseStore):
|
||||||
* An integer count of the number of items to update in this batch.
|
* An integer count of the number of items to update in this batch.
|
||||||
|
|
||||||
The handler should return a deferred integer count of items updated.
|
The handler should return a deferred integer count of items updated.
|
||||||
The hander is responsible for updating the progress of the update.
|
The handler is responsible for updating the progress of the update.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
update_name(str): The name of the update that this code handles.
|
update_name(str): The name of the update that this code handles.
|
||||||
|
|
Loading…
Reference in a new issue