From afb0306160732cec63069177a584a48f23c965e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 21 Jul 2018 13:19:01 +0200 Subject: [PATCH] Move security labels into own module --- gajim/chat_control_base.py | 30 +++++--- gajim/common/connection.py | 15 +--- gajim/common/connection_handlers.py | 33 -------- gajim/common/connection_handlers_events.py | 7 +- gajim/common/modules/message.py | 2 +- gajim/common/modules/misc.py | 9 --- gajim/common/modules/security_labels.py | 88 ++++++++++++++++++++++ 7 files changed, 112 insertions(+), 72 deletions(-) create mode 100644 gajim/common/modules/security_labels.py diff --git a/gajim/chat_control_base.py b/gajim/chat_control_base.py index 9cb8f2b2e..931617869 100644 --- a/gajim/chat_control_base.py +++ b/gajim/chat_control_base.py @@ -207,19 +207,23 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): self.seclabel_combo.pack_start(cell, True) # text to show is in in first column of liststore self.seclabel_combo.add_attribute(cell, 'text', 0) - if app.connections[self.account].seclabel_supported: - app.connections[self.account].seclabel_catalogue(self.contact.jid, self.on_seclabels_ready) + con = app.connections[self.account] + if con.get_module('SecLabels').supported: + con.get_module('SecLabels').request_catalog(self.contact.jid) - def on_seclabels_ready(self): + def _sec_labels_received(self, event): + if event.account != self.account: + return + if event.jid != self.contact.jid: + return lb = self.seclabel_combo.get_model() lb.clear() i = 0 sel = 0 - catalogue = app.connections[self.account].seclabel_catalogues[ - self.contact.jid] - for label in catalogue[2]: + label_, labellist, default = event.catalog + for label in labellist: lb.append([label]) - if label == catalogue[3]: + if label == default: sel = i i += 1 self.seclabel_combo.set_active(sel) @@ -376,6 +380,8 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): self._nec_ping) app.ged.register_event_handler('ping-error', ged.GUI1, self._nec_ping) + app.ged.register_event_handler('sec-label-received', ged.GUI1, + self._sec_labels_received) # This is basically a very nasty hack to surpass the inability # to properly use the super, because of the old code. @@ -550,6 +556,8 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): 'chat_control_base_draw_banner', self) app.ged.remove_event_handler('our-show', ged.GUI1, self._nec_our_status) + app.ged.remove_event_handler('sec-label-received', ged.GUI1, + self._sec_labels_received) def on_msg_textview_populate_popup(self, textview, menu): """ @@ -782,9 +790,11 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools): if self.seclabel_combo is not None: idx = self.seclabel_combo.get_active() if idx != -1: - cat = app.connections[self.account].seclabel_catalogues[self.contact.jid] - lname = cat[2][idx] - label = cat[1][lname] + con = app.connections[self.account] + catalog = con.get_module('SecLabels').get_catalog(self.contact.jid) + labels, label_list, _ = catalog + lname = label_list[idx] + label = labels[lname] return label def send_message(self, message, keyID='', type_='chat', chatstate=None, diff --git a/gajim/common/connection.py b/gajim/common/connection.py index 585d3ab8a..b0947a9fe 100644 --- a/gajim/common/connection.py +++ b/gajim/common/connection.py @@ -103,9 +103,6 @@ class CommonConnection: self.priority = app.get_priority(name, 'offline') self.time_to_reconnect = None - self.seclabel_supported = False - self.seclabel_catalogues = {} - self.pep_supported = False self.pep = {} # Do we continue connection when we get roster (send presence,get vcard..) @@ -1617,7 +1614,7 @@ class Connection(CommonConnection, ConnectionHandlers): if obj.fjid == hostname: if nbxmpp.NS_SECLABEL in obj.features: - self.seclabel_supported = True + self.get_module('SecLabels').supported = True if nbxmpp.NS_VCARD in obj.features: self.vcard_supported = True get_action(self.name + '-profile').set_enabled(True) @@ -1897,16 +1894,6 @@ class Connection(CommonConnection, ConnectionHandlers): query.setTagData('prompt', prompt) self.connection.SendAndCallForResponse(iq, _on_prompt_result) - def seclabel_catalogue(self, to, callback): - if not app.account_is_connected(self.name): - return - self.seclabel_catalogue_request(to, callback) - server = app.get_jid_from_account(self.name).split("@")[1] # Really, no better way? - iq = nbxmpp.Iq(typ='get', to=server) - iq2 = iq.addChild(name='catalog', namespace=nbxmpp.NS_SECLABEL_CATALOG) - iq2.setAttr('to', to) - self.connection.send(iq) - def bookmarks_available(self): if self.private_storage_supported: return True diff --git a/gajim/common/connection_handlers.py b/gajim/common/connection_handlers.py index 90e51a376..c4f4ce1d5 100644 --- a/gajim/common/connection_handlers.py +++ b/gajim/common/connection_handlers.py @@ -784,37 +784,6 @@ class ConnectionHandlers(ConnectionSocks5Bytestream, ConnectionDisco, conn=self, stanza=obj.stanza)) return True - def _SecLabelCB(self, con, iq_obj): - """ - Security Label callback, used for catalogues. - """ - log.debug('SecLabelCB') - query = iq_obj.getTag('catalog') - to = query.getAttr('to') - items = query.getTags('item') - labels = {} - ll = [] - default = None - for item in items: - label = item.getAttr('selector') - labels[label] = item.getTag('securitylabel') - ll.append(label) - if item.getAttr('default') == 'true': - default = label - if to not in self.seclabel_catalogues: - self.seclabel_catalogues[to] = [[], None, None, None] - self.seclabel_catalogues[to][1] = labels - self.seclabel_catalogues[to][2] = ll - self.seclabel_catalogues[to][3] = default - for callback in self.seclabel_catalogues[to][0]: - callback() - self.seclabel_catalogues[to][0] = [] - - def seclabel_catalogue_request(self, to, callback): - if to not in self.seclabel_catalogues: - self.seclabel_catalogues[to] = [[], None, None, None] - self.seclabel_catalogues[to][0].append(callback) - def _rosterSetCB(self, con, iq_obj): log.debug('rosterSetCB') app.nec.push_incoming_event(RosterSetReceivedEvent(None, conn=self, @@ -1169,8 +1138,6 @@ class ConnectionHandlers(ConnectionSocks5Bytestream, ConnectionDisco, nbxmpp.NS_DISCO_INFO) con.RegisterHandler('iq', self._DiscoverInfoErrorCB, 'error', nbxmpp.NS_DISCO_INFO) - con.RegisterHandler('iq', self._SecLabelCB, 'result', - nbxmpp.NS_SECLABEL_CATALOG) con.RegisterHandler('iq', self._DiscoverInfoGetCB, 'get', nbxmpp.NS_DISCO_INFO) con.RegisterHandler('iq', self._DiscoverItemsGetCB, 'get', diff --git a/gajim/common/connection_handlers_events.py b/gajim/common/connection_handlers_events.py index 543d3bbab..8181057d6 100644 --- a/gajim/common/connection_handlers_events.py +++ b/gajim/common/connection_handlers_events.py @@ -670,11 +670,8 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent): form_node=self.msg_obj.form_node) return - self.displaymarking = None - seclabel = self.stanza.getTag('securitylabel') - if seclabel and seclabel.getNamespace() == nbxmpp.NS_SECLABEL: - # Ignore message from room in which we are not - self.displaymarking = seclabel.getTag('displaymarking') + from gajim.common.modules.security_labels import parse_securitylabel + self.displaymarking = parse_securitylabel(self.stanza) self.captcha_form = None captcha_tag = self.stanza.getTag('captcha', namespace=nbxmpp.NS_CAPTCHA) diff --git a/gajim/common/modules/message.py b/gajim/common/modules/message.py index 25d363359..c990a1a48 100644 --- a/gajim/common/modules/message.py +++ b/gajim/common/modules/message.py @@ -22,6 +22,7 @@ import nbxmpp from gajim.common import app from gajim.common import helpers from gajim.common.nec import NetworkIncomingEvent, NetworkEvent +from gajim.common.modules.security_labels import parse_securitylabel from gajim.common.modules.user_nickname import parse_nickname from gajim.common.modules.chatstates import parse_chatstate from gajim.common.modules.carbons import parse_carbon @@ -29,7 +30,6 @@ from gajim.common.modules.misc import parse_delay from gajim.common.modules.misc import parse_eme from gajim.common.modules.misc import parse_correction from gajim.common.modules.misc import parse_attention -from gajim.common.modules.misc import parse_securitylabel from gajim.common.modules.misc import parse_form from gajim.common.modules.misc import parse_oob from gajim.common.modules.misc import parse_xhtml diff --git a/gajim/common/modules/misc.py b/gajim/common/modules/misc.py index d97b579d9..056467461 100644 --- a/gajim/common/modules/misc.py +++ b/gajim/common/modules/misc.py @@ -126,15 +126,6 @@ def parse_attention(stanza): return True -# XEP-0258: Security Labels in XMPP - -def parse_securitylabel(stanza): - seclabel = stanza.getTag('securitylabel', namespace=nbxmpp.NS_SECLABEL) - if seclabel is None: - return None - return seclabel.getTag('displaymarking') - - # XEP-0004: Data Forms def parse_form(stanza): diff --git a/gajim/common/modules/security_labels.py b/gajim/common/modules/security_labels.py new file mode 100644 index 000000000..d99389a11 --- /dev/null +++ b/gajim/common/modules/security_labels.py @@ -0,0 +1,88 @@ +# This file is part of Gajim. +# +# Gajim is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; version 3 only. +# +# Gajim is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Gajim. If not, see . + +# XEP-0258: Security Labels in XMPP + +import logging + +import nbxmpp + +from gajim.common import app +from gajim.common.nec import NetworkIncomingEvent + +log = logging.getLogger('gajim.c.m.security_labels') + + +class SecLabels: + def __init__(self, con): + self._con = con + self._account = con.name + + self.handlers = [] + + self._catalogs = {} + self.supported = False + + def request_catalog(self, jid): + server = app.get_jid_from_account(self._account).split("@")[1] + iq = nbxmpp.Iq(typ='get', to=server) + iq.addChild(name='catalog', + namespace=nbxmpp.NS_SECLABEL_CATALOG, + attrs={'to': jid}) + log.info('Request catalog: server: %s, to: %s', server, jid) + self._con.connection.SendAndCallForResponse( + iq, self._catalog_received) + + def _catalog_received(self, stanza): + if not nbxmpp.isResultNode(stanza): + log.info('Error: %s', stanza.getError()) + return + + query = stanza.getTag('catalog', namespace=nbxmpp.NS_SECLABEL_CATALOG) + to = query.getAttr('to') + items = query.getTags('item') + + labels = {} + label_list = [] + default = None + for item in items: + label = item.getAttr('selector') + labels[label] = item.getTag('securitylabel') + label_list.append(label) + if item.getAttr('default') == 'true': + default = label + + catalog = (labels, label_list, default) + self._catalogs[to] = catalog + + app.nec.push_incoming_event(SecLabelCatalog( + None, account=self._account, jid=to, catalog=catalog)) + + def get_catalog(self, jid): + return self._catalogs.get(jid) + + +def parse_securitylabel(stanza): + seclabel = stanza.getTag('securitylabel', namespace=nbxmpp.NS_SECLABEL) + if seclabel is None: + return None + return seclabel.getTag('displaymarking') + + +class SecLabelCatalog(NetworkIncomingEvent): + name = 'sec-catalog-received' + + +def get_instance(*args, **kwargs): + return SecLabels(*args, **kwargs), 'SecLabels'