Merge branch 'precondition-not-met-fallback' into 'master'

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

Closes #6

See merge request poezio/slixmpp-omemo!2
This commit is contained in:
Maxime Buquet 2019-10-25 03:20:37 +02:00
commit 753c5de27c

View file

@ -54,6 +54,7 @@ except (ImportError,):
TRUE_VALUES = {True, 'true', '1'} TRUE_VALUES = {True, 'true', '1'}
PUBLISH_OPTIONS_NODE = 'http://jabber.org/protocol/pubsub#publish-options' PUBLISH_OPTIONS_NODE = 'http://jabber.org/protocol/pubsub#publish-options'
PUBSUB_ERRORS = 'http://jabber.org/protocol/pubsub#errors'
def b64enc(data: bytes) -> str: def b64enc(data: bytes) -> str:
@ -245,6 +246,38 @@ class XEP_0384(BasePlugin):
def my_device_id(self) -> int: def my_device_id(self) -> int:
return self._device_id 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: async def _generate_bundle_iq(self) -> Iq:
bundle = self._omemo.public_bundle.serialize(self.omemo_backend) bundle = self._omemo.public_bundle.serialize(self.omemo_backend)
@ -286,7 +319,19 @@ class XEP_0384(BasePlugin):
async def _publish_bundle(self) -> None: async def _publish_bundle(self) -> None:
if self._omemo.republish_bundle: if self._omemo.republish_bundle:
iq = await self._generate_bundle_iq() 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]: async def _fetch_bundle(self, jid: str, device_id: int) -> Optional[ExtendedPublicBundle]:
node = '%s:%d' % (OMEMO_BUNDLES_NS, device_id) node = '%s:%d' % (OMEMO_BUNDLES_NS, device_id)
@ -374,9 +419,21 @@ class XEP_0384(BasePlugin):
'pubsub#access_model': 'open', 'pubsub#access_model': 'open',
}) })
await self.xmpp['xep_0060'].publish( try:
own_jid.bare, OMEMO_DEVICES_NS, payload=payload, options=options, 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]: def get_device_list(self, jid: JID) -> List[str]:
"""Return active device ids. Always contains our own device id.""" """Return active device ids. Always contains our own device id."""