Implement fallback on precondition-not-met error when publishing devicelist and bundle

Signed-off-by: Maxime Buquet's avatarMaxime “pep” Buquet <pep@bouah.net>
parent 9e2dcc55
......@@ -54,6 +54,7 @@ except (ImportError,):
TRUE_VALUES = {True, 'true', '1'}
PUBLISH_OPTIONS_NODE = 'http://jabber.org/protocol/pubsub#publish-options'
PUBSUB_ERRORS = 'http://jabber.org/protocol/pubsub#errors'
def b64enc(data: bytes) -> str:
......@@ -245,6 +246,38 @@ class XEP_0384(BasePlugin):
def my_device_id(self) -> int:
return self._device_id
def _set_node_config(
self,
node: str,
persist_items: bool = True,
access_model: Optional[str] = None,
) -> asyncio.Future:
form = Form()
form['type'] = 'submit'
form.add_field(
var='FORM_TYPE',
ftype='hidden',
value='http://jabber.org/protocol/pubsub#node_config',
)
if persist_items:
form.add_field(
var='pubsub#persist_items',
ftype='boolean',
value=True,
)
if access_model is not None:
form.add_field(
var='FORM_TYPE',
ftype='text-single',
value=access_model,
)
return self.xmpp['xep_0060'].set_node_config(
self.xmpp.boundjid.bare,
node,
form,
)
async def _generate_bundle_iq(self) -> Iq:
bundle = self._omemo.public_bundle.serialize(self.omemo_backend)
......@@ -286,7 +319,19 @@ class XEP_0384(BasePlugin):
async def _publish_bundle(self) -> None:
if self._omemo.republish_bundle:
iq = await self._generate_bundle_iq()
await iq.send()
try:
await iq.send()
except IqError as e:
# TODO: Slixmpp should handle pubsub#errors so we don't have to
# fish the element ourselves
precondition = e.iq['error'].xml.find(
'{%s}%s' % (PUBSUB_ERRORS, 'precondition-not-met'),
)
if precondition is not None:
log.debug('The node we tried to publish was already '
'existing with a different configuration. '
'Trying to configure manually..')
await self._set_node_config(OMEMO_BUNDLES_NS)
async def _fetch_bundle(self, jid: str, device_id: int) -> Optional[ExtendedPublicBundle]:
node = '%s:%d' % (OMEMO_BUNDLES_NS, device_id)
......@@ -374,9 +419,21 @@ class XEP_0384(BasePlugin):
'pubsub#access_model': 'open',
})
await self.xmpp['xep_0060'].publish(
own_jid.bare, OMEMO_DEVICES_NS, payload=payload, options=options,
)
try:
await self.xmpp['xep_0060'].publish(
own_jid.bare, OMEMO_DEVICES_NS, payload=payload, options=options,
)
except IqError as e:
# TODO: Slixmpp should handle pubsub#errors so we don't have to
# fish the element ourselves
precondition = e.iq['error'].xml.find(
'{%s}%s' % (PUBSUB_ERRORS, 'precondition-not-met'),
)
if precondition is not None:
log.debug('The node we tried to publish was already '
'existing with a different configuration. '
'Trying to configure manually..')
await self._set_node_config(OMEMO_DEVICES_NS)
def get_device_list(self, jid: JID) -> List[str]:
"""Return active device ids. Always contains our own device id."""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment