Commit 2071fad4 authored by ValdikSS's avatar ValdikSS

Set access_model=open on OMEMO PEP elements. Fixes #444.

OMEMO plugin should set `pubsub#access_model` to `open` for
`eu.siacs.conversations.axolotl.devicelist` and
`eu.siacs.conversations.axolotl.bundles` PEP nodes to allow using OMEMO
between non-subscribers (e.g. in multiuser groups).

If `devicelist` node already exists and not configured with
`pubsub#access_model`, publishing to it with publish-options could return
`precondition-not-met`. The plugin will try to reconfigures this PEP node.

NOTE: this modification does not check the presence of pubsub#config-node
and pubsub#create-and-configure features and tries to use it anyway.

NOTE 2: reconfiguration uses Data Forms protocol but does not
request a Form first, and just tries to reconfigure a single
form element.
parent 13d61751
......@@ -664,7 +664,21 @@ class OMEMOConnection:
# Enable Encryption on receiving first Device List
# TODO
def publish_own_devices_list(self, new=False):
def pep_reconfigure(self, ns, cb):
options = Node(nbxmpp.NS_DATA + ' x',
attrs={'type': 'submit'})
field = options.addChild('field',
attrs={'var': 'FORM_TYPE', 'type': 'hidden'})
field.setTagData('value', nbxmpp.NS_PUBSUB_PUBLISH_OPTIONS)
field = options.addChild('field', attrs={'var': 'pubsub#access_model'})
field.setTagData('value', 'open')
con = app.connections[self.account]
con.get_module('PubSub').send_pb_configure(
'', ns, options,
cb=cb)
def publish_own_devices_list(self, new=False, secondTime=False, useOptions=True):
""" Get all currently known own active device ids and publish them
Parameters
......@@ -672,6 +686,10 @@ class OMEMOConnection:
new : bool
if True, a devicelist with only one
(the current id of this instance) device id is pushed
secondTime : bool
if True, no PEP reconfiguration will be performed
useOptions : bool
if True, form options with access_model=open will be used
"""
if new:
devices_list = [self.omemo.own_device_id]
......@@ -685,10 +703,25 @@ class OMEMOConnection:
for device in devices_list:
list_node.addChild('device').setAttr('id', device)
options = None
if useOptions:
options = Node(nbxmpp.NS_DATA + ' x',
attrs={'type': 'submit'})
field = options.addChild('field',
attrs={'var': 'FORM_TYPE', 'type': 'hidden'})
field.setTagData('value', nbxmpp.NS_PUBSUB_PUBLISH_OPTIONS)
field = options.addChild('field', attrs={'var': 'pubsub#access_model'})
field.setTagData('value', 'open')
pub_callback = self.device_list_publish_result_with_check
if secondTime:
pub_callback = self.device_list_publish_result
con = app.connections[self.account]
con.get_module('PubSub').send_pb_publish(
'', NS_DEVICE_LIST, list_node, 'current',
cb=self.device_list_publish_result)
options=options,
cb=pub_callback)
log.info('%s => Publishing own Devices: %s',
self.account, devices_list)
......@@ -698,6 +731,20 @@ class OMEMOConnection:
log.error('%s => Publishing devicelist failed: %s',
self.account, stanza.getError())
def device_list_publish_result_with_check(self, _con, stanza):
if not nbxmpp.isResultNode(stanza):
log.info('%s => Publishing devicelist failed: %s, trying to reconfigure',
self.account, stanza.getError())
self.pep_reconfigure(NS_DEVICE_LIST, self.device_list_reconfigure_result_with_check)
def device_list_reconfigure_result_with_check(self, _con, stanza):
if not nbxmpp.isResultNode(stanza):
log.error('%s => Reconfiguring devicelist failed: %s',
self.account, stanza.getError())
self.publish_own_devices_list(secondTime=True, useOptions=False)
else:
self.publish_own_devices_list(secondTime=True)
def are_keys_missing(self, contact_jid):
""" Checks if devicekeys are missing and querys the
bundles
......@@ -812,17 +859,41 @@ class OMEMOConnection:
data={'fetch_bundle': fetch_bundle})
self.query_for_devicelists.append(jid)
def publish_bundle(self):
""" Publish our bundle information to the PEP node """
def publish_bundle(self, secondTime=False, useOptions=True):
""" Publish our bundle information to the PEP node
Parameters
----------
secondTime : bool
if True, no PEP reconfiguration will be performed
useOptions : bool
if True, form options with access_model=open will be used
"""
bundle = make_bundle(self.omemo.bundle)
node = '%s%s' % (NS_BUNDLES, self.omemo.own_device_id)
log.info('%s => Publishing bundle ...', self.account)
options = None
if useOptions:
options = Node(nbxmpp.NS_DATA + ' x',
attrs={'type': 'submit'})
field = options.addChild('field',
attrs={'var': 'FORM_TYPE', 'type': 'hidden'})
field.setTagData('value', nbxmpp.NS_PUBSUB_PUBLISH_OPTIONS)
field = options.addChild('field', attrs={'var': 'pubsub#access_model'})
field.setTagData('value', 'open')
pub_callback = self.handle_publish_result_with_check
if secondTime:
pub_callback = self.handle_publish_result
con = app.connections[self.account]
con.get_module('PubSub').send_pb_publish(
'', node, bundle, 'current', cb=self.handle_publish_result)
'', node, bundle, 'current',
options=options,
cb=pub_callback)
def handle_publish_result(self, _con, stanza):
""" Log if publishing our bundle was successful
......@@ -838,6 +909,31 @@ class OMEMOConnection:
log.error('%s => Publishing bundle was NOT successful',
self.account)
def handle_publish_result_with_check(self, _con, stanza):
""" Check if publishing our bundle was successful and reconfigure if needed
Parameters
----------
stanza : nbxmpp.Iq
The stanza
"""
if successful(stanza):
log.info('%s => Publishing bundle was successful', self.account)
else:
log.info('%s => Publishing bundle was NOT successful, trying to reconfigure',
self.account)
bundle = make_bundle(self.omemo.bundle)
node = '%s%s' % (NS_BUNDLES, self.omemo.own_device_id)
self.pep_reconfigure(node, self.handle_publish_reconfigure_result_with_check)
def handle_publish_reconfigure_result_with_check(self, _con, stanza):
if not nbxmpp.isResultNode(stanza):
log.info('%s => Reconfiguring bundle failed: %s',
self.account, stanza.getError())
self.publish_bundle(secondTime=True, useOptions=False)
else:
self.publish_bundle(secondTime=True)
def handle_devicelist_result(self, stanza):
""" If query was successful add own device to the list.
......
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