def _generate_sync_config(self, user_id): return SyncConfig( user=UserID(user_id.split(":")[0][1:], user_id.split(":")[1]), filter_collection=DEFAULT_FILTER_COLLECTION, is_guest=False, request_key="request_key", device_id="device_id", )
def generate_sync_config(user_id: str, device_id: Optional[str] = "device_id") -> SyncConfig: """Generate a sync config (with a unique request key).""" global _request_key _request_key += 1 return SyncConfig( user=UserID.from_string(user_id), filter_collection=Filtering(Mock()).DEFAULT_FILTER_COLLECTION, is_guest=False, request_key=("request_key", _request_key), device_id=device_id, )
def on_GET(self, request): if b"from" in request.args: # /events used to use 'from', but /sync uses 'since'. # Lets be helpful and whine if we see a 'from'. raise SynapseError( 400, "'from' is not a valid query parameter. Did you mean 'since'?") requester = yield self.auth.get_user_by_req(request, allow_guest=True) user = requester.user device_id = requester.device_id timeout = parse_integer(request, "timeout", default=0) since = parse_string(request, "since") set_presence = parse_string( request, "set_presence", default="online", allowed_values=self.ALLOWED_PRESENCE, ) filter_id = parse_string(request, "filter", default=None) full_state = parse_boolean(request, "full_state", default=False) logger.debug( "/sync: user=%r, timeout=%r, since=%r," " set_presence=%r, filter_id=%r, device_id=%r" % (user, timeout, since, set_presence, filter_id, device_id)) request_key = (user, timeout, since, filter_id, full_state, device_id) if filter_id: if filter_id.startswith("{"): try: filter_object = json.loads(filter_id) set_timeline_upper_limit( filter_object, self.hs.config.filter_timeline_limit) except Exception: raise SynapseError(400, "Invalid filter JSON") self.filtering.check_valid_filter(filter_object) filter = FilterCollection(filter_object) else: filter = yield self.filtering.get_user_filter( user.localpart, filter_id) else: filter = DEFAULT_FILTER_COLLECTION sync_config = SyncConfig( user=user, filter_collection=filter, is_guest=requester.is_guest, request_key=request_key, device_id=device_id, ) if since is not None: since_token = StreamToken.from_string(since) else: since_token = None # send any outstanding server notices to the user. yield self._server_notices_sender.on_user_syncing(user.to_string()) affect_presence = set_presence != PresenceState.OFFLINE if affect_presence: yield self.presence_handler.set_state(user, {"presence": set_presence}, True) context = yield self.presence_handler.user_syncing( user.to_string(), affect_presence=affect_presence) with context: sync_result = yield self.sync_handler.wait_for_sync_for_user( sync_config, since_token=since_token, timeout=timeout, full_state=full_state, ) time_now = self.clock.time_msec() response_content = yield self.encode_response( time_now, sync_result, requester.access_token_id, filter) return 200, response_content
def on_GET(self, request): if "from" in request.args: # /events used to use 'from', but /sync uses 'since'. # Lets be helpful and whine if we see a 'from'. raise SynapseError( 400, "'from' is not a valid query parameter. Did you mean 'since'?") requester = yield self.auth.get_user_by_req(request, allow_guest=True) user = requester.user device_id = requester.device_id timeout = parse_integer(request, "timeout", default=0) since = parse_string(request, "since") set_presence = parse_string(request, "set_presence", default="online", allowed_values=self.ALLOWED_PRESENCE) filter_id = parse_string(request, "filter", default=None) full_state = parse_boolean(request, "full_state", default=False) logger.info("/sync: user=%r, timeout=%r, since=%r," " set_presence=%r, filter_id=%r, device_id=%r" % (user, timeout, since, set_presence, filter_id, device_id)) request_key = (user, timeout, since, filter_id, full_state, device_id) if filter_id: if filter_id.startswith('{'): try: filter_object = json.loads(filter_id) except: raise SynapseError(400, "Invalid filter JSON") self.filtering.check_valid_filter(filter_object) filter = FilterCollection(filter_object) else: filter = yield self.filtering.get_user_filter( user.localpart, filter_id) else: filter = DEFAULT_FILTER_COLLECTION sync_config = SyncConfig( user=user, filter_collection=filter, is_guest=requester.is_guest, request_key=request_key, device_id=device_id, ) if since is not None: since_token = StreamToken.from_string(since) else: since_token = None affect_presence = set_presence != PresenceState.OFFLINE if affect_presence: yield self.presence_handler.set_state(user, {"presence": set_presence}, True) context = yield self.presence_handler.user_syncing( user.to_string(), affect_presence=affect_presence, ) with context: sync_result = yield self.sync_handler.wait_for_sync_for_user( sync_config, since_token=since_token, timeout=timeout, full_state=full_state) time_now = self.clock.time_msec() joined = self.encode_joined(sync_result.joined, time_now, requester.access_token_id, filter.event_fields) invited = self.encode_invited(sync_result.invited, time_now, requester.access_token_id) archived = self.encode_archived( sync_result.archived, time_now, requester.access_token_id, filter.event_fields, ) response_content = { "account_data": { "events": sync_result.account_data }, "to_device": { "events": sync_result.to_device }, "device_lists": { "changed": list(sync_result.device_lists), }, "presence": self.encode_presence(sync_result.presence, time_now), "rooms": { "join": joined, "invite": invited, "leave": archived, }, "next_batch": sync_result.next_batch.to_string(), } defer.returnValue((200, response_content))
async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]: # This will always be set by the time Twisted calls us. assert request.args is not None if b"from" in request.args: # /events used to use 'from', but /sync uses 'since'. # Lets be helpful and whine if we see a 'from'. raise SynapseError( 400, "'from' is not a valid query parameter. Did you mean 'since'?" ) requester = await self.auth.get_user_by_req(request, allow_guest=True) user = requester.user device_id = requester.device_id timeout = parse_integer(request, "timeout", default=0) since = parse_string(request, "since") set_presence = parse_string( request, "set_presence", default="online", allowed_values=self.ALLOWED_PRESENCE, ) filter_id = parse_string(request, "filter") full_state = parse_boolean(request, "full_state", default=False) logger.debug( "/sync: user=%r, timeout=%r, since=%r, " "set_presence=%r, filter_id=%r, device_id=%r", user, timeout, since, set_presence, filter_id, device_id, ) request_key = (user, timeout, since, filter_id, full_state, device_id) if filter_id is None: filter_collection = DEFAULT_FILTER_COLLECTION elif filter_id.startswith("{"): try: filter_object = json_decoder.decode(filter_id) set_timeline_upper_limit( filter_object, self.hs.config.server.filter_timeline_limit ) except Exception: raise SynapseError(400, "Invalid filter JSON") self.filtering.check_valid_filter(filter_object) filter_collection = FilterCollection(filter_object) else: try: filter_collection = await self.filtering.get_user_filter( user.localpart, filter_id ) except StoreError as err: if err.code != 404: raise # fix up the description and errcode to be more useful raise SynapseError(400, "No such filter", errcode=Codes.INVALID_PARAM) sync_config = SyncConfig( user=user, filter_collection=filter_collection, is_guest=requester.is_guest, request_key=request_key, device_id=device_id, ) since_token = None if since is not None: since_token = await StreamToken.from_string(self.store, since) # send any outstanding server notices to the user. await self._server_notices_sender.on_user_syncing(user.to_string()) affect_presence = set_presence != PresenceState.OFFLINE if affect_presence: await self.presence_handler.set_state( user, {"presence": set_presence}, True ) context = await self.presence_handler.user_syncing( user.to_string(), affect_presence=affect_presence ) with context: sync_result = await self.sync_handler.wait_for_sync_for_user( requester, sync_config, since_token=since_token, timeout=timeout, full_state=full_state, ) # the client may have disconnected by now; don't bother to serialize the # response if so. if request._disconnected: logger.info("Client has disconnected; not serializing response.") return 200, {} time_now = self.clock.time_msec() # We know that the the requester has an access token since appservices # cannot use sync. response_content = await self.encode_response( time_now, sync_result, requester.access_token_id, filter_collection ) logger.debug("Event formatting complete") return 200, response_content
def on_GET(self, request): user, client = yield self.auth.get_user_by_req(request) timeout = self.parse_integer(request, "timeout", default=0) limit = self.parse_integer(request, "limit", required=True) gap = self.parse_boolean(request, "gap", default=True) sort = self.parse_string( request, "sort", default="timeline,asc", allowed_values=self.ALLOWED_SORT ) since = self.parse_string(request, "since") set_presence = self.parse_string( request, "set_presence", default="online", allowed_values=self.ALLOWED_PRESENCE ) backfill = self.parse_boolean(request, "backfill", default=False) filter_id = self.parse_string(request, "filter", default=None) logger.info( "/sync: user=%r, timeout=%r, limit=%r, gap=%r, sort=%r, since=%r," " set_presence=%r, backfill=%r, filter_id=%r" % ( user, timeout, limit, gap, sort, since, set_presence, backfill, filter_id ) ) # TODO(mjark): Load filter and apply overrides. try: filter = yield self.filtering.get_user_filter( user.localpart, filter_id ) except: filter = Filter({}) # filter = filter.apply_overrides(http_request) # if filter.matches(event): # # stuff sync_config = SyncConfig( user=user, client_info=client, gap=gap, limit=limit, sort=sort, backfill=backfill, filter=filter, ) if since is not None: since_token = StreamToken.from_string(since) else: since_token = None sync_result = yield self.sync_handler.wait_for_sync_for_user( sync_config, since_token=since_token, timeout=timeout ) time_now = self.clock.time_msec() response_content = { "public_user_data": self.encode_user_data( sync_result.public_user_data, filter, time_now ), "private_user_data": self.encode_user_data( sync_result.private_user_data, filter, time_now ), "rooms": self.encode_rooms( sync_result.rooms, filter, time_now, client.token_id ), "next_batch": sync_result.next_batch.to_string(), } defer.returnValue((200, response_content))
def on_GET(self, request): user, token_id, is_guest = yield self.auth.get_user_by_req( request, allow_guest=True ) timeout = parse_integer(request, "timeout", default=0) since = parse_string(request, "since") set_presence = parse_string( request, "set_presence", default="online", allowed_values=self.ALLOWED_PRESENCE ) filter_id = parse_string(request, "filter", default=None) full_state = parse_boolean(request, "full_state", default=False) logger.info( "/sync: user=%r, timeout=%r, since=%r," " set_presence=%r, filter_id=%r" % ( user, timeout, since, set_presence, filter_id ) ) if filter_id and filter_id.startswith('{'): try: filter_object = json.loads(filter_id) except: raise SynapseError(400, "Invalid filter JSON") self.filtering._check_valid_filter(filter_object) filter = FilterCollection(filter_object) else: try: filter = yield self.filtering.get_user_filter( user.localpart, filter_id ) except: filter = FilterCollection({}) if is_guest and filter.list_rooms() is None: raise SynapseError( 400, "Guest users must provide a list of rooms in the filter" ) sync_config = SyncConfig( user=user, is_guest=is_guest, filter=filter, ) if since is not None: since_token = StreamToken.from_string(since) else: since_token = None if set_presence == "online": yield self.event_stream_handler.started_stream(user) try: sync_result = yield self.sync_handler.wait_for_sync_for_user( sync_config, since_token=since_token, timeout=timeout, full_state=full_state ) finally: if set_presence == "online": self.event_stream_handler.stopped_stream(user) time_now = self.clock.time_msec() joined = self.encode_joined( sync_result.joined, filter, time_now, token_id ) invited = self.encode_invited( sync_result.invited, filter, time_now, token_id ) archived = self.encode_archived( sync_result.archived, filter, time_now, token_id ) response_content = { "account_data": self.encode_account_data( sync_result.account_data, filter, time_now ), "presence": self.encode_presence( sync_result.presence, filter, time_now ), "rooms": { "join": joined, "invite": invited, "leave": archived, }, "next_batch": sync_result.next_batch.to_string(), } defer.returnValue((200, response_content))