plugin XEP-0060: better filtering when looking for default pubsub service

This commit is contained in:
Goffi 2022-05-13 18:22:06 +02:00
commit 24a1355686

View file

@ -65,6 +65,12 @@ Extra = namedtuple("Extra", ("rsm_request", "extra"))
# 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 @@ class XEP_0060(object):
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 @@ class XEP_0060(object):
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: