Add conn_id field

This commit is contained in:
Erik Johnston 2024-07-17 13:54:00 +01:00
parent d44f7e12b1
commit 53273db3e8
4 changed files with 36 additions and 5 deletions

View file

@ -1807,7 +1807,7 @@ class SlidingSyncHandler:
""" """
user_id = sync_config.user.to_string() user_id = sync_config.user.to_string()
device_id = sync_config.device_id device_id = sync_config.requester.device_id
# Check that this request has a valid device ID (not all requests have # Check that this request has a valid device ID (not all requests have
# to belong to a device, and so device_id is None), and that the # to belong to a device, and so device_id is None), and that the

View file

@ -881,7 +881,6 @@ class SlidingSyncRestServlet(RestServlet):
) )
user = requester.user user = requester.user
device_id = requester.device_id
timeout = parse_integer(request, "timeout", default=0) timeout = parse_integer(request, "timeout", default=0)
# Position in the stream # Position in the stream
@ -902,11 +901,12 @@ class SlidingSyncRestServlet(RestServlet):
sync_config = SlidingSyncConfig( sync_config = SlidingSyncConfig(
user=user, user=user,
device_id=device_id, requester=requester,
# FIXME: Currently, we're just manually copying the fields from the # FIXME: Currently, we're just manually copying the fields from the
# `SlidingSyncBody` into the config. How can we gurantee into the future # `SlidingSyncBody` into the config. How can we guarantee into the future
# that we don't forget any? I would like something more structured like # that we don't forget any? I would like something more structured like
# `copy_attributes(from=body, to=config)` # `copy_attributes(from=body, to=config)`
conn_id=body.conn_id,
lists=body.lists, lists=body.lists,
room_subscriptions=body.room_subscriptions, room_subscriptions=body.room_subscriptions,
extensions=body.extensions, extensions=body.extensions,

View file

@ -34,6 +34,7 @@ from synapse.events import EventBase
from synapse.types import ( from synapse.types import (
JsonDict, JsonDict,
JsonMapping, JsonMapping,
Requester,
SlidingSyncStreamToken, SlidingSyncStreamToken,
StreamToken, StreamToken,
UserID, UserID,
@ -108,7 +109,7 @@ class SlidingSyncConfig(SlidingSyncBody):
""" """
user: UserID user: UserID
device_id: Optional[str] requester: Requester
# Pydantic config # Pydantic config
class Config: class Config:
@ -119,6 +120,31 @@ class SlidingSyncConfig(SlidingSyncBody):
# Allow custom types like `UserID` to be used in the model # Allow custom types like `UserID` to be used in the model
arbitrary_types_allowed = True arbitrary_types_allowed = True
def connection_id(self) -> str:
"""Return a string identifier for this connection. May clash with
connection IDs from different users.
This is generally a combination of device ID and conn_id. However, both
these two are optional (e.g. puppet access tokens don't have device
IDs), so this handles those edge cases.
"""
# `conn_id` can be null, in which case we default to the empty string
# (if conn ID is empty then the client can't have multiple sync loops)
conn_id = self.conn_id or ""
if self.requester.device_id:
return f"D/{self.requester.device_id}/{conn_id}"
if self.requester.access_token_id:
# If we don't have a device, then the access token ID should be a
# stable ID.
return f"A/{self.requester.access_token_id}/{conn_id}"
# If we have neither then its likely an AS or some weird token. Either
# way we can just fail here.
raise Exception("Cannot use sliding sync with access token type")
class OperationType(Enum): class OperationType(Enum):
""" """

View file

@ -120,6 +120,9 @@ class SlidingSyncBody(RequestBodyModel):
Sliding Sync API request body. Sliding Sync API request body.
Attributes: Attributes:
conn_id: An optional string to identify this connection to the server. If this
is missing, only 1 sliding sync connection can be made to the server at
any one time.
lists: Sliding window API. A map of list key to list information lists: Sliding window API. A map of list key to list information
(:class:`SlidingSyncList`). Max lists: 100. The list keys should be (:class:`SlidingSyncList`). Max lists: 100. The list keys should be
arbitrary strings which the client is using to refer to the list. Keep this arbitrary strings which the client is using to refer to the list. Keep this
@ -315,6 +318,8 @@ class SlidingSyncBody(RequestBodyModel):
to_device: Optional[ToDeviceExtension] = None to_device: Optional[ToDeviceExtension] = None
conn_id: Optional[str]
# mypy workaround via https://github.com/pydantic/pydantic/issues/156#issuecomment-1130883884 # mypy workaround via https://github.com/pydantic/pydantic/issues/156#issuecomment-1130883884
if TYPE_CHECKING: if TYPE_CHECKING:
lists: Optional[Dict[str, SlidingSyncList]] = None lists: Optional[Dict[str, SlidingSyncList]] = None