class RoomInitialSyncRestServlet(RestServlet): PATTERNS = client_patterns("/rooms/(?P<room_id>[^/]*)/initialSync$", v1=True) def __init__(self, hs): super(RoomInitialSyncRestServlet, self).__init__() self.initial_sync_handler = hs.get_initial_sync_handler() self.auth = hs.get_auth() @defer.inlineCallbacks def on_GET(self, request, room_id): requester = yield self.auth.get_user_by_req(request, allow_guest=True) pagination_config = PaginationConfig.from_request(request) content = yield self.initial_sync_handler.room_initial_sync( room_id=room_id, requester=requester, pagin_config=pagination_config ) defer.returnValue((200, content))
class RoomInitialSyncRestServlet(RestServlet): PATTERNS = client_patterns("/rooms/(?P<room_id>[^/]*)/initialSync$", v1=True) def __init__(self, hs): super().__init__() self.initial_sync_handler = hs.get_initial_sync_handler() self.auth = hs.get_auth() self.store = hs.get_datastore() async def on_GET(self, request, room_id): requester = await self.auth.get_user_by_req(request, allow_guest=True) pagination_config = await PaginationConfig.from_request(self.store, request) content = await self.initial_sync_handler.room_initial_sync( room_id=room_id, requester=requester, pagin_config=pagination_config ) return 200, content
class JoinedRoomMemberListRestServlet(RestServlet): PATTERNS = client_patterns("/rooms/(?P<room_id>[^/]*)/joined_members$", v1=True) def __init__(self, hs): super(JoinedRoomMemberListRestServlet, self).__init__() self.message_handler = hs.get_message_handler() self.auth = hs.get_auth() async def on_GET(self, request, room_id): requester = await self.auth.get_user_by_req(request) users_with_profile = await self.message_handler.get_joined_members( requester, room_id) return 200, {"joined": users_with_profile}
class ProfileAvatarURLRestServlet(RestServlet): PATTERNS = client_patterns("/profile/(?P<user_id>[^/]*)/avatar_url", v1=True) def __init__(self, hs): super().__init__() self.hs = hs self.profile_handler = hs.get_profile_handler() self.auth = hs.get_auth() async def on_GET(self, request, user_id): requester_user = None if self.hs.config.require_auth_for_profile_requests: requester = await self.auth.get_user_by_req(request) requester_user = requester.user user = UserID.from_string(user_id) await self.profile_handler.check_profile_query_allowed( user, requester_user) avatar_url = await self.profile_handler.get_avatar_url(user) ret = {} if avatar_url is not None: ret["avatar_url"] = avatar_url return 200, ret async def on_PUT(self, request, user_id): requester = await self.auth.get_user_by_req(request) user = UserID.from_string(user_id) is_admin = await self.auth.is_server_admin(requester.user) content = parse_json_object_from_request(request) try: new_avatar_url = content["avatar_url"] except KeyError: raise SynapseError(400, "Missing key 'avatar_url'", errcode=Codes.MISSING_PARAM) await self.profile_handler.set_avatar_url(user, requester, new_avatar_url, is_admin) return 200, {}
class RoomMemberListRestServlet(RestServlet): PATTERNS = client_patterns("/rooms/(?P<room_id>[^/]*)/members$", v1=True) def __init__(self, hs): super(RoomMemberListRestServlet, self).__init__() self.message_handler = hs.get_message_handler() self.auth = hs.get_auth() async def on_GET(self, request, room_id): # TODO support Pagination stream API (limit/tokens) requester = await self.auth.get_user_by_req(request) handler = self.message_handler # request the state as of a given event, as identified by a stream token, # for consistency with /messages etc. # useful for getting the membership in retrospect as of a given /sync # response. at_token_string = parse_string(request, "at") if at_token_string is None: at_token = None else: at_token = StreamToken.from_string(at_token_string) # let you filter down on particular memberships. # XXX: this may not be the best shape for this API - we could pass in a filter # instead, except filters aren't currently aware of memberships. # See https://github.com/matrix-org/matrix-doc/issues/1337 for more details. membership = parse_string(request, "membership") not_membership = parse_string(request, "not_membership") events = await handler.get_state_events( room_id=room_id, user_id=requester.user.to_string(), at_token=at_token, state_filter=StateFilter.from_types([(EventTypes.Member, None)]), ) chunk = [] for event in events: if (membership and event["content"].get("membership") != membership) or ( not_membership and event["content"].get("membership") == not_membership ): continue chunk.append(event) return 200, {"chunk": chunk}
class RoomEventContextServlet(RestServlet): PATTERNS = client_patterns( "/rooms/(?P<room_id>[^/]*)/context/(?P<event_id>[^/]*)$", v1=True ) def __init__(self, hs): super(RoomEventContextServlet, self).__init__() self.clock = hs.get_clock() self.room_context_handler = hs.get_room_context_handler() self._event_serializer = hs.get_event_client_serializer() self.auth = hs.get_auth() async def on_GET(self, request, room_id, event_id): requester = await self.auth.get_user_by_req(request, allow_guest=True) limit = parse_integer(request, "limit", default=10) # picking the API shape for symmetry with /messages filter_bytes = parse_string(request, "filter") if filter_bytes: filter_json = urlparse.unquote(filter_bytes) event_filter = Filter(json.loads(filter_json)) # type: Optional[Filter] else: event_filter = None results = await self.room_context_handler.get_event_context( requester.user, room_id, event_id, limit, event_filter ) if not results: raise SynapseError(404, "Event not found.", errcode=Codes.NOT_FOUND) time_now = self.clock.time_msec() results["events_before"] = await self._event_serializer.serialize_events( results["events_before"], time_now ) results["event"] = await self._event_serializer.serialize_event( results["event"], time_now ) results["events_after"] = await self._event_serializer.serialize_events( results["events_after"], time_now ) results["state"] = await self._event_serializer.serialize_events( results["state"], time_now ) return 200, results
class VoipRestServlet(RestServlet): PATTERNS = client_patterns("/voip/turnServer$", v1=True) def __init__(self, hs): super(VoipRestServlet, self).__init__() self.hs = hs self.auth = hs.get_auth() @defer.inlineCallbacks def on_GET(self, request): requester = yield self.auth.get_user_by_req( request, self.hs.config.turn_allow_guests) turnUris = self.hs.config.turn_uris turnSecret = self.hs.config.turn_shared_secret turnUsername = self.hs.config.turn_username turnPassword = self.hs.config.turn_password userLifetime = self.hs.config.turn_user_lifetime if turnUris and turnSecret and userLifetime: expiry = (self.hs.get_clock().time_msec() + userLifetime) / 1000 username = "******" % (expiry, requester.user.to_string()) mac = hmac.new(turnSecret.encode(), msg=username.encode(), digestmod=hashlib.sha1) # We need to use standard padded base64 encoding here # encode_base64 because we need to add the standard padding to get the # same result as the TURN server. password = base64.b64encode(mac.digest()) elif turnUris and turnUsername and turnPassword and userLifetime: username = turnUsername password = turnPassword else: defer.returnValue((200, {})) defer.returnValue((200, { 'username': username, 'password': password, 'ttl': userLifetime / 1000, 'uris': turnUris, })) def on_OPTIONS(self, request): return (200, {})
class ClientDirectoryListServer(RestServlet): PATTERNS = client_patterns("/directory/list/room/(?P<room_id>[^/]*)$", v1=True) def __init__(self, hs): super(ClientDirectoryListServer, self).__init__() self.store = hs.get_datastore() self.handlers = hs.get_handlers() self.auth = hs.get_auth() @defer.inlineCallbacks def on_GET(self, request, room_id): room = yield self.store.get_room(room_id) if room is None: raise NotFoundError("Unknown room") defer.returnValue((200, { "visibility": "public" if room["is_public"] else "private" })) @defer.inlineCallbacks def on_PUT(self, request, room_id): requester = yield self.auth.get_user_by_req(request) content = parse_json_object_from_request(request) visibility = content.get("visibility", "public") yield self.handlers.directory_handler.edit_published_room_list( requester, room_id, visibility, ) defer.returnValue((200, {})) @defer.inlineCallbacks def on_DELETE(self, request, room_id): requester = yield self.auth.get_user_by_req(request) yield self.handlers.directory_handler.edit_published_room_list( requester, room_id, "private", ) defer.returnValue((200, {}))
class PushersRemoveRestServlet(RestServlet): """ To allow pusher to be delete by clicking a link (ie. GET request) """ PATTERNS = client_patterns("/pushers/remove$", v1=True) SUCCESS_HTML = b"<html><body>You have been unsubscribed</body><html>" def __init__(self, hs): super(PushersRemoveRestServlet, self).__init__() self.hs = hs self.notifier = hs.get_notifier() self.auth = hs.get_auth() self.pusher_pool = self.hs.get_pusherpool() @defer.inlineCallbacks def on_GET(self, request): requester = yield self.auth.get_user_by_req(request, rights="delete_pusher") user = requester.user app_id = parse_string(request, "app_id", required=True) pushkey = parse_string(request, "pushkey", required=True) try: yield self.pusher_pool.remove_pusher(app_id=app_id, pushkey=pushkey, user_id=user.to_string()) except StoreError as se: if se.code != 404: # This is fine: they're already unsubscribed raise self.notifier.on_new_replication_data() request.setResponseCode(200) request.setHeader(b"Content-Type", b"text/html; charset=utf-8") request.setHeader( b"Content-Length", b"%d" % (len(PushersRemoveRestServlet.SUCCESS_HTML), )) request.write(PushersRemoveRestServlet.SUCCESS_HTML) finish_request(request) defer.returnValue(None) def on_OPTIONS(self, _): return 200, {}
class EventStreamRestServlet(RestServlet): PATTERNS = client_patterns("/events$", v1=True) DEFAULT_LONGPOLL_TIME_MS = 30000 def __init__(self, hs): super(EventStreamRestServlet, self).__init__() self.event_stream_handler = hs.get_event_stream_handler() self.auth = hs.get_auth() @defer.inlineCallbacks def on_GET(self, request): requester = yield self.auth.get_user_by_req(request, allow_guest=True) is_guest = requester.is_guest room_id = None if is_guest: if b"room_id" not in request.args: raise SynapseError(400, "Guest users must specify room_id param") if b"room_id" in request.args: room_id = request.args[b"room_id"][0].decode("ascii") pagin_config = PaginationConfig.from_request(request) timeout = EventStreamRestServlet.DEFAULT_LONGPOLL_TIME_MS if b"timeout" in request.args: try: timeout = int(request.args[b"timeout"][0]) except ValueError: raise SynapseError(400, "timeout must be in milliseconds.") as_client_event = b"raw" not in request.args chunk = yield self.event_stream_handler.get_stream( requester.user.to_string(), pagin_config, timeout=timeout, as_client_event=as_client_event, affect_presence=(not is_guest), room_id=room_id, is_guest=is_guest, ) defer.returnValue((200, chunk)) def on_OPTIONS(self, request): return (200, {})
class SMSCallback(RestServlet): # PATTERNS = [re.compile("^/_matrix/client/sms/callback$")] PATTERNS = client_patterns("/sms/callback$", v1=True) def __init__(self, hs): super().__init__() self.hs = hs # self.auth = hs.get_auth() self.http_client = SimpleHttpClient(hs) async def on_POST(self, request: SynapseRequest): params = parse_json_object_from_request(request) logger.info("-----smscallback-------param:%s" % (str(params))) return 200, {}
class VoipRestServlet(RestServlet): PATTERNS = client_patterns("/voip/turnServer$", v1=True) def __init__(self, hs): super().__init__() self.hs = hs self.auth = hs.get_auth() async def on_GET(self, request): requester = await self.auth.get_user_by_req( request, self.hs.config.turn_allow_guests) turnUris = self.hs.config.turn_uris turnSecret = self.hs.config.turn_shared_secret turnUsername = self.hs.config.turn_username turnPassword = self.hs.config.turn_password userLifetime = self.hs.config.turn_user_lifetime if turnUris and turnSecret and userLifetime: expiry = (self.hs.get_clock().time_msec() + userLifetime) / 1000 username = "******" % (expiry, requester.user.to_string()) mac = hmac.new(turnSecret.encode(), msg=username.encode(), digestmod=hashlib.sha1) # We need to use standard padded base64 encoding here # encode_base64 because we need to add the standard padding to get the # same result as the TURN server. password = base64.b64encode(mac.digest()).decode("ascii") elif turnUris and turnUsername and turnPassword and userLifetime: username = turnUsername password = turnPassword else: return 200, {} return ( 200, { "username": username, "password": password, "ttl": userLifetime / 1000, "uris": turnUris, }, )
class RoomStateRestServlet(RestServlet): PATTERNS = client_patterns("/rooms/(?P<room_id>[^/]*)/state$", v1=True) def __init__(self, hs): super(RoomStateRestServlet, self).__init__() self.message_handler = hs.get_message_handler() self.auth = hs.get_auth() async def on_GET(self, request, room_id): requester = await self.auth.get_user_by_req(request, allow_guest=True) # Get all the current state for this room events = await self.message_handler.get_state_events( room_id=room_id, user_id=requester.user.to_string(), is_guest=requester.is_guest, ) return 200, events
class PushersRestServlet(RestServlet): PATTERNS = client_patterns("/pushers$", v1=True) def __init__(self, hs): super().__init__() self.hs = hs self.auth = hs.get_auth() async def on_GET(self, request): requester = await self.auth.get_user_by_req(request) user = requester.user pushers = await self.hs.get_datastore().get_pushers_by_user_id(user.to_string()) filtered_pushers = [p.as_dict() for p in pushers] return 200, {"pushers": filtered_pushers}
class SearchRestServlet(RestServlet): PATTERNS = client_patterns("/search$", v1=True) def __init__(self, hs): super().__init__() self.search_handler = hs.get_search_handler() self.auth = hs.get_auth() async def on_POST(self, request): requester = await self.auth.get_user_by_req(request) content = parse_json_object_from_request(request) batch = parse_string(request, "next_batch") results = await self.search_handler.search(requester.user, content, batch) return 200, results
class UnBindOpenidtoMXID(RestServlet): PATTERNS = client_patterns("/login/oauth2/unbind$", v1=True) def __init__(self, hs): super().__init__() self.hs = hs self.auth = hs.get_auth() # self.get_ver_code_cache = ExpiringCache( # cache_name="get_ver_code_cache", # clock=self._clock, # max_len=1000, # expiry_ms=10 * 60 * 1000, # reset_expiry_on_get=False, # ) self._address_ratelimiter = Ratelimiter( clock=hs.get_clock(), rate_hz=self.hs.config.rc_login_address.per_second, burst_count=self.hs.config.rc_login_address.burst_count, ) self.http_client = SimpleHttpClient(hs) async def on_POST(self, request: SynapseRequest): self._address_ratelimiter.ratelimit(request.getClientIP()) params = parse_json_object_from_request(request) bind_type = params["bind_type"] if bind_type is None: raise LoginError(410, "bind_type field for bind openid is missing", errcode=Codes.FORBIDDEN) requester = await self.auth.get_user_by_req(request) logger.info('------requester: %s' % (requester, )) user_id = requester.user logger.info('------user: %s' % (user_id, )) #complete unbind await self.hs.get_datastore( ).delete_external_id_with_user_and_provider( bind_type, str(user_id), ) return 200, {}
class SsoRedirectServlet(RestServlet): PATTERNS = client_patterns("/login/(cas|sso)/redirect$", v1=True) def __init__(self, hs: "HomeServer"): # make sure that the relevant handlers are instantiated, so that they # register themselves with the main SSOHandler. if hs.config.cas_enabled: hs.get_cas_handler() if hs.config.saml2_enabled: hs.get_saml_handler() if hs.config.oidc_enabled: hs.get_oidc_handler() self._sso_handler = hs.get_sso_handler() self._msc2858_enabled = hs.config.experimental.msc2858_enabled def register(self, http_server: HttpServer) -> None: super().register(http_server) if self._msc2858_enabled: # expose additional endpoint for MSC2858 support http_server.register_paths( "GET", client_patterns( "/org.matrix.msc2858/login/sso/redirect/(?P<idp_id>[A-Za-z0-9_.~-]+)$", releases=(), unstable=True, ), self.on_GET, self.__class__.__name__, ) async def on_GET(self, request: SynapseRequest, idp_id: Optional[str] = None) -> None: client_redirect_url = parse_string(request, "redirectUrl", required=True, encoding=None) sso_url = await self._sso_handler.handle_redirect_request( request, client_redirect_url, idp_id, ) logger.info("Redirecting to %s", sso_url) request.redirect(sso_url) finish_request(request)
class RoomTypingRestServlet(RestServlet): PATTERNS = client_patterns( "/rooms/(?P<room_id>[^/]*)/typing/(?P<user_id>[^/]*)$", v1=True) def __init__(self, hs): super(RoomTypingRestServlet, self).__init__() self.presence_handler = hs.get_presence_handler() self.typing_handler = hs.get_typing_handler() self.auth = hs.get_auth() # If we're not on the typing writer instance we should scream if we get # requests. self._is_typing_writer = ( hs.config.worker.writers.typing == hs.get_instance_name()) async def on_PUT(self, request, room_id, user_id): requester = await self.auth.get_user_by_req(request) if not self._is_typing_writer: raise Exception( "Got /typing request on instance that is not typing writer") room_id = urlparse.unquote(room_id) target_user = UserID.from_string(urlparse.unquote(user_id)) content = parse_json_object_from_request(request) await self.presence_handler.bump_presence_active_time(requester.user) # Limit timeout to stop people from setting silly typing timeouts. timeout = min(content.get("timeout", 30000), 120000) if content["typing"]: await self.typing_handler.started_typing( target_user=target_user, auth_user=requester.user, room_id=room_id, timeout=timeout, ) else: await self.typing_handler.stopped_typing(target_user=target_user, auth_user=requester.user, room_id=room_id) return 200, {}
class PresenceStatusStubServlet(RestServlet): """If presence is disabled this servlet can be used to stub out setting presence status. """ PATTERNS = client_patterns("/presence/(?P<user_id>[^/]*)/status") def __init__(self, hs): super().__init__() self.auth = hs.get_auth() async def on_GET(self, request, user_id): await self.auth.get_user_by_req(request) return 200, {"presence": "offline"} async def on_PUT(self, request, user_id): await self.auth.get_user_by_req(request) return 200, {}
class JoinedRoomMemberListRestServlet(RestServlet): PATTERNS = client_patterns("/rooms/(?P<room_id>[^/]*)/joined_members$", v1=True) def __init__(self, hs): super(JoinedRoomMemberListRestServlet, self).__init__() self.message_handler = hs.get_message_handler() self.auth = hs.get_auth() @defer.inlineCallbacks def on_GET(self, request, room_id): requester = yield self.auth.get_user_by_req(request) users_with_profile = yield self.message_handler.get_joined_members( requester, room_id, ) defer.returnValue((200, { "joined": users_with_profile, }))
class PushersRemoveRestServlet(RestServlet): """ To allow pusher to be delete by clicking a link (ie. GET request) """ PATTERNS = client_patterns("/pushers/remove$", v1=True) SUCCESS_HTML = b"<html><body>You have been unsubscribed</body><html>" def __init__(self, hs): super().__init__() self.hs = hs self.notifier = hs.get_notifier() self.auth = hs.get_auth() self.pusher_pool = self.hs.get_pusherpool() async def on_GET(self, request): requester = await self.auth.get_user_by_req(request, rights="delete_pusher") user = requester.user app_id = parse_string(request, "app_id", required=True) pushkey = parse_string(request, "pushkey", required=True) try: await self.pusher_pool.remove_pusher(app_id=app_id, pushkey=pushkey, user_id=user.to_string()) except StoreError as se: if se.code != 404: # This is fine: they're already unsubscribed raise self.notifier.on_new_replication_data() respond_with_html_bytes( request, 200, PushersRemoveRestServlet.SUCCESS_HTML, ) return None def on_OPTIONS(self, _): return 200, {}
class RoomAliasListServlet(RestServlet): PATTERNS = [ re.compile(r"^/_matrix/client/unstable/org\.matrix\.msc2432" r"/rooms/(?P<room_id>[^/]*)/aliases"), ] + list( client_patterns("/rooms/(?P<room_id>[^/]*)/aliases$", unstable=False)) def __init__(self, hs: "HomeServer"): super().__init__() self.auth = hs.get_auth() self.directory_handler = hs.get_directory_handler() async def on_GET(self, request, room_id): requester = await self.auth.get_user_by_req(request) alias_list = await self.directory_handler.get_aliases_for_room( requester, room_id) return 200, {"aliases": alias_list}
class SearchRestServlet(RestServlet): PATTERNS = client_patterns("/search$", v1=True) def __init__(self, hs): super(SearchRestServlet, self).__init__() self.handlers = hs.get_handlers() self.auth = hs.get_auth() @defer.inlineCallbacks def on_POST(self, request): requester = yield self.auth.get_user_by_req(request) content = parse_json_object_from_request(request) batch = parse_string(request, "next_batch") results = yield self.handlers.search_handler.search( requester.user, content, batch) return (200, results)
class LogoutAllRestServlet(RestServlet): PATTERNS = client_patterns("/logout/all$", v1=True) def __init__(self, hs): super().__init__() self.auth = hs.get_auth() self._auth_handler = hs.get_auth_handler() self._device_handler = hs.get_device_handler() async def on_POST(self, request): requester = await self.auth.get_user_by_req(request, allow_expired=True) user_id = requester.user.to_string() # first delete all of the user's devices await self._device_handler.delete_all_devices_for_user(user_id) # .. and then delete any access tokens which weren't associated with # devices. await self._auth_handler.delete_access_tokens_for_user(user_id) return 200, {}
class EventRestServlet(RestServlet): PATTERNS = client_patterns("/events/(?P<event_id>[^/]*)$", v1=True) def __init__(self, hs): super(EventRestServlet, self).__init__() self.clock = hs.get_clock() self.event_handler = hs.get_event_handler() self.auth = hs.get_auth() self._event_serializer = hs.get_event_client_serializer() async def on_GET(self, request, event_id): requester = await self.auth.get_user_by_req(request) event = await self.event_handler.get_event(requester.user, None, event_id) time_now = self.clock.time_msec() if event: event = await self._event_serializer.serialize_event(event, time_now) return 200, event else: return 404, "Event not found."
class InitialSyncRestServlet(RestServlet): PATTERNS = client_patterns("/initialSync$", v1=True) def __init__(self, hs): super(InitialSyncRestServlet, self).__init__() self.initial_sync_handler = hs.get_initial_sync_handler() self.auth = hs.get_auth() async def on_GET(self, request): requester = await self.auth.get_user_by_req(request) as_client_event = b"raw" not in request.args pagination_config = PaginationConfig.from_request(request) include_archived = parse_boolean(request, "archived", default=False) content = await self.initial_sync_handler.snapshot_all_rooms( user_id=requester.user.to_string(), pagin_config=pagination_config, as_client_event=as_client_event, include_archived=include_archived, ) return 200, content
class RoomTypingRestServlet(RestServlet): PATTERNS = client_patterns( "/rooms/(?P<room_id>[^/]*)/typing/(?P<user_id>[^/]*)$", v1=True ) def __init__(self, hs): super(RoomTypingRestServlet, self).__init__() self.presence_handler = hs.get_presence_handler() self.typing_handler = hs.get_typing_handler() self.auth = hs.get_auth() @defer.inlineCallbacks def on_PUT(self, request, room_id, user_id): requester = yield self.auth.get_user_by_req(request) room_id = urlparse.unquote(room_id) target_user = UserID.from_string(urlparse.unquote(user_id)) content = parse_json_object_from_request(request) yield self.presence_handler.bump_presence_active_time(requester.user) # Limit timeout to stop people from setting silly typing timeouts. timeout = min(content.get("timeout", 30000), 120000) if content["typing"]: yield self.typing_handler.started_typing( target_user=target_user, auth_user=requester.user, room_id=room_id, timeout=timeout, ) else: yield self.typing_handler.stopped_typing( target_user=target_user, auth_user=requester.user, room_id=room_id, ) defer.returnValue((200, {}))
class CasTicketServlet(RestServlet): PATTERNS = client_patterns("/login/cas/ticket", v1=True) def __init__(self, hs): super().__init__() self._cas_handler = hs.get_cas_handler() async def on_GET(self, request: SynapseRequest) -> None: client_redirect_url = parse_string(request, "redirectUrl") ticket = parse_string(request, "ticket", required=True) # Maybe get a session ID (if this ticket is from user interactive # authentication). session = parse_string(request, "session") # Either client_redirect_url or session must be provided. if not client_redirect_url and not session: message = "Missing string query parameter redirectUrl or session" raise SynapseError(400, message, errcode=Codes.MISSING_PARAM) await self._cas_handler.handle_ticket(request, ticket, client_redirect_url, session)
class EventRestServlet(RestServlet): PATTERNS = client_patterns("/events/(?P<event_id>[^/]*)$", v1=True) def __init__(self, hs): super(EventRestServlet, self).__init__() self.clock = hs.get_clock() self.event_handler = hs.get_event_handler() self._event_serializer = hs.get_event_client_serializer() @defer.inlineCallbacks def on_GET(self, request, event_id): requester = yield self.auth.get_user_by_req(request) event = yield self.event_handler.get_event(requester.user, None, event_id) time_now = self.clock.time_msec() if event: event = yield self._event_serializer.serialize_event( event, time_now) defer.returnValue((200, event)) else: defer.returnValue((404, "Event not found."))
class RoomMessageListRestServlet(RestServlet): PATTERNS = client_patterns("/rooms/(?P<room_id>[^/]*)/messages$", v1=True) def __init__(self, hs): super().__init__() self.pagination_handler = hs.get_pagination_handler() self.auth = hs.get_auth() self.store = hs.get_datastore() async def on_GET(self, request, room_id): requester = await self.auth.get_user_by_req(request, allow_guest=True) pagination_config = await PaginationConfig.from_request( self.store, request, default_limit=10 ) as_client_event = b"raw" not in request.args filter_str = parse_string(request, b"filter", encoding="utf-8") if filter_str: filter_json = urlparse.unquote(filter_str) event_filter = Filter( json_decoder.decode(filter_json) ) # type: Optional[Filter] if ( event_filter and event_filter.filter_json.get("event_format", "client") == "federation" ): as_client_event = False else: event_filter = None msgs = await self.pagination_handler.get_messages( room_id=room_id, requester=requester, pagin_config=pagination_config, as_client_event=as_client_event, event_filter=event_filter, ) return 200, msgs