# HG changeset patch # User Goffi # Date 1652458926 -7200 # Node ID aa923e6b369fb33746fbccaf0858c28e8adb528c # Parent e14847bf65c0120c0fed8834f3e27eabb2306221 plugin XEP-0060: better filtering when looking for default pubsub service diff -r e14847bf65c0 -r aa923e6b369f sat/plugins/plugin_xep_0060.py --- a/sat/plugins/plugin_xep_0060.py Fri May 13 18:19:56 2022 +0200 +++ b/sat/plugins/plugin_xep_0060.py Fri May 13 18:22:06 2022 +0200 @@ -65,6 +65,12 @@ # rsm_request is the rsm.RSMRequest build with rsm_ prefixed keys, or None # extra is a potentially empty dict TIMEOUT = 30 +# minimum features that a pubsub service must have to be selectable as default +DEFAULT_PUBSUB_MIN_FEAT = { + 'http://jabber.org/protocol/pubsub#persistent-items', + 'http://jabber.org/protocol/pubsub#publish', + 'http://jabber.org/protocol/pubsub#retract-items', +} class XEP_0060(object): OPT_ACCESS_MODEL = "pubsub#access_model" @@ -315,8 +321,7 @@ client.pubsub_client = SatPubSubClient(self.host, self) return client.pubsub_client - @defer.inlineCallbacks - def profileConnected(self, client): + async def profileConnected(self, client): client.pubsub_watching = set() try: client.pubsub_service = jid.JID( @@ -325,12 +330,39 @@ except RuntimeError: log.info( _( - "Can't retrieve pubsub_service from conf, we'll use first one that we find" + "Can't retrieve pubsub_service from conf, we'll use first one that " + "we find" ) ) - client.pubsub_service = yield self.host.findServiceEntity( + pubsub_services = await self.host.findServiceEntities( client, "pubsub", "service" ) + for service_jid in pubsub_services: + infos = await self.host.memory.disco.getInfos(client, service_jid) + if not DEFAULT_PUBSUB_MIN_FEAT.issubset(infos.features): + continue + names = {(n or "").lower() for n in infos.identities.values()} + if "libervia pubsub service" in names: + # this is the name of Libervia's side project pubsub service, we know + # that it is a suitable default pubsub service + client.pubsub_service = service_jid + break + categories = {(i[0] or "").lower() for i in infos.identities.keys()} + if "gateway" in categories or "gateway" in names: + # we don't want to use a gateway as default pubsub service + continue + if "jabber:iq:register" in infos.features: + # may be present on gateways, and we don't want a service + # where registration is needed + continue + client.pubsub_service = service_jid + break + else: + client.pubsub_service = None + pubsub_service_str = ( + client.pubsub_service.full() if client.pubsub_service else "PEP" + ) + log.info(f"default pubsub service: {pubsub_service_str}") def getFeatures(self, profile): try: