Philipp Hörist pushed to branch master at gajim / gajim
Commits: 8b9cc5f7 by lovetox at 2020-04-04T11:27:42+02:00 Refactor handling of entity caps
- Let nbxmpp handle responding to entity caps requests - Move code into Caps module
- - - - - 49075675 by lovetox at 2020-04-04T14:03:53+02:00 Presence: Don't auto subscribe to transports
- - - - - a51612f7 by lovetox at 2020-04-04T16:06:55+02:00 Roster: Add debug logging when loading roster
- - - - - 13f6af23 by lovetox at 2020-04-04T16:23:12+02:00 Gateways: Remove not needed code
- - - - - f8b22b1d by lovetox at 2020-04-04T21:48:04+02:00 Presence: Send nickname on subscribe
- - - - -
13 changed files:
- + enterenter - gajim/common/app.py - gajim/common/connection.py - gajim/common/const.py - gajim/common/helpers.py - gajim/common/modules/caps.py - gajim/common/modules/discovery.py - gajim/common/modules/presence.py - gajim/common/modules/register.py - gajim/common/modules/roster.py - gajim/gui_interface.py - gajim/roster_window.py - test/lib/gajim_mocks.py
Changes:
===================================== enterenter =====================================
===================================== gajim/common/app.py ===================================== @@ -38,7 +38,6 @@ from pathlib import Path from collections import namedtuple
import nbxmpp -from nbxmpp.structs import DiscoIdentity from gi.repository import Gdk
import gajim @@ -148,52 +147,6 @@ gupnp_igd = None
gsound_ctx = None
-gajim_identity = DiscoIdentity(category='client', - type='pc', - name='Gajim') - -gajim_common_features = [ - nbxmpp.NS_BYTESTREAM, - nbxmpp.NS_MUC, - nbxmpp.NS_COMMANDS, - nbxmpp.NS_DISCO_INFO, - nbxmpp.NS_LAST, - nbxmpp.NS_DATA, - nbxmpp.NS_ENCRYPTED, - nbxmpp.NS_PING, - nbxmpp.NS_CHATSTATES, - nbxmpp.NS_RECEIPTS, - nbxmpp.NS_TIME_REVISED, - nbxmpp.NS_VERSION, - nbxmpp.NS_ROSTERX, - nbxmpp.NS_SECLABEL, - nbxmpp.NS_CONFERENCE, - nbxmpp.NS_CORRECT, - nbxmpp.NS_EME, - nbxmpp.NS_XHTML_IM, - nbxmpp.NS_HASHES_2, - nbxmpp.NS_HASHES_MD5, - nbxmpp.NS_HASHES_SHA1, - nbxmpp.NS_HASHES_SHA256, - nbxmpp.NS_HASHES_SHA512, - nbxmpp.NS_HASHES_SHA3_256, - nbxmpp.NS_HASHES_SHA3_512, - nbxmpp.NS_HASHES_BLAKE2B_256, - nbxmpp.NS_HASHES_BLAKE2B_512, - nbxmpp.NS_JINGLE, - nbxmpp.NS_JINGLE_FILE_TRANSFER_5, - nbxmpp.NS_JINGLE_XTLS, - nbxmpp.NS_JINGLE_BYTESTREAM, - nbxmpp.NS_JINGLE_IBB, - nbxmpp.NS_AVATAR_METADATA + '+notify', -] - -# Optional features gajim supports per account -gajim_optional_features = {} # type: Dict[str, List[str]] - -# Capabilities hash per account -caps_hash = {} # type: Dict[str, List[str]] - _dependencies = { 'AVAHI': False, 'PYBONJOUR': False,
===================================== gajim/common/connection.py ===================================== @@ -70,9 +70,6 @@ class CommonConnection:
self.pep = {}
- # Remember where we are in the register agent process - self.agent_registrations = {} - self.roster_supported = True self.avatar_conversion = False
===================================== gajim/common/const.py ===================================== @@ -3,6 +3,8 @@ from collections import namedtuple
from gi.repository import Gio
+import nbxmpp + from gajim.common.i18n import _ from gajim.common.i18n import Q_
@@ -910,3 +912,40 @@ SASL_ERRORS = { 'not-authorized': _('Authentication failed'), 'temporary-auth-failure': _('Authentication currently not possible'), } + + +COMMON_FEATURES = [ + nbxmpp.NS_BYTESTREAM, + nbxmpp.NS_MUC, + nbxmpp.NS_COMMANDS, + nbxmpp.NS_DISCO_INFO, + nbxmpp.NS_LAST, + nbxmpp.NS_DATA, + nbxmpp.NS_ENCRYPTED, + nbxmpp.NS_PING, + nbxmpp.NS_CHATSTATES, + nbxmpp.NS_RECEIPTS, + nbxmpp.NS_TIME_REVISED, + nbxmpp.NS_VERSION, + nbxmpp.NS_ROSTERX, + nbxmpp.NS_SECLABEL, + nbxmpp.NS_CONFERENCE, + nbxmpp.NS_CORRECT, + nbxmpp.NS_EME, + nbxmpp.NS_XHTML_IM, + nbxmpp.NS_HASHES_2, + nbxmpp.NS_HASHES_MD5, + nbxmpp.NS_HASHES_SHA1, + nbxmpp.NS_HASHES_SHA256, + nbxmpp.NS_HASHES_SHA512, + nbxmpp.NS_HASHES_SHA3_256, + nbxmpp.NS_HASHES_SHA3_512, + nbxmpp.NS_HASHES_BLAKE2B_256, + nbxmpp.NS_HASHES_BLAKE2B_512, + nbxmpp.NS_JINGLE, + nbxmpp.NS_JINGLE_FILE_TRANSFER_5, + nbxmpp.NS_JINGLE_XTLS, + nbxmpp.NS_JINGLE_BYTESTREAM, + nbxmpp.NS_JINGLE_IBB, + nbxmpp.NS_AVATAR_METADATA + '+notify', +]
===================================== gajim/common/helpers.py ===================================== @@ -59,9 +59,7 @@ from encodings.punycode import punycode_encode from functools import wraps
import nbxmpp -from nbxmpp.util import compute_caps_hash from nbxmpp.stringprepare import nameprep -from nbxmpp.structs import DiscoInfo from nbxmpp.const import Role from nbxmpp.const import ConnectionProtocol from nbxmpp.const import ConnectionType @@ -1024,50 +1022,31 @@ def get_current_show(account): return 'offline' return app.connections[account].status
-def update_optional_features(account=None): - if account is not None: - accounts = [account] - else: - accounts = app.connections.keys() - - for account_ in accounts: - features = [] - app.gajim_optional_features[account_] = features - if app.config.get_per('accounts', account_, 'subscribe_mood'): - features.append(nbxmpp.NS_MOOD + '+notify') - if app.config.get_per('accounts', account_, 'subscribe_activity'): - features.append(nbxmpp.NS_ACTIVITY + '+notify') - if app.config.get_per('accounts', account_, 'subscribe_tune'): - features.append(nbxmpp.NS_TUNE + '+notify') - if app.config.get_per('accounts', account_, 'subscribe_nick'): - features.append(nbxmpp.NS_NICK + '+notify') - if app.config.get_per('accounts', account_, 'subscribe_location'): - features.append(nbxmpp.NS_LOCATION + '+notify') - if app.connections[account_].get_module('Bookmarks').using_bookmark_2: - features.append(nbxmpp.NS_BOOKMARKS_2 + '+notify') - elif app.connections[account_].get_module('Bookmarks').using_bookmark_1: - features.append(nbxmpp.NS_BOOKMARKS + '+notify') - if app.is_installed('AV'): - features.append(nbxmpp.NS_JINGLE_RTP) - features.append(nbxmpp.NS_JINGLE_RTP_AUDIO) - features.append(nbxmpp.NS_JINGLE_RTP_VIDEO) - features.append(nbxmpp.NS_JINGLE_ICE_UDP) - - # Give plugins the possibility to add their features - app.plugin_manager.extension_point('update_caps', account_) - - disco_info = DiscoInfo(None, - [app.gajim_identity], - app.gajim_common_features + features, - []) - app.caps_hash[account_] = compute_caps_hash(disco_info, compare=False) - # re-send presence with new hash - if not app.account_is_connected(account_): - return - - status = app.connections[account_].status - app.connections[account_].change_status( - status, app.connections[account_].status_message) +def get_optional_features(account): + features = [] + if app.config.get_per('accounts', account, 'subscribe_mood'): + features.append(nbxmpp.NS_MOOD + '+notify') + if app.config.get_per('accounts', account, 'subscribe_activity'): + features.append(nbxmpp.NS_ACTIVITY + '+notify') + if app.config.get_per('accounts', account, 'subscribe_tune'): + features.append(nbxmpp.NS_TUNE + '+notify') + if app.config.get_per('accounts', account, 'subscribe_nick'): + features.append(nbxmpp.NS_NICK + '+notify') + if app.config.get_per('accounts', account, 'subscribe_location'): + features.append(nbxmpp.NS_LOCATION + '+notify') + if app.connections[account].get_module('Bookmarks').using_bookmark_2: + features.append(nbxmpp.NS_BOOKMARKS_2 + '+notify') + elif app.connections[account].get_module('Bookmarks').using_bookmark_1: + features.append(nbxmpp.NS_BOOKMARKS + '+notify') + if app.is_installed('AV'): + features.append(nbxmpp.NS_JINGLE_RTP) + features.append(nbxmpp.NS_JINGLE_RTP_AUDIO) + features.append(nbxmpp.NS_JINGLE_RTP_VIDEO) + features.append(nbxmpp.NS_JINGLE_ICE_UDP) + + # Give plugins the possibility to add their features + app.plugin_manager.extension_point('update_caps', account, features) + return features
def jid_is_blocked(account, jid): con = app.connections[account]
===================================== gajim/common/modules/caps.py ===================================== @@ -19,16 +19,26 @@
import nbxmpp from nbxmpp.structs import StanzaHandler +from nbxmpp.structs import DiscoIdentity from nbxmpp.util import is_error_result from nbxmpp.util import compute_caps_hash
from gajim.common import caps_cache from gajim.common import app +from gajim.common.const import COMMON_FEATURES +from gajim.common.helpers import get_optional_features from gajim.common.nec import NetworkEvent from gajim.common.modules.base import BaseModule
class Caps(BaseModule): + + _nbxmpp_extends = 'EntityCaps' + _nbxmpp_methods = [ + 'caps', + 'set_caps' + ] + def __init__(self, con): BaseModule.__init__(self, con)
@@ -43,6 +53,10 @@ class Caps(BaseModule): self._create_suitable_client_caps = \ caps_cache.create_suitable_client_caps
+ self._identities = [ + DiscoIdentity(category='client', type='pc', name='Gajim') + ] + def _entity_caps(self, _con, _stanza, properties): if properties.type.is_error or properties.type.is_unavailable: return @@ -139,6 +153,19 @@ class Caps(BaseModule): fjid=str(info.jid), jid=bare_jid))
+ def update_caps(self): + if not app.account_is_connected(self._account): + return + + optional_features = get_optional_features(self._account) + self.set_caps(self._identities, + COMMON_FEATURES + optional_features, + 'https://gajim.org') + + app.connections[self._account].change_status( + app.connections[self._account].status, + app.connections[self._account].status_message) +
def get_instance(*args, **kwargs): return Caps(*args, **kwargs), 'Caps'
===================================== gajim/common/modules/discovery.py ===================================== @@ -22,7 +22,6 @@ from gajim.common import app from gajim.common.nec import NetworkIncomingEvent from gajim.common.nec import NetworkEvent from gajim.common.modules.base import BaseModule -from gajim.common.helpers import update_optional_features
class Discovery(BaseModule): @@ -120,7 +119,7 @@ class Discovery(BaseModule): if 'urn:xmpp:pep-vcard-conversion:0' in result.features: self._con.avatar_conversion = True
- update_optional_features() + self._con.get_module('Caps').update_caps()
def discover_server_info(self): # Calling this method starts the connect_maschine() @@ -194,23 +193,6 @@ class Discovery(BaseModule): if self._con.get_module('AdHocCommands').command_info_query(stanza): raise nbxmpp.NodeProcessed
- node = stanza.getQuerynode() - iq = stanza.buildReply('result') - query = iq.setQuery() - if node: - query.setAttr('node', node) - query.addChild('identity', attrs=app.gajim_identity._asdict()) - client_version = 'http://gajim.org#' + app.caps_hash[self._account] - - if node in (None, client_version): - for feature in app.gajim_common_features: - query.addChild('feature', attrs={'var': feature}) - for feature in app.gajim_optional_features[self._account]: - query.addChild('feature', attrs={'var': feature}) - - self._con.connection.send(iq) - raise nbxmpp.NodeProcessed - def disco_muc(self, jid, callback=None): if not app.account_is_connected(self._account): return
===================================== gajim/common/modules/presence.py ===================================== @@ -252,13 +252,7 @@ class Presence(BaseModule): properties.jid, is_transport, auto_auth, properties.nickname)
- if is_transport and fjid in self._con.agent_registrations: - self._con.agent_registrations[fjid]['sub_received'] = True - if not self._con.agent_registrations[fjid]['roster_push']: - # We'll reply after roster push result - raise nbxmpp.NodeProcessed - - if auto_auth or is_transport or jid in self.jids_for_auto_auth: + if auto_auth or jid in self.jids_for_auto_auth: self.send_presence(fjid, 'subscribed') self._log.info('Auto respond with subscribed: %s', jid) return @@ -348,7 +342,10 @@ class Presence(BaseModule): item.addChild('group').setData(group) self._con.connection.send(iq)
- self.send_presence(jid, 'subscribe', status=msg) + self.send_presence(jid, + 'subscribe', + status=msg, + nick=app.nicks[self._account])
def get_presence(self, to=None, typ=None, priority=None, show=None, status=None, nick=None, caps=True, @@ -371,11 +368,11 @@ class Presence(BaseModule): # we add the avatar sha to our presence self._con.get_module('VCardAvatars').add_update_node(presence)
- if caps: - attrs = {'hash': 'sha-1', - 'node': 'http://gajim.org', - 'ver': app.caps_hash[self._account]} - presence.setTag('c', namespace=nbxmpp.NS_CAPS, attrs=attrs) + caps = self._con.get_module('Caps').caps + if caps is not None and typ != 'unavailable': + presence.setTag('c', + namespace=nbxmpp.NS_CAPS, + attrs=caps._asdict())
return presence
===================================== gajim/common/modules/register.py ===================================== @@ -58,9 +58,6 @@ class Register(BaseModule): 'success_cb': weak_success_cb, 'error_cb': weak_error_cb})
- self.agent_registrations[agent] = {'roster_push': False, - 'sub_received': False} - def _register_agent_response(self, _nbxmpp_client, stanza, agent, success_cb, error_cb): if not nbxmpp.isResultNode(stanza): @@ -75,10 +72,6 @@ class Register(BaseModule):
self._con.get_module('Presence').subscribe(agent, auto_auth=True)
- self.agent_registrations[agent]['roster_push'] = True - if self.agent_registrations[agent]['sub_received']: - self._con.get_module('Presence').subscribed(agent) - if success_cb() is not None: success_cb()()
===================================== gajim/common/modules/roster.py ===================================== @@ -49,6 +49,7 @@ class Roster(BaseModule): if data: self.set_raw(data) for jid, item in self._data.items(): + self._log.debug('%s: %s', jid, item) app.nec.push_incoming_event(NetworkEvent( 'roster-info', conn=self._con,
===================================== gajim/gui_interface.py ===================================== @@ -67,7 +67,6 @@ from gajim.session import ChatControlSession
from gajim.common import idle from gajim.common.zeroconf import connection_zeroconf -from gajim.common import caps_cache from gajim.common import proxy65_manager from gajim.common import socks5 from gajim.common import helpers @@ -1729,9 +1728,6 @@ class Interface: app.sleeper_state[account] = 'off' app.last_message_time[account] = {} app.status_before_autoaway[account] = '' - app.gajim_optional_features[account] = [] - app.caps_hash[account] = '' - helpers.update_optional_features(account) # refresh roster if len(app.connections) >= 2: # Do not merge accounts if only one exists @@ -1774,8 +1770,6 @@ class Interface: del app.sleeper_state[account] del app.last_message_time[account] del app.status_before_autoaway[account] - del app.gajim_optional_features[account] - del app.caps_hash[account] if len(app.connections) >= 2: # Do not merge accounts if only one exists self.roster.regroup = app.config.get('mergeaccounts') @@ -2005,15 +1999,6 @@ class Interface: app.plugin_manager = plugins.PluginManager() app.plugin_manager.init_plugins()
- helpers.update_optional_features() - # prepopulate data which we are sure of; note: we do not log these info - for account in app.connections: - gajimcaps = caps_cache.capscache[ - ('sha-1', app.caps_hash[account])] - gajimcaps.identities = [app.gajim_identity] - gajimcaps.features = app.gajim_common_features + \ - app.gajim_optional_features[account] - self.roster._before_fill() for account in app.connections: app.connections[account].get_module('Roster').load_roster() @@ -2162,8 +2147,6 @@ class Interface: app.sleeper_state[a] = 0 app.last_message_time[a] = {} app.status_before_autoaway[a] = '' - app.gajim_optional_features[a] = [] - app.caps_hash[a] = ''
if sys.platform not in ('win32', 'darwin'): logind.enable()
===================================== gajim/roster_window.py ===================================== @@ -3439,7 +3439,7 @@ class RosterWindow: else: app.interface.disable_music_listener()
- helpers.update_optional_features(account) + app.connections[account].get_module('Caps').update_caps()
def on_publish_location_toggled(self, widget, account): active = widget.get_active() @@ -3449,7 +3449,7 @@ class RosterWindow: else: app.connections[account].get_module('UserLocation').set_location(None)
- helpers.update_optional_features(account) + app.connections[account].get_module('Caps').update_caps()
def on_add_new_contact(self, widget, account): AddNewContactWindow(account)
===================================== test/lib/gajim_mocks.py ===================================== @@ -37,8 +37,6 @@ class MockConnection(Mock, ConnectionHandlers): app.sleeper_state[account] = 0 app.last_message_time[account] = {} app.status_before_autoaway[account] = '' - app.gajim_optional_features[account] = [] - app.caps_hash[account] = ''
app.connections[account] = self
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/compare/6ec7a686c9ace16359b1c523bd94519b...