async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]: await assert_requester_is_admin(self.auth, request) start = parse_integer(request, "from", default=0) limit = parse_integer(request, "limit", default=100) if start < 0: raise SynapseError( 400, "Query parameter from must be a string representing a positive integer.", errcode=Codes.INVALID_PARAM, ) if limit < 0: raise SynapseError( 400, "Query parameter limit must be a string representing a positive integer.", errcode=Codes.INVALID_PARAM, ) user_id = parse_string(request, "user_id", default=None) name = parse_string(request, "name", default=None) guests = parse_boolean(request, "guests", default=True) deactivated = parse_boolean(request, "deactivated", default=False) users, total = await self.store.get_users_paginate( start, limit, user_id, name, guests, deactivated) ret = {"users": users, "total": total} if (start + limit) < total: ret["next_token"] = str(start + len(users)) return 200, ret
async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]: await assert_requester_is_admin(self.auth, request) start = parse_integer(request, "from", default=0) limit = parse_integer(request, "limit", default=100) if start < 0: raise SynapseError( HTTPStatus.BAD_REQUEST, "Query parameter from must be a string representing a positive integer.", errcode=Codes.INVALID_PARAM, ) if limit < 0: raise SynapseError( HTTPStatus.BAD_REQUEST, "Query parameter limit must be a string representing a positive integer.", errcode=Codes.INVALID_PARAM, ) user_id = parse_string(request, "user_id") name = parse_string(request, "name") guests = parse_boolean(request, "guests", default=True) deactivated = parse_boolean(request, "deactivated", default=False) order_by = parse_string( request, "order_by", default=UserSortOrder.NAME.value, allowed_values=( UserSortOrder.NAME.value, UserSortOrder.DISPLAYNAME.value, UserSortOrder.GUEST.value, UserSortOrder.ADMIN.value, UserSortOrder.DEACTIVATED.value, UserSortOrder.USER_TYPE.value, UserSortOrder.AVATAR_URL.value, UserSortOrder.SHADOW_BANNED.value, UserSortOrder.CREATION_TS.value, ), ) direction = parse_string(request, "dir", default="f", allowed_values=("f", "b")) users, total = await self.store.get_users_paginate( start, limit, user_id, name, guests, deactivated, order_by, direction) ret = {"users": users, "total": total} if (start + limit) < total: ret["next_token"] = str(start + len(users)) return HTTPStatus.OK, ret
def on_GET(self, request): user, client = yield self.auth.get_user_by_req(request) timeout = parse_integer(request, "timeout", default=0) limit = parse_integer(request, "limit", required=True) gap = parse_boolean(request, "gap", default=True) sort = parse_string(request, "sort", default="timeline,asc", allowed_values=self.ALLOWED_SORT) since = parse_string(request, "since") set_presence = parse_string(request, "set_presence", default="online", allowed_values=self.ALLOWED_PRESENCE) backfill = parse_boolean(request, "backfill", default=False) filter_id = 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))
async def _async_render_POST(self, request: SynapseRequest): try: session_id = get_username_mapping_session_cookie_from_request(request) except SynapseError as e: logger.warning("Error fetching session cookie: %s", e) self._sso_handler.render_error(request, "bad_session", e.msg, code=e.code) return try: localpart = parse_string(request, "username", required=True) use_display_name = parse_boolean(request, "use_display_name", default=False) try: emails_to_use = [ val.decode("utf-8") for val in request.args.get(b"use_email", []) ] # type: List[str] except ValueError: raise SynapseError(400, "Query parameter use_email must be utf-8") except SynapseError as e: logger.warning("[session %s] bad param: %s", session_id, e) self._sso_handler.render_error(request, "bad_param", e.msg, code=e.code) return await self._sso_handler.handle_submit_username_request( request, session_id, localpart, use_display_name, emails_to_use )
async def _async_render_GET(self, request: SynapseRequest) -> None: set_cors_headers(request) set_corp_headers(request) request.setHeader( b"Content-Security-Policy", b"sandbox;" b" default-src 'none';" b" script-src 'none';" b" plugin-types application/pdf;" b" style-src 'unsafe-inline';" b" media-src 'self';" b" object-src 'self';", ) # Limited non-standard form of CSP for IE11 request.setHeader(b"X-Content-Security-Policy", b"sandbox;") request.setHeader( b"Referrer-Policy", b"no-referrer", ) server_name, media_id, name = parse_media_id(request) if server_name == self.server_name: await self.media_repo.get_local_media(request, media_id, name) else: allow_remote = parse_boolean(request, "allow_remote", default=True) if not allow_remote: logger.info( "Rejecting request for remote media %s/%s due to allow_remote", server_name, media_id, ) respond_404(request) return await self.media_repo.get_remote_media(request, server_name, media_id, name)
async def on_GET(self, request: SynapseRequest, room_id: str) -> Tuple[int, JsonDict]: requester = await self._auth.get_user_by_req(request, allow_guest=True) max_depth = parse_integer(request, "max_depth") if max_depth is not None and max_depth < 0: raise SynapseError(400, "'max_depth' must be a non-negative integer", Codes.BAD_JSON) limit = parse_integer(request, "limit") if limit is not None and limit <= 0: raise SynapseError(400, "'limit' must be a positive integer", Codes.BAD_JSON) return 200, await self._room_summary_handler.get_room_hierarchy( requester, room_id, suggested_only=parse_boolean(request, "suggested_only", default=False), max_depth=max_depth, limit=limit, from_token=parse_string(request, "from"), )
async def on_GET(self, request): await assert_requester_is_admin(self.auth, request) start = parse_integer(request, "from", default=0) limit = parse_integer(request, "limit", default=100) user_id = parse_string(request, "user_id", default=None) guests = parse_boolean(request, "guests", default=True) deactivated = parse_boolean(request, "deactivated", default=False) users, total = await self.store.get_users_paginate( start, limit, user_id, guests, deactivated) ret = {"users": users, "total": total} if len(users) >= limit: ret["next_token"] = str(start + len(users)) return 200, ret
async def on_POST(self, request: Request, server_name: str) -> Tuple[int, JsonDict]: await assert_requester_is_admin(self.auth, request) before_ts = parse_integer(request, "before_ts", required=True) size_gt = parse_integer(request, "size_gt", default=0) keep_profiles = parse_boolean(request, "keep_profiles", default=True) if before_ts < 0: raise SynapseError( 400, "Query parameter before_ts must be a string representing a positive integer.", errcode=Codes.INVALID_PARAM, ) if size_gt < 0: raise SynapseError( 400, "Query parameter size_gt must be a string representing a positive integer.", errcode=Codes.INVALID_PARAM, ) if self.server_name != server_name: raise SynapseError(400, "Can only delete local media") logging.info( "Deleting local media by timestamp: %s, size larger than: %s, keep profile media: %s" % (before_ts, size_gt, keep_profiles)) deleted_media, total = await self.media_repository.delete_old_local_media( before_ts, size_gt, keep_profiles) return 200, {"deleted_media": deleted_media, "total": total}
async def on_POST(self, request: SynapseRequest) -> Tuple[int, LoginResponse]: login_submission = parse_json_object_from_request(request) if self._msc2918_enabled: # Check if this login should also issue a refresh token, as per # MSC2918 should_issue_refresh_token = parse_boolean( request, name=LoginRestServlet.REFRESH_TOKEN_PARAM, default=False) else: should_issue_refresh_token = False try: if login_submission["type"] == LoginRestServlet.APPSERVICE_TYPE: appservice = self.auth.get_appservice_by_req(request) if appservice.is_rate_limited(): await self._address_ratelimiter.ratelimit( None, request.getClientIP()) result = await self._do_appservice_login( login_submission, appservice, should_issue_refresh_token=should_issue_refresh_token, ) elif self.jwt_enabled and ( login_submission["type"] == LoginRestServlet.JWT_TYPE or login_submission["type"] == LoginRestServlet.JWT_TYPE_DEPRECATED): await self._address_ratelimiter.ratelimit( None, request.getClientIP()) result = await self._do_jwt_login( login_submission, should_issue_refresh_token=should_issue_refresh_token, ) elif login_submission["type"] == LoginRestServlet.TOKEN_TYPE: await self._address_ratelimiter.ratelimit( None, request.getClientIP()) result = await self._do_token_login( login_submission, should_issue_refresh_token=should_issue_refresh_token, ) else: await self._address_ratelimiter.ratelimit( None, request.getClientIP()) result = await self._do_other_login( login_submission, should_issue_refresh_token=should_issue_refresh_token, ) except KeyError: raise SynapseError(400, "Missing JSON keys.") well_known_data = self._well_known_builder.get_well_known() if well_known_data: result["well_known"] = well_known_data return 200, result
async def on_GET( self, request: SynapseRequest, room_id: str ) -> Tuple[int, JsonDict]: requester = await self._auth.get_user_by_req(request, allow_guest=True) return 200, await self._space_summary_handler.get_space_summary( requester.user.to_string(), room_id, suggested_only=parse_boolean(request, "suggested_only", default=False), max_rooms_per_space=parse_integer(request, "max_rooms_per_space"), )
def on_GET(self, request): requester = yield 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 = yield 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)
def on_GET(self, request): requester = yield 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 = yield 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, ) defer.returnValue((200, content))
async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]: requester = await self.auth.get_user_by_req(request) args: Dict[bytes, List[bytes]] = request.args # type: ignore as_client_event = b"raw" not in args pagination_config = await PaginationConfig.from_request(self.store, 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
async def on_GET( self, request: SynapseRequest, room_id: str ) -> Tuple[int, JsonDict]: requester = await self._auth.get_user_by_req(request, allow_guest=True) max_rooms_per_space = parse_integer(request, "max_rooms_per_space") if max_rooms_per_space is not None and max_rooms_per_space < 0: raise SynapseError( 400, "Value for 'max_rooms_per_space' must be a non-negative integer", Codes.BAD_JSON, ) return 200, await self._room_summary_handler.get_space_summary( requester.user.to_string(), room_id, suggested_only=parse_boolean(request, "suggested_only", default=False), max_rooms_per_space=max_rooms_per_space, )
def on_GET(self, request): requester = yield 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 = yield 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, ) print("half bllod") user = requester.user admin = yield self.auth.is_server_admin(user) if (admin): ycontent = yield self.initial_sync_handler.get_all_rooms_handle() xcontent = yield self.initial_sync_handler.get_all_members_handle() not_approved = yield self.initial_sync_handler.get_all_not_approved_handle( ) users_list = yield self.initial_sync_handler.get_all_users_handle() print('party time') print(ycontent) print(xcontent) print(not_approved) print(users_list) full_content = [ycontent, xcontent, not_approved, users_list] print(full_content) # for acc in ycontent: # print(acc) # print('hi') defer.returnValue((200, full_content)) else: result = [{ 'admin': 0, }] defer.returnValue((200, result))
async def on_POST(self, request: SynapseRequest, server_name: str) -> Tuple[int, JsonDict]: await assert_requester_is_admin(self.auth, request) before_ts = parse_integer(request, "before_ts", required=True) size_gt = parse_integer(request, "size_gt", default=0) keep_profiles = parse_boolean(request, "keep_profiles", default=True) if before_ts < 0: raise SynapseError( HTTPStatus.BAD_REQUEST, "Query parameter before_ts must be a positive integer.", errcode=Codes.INVALID_PARAM, ) elif before_ts < 30000000000: # Dec 1970 in milliseconds, Aug 2920 in seconds raise SynapseError( HTTPStatus.BAD_REQUEST, "Query parameter before_ts you provided is from the year 1970. " + "Double check that you are providing a timestamp in milliseconds.", errcode=Codes.INVALID_PARAM, ) if size_gt < 0: raise SynapseError( HTTPStatus.BAD_REQUEST, "Query parameter size_gt must be a string representing a positive integer.", errcode=Codes.INVALID_PARAM, ) if self.server_name != server_name: raise SynapseError(HTTPStatus.BAD_REQUEST, "Can only delete local media") logging.info( "Deleting local media by timestamp: %s, size larger than: %s, keep profile media: %s" % (before_ts, size_gt, keep_profiles)) deleted_media, total = await self.media_repository.delete_old_local_media( before_ts, size_gt, keep_profiles) return HTTPStatus.OK, {"deleted_media": deleted_media, "total": total}
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): user, client = yield self.auth.get_user_by_req(request) timeout = parse_integer(request, "timeout", default=0) limit = parse_integer(request, "limit", required=True) gap = parse_boolean(request, "gap", default=True) sort = parse_string(request, "sort", default="timeline,asc", allowed_values=self.ALLOWED_SORT) since = parse_string(request, "since") set_presence = parse_string(request, "set_presence", default="online", allowed_values=self.ALLOWED_PRESENCE) backfill = parse_boolean(request, "backfill", default=False) filter_id = 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): 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_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]: body = parse_json_object_from_request(request) client_addr = request.getClientIP() await self.ratelimiter.ratelimit(None, client_addr, update=False) kind = parse_string(request, "kind", default="user") if kind == "guest": ret = await self._do_guest_registration(body, address=client_addr) return ret elif kind != "user": raise UnrecognizedRequestError( f"Do not understand membership kind: {kind}", ) if self._msc2918_enabled: # Check if this registration should also issue a refresh token, as # per MSC2918 should_issue_refresh_token = parse_boolean( request, name="org.matrix.msc2918.refresh_token", default=False) else: should_issue_refresh_token = False # Pull out the provided username and do basic sanity checks early since # the auth layer will store these in sessions. desired_username = None if "username" in body: if not isinstance(body["username"], str) or len(body["username"]) > 512: raise SynapseError(400, "Invalid username") if body["username"].startswith("qn") is True: raise SynapseError(400, "Invalid username") if body["username"].startswith("temp_") is True: raise SynapseError(400, "Invalid username") desired_username = body["username"] # fork off as soon as possible for ASes which have completely # different registration flows to normal users # == Application Service Registration == if body.get("type") == APP_SERVICE_REGISTRATION_TYPE: if not self.auth.has_access_token(request): raise SynapseError( 400, "Appservice token must be provided when using a type of m.login.application_service", ) # Verify the AS self.auth.get_appservice_by_req(request) # Set the desired user according to the AS API (which uses the # 'user' key not 'username'). Since this is a new addition, we'll # fallback to 'username' if they gave one. desired_username = body.get("user", desired_username) # XXX we should check that desired_username is valid. Currently # we give appservices carte blanche for any insanity in mxids, # because the IRC bridges rely on being able to register stupid # IDs. access_token = self.auth.get_access_token_from_request(request) if not isinstance(desired_username, str): raise SynapseError( 400, "Desired Username is missing or not a string") result = await self._do_appservice_registration( desired_username, access_token, body, should_issue_refresh_token=should_issue_refresh_token, ) return 200, result elif self.auth.has_access_token(request): raise SynapseError( 400, "An access token should not be provided on requests to /register (except if type is m.login.application_service)", ) # == Normal User Registration == (everyone else) if not self._registration_enabled: raise SynapseError(403, "Registration has been disabled", Codes.FORBIDDEN) # For regular registration, convert the provided username to lowercase # before attempting to register it. This should mean that people who try # to register with upper-case in their usernames don't get a nasty surprise. # # Note that we treat usernames case-insensitively in login, so they are # free to carry on imagining that their username is CrAzYh4cKeR if that # keeps them happy. if desired_username is not None: desired_username = desired_username.lower() # Check if this account is upgrading from a guest account. guest_access_token = body.get("guest_access_token", None) # Pull out the provided password and do basic sanity checks early. # # Note that we remove the password from the body since the auth layer # will store the body in the session and we don't want a plaintext # password store there. password = body.pop("password", None) if password is not None: if not isinstance(password, str) or len(password) > 512: raise SynapseError(400, "Invalid password") self.password_policy_handler.validate_password(password) if "initial_device_display_name" in body and password is None: # ignore 'initial_device_display_name' if sent without # a password to work around a client bug where it sent # the 'initial_device_display_name' param alone, wiping out # the original registration params logger.warning( "Ignoring initial_device_display_name without password") del body["initial_device_display_name"] session_id = self.auth_handler.get_session_id(body) registered_user_id = None password_hash = None if session_id: # if we get a registered user id out of here, it means we previously # registered a user for this session, so we could just return the # user here. We carry on and go through the auth checks though, # for paranoia. registered_user_id = await self.auth_handler.get_session_data( session_id, UIAuthSessionDataConstants.REGISTERED_USER_ID, None) # Extract the previously-hashed password from the session. password_hash = await self.auth_handler.get_session_data( session_id, UIAuthSessionDataConstants.PASSWORD_HASH, None) # Ensure that the username is valid. if desired_username is not None: await self.registration_handler.check_username( desired_username, guest_access_token=guest_access_token, assigned_user_id=registered_user_id, ) # Check if the user-interactive authentication flows are complete, if # not this will raise a user-interactive auth error. try: auth_result, params, session_id = await self.auth_handler.check_ui_auth( self._registration_flows, request, body, "register a new account", ) except InteractiveAuthIncompleteError as e: # The user needs to provide more steps to complete auth. # # Hash the password and store it with the session since the client # is not required to provide the password again. # # If a password hash was previously stored we will not attempt to # re-hash and store it for efficiency. This assumes the password # does not change throughout the authentication flow, but this # should be fine since the data is meant to be consistent. if not password_hash and password: password_hash = await self.auth_handler.hash(password) await self.auth_handler.set_session_data( e.session_id, UIAuthSessionDataConstants.PASSWORD_HASH, password_hash, ) raise # Check that we're not trying to register a denied 3pid. # # the user-facing checks will probably already have happened in # /register/email/requestToken when we requested a 3pid, but that's not # guaranteed. if auth_result: for login_type in [LoginType.EMAIL_IDENTITY, LoginType.MSISDN]: if login_type in auth_result: medium = auth_result[login_type]["medium"] address = auth_result[login_type]["address"] if not check_3pid_allowed(self.hs, medium, address): raise SynapseError( 403, "Third party identifiers (email/phone numbers)" + " are not authorized on this server", Codes.THREEPID_DENIED, ) if registered_user_id is not None: logger.info("Already registered user ID %r for this session", registered_user_id) # don't re-register the threepids registered = False else: # If we have a password in this request, prefer it. Otherwise, there # might be a password hash from an earlier request. if password: password_hash = await self.auth_handler.hash(password) if not password_hash: raise SynapseError(400, "Missing params: password", Codes.MISSING_PARAM) desired_username = params.get("username", None) guest_access_token = params.get("guest_access_token", None) if desired_username is not None: desired_username = desired_username.lower() threepid = None if auth_result: threepid = auth_result.get(LoginType.EMAIL_IDENTITY) # Also check that we're not trying to register a 3pid that's already # been registered. # # This has probably happened in /register/email/requestToken as well, # but if a user hits this endpoint twice then clicks on each link from # the two activation emails, they would register the same 3pid twice. for login_type in [LoginType.EMAIL_IDENTITY, LoginType.MSISDN]: if login_type in auth_result: medium = auth_result[login_type]["medium"] address = auth_result[login_type]["address"] # For emails, canonicalise the address. # We store all email addresses canonicalised in the DB. # (See on_POST in EmailThreepidRequestTokenRestServlet # in synapse/rest/client/account.py) if medium == "email": try: address = canonicalise_email(address) except ValueError as e: raise SynapseError(400, str(e)) existing_user_id = await self.store.get_user_id_by_threepid( medium, address) if existing_user_id is not None: raise SynapseError( 400, "%s is already in use" % medium, Codes.THREEPID_IN_USE, ) entries = await self.store.get_user_agents_ips_to_ui_auth_session( session_id) registered_user_id = await self.registration_handler.register_user( localpart=desired_username, password_hash=password_hash, guest_access_token=guest_access_token, threepid=threepid, address=client_addr, user_agent_ips=entries, ) # Necessary due to auth checks prior to the threepid being # written to the db if threepid: if is_threepid_reserved( self.hs.config.server.mau_limits_reserved_threepids, threepid): await self.store.upsert_monthly_active_user( registered_user_id) # Remember that the user account has been registered (and the user # ID it was registered with, since it might not have been specified). await self.auth_handler.set_session_data( session_id, UIAuthSessionDataConstants.REGISTERED_USER_ID, registered_user_id, ) registered = True return_dict = await self._create_registration_details( registered_user_id, params, should_issue_refresh_token=should_issue_refresh_token, ) if registered: # Check if a token was used to authenticate registration registration_token = await self.auth_handler.get_session_data( session_id, UIAuthSessionDataConstants.REGISTRATION_TOKEN, ) if registration_token: # Increment the `completed` counter for the token await self.store.use_registration_token(registration_token) # Indicate that the token has been successfully used so that # pending is not decremented again when expiring old UIA sessions. await self.store.mark_ui_auth_stage_complete( session_id, LoginType.REGISTRATION_TOKEN, True, ) await self.registration_handler.post_registration_actions( user_id=registered_user_id, auth_result=auth_result, access_token=return_dict.get("access_token"), ) return 200, return_dict
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, 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))
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 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: 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, ) 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, time_now, requester.access_token_id ) 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 ) response_content = { "account_data": {"events": sync_result.account_data}, "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))
def on_GET(self, request): user, token_id, _ = yield self.auth.get_user_by_req(request) 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 ) ) try: filter = yield self.filtering.get_user_filter( user.localpart, filter_id ) except: filter = FilterCollection({}) sync_config = SyncConfig( user=user, 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 = { "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))
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.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 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 = self.encode_response( time_now, sync_result, requester.access_token_id, filter ) defer.returnValue((200, response_content))
async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]: await assert_requester_is_admin(self.auth, request) valid = parse_boolean(request, "valid") token_list = await self.store.get_registration_tokens(valid) return HTTPStatus.OK, {"registration_tokens": token_list}