mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-12-10 20:44:58 -05:00
Faster Remote Room Joins: tell remote homeservers that we are unable to authorise them if they query a room which has partial state on our server. (#13823)
This commit is contained in:
parent
ac7e5683d6
commit
c06b2b7142
11 changed files with 58 additions and 42 deletions
|
|
@ -31,7 +31,6 @@ from synapse.events import EventBase
|
|||
from synapse.events.builder import EventBuilder
|
||||
from synapse.events.snapshot import EventContext
|
||||
from synapse.types import StateMap, get_domain_from_id
|
||||
from synapse.util.metrics import Measure
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.server import HomeServer
|
||||
|
|
@ -156,9 +155,33 @@ class EventAuthHandler:
|
|||
Codes.UNABLE_TO_GRANT_JOIN,
|
||||
)
|
||||
|
||||
async def check_host_in_room(self, room_id: str, host: str) -> bool:
|
||||
with Measure(self._clock, "check_host_in_room"):
|
||||
return await self._store.is_host_joined(room_id, host)
|
||||
async def is_host_in_room(self, room_id: str, host: str) -> bool:
|
||||
return await self._store.is_host_joined(room_id, host)
|
||||
|
||||
async def assert_host_in_room(
|
||||
self, room_id: str, host: str, allow_partial_state_rooms: bool = False
|
||||
) -> None:
|
||||
"""
|
||||
Asserts that the host is in the room, or raises an AuthError.
|
||||
|
||||
If the room is partial-stated, we raise an AuthError with the
|
||||
UNABLE_DUE_TO_PARTIAL_STATE error code, unless `allow_partial_state_rooms` is true.
|
||||
|
||||
If allow_partial_state_rooms is True and the room is partial-stated,
|
||||
this function may return an incorrect result as we are not able to fully
|
||||
track server membership in a room without full state.
|
||||
"""
|
||||
if not allow_partial_state_rooms and await self._store.is_partial_state_room(
|
||||
room_id
|
||||
):
|
||||
raise AuthError(
|
||||
403,
|
||||
"Unable to authorise you right now; room is partial-stated here.",
|
||||
errcode=Codes.UNABLE_DUE_TO_PARTIAL_STATE,
|
||||
)
|
||||
|
||||
if not await self.is_host_in_room(room_id, host):
|
||||
raise AuthError(403, "Host not in room.")
|
||||
|
||||
async def check_restricted_join_rules(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -804,7 +804,7 @@ class FederationHandler:
|
|||
)
|
||||
|
||||
# now check that we are *still* in the room
|
||||
is_in_room = await self._event_auth_handler.check_host_in_room(
|
||||
is_in_room = await self._event_auth_handler.is_host_in_room(
|
||||
room_id, self.server_name
|
||||
)
|
||||
if not is_in_room:
|
||||
|
|
@ -1150,9 +1150,7 @@ class FederationHandler:
|
|||
async def on_backfill_request(
|
||||
self, origin: str, room_id: str, pdu_list: List[str], limit: int
|
||||
) -> List[EventBase]:
|
||||
in_room = await self._event_auth_handler.check_host_in_room(room_id, origin)
|
||||
if not in_room:
|
||||
raise AuthError(403, "Host not in room.")
|
||||
await self._event_auth_handler.assert_host_in_room(room_id, origin)
|
||||
|
||||
# Synapse asks for 100 events per backfill request. Do not allow more.
|
||||
limit = min(limit, 100)
|
||||
|
|
@ -1198,21 +1196,17 @@ class FederationHandler:
|
|||
event_id, allow_none=True, allow_rejected=True
|
||||
)
|
||||
|
||||
if event:
|
||||
in_room = await self._event_auth_handler.check_host_in_room(
|
||||
event.room_id, origin
|
||||
)
|
||||
if not in_room:
|
||||
raise AuthError(403, "Host not in room.")
|
||||
|
||||
events = await filter_events_for_server(
|
||||
self._storage_controllers, origin, [event]
|
||||
)
|
||||
event = events[0]
|
||||
return event
|
||||
else:
|
||||
if not event:
|
||||
return None
|
||||
|
||||
await self._event_auth_handler.assert_host_in_room(event.room_id, origin)
|
||||
|
||||
events = await filter_events_for_server(
|
||||
self._storage_controllers, origin, [event]
|
||||
)
|
||||
event = events[0]
|
||||
return event
|
||||
|
||||
async def on_get_missing_events(
|
||||
self,
|
||||
origin: str,
|
||||
|
|
@ -1221,9 +1215,7 @@ class FederationHandler:
|
|||
latest_events: List[str],
|
||||
limit: int,
|
||||
) -> List[EventBase]:
|
||||
in_room = await self._event_auth_handler.check_host_in_room(room_id, origin)
|
||||
if not in_room:
|
||||
raise AuthError(403, "Host not in room.")
|
||||
await self._event_auth_handler.assert_host_in_room(room_id, origin)
|
||||
|
||||
# Only allow up to 20 events to be retrieved per request.
|
||||
limit = min(limit, 20)
|
||||
|
|
@ -1257,7 +1249,7 @@ class FederationHandler:
|
|||
"state_key": target_user_id,
|
||||
}
|
||||
|
||||
if await self._event_auth_handler.check_host_in_room(room_id, self.hs.hostname):
|
||||
if await self._event_auth_handler.is_host_in_room(room_id, self.hs.hostname):
|
||||
room_version_obj = await self.store.get_room_version(room_id)
|
||||
builder = self.event_builder_factory.for_room_version(
|
||||
room_version_obj, event_dict
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ class FederationEventHandler:
|
|||
#
|
||||
# Note that if we were never in the room then we would have already
|
||||
# dropped the event, since we wouldn't know the room version.
|
||||
is_in_room = await self._event_auth_handler.check_host_in_room(
|
||||
is_in_room = await self._event_auth_handler.is_host_in_room(
|
||||
room_id, self._server_name
|
||||
)
|
||||
if not is_in_room:
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class ReceiptsHandler:
|
|||
# If we're not in the room just ditch the event entirely. This is
|
||||
# probably an old server that has come back and thinks we're still in
|
||||
# the room (or we've been rejoined to the room by a state reset).
|
||||
is_in_room = await self.event_auth_handler.check_host_in_room(
|
||||
is_in_room = await self.event_auth_handler.is_host_in_room(
|
||||
room_id, self.server_name
|
||||
)
|
||||
if not is_in_room:
|
||||
|
|
|
|||
|
|
@ -609,7 +609,7 @@ class RoomSummaryHandler:
|
|||
# If this is a request over federation, check if the host is in the room or
|
||||
# has a user who could join the room.
|
||||
elif origin:
|
||||
if await self._event_auth_handler.check_host_in_room(
|
||||
if await self._event_auth_handler.is_host_in_room(
|
||||
room_id, origin
|
||||
) or await self._store.is_host_invited(room_id, origin):
|
||||
return True
|
||||
|
|
@ -624,9 +624,7 @@ class RoomSummaryHandler:
|
|||
await self._event_auth_handler.get_rooms_that_allow_join(state_ids)
|
||||
)
|
||||
for space_id in allowed_rooms:
|
||||
if await self._event_auth_handler.check_host_in_room(
|
||||
space_id, origin
|
||||
):
|
||||
if await self._event_auth_handler.is_host_in_room(space_id, origin):
|
||||
return True
|
||||
|
||||
logger.info(
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ class TypingWriterHandler(FollowerTypingHandler):
|
|||
# If we're not in the room just ditch the event entirely. This is
|
||||
# probably an old server that has come back and thinks we're still in
|
||||
# the room (or we've been rejoined to the room by a state reset).
|
||||
is_in_room = await self.event_auth_handler.check_host_in_room(
|
||||
is_in_room = await self.event_auth_handler.is_host_in_room(
|
||||
room_id, self.server_name
|
||||
)
|
||||
if not is_in_room:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue