Implement fallback on precondition-not-met error when publishing devicelist and bundle
Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
This commit is contained in:
parent
9e2dcc5529
commit
6850051b32
1 changed files with 61 additions and 4 deletions
|
@ -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."""
|
||||||
|
|
Loading…
Reference in a new issue