forked from MirrorHub/synapse
Prevent message search in upgraded rooms we're not in (#6385)
This commit is contained in:
parent
54ae52ba96
commit
ea0f0ad414
4 changed files with 41 additions and 16 deletions
1
changelog.d/6385.bugfix
Normal file
1
changelog.d/6385.bugfix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Prevent error on trying to search a upgraded room when the server is not in the predecessor room.
|
|
@ -1299,7 +1299,7 @@ class FederationHandler(BaseHandler):
|
||||||
# Check whether this room is the result of an upgrade of a room we already know
|
# Check whether this room is the result of an upgrade of a room we already know
|
||||||
# about. If so, migrate over user information
|
# about. If so, migrate over user information
|
||||||
predecessor = yield self.store.get_room_predecessor(room_id)
|
predecessor = yield self.store.get_room_predecessor(room_id)
|
||||||
if not predecessor:
|
if not predecessor or not isinstance(predecessor.get("room_id"), str):
|
||||||
return
|
return
|
||||||
old_room_id = predecessor["room_id"]
|
old_room_id = predecessor["room_id"]
|
||||||
logger.debug(
|
logger.debug(
|
||||||
|
@ -1542,7 +1542,7 @@ class FederationHandler(BaseHandler):
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def do_remotely_reject_invite(self, target_hosts, room_id, user_id, content):
|
def do_remotely_reject_invite(self, target_hosts, room_id, user_id, content):
|
||||||
origin, event, event_format_version = yield self._make_and_verify_event(
|
origin, event, event_format_version = yield self._make_and_verify_event(
|
||||||
target_hosts, room_id, user_id, "leave", content=content,
|
target_hosts, room_id, user_id, "leave", content=content
|
||||||
)
|
)
|
||||||
# Mark as outlier as we don't have any state for this event; we're not
|
# Mark as outlier as we don't have any state for this event; we're not
|
||||||
# even in the room.
|
# even in the room.
|
||||||
|
|
|
@ -21,7 +21,7 @@ from unpaddedbase64 import decode_base64, encode_base64
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
|
|
||||||
from synapse.api.constants import EventTypes, Membership
|
from synapse.api.constants import EventTypes, Membership
|
||||||
from synapse.api.errors import SynapseError
|
from synapse.api.errors import NotFoundError, SynapseError
|
||||||
from synapse.api.filtering import Filter
|
from synapse.api.filtering import Filter
|
||||||
from synapse.storage.state import StateFilter
|
from synapse.storage.state import StateFilter
|
||||||
from synapse.visibility import filter_events_for_client
|
from synapse.visibility import filter_events_for_client
|
||||||
|
@ -37,6 +37,7 @@ class SearchHandler(BaseHandler):
|
||||||
self._event_serializer = hs.get_event_client_serializer()
|
self._event_serializer = hs.get_event_client_serializer()
|
||||||
self.storage = hs.get_storage()
|
self.storage = hs.get_storage()
|
||||||
self.state_store = self.storage.state
|
self.state_store = self.storage.state
|
||||||
|
self.auth = hs.get_auth()
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_old_rooms_from_upgraded_room(self, room_id):
|
def get_old_rooms_from_upgraded_room(self, room_id):
|
||||||
|
@ -53,23 +54,38 @@ class SearchHandler(BaseHandler):
|
||||||
room_id (str): id of the room to search through.
|
room_id (str): id of the room to search through.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Deferred[iterable[unicode]]: predecessor room ids
|
Deferred[iterable[str]]: predecessor room ids
|
||||||
"""
|
"""
|
||||||
|
|
||||||
historical_room_ids = []
|
historical_room_ids = []
|
||||||
|
|
||||||
while True:
|
# The initial room must have been known for us to get this far
|
||||||
predecessor = yield self.store.get_room_predecessor(room_id)
|
predecessor = yield self.store.get_room_predecessor(room_id)
|
||||||
|
|
||||||
# If no predecessor, assume we've hit a dead end
|
while True:
|
||||||
if not predecessor:
|
if not predecessor:
|
||||||
|
# We have reached the end of the chain of predecessors
|
||||||
break
|
break
|
||||||
|
|
||||||
# Add predecessor's room ID
|
if not isinstance(predecessor.get("room_id"), str):
|
||||||
historical_room_ids.append(predecessor["room_id"])
|
# This predecessor object is malformed. Exit here
|
||||||
|
break
|
||||||
|
|
||||||
# Scan through the old room for further predecessors
|
predecessor_room_id = predecessor["room_id"]
|
||||||
room_id = predecessor["room_id"]
|
|
||||||
|
# Don't add it to the list until we have checked that we are in the room
|
||||||
|
try:
|
||||||
|
next_predecessor_room = yield self.store.get_room_predecessor(
|
||||||
|
predecessor_room_id
|
||||||
|
)
|
||||||
|
except NotFoundError:
|
||||||
|
# The predecessor is not a known room, so we are done here
|
||||||
|
break
|
||||||
|
|
||||||
|
historical_room_ids.append(predecessor_room_id)
|
||||||
|
|
||||||
|
# And repeat
|
||||||
|
predecessor = next_predecessor_room
|
||||||
|
|
||||||
return historical_room_ids
|
return historical_room_ids
|
||||||
|
|
||||||
|
|
|
@ -278,7 +278,7 @@ class StateGroupWorkerStore(
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_room_predecessor(self, room_id):
|
def get_room_predecessor(self, room_id):
|
||||||
"""Get the predecessor room of an upgraded room if one exists.
|
"""Get the predecessor of an upgraded room if it exists.
|
||||||
Otherwise return None.
|
Otherwise return None.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -291,14 +291,22 @@ class StateGroupWorkerStore(
|
||||||
* room_id (str): The room ID of the predecessor room
|
* room_id (str): The room ID of the predecessor room
|
||||||
* event_id (str): The ID of the tombstone event in the predecessor room
|
* event_id (str): The ID of the tombstone event in the predecessor room
|
||||||
|
|
||||||
|
None if a predecessor key is not found, or is not a dictionary.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
NotFoundError if the room is unknown
|
NotFoundError if the given room is unknown
|
||||||
"""
|
"""
|
||||||
# Retrieve the room's create event
|
# Retrieve the room's create event
|
||||||
create_event = yield self.get_create_event_for_room(room_id)
|
create_event = yield self.get_create_event_for_room(room_id)
|
||||||
|
|
||||||
# Return predecessor if present
|
# Retrieve the predecessor key of the create event
|
||||||
return create_event.content.get("predecessor", None)
|
predecessor = create_event.content.get("predecessor", None)
|
||||||
|
|
||||||
|
# Ensure the key is a dictionary
|
||||||
|
if not isinstance(predecessor, dict):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return predecessor
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_create_event_for_room(self, room_id):
|
def get_create_event_for_room(self, room_id):
|
||||||
|
@ -318,7 +326,7 @@ class StateGroupWorkerStore(
|
||||||
|
|
||||||
# If we can't find the create event, assume we've hit a dead end
|
# If we can't find the create event, assume we've hit a dead end
|
||||||
if not create_id:
|
if not create_id:
|
||||||
raise NotFoundError("Unknown room %s" % (room_id))
|
raise NotFoundError("Unknown room %s" % (room_id,))
|
||||||
|
|
||||||
# Retrieve the room's create event and return
|
# Retrieve the room's create event and return
|
||||||
create_event = yield self.get_event(create_id)
|
create_event = yield self.get_event(create_id)
|
||||||
|
|
Loading…
Reference in a new issue