# HG changeset patch # User Goffi # Date 1528105939 -7200 # Node ID 7ec1ba86d38d8bcb440d58ae1a7b70f294900bba # Parent 2066d4fd90361215f9350d6defa70ae75876a547 server: replaced blocking calls to bridge by bridgeCall which is not blocking diff -r 2066d4fd9036 -r 7ec1ba86d38d src/server/server.py --- a/src/server/server.py Sun Jun 03 14:04:05 2018 +0200 +++ b/src/server/server.py Mon Jun 04 11:52:19 2018 +0200 @@ -398,13 +398,14 @@ return jsonrpc.JSONRPC._cbRender(self, fault, request, parsed.get('id'), parsed.get('jsonrpc')) # pylint: disable=E1103 return jsonrpc.JSONRPC.render(self, request) + @defer.inlineCallbacks def jsonrpc_getVersion(self): """Return SàT version""" try: - return self._version_cache + defer.returnValue(self._version_cache) except AttributeError: - self._version_cache = self.sat_host.bridge.getVersion() - return self._version_cache + self._version_cache = yield self.sat_host.bridgeCall("getVersion") + defer.returnValue(self._version_cache) def jsonrpc_getLiberviaVersion(self): """Return Libervia version""" @@ -414,39 +415,40 @@ """Disconnect the profile""" sat_session = session_iface.ISATSession(self.session) profile = sat_session.profile - self.sat_host.bridge.disconnect(profile) + self.sat_host.bridgeCall("disconnect", profile) def jsonrpc_getContacts(self): """Return all passed args.""" profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.getContacts(profile) + return self.sat_host.bridgeCall("getContacts", profile) + @defer.inlineCallbacks def jsonrpc_addContact(self, entity, name, groups): """Subscribe to contact presence, and add it to the given groups""" profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.addContact(entity, profile) - self.sat_host.bridge.updateContact(entity, name, groups, profile) + yield self.sat_host.bridgeCall("addContact", entity, profile) + yield self.sat_host.bridgeCall("updateContact", entity, name, groups, profile) def jsonrpc_delContact(self, entity): """Remove contact from contacts list""" profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.delContact(entity, profile) + return self.sat_host.bridgeCall("delContact", entity, profile) def jsonrpc_updateContact(self, entity, name, groups): """Update contact's roster item""" profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.updateContact(entity, name, groups, profile) + return self.sat_host.bridgeCall("updateContact", entity, name, groups, profile) def jsonrpc_subscription(self, sub_type, entity): """Confirm (or infirm) subscription, and setup user roster in case of subscription""" profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.subscription(sub_type, entity, profile) + return self.sat_host.bridgeCall("subscription", sub_type, entity, profile) def jsonrpc_getWaitingSub(self): """Return list of room already joined by user""" profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.getWaitingSub(profile) + return self.sat_host.bridgeCall("getWaitingSub", profile) def jsonrpc_setStatus(self, presence, status): """Change the presence and/or status @@ -454,7 +456,7 @@ @param status: any string to describe your status """ profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.setPresence('', presence, {'': status}, profile) + return self.sat_host.bridgeCall("setPresence", '', presence, {'': status}, profile) def jsonrpc_messageSend(self, to_jid, msg, subject, type_, extra={}): """send message""" @@ -540,7 +542,7 @@ @return (str): RT Deferred session id """ profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.mbGetFromMany(publishers_type, publishers, max_items, extra, profile) + return self.sat_host.bridgeCall("mbGetFromMany", publishers_type, publishers, max_items, extra, profile) def jsonrpc_mbGetFromManyRTResult(self, rt_session): """Get results from RealTime mbGetFromMany session @@ -563,7 +565,7 @@ @return (str): RT Deferred session id """ profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.mbGetFromManyWithComments(publishers_type, publishers, max_items, max_comments, rsm_dict, rsm_comments_dict, profile) + return self.sat_host.bridgeCall("mbGetFromManyWithComments", publishers_type, publishers, max_items, max_comments, rsm_dict, rsm_comments_dict, profile) def jsonrpc_mbGetFromManyWithCommentsRTResult(self, rt_session): """Get results from RealTime mbGetFromManyWithComments session @@ -680,7 +682,7 @@ def jsonrpc_getPresenceStatuses(self): """Get Presence information for connected contacts""" profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.getPresenceStatuses(profile) + return self.sat_host.bridgeCall("getPresenceStatuses", profile) def jsonrpc_historyGet(self, from_jid, to_jid, size, between, search=''): """Return history for the from_jid/to_jid couple""" @@ -688,8 +690,7 @@ profile = sat_session.profile sat_jid = sat_session.jid if not sat_jid: - # we keep a session cache for jid to avoir jid spoofing - sat_jid = sat_session.jid = jid.JID(self.sat_host.bridge.getParamA("JabberID", "Connection", profile_key=profile)) + raise exceptions.InternalError('session jid should be set') if jid.JID(from_jid).userhost() != sat_jid.userhost() and jid.JID(to_jid).userhost() != sat_jid.userhost(): log.error(u"Trying to get history from a different jid (given (browser): {}, real (backend): {}), maybe a hack attempt ?".format(from_jid, sat_jid)) return {} @@ -725,7 +726,7 @@ profile = session_iface.ISATSession(self.session).profile room_id = room_jid.split("@")[0] service = room_jid.split("@")[1] - self.sat_host.bridge.inviteMUC(contact_jid, service, room_id, {}, profile) + return self.sat_host.bridgeCall("inviteMUC", contact_jid, service, room_id, {}, profile) def jsonrpc_mucLeave(self, room_jid): """Quit a Multi-User Chat room""" @@ -735,12 +736,12 @@ except: log.warning('Invalid room jid') return - self.sat_host.bridge.mucLeave(room_jid.userhost(), profile) + return self.sat_host.bridgeCall("mucLeave", room_jid.userhost(), profile) def jsonrpc_mucGetRoomsJoined(self): """Return list of room already joined by user""" profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.mucGetRoomsJoined(profile) + return self.sat_host.bridgeCall("mucGetRoomsJoined", profile) def jsonrpc_mucGetDefaultService(self): """@return: the default MUC""" @@ -754,7 +755,7 @@ @param room_jid (unicode): room JID or empty string to generate a unique name """ profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.tarotGameLaunch(other_players, room_jid, profile) + return self.sat_host.bridgeCall("tarotGameLaunch", other_players, room_jid, profile) def jsonrpc_getTarotCardsPaths(self): """Give the path of all the tarot cards""" @@ -765,12 +766,12 @@ def jsonrpc_tarotGameReady(self, player, referee): """Tell to the server that we are ready to start the game""" profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.tarotGameReady(player, referee, profile) + return self.sat_host.bridgeCall("tarotGameReady", player, referee, profile) def jsonrpc_tarotGamePlayCards(self, player_nick, referee, cards): """Tell to the server the cards we want to put on the table""" profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.tarotGamePlayCards(player_nick, referee, cards, profile) + return self.sat_host.bridgeCall("tarotGamePlayCards", player_nick, referee, cards, profile) def jsonrpc_launchRadioCollective(self, invited, room_jid=""): """Create a room, invite people, and start a radio collective. @@ -779,7 +780,7 @@ @param room_jid (unicode): room JID or empty string to generate a unique name """ profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.radiocolLaunch(invited, room_jid, profile) + return self.sat_host.bridgeCall("radiocolLaunch", invited, room_jid, profile) def jsonrpc_getEntitiesData(self, jids, keys): """Get cached data for several entities at once @@ -791,7 +792,7 @@ raise exceptions.PermissionError("Trying to access unallowed data (hack attempt ?)") profile = session_iface.ISATSession(self.session).profile try: - return self.sat_host.bridge.getEntitiesData(jids, keys, profile) + return self.sat_host.bridgeCall("getEntitiesData", jids, keys, profile) except Exception as e: raise failure.Failure(jsonrpclib.Fault(C.ERRNUM_BRIDGE_ERRBACK, unicode(e))) @@ -805,7 +806,7 @@ raise exceptions.PermissionError("Trying to access unallowed data (hack attempt ?)") profile = session_iface.ISATSession(self.session).profile try: - return self.sat_host.bridge.getEntityData(jid, keys, profile) + return self.sat_host.bridgeCall("getEntityData", jid, keys, profile) except Exception as e: raise failure.Failure(jsonrpclib.Fault(C.ERRNUM_BRIDGE_ERRBACK, unicode(e))) @@ -814,7 +815,7 @@ @param jid_: jid of contact from who we want data @return: id to retrieve the profile""" profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.getCard(jid_, profile) + return self.sat_host.bridgeCall("getCard", jid_, profile) @defer.inlineCallbacks def jsonrpc_avatarGet(self, entity, cache_only, hash_only): @@ -833,7 +834,7 @@ """Get the dialog for managing user account @return: XML string of the XMLUI""" profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.getAccountDialogUI(profile) + return self.sat_host.bridgeCall("getAccountDialogUI", profile) def jsonrpc_getParamsUI(self): """Return the parameters XML for profile""" @@ -854,7 +855,7 @@ def jsonrpc_setParam(self, name, value, category): profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.setParam(name, value, category, C.SECURITY_LIMIT, profile) + return self.sat_host.bridgeCall("setParam", name, value, category, C.SECURITY_LIMIT, profile) def jsonrpc_launchAction(self, callback_id, data): #FIXME: any action can be launched, this can be a huge security issue if callback_id can be guessed @@ -868,7 +869,7 @@ @param to_jid_s: contact the user is composing to """ profile = session_iface.ISATSession(self.session).profile - self.sat_host.bridge.chatStateComposing(to_jid_s, profile) + return self.sat_host.bridgeCall("chatStateComposing", to_jid_s, profile) def jsonrpc_getNewAccountDomain(self): """@return: the domain for new account creation""" @@ -883,22 +884,22 @@ @param safe: clean resulting XHTML to avoid malicious code if True (forced here) @return: converted text """ profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.syntaxConvert(text, syntax_from, syntax_to, True, profile) + return self.sat_host.bridgeCall("syntaxConvert", text, syntax_from, syntax_to, True, profile) def jsonrpc_getLastResource(self, jid_s): """Get the last active resource of that contact.""" profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.getLastResource(jid_s, profile) + return self.sat_host.bridgeCall("getLastResource", jid_s, profile) def jsonrpc_getFeatures(self): """Return the available features in the backend for profile""" profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.getFeatures(profile) + return self.sat_host.bridgeCall("getFeatures", profile) def jsonrpc_skipOTR(self): """Tell the backend to leave OTR handling to Libervia.""" profile = session_iface.ISATSession(self.session).profile - return self.sat_host.bridge.skipOTR(profile) + return self.sat_host.bridgeCall("skipOTR", profile) def jsonrpc_namespacesGet(self): return self.sat_host.bridgeCall('namespacesGet') @@ -1077,7 +1078,7 @@ def jsonrpc_isConnected(self): _session = self.request.getSession() profile = session_iface.ISATSession(_session).profile - return self.sat_host.bridge.isConnected(profile) + return self.sat_host.bridgeCall("isConnected", profile) def jsonrpc_connect(self): _session = self.request.getSession() @@ -1085,7 +1086,7 @@ if self.waiting_profiles.getRequest(profile): raise jsonrpclib.Fault(1, C.ALREADY_WAITING) # FIXME: define some standard error codes for libervia self.waiting_profiles.setRequest(self.request, profile) - self.sat_host.bridge.connect(profile) + self.sat_host.bridgeCall("connect", profile) return server.NOT_DONE_YET def jsonrpc_getSessionMetadata(self): @@ -1120,7 +1121,7 @@ def jsonrpc_menusGet(self): """Return the parameters XML for profile""" # XXX: we put this method in Register because we get menus before being logged - return self.sat_host.bridge.menusGet('', C.SECURITY_LIMIT) + return self.sat_host.bridgeCall("menusGet", '', C.SECURITY_LIMIT) def _getSecurityWarning(self): """@return: a security warning message, or None if the connection is secure""" @@ -1254,11 +1255,12 @@ log.error(_(u'Service profile disconnected twice in a short time, please check connection')) else: log.info(_(u"Service profile has been disconnected, but we need it! Reconnecting it...")) - self.sat_host.bridge.connect(profile, + d = self.sat_host.bridgeCall("connect", profile, self.sat_host.options['passphrase'], {}, - errback=lambda failure_: log.error(_(u"Can't reconnect service profile, please check connection: {reason}").format(reason=failure_)) ) + d.addErrback(lambda failure_: log.error(_(u"Can't reconnect service profile, please check connection: {reason}").format( + reason=failure_))) self._last_service_prof_disconnect = time.time() return @@ -2094,12 +2096,13 @@ else: reactor.listenTCP(self.options['port'], self.site) + @defer.inlineCallbacks def stopService(self): log.info(_("launching cleaning methods")) for callback, args, kwargs in self._cleanup: callback(*args, **kwargs) try: - self.bridge.disconnect(C.SERVICE_PROFILE) + yield self.bridgeCall("disconnect", C.SERVICE_PROFILE) except Exception: log.warning(u"Can't disconnect service profile")