2008-08-15 19:31:51 +02:00
|
|
|
# -*- coding:utf-8 -*-
|
2008-08-15 05:20:23 +02:00
|
|
|
## src/common/connection_handlers.py
|
2006-03-19 15:54:00 +01:00
|
|
|
##
|
2008-08-15 05:20:23 +02:00
|
|
|
## Copyright (C) 2006 Dimitur Kirov <dkirov AT gmail.com>
|
2008-08-15 19:31:51 +02:00
|
|
|
## Junglecow J <junglecow AT gmail.com>
|
2008-08-15 05:20:23 +02:00
|
|
|
## Copyright (C) 2006-2007 Tomasz Melcer <liori AT exroot.org>
|
|
|
|
## Travis Shirk <travis AT pobox.com>
|
|
|
|
## Nikos Kouremenos <kourem AT gmail.com>
|
2014-01-02 09:33:54 +01:00
|
|
|
## Copyright (C) 2006-2014 Yann Leboulanger <asterix AT lagaule.org>
|
2008-08-15 05:20:23 +02:00
|
|
|
## Copyright (C) 2007 Julien Pivotto <roidelapluie AT gmail.com>
|
|
|
|
## Copyright (C) 2007-2008 Brendan Taylor <whateley AT gmail.com>
|
|
|
|
## Jean-Marie Traissard <jim AT lapin.org>
|
|
|
|
## Stephan Erb <steve-e AT h3c.de>
|
|
|
|
## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
|
2006-03-19 15:54:00 +01:00
|
|
|
##
|
2007-12-12 09:44:46 +01:00
|
|
|
## This file is part of Gajim.
|
|
|
|
##
|
|
|
|
## Gajim is free software; you can redistribute it and/or modify
|
2006-03-19 15:54:00 +01:00
|
|
|
## it under the terms of the GNU General Public License as published
|
2007-12-12 09:44:46 +01:00
|
|
|
## by the Free Software Foundation; version 3 only.
|
2006-03-19 15:54:00 +01:00
|
|
|
##
|
2007-12-12 09:44:46 +01:00
|
|
|
## Gajim is distributed in the hope that it will be useful,
|
2006-03-19 15:54:00 +01:00
|
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2008-08-15 05:20:23 +02:00
|
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2006-03-19 15:54:00 +01:00
|
|
|
## GNU General Public License for more details.
|
|
|
|
##
|
2007-12-12 09:44:46 +01:00
|
|
|
## You should have received a copy of the GNU General Public License
|
2008-08-15 05:20:23 +02:00
|
|
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
2007-12-12 09:44:46 +01:00
|
|
|
##
|
2006-03-19 15:54:00 +01:00
|
|
|
|
|
|
|
import os
|
2006-03-21 16:57:44 +01:00
|
|
|
import base64
|
2017-10-17 20:36:27 +02:00
|
|
|
import binascii
|
2008-12-03 23:07:44 +01:00
|
|
|
import operator
|
2009-01-08 17:51:26 +01:00
|
|
|
import hashlib
|
2006-03-19 15:54:00 +01:00
|
|
|
|
2017-02-07 20:56:26 +01:00
|
|
|
from time import (altzone, daylight, gmtime, localtime, strftime,
|
2010-02-08 15:08:40 +01:00
|
|
|
time as time_time, timezone, tzname)
|
2017-02-07 20:56:26 +01:00
|
|
|
|
|
|
|
from gi.repository import GLib
|
2006-03-19 15:54:00 +01:00
|
|
|
|
2012-12-09 21:37:51 +01:00
|
|
|
import nbxmpp
|
2017-06-13 23:58:06 +02:00
|
|
|
from gajim.common import caps_cache as capscache
|
2006-03-19 15:54:00 +01:00
|
|
|
|
2017-06-13 23:58:06 +02:00
|
|
|
from gajim.common import helpers
|
2017-08-13 13:18:56 +02:00
|
|
|
from gajim.common import app
|
2017-06-13 23:58:06 +02:00
|
|
|
from gajim.common import dataforms
|
|
|
|
from gajim.common import jingle_xtls
|
2018-04-25 20:49:37 +02:00
|
|
|
from gajim.common import configpaths
|
2017-11-11 21:46:34 +01:00
|
|
|
from gajim.common.caps_cache import muc_caps_cache
|
2017-06-13 23:58:06 +02:00
|
|
|
from gajim.common.commands import ConnectionCommands
|
|
|
|
from gajim.common.protocol.caps import ConnectionCaps
|
|
|
|
from gajim.common.protocol.bytestream import ConnectionSocks5Bytestream
|
|
|
|
from gajim.common.protocol.bytestream import ConnectionIBBytestream
|
|
|
|
from gajim.common.message_archiving import ConnectionArchive313
|
2017-12-27 13:17:13 +01:00
|
|
|
from gajim.common.httpupload import ConnectionHTTPUpload
|
2017-06-13 23:58:06 +02:00
|
|
|
from gajim.common.connection_handlers_events import *
|
2010-08-11 18:43:41 +02:00
|
|
|
|
2017-06-13 23:58:06 +02:00
|
|
|
from gajim.common import ged
|
|
|
|
from gajim.common import nec
|
|
|
|
from gajim.common.nec import NetworkEvent
|
2018-04-23 18:32:01 +02:00
|
|
|
from gajim.common.const import KindConstant
|
2010-09-14 19:31:35 +02:00
|
|
|
|
2017-06-13 23:58:06 +02:00
|
|
|
from gajim.common.jingle import ConnectionJingle
|
2006-03-19 15:54:00 +01:00
|
|
|
|
2008-12-24 13:11:02 +01:00
|
|
|
import logging
|
|
|
|
log = logging.getLogger('gajim.c.connection_handlers')
|
|
|
|
|
2006-03-19 15:54:00 +01:00
|
|
|
# kind of events we can wait for an answer
|
2006-05-01 20:29:12 +02:00
|
|
|
AGENT_REMOVED = 'agent_removed'
|
2006-09-13 18:47:58 +02:00
|
|
|
METACONTACTS_ARRIVED = 'metacontacts_arrived'
|
2009-06-27 17:56:04 +02:00
|
|
|
ROSTER_ARRIVED = 'roster_arrived'
|
2010-12-11 12:57:09 +01:00
|
|
|
DELIMITER_ARRIVED = 'delimiter_arrived'
|
2006-11-18 21:52:28 +01:00
|
|
|
PRIVACY_ARRIVED = 'privacy_arrived'
|
2008-02-15 23:55:21 +01:00
|
|
|
PEP_CONFIG = 'pep_config'
|
2006-03-19 15:54:00 +01:00
|
|
|
|
|
|
|
|
|
|
|
class ConnectionDisco:
|
2010-02-08 15:08:40 +01:00
|
|
|
"""
|
|
|
|
Holds xmpppy handlers and public methods for discover services
|
|
|
|
"""
|
|
|
|
|
2010-10-06 21:11:23 +02:00
|
|
|
def discoverItems(self, jid, node=None, id_prefix=None):
|
2010-02-08 15:08:40 +01:00
|
|
|
"""
|
|
|
|
According to XEP-0030:
|
2010-10-06 21:11:23 +02:00
|
|
|
jid is mandatory;
|
|
|
|
name, node, action is optional.
|
2010-02-08 15:08:40 +01:00
|
|
|
"""
|
2013-07-30 20:09:52 +02:00
|
|
|
id_ = self._discover(nbxmpp.NS_DISCO_ITEMS, jid, node, id_prefix)
|
|
|
|
self.disco_items_ids.append(id_)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2010-10-06 21:11:23 +02:00
|
|
|
def discoverInfo(self, jid, node=None, id_prefix=None):
|
2010-02-08 15:08:40 +01:00
|
|
|
"""
|
|
|
|
According to XEP-0030:
|
2010-10-06 21:11:23 +02:00
|
|
|
For identity: category, type is mandatory, name is optional.
|
|
|
|
For feature: var is mandatory.
|
2010-02-08 15:08:40 +01:00
|
|
|
"""
|
2013-07-30 20:09:52 +02:00
|
|
|
id_ = self._discover(nbxmpp.NS_DISCO_INFO, jid, node, id_prefix)
|
|
|
|
self.disco_info_ids.append(id_)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2018-06-01 20:00:22 +02:00
|
|
|
def discoverMUC(self, jid, callback, update=False):
|
|
|
|
if muc_caps_cache.is_cached(jid) and not update:
|
2017-11-25 15:33:54 +01:00
|
|
|
callback()
|
|
|
|
return
|
2017-11-11 21:46:34 +01:00
|
|
|
disco_info = nbxmpp.Iq(typ='get', to=jid, queryNS=nbxmpp.NS_DISCO_INFO)
|
|
|
|
self.connection.SendAndCallForResponse(
|
|
|
|
disco_info, self.received_muc_info, {'callback': callback})
|
|
|
|
|
|
|
|
def received_muc_info(self, conn, stanza, callback):
|
|
|
|
if nbxmpp.isResultNode(stanza):
|
|
|
|
app.log('gajim.muc').info(
|
|
|
|
'Received MUC DiscoInfo for %s', stanza.getFrom())
|
|
|
|
muc_caps_cache.append(stanza)
|
|
|
|
callback()
|
|
|
|
else:
|
|
|
|
error = stanza.getError()
|
|
|
|
if error == 'item-not-found':
|
|
|
|
# Groupchat does not exist
|
|
|
|
callback()
|
|
|
|
return
|
|
|
|
app.nec.push_incoming_event(
|
2017-12-09 00:15:26 +01:00
|
|
|
InformationEvent(
|
|
|
|
None, dialog_name='unable-join-groupchat', args=error))
|
2017-11-11 21:46:34 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def request_register_agent_info(self, agent):
|
|
|
|
if not self.connection or self.connected < 2:
|
|
|
|
return None
|
2012-12-09 21:37:51 +01:00
|
|
|
iq = nbxmpp.Iq('get', nbxmpp.NS_REGISTER, to=agent)
|
2010-02-08 15:08:40 +01:00
|
|
|
id_ = self.connection.getAnID()
|
|
|
|
iq.setID(id_)
|
|
|
|
# Wait the answer during 30 secondes
|
2017-08-13 13:18:56 +02:00
|
|
|
self.awaiting_timeouts[app.idlequeue.current_time() + 30] = (id_,
|
2010-10-06 21:11:23 +02:00
|
|
|
_('Registration information for transport %s has not arrived in '
|
|
|
|
'time') % agent)
|
2010-02-08 15:08:40 +01:00
|
|
|
self.connection.SendAndCallForResponse(iq, self._ReceivedRegInfo,
|
2010-10-06 21:11:23 +02:00
|
|
|
{'agent': agent})
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _agent_registered_cb(self, con, resp, agent):
|
|
|
|
if resp.getType() == 'result':
|
2017-12-09 00:15:26 +01:00
|
|
|
app.nec.push_incoming_event(InformationEvent(
|
|
|
|
None, dialog_name='agent-register-success', args=agent))
|
2010-02-08 15:08:40 +01:00
|
|
|
self.request_subscription(agent, auto_auth=True)
|
|
|
|
self.agent_registrations[agent]['roster_push'] = True
|
|
|
|
if self.agent_registrations[agent]['sub_received']:
|
2012-12-09 21:37:51 +01:00
|
|
|
p = nbxmpp.Presence(agent, 'subscribed')
|
2010-02-08 15:08:40 +01:00
|
|
|
p = self.add_sha(p)
|
|
|
|
self.connection.send(p)
|
|
|
|
if resp.getType() == 'error':
|
2017-12-09 00:15:26 +01:00
|
|
|
app.nec.push_incoming_event(InformationEvent(
|
|
|
|
None, dialog_name='agent-register-error',
|
|
|
|
kwargs={'agent': agent,
|
|
|
|
'error': resp.getError(),
|
|
|
|
'error_msg': resp.getErrorMsg()}))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2010-10-06 21:11:23 +02:00
|
|
|
def register_agent(self, agent, info, is_form=False):
|
2010-02-08 15:08:40 +01:00
|
|
|
if not self.connection or self.connected < 2:
|
|
|
|
return
|
|
|
|
if is_form:
|
2012-12-09 21:37:51 +01:00
|
|
|
iq = nbxmpp.Iq('set', nbxmpp.NS_REGISTER, to=agent)
|
2011-10-31 10:47:28 +01:00
|
|
|
query = iq.setQuery()
|
2010-02-08 15:08:40 +01:00
|
|
|
info.setAttr('type', 'submit')
|
|
|
|
query.addChild(node=info)
|
2010-10-06 21:11:23 +02:00
|
|
|
self.connection.SendAndCallForResponse(iq,
|
|
|
|
self._agent_registered_cb, {'agent': agent})
|
2010-02-08 15:08:40 +01:00
|
|
|
else:
|
|
|
|
# fixed: blocking
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.features_nb.register(self.connection, agent, info,
|
2010-10-06 21:11:23 +02:00
|
|
|
self._agent_registered_cb, {'agent': agent})
|
2010-02-08 15:08:40 +01:00
|
|
|
self.agent_registrations[agent] = {'roster_push': False,
|
2010-10-06 21:11:23 +02:00
|
|
|
'sub_received': False}
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _discover(self, ns, jid, node=None, id_prefix=None):
|
|
|
|
if not self.connection or self.connected < 2:
|
|
|
|
return
|
2012-12-09 21:37:51 +01:00
|
|
|
iq = nbxmpp.Iq(typ='get', to=jid, queryNS=ns)
|
2013-07-30 20:09:52 +02:00
|
|
|
id_ = self.connection.getAnID()
|
2010-02-08 15:08:40 +01:00
|
|
|
if id_prefix:
|
2013-07-30 20:09:52 +02:00
|
|
|
id_ = id_prefix + id_
|
|
|
|
iq.setID(id_)
|
2010-02-08 15:08:40 +01:00
|
|
|
if node:
|
|
|
|
iq.setQuerynode(node)
|
|
|
|
self.connection.send(iq)
|
2013-07-30 20:09:52 +02:00
|
|
|
return id_
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _ReceivedRegInfo(self, con, resp, agent):
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.features_nb._ReceivedRegInfo(con, resp, agent)
|
2010-02-08 15:08:40 +01:00
|
|
|
self._IqCB(con, resp)
|
|
|
|
|
|
|
|
def _discoGetCB(self, con, iq_obj):
|
|
|
|
"""
|
|
|
|
Get disco info
|
|
|
|
"""
|
|
|
|
if not self.connection or self.connected < 2:
|
|
|
|
return
|
|
|
|
frm = helpers.get_full_jid_from_iq(iq_obj)
|
2013-01-01 21:06:16 +01:00
|
|
|
to = iq_obj.getAttr('to')
|
|
|
|
id_ = iq_obj.getAttr('id')
|
2012-12-09 21:37:51 +01:00
|
|
|
iq = nbxmpp.Iq(to=frm, typ='result', queryNS=nbxmpp.NS_DISCO, frm=to)
|
2010-02-08 15:08:40 +01:00
|
|
|
iq.setAttr('id', id_)
|
|
|
|
query = iq.setTag('query')
|
2017-08-13 13:18:56 +02:00
|
|
|
query.setAttr('node', 'http://gajim.org#' + app.version.split('-', 1)[
|
2010-10-06 21:11:23 +02:00
|
|
|
0])
|
2012-12-09 21:37:51 +01:00
|
|
|
for f in (nbxmpp.NS_BYTESTREAM, nbxmpp.NS_SI, nbxmpp.NS_FILE,
|
2017-06-14 21:31:29 +02:00
|
|
|
nbxmpp.NS_COMMANDS, nbxmpp.NS_JINGLE_FILE_TRANSFER_5,
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_JINGLE_XTLS, nbxmpp.NS_PUBKEY_PUBKEY, nbxmpp.NS_PUBKEY_REVOKE,
|
|
|
|
nbxmpp.NS_PUBKEY_ATTEST):
|
|
|
|
feature = nbxmpp.Node('feature')
|
2010-02-08 15:08:40 +01:00
|
|
|
feature.setAttr('var', f)
|
|
|
|
query.addChild(node=feature)
|
|
|
|
|
|
|
|
self.connection.send(iq)
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _DiscoverItemsErrorCB(self, con, iq_obj):
|
|
|
|
log.debug('DiscoverItemsErrorCB')
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(AgentItemsErrorReceivedEvent(None,
|
2010-11-29 12:53:50 +01:00
|
|
|
conn=self, stanza=iq_obj))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _DiscoverItemsCB(self, con, iq_obj):
|
|
|
|
log.debug('DiscoverItemsCB')
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(AgentItemsReceivedEvent(None, conn=self,
|
2010-11-29 12:53:50 +01:00
|
|
|
stanza=iq_obj))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _DiscoverItemsGetCB(self, con, iq_obj):
|
|
|
|
log.debug('DiscoverItemsGetCB')
|
|
|
|
|
|
|
|
if not self.connection or self.connected < 2:
|
|
|
|
return
|
|
|
|
|
|
|
|
if self.commandItemsQuery(con, iq_obj):
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
2010-02-08 15:08:40 +01:00
|
|
|
node = iq_obj.getTagAttr('query', 'node')
|
|
|
|
if node is None:
|
|
|
|
result = iq_obj.buildReply('result')
|
|
|
|
self.connection.send(result)
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
|
|
|
if node == nbxmpp.NS_COMMANDS:
|
2010-02-08 15:08:40 +01:00
|
|
|
self.commandListQuery(con, iq_obj)
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _DiscoverInfoGetCB(self, con, iq_obj):
|
|
|
|
log.debug('DiscoverInfoGetCB')
|
|
|
|
if not self.connection or self.connected < 2:
|
|
|
|
return
|
2011-10-31 10:47:28 +01:00
|
|
|
node = iq_obj.getQuerynode()
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
if self.commandInfoQuery(con, iq_obj):
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2013-01-01 21:06:16 +01:00
|
|
|
id_ = iq_obj.getAttr('id')
|
2010-02-08 15:08:40 +01:00
|
|
|
if id_[:6] == 'Gajim_':
|
|
|
|
# We get this request from echo.server
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
iq = iq_obj.buildReply('result')
|
2011-10-31 10:47:28 +01:00
|
|
|
q = iq.setQuery()
|
2010-02-08 15:08:40 +01:00
|
|
|
if node:
|
|
|
|
q.setAttr('node', node)
|
2017-08-13 13:18:56 +02:00
|
|
|
q.addChild('identity', attrs=app.gajim_identity)
|
|
|
|
client_version = 'http://gajim.org#' + app.caps_hash[self.name]
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
if node in (None, client_version):
|
2017-08-13 13:18:56 +02:00
|
|
|
for f in app.gajim_common_features:
|
2010-10-06 21:11:23 +02:00
|
|
|
q.addChild('feature', attrs={'var': f})
|
2017-08-13 13:18:56 +02:00
|
|
|
for f in app.gajim_optional_features[self.name]:
|
2010-10-06 21:11:23 +02:00
|
|
|
q.addChild('feature', attrs={'var': f})
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
if q.getChildren():
|
|
|
|
self.connection.send(iq)
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _DiscoverInfoErrorCB(self, con, iq_obj):
|
|
|
|
log.debug('DiscoverInfoErrorCB')
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(AgentInfoErrorReceivedEvent(None,
|
2010-11-29 12:53:50 +01:00
|
|
|
conn=self, stanza=iq_obj))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _DiscoverInfoCB(self, con, iq_obj):
|
|
|
|
log.debug('DiscoverInfoCB')
|
|
|
|
if not self.connection or self.connected < 2:
|
|
|
|
return
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(AgentInfoReceivedEvent(None, conn=self,
|
2010-11-29 12:53:50 +01:00
|
|
|
stanza=iq_obj))
|
2006-03-19 15:54:00 +01:00
|
|
|
|
2008-05-17 04:23:46 +02:00
|
|
|
# basic connection handlers used here and in zeroconf
|
|
|
|
class ConnectionHandlersBase:
|
2010-02-08 15:08:40 +01:00
|
|
|
def __init__(self):
|
|
|
|
# List of IDs we are waiting answers for {id: (type_of_request, data), }
|
|
|
|
self.awaiting_answers = {}
|
|
|
|
# List of IDs that will produce a timeout is answer doesn't arrive
|
|
|
|
# {time_of_the_timeout: (id, message to send to gui), }
|
|
|
|
self.awaiting_timeouts = {}
|
|
|
|
# keep the jids we auto added (transports contacts) to not send the
|
|
|
|
# SUBSCRIBED event to gui
|
|
|
|
self.automatically_added = []
|
|
|
|
|
|
|
|
# keep track of sessions this connection has with other JIDs
|
|
|
|
self.sessions = {}
|
|
|
|
|
2016-11-24 22:44:52 +01:00
|
|
|
# IDs of sent messages (https://trac.gajim.org/ticket/8222)
|
|
|
|
self.sent_message_ids = []
|
|
|
|
|
2012-09-18 16:07:11 +02:00
|
|
|
# We decrypt GPG messages one after the other. Keep queue in mem
|
|
|
|
self.gpg_messages_to_decrypt = []
|
|
|
|
|
2018-07-05 21:09:55 +02:00
|
|
|
# XEPs that are based on Message
|
|
|
|
self._message_namespaces = set([nbxmpp.NS_HTTP_AUTH,
|
|
|
|
nbxmpp.NS_PUBSUB_EVENT,
|
|
|
|
nbxmpp.NS_ROSTERX])
|
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('iq-error-received', ged.CORE,
|
2010-10-04 13:51:42 +02:00
|
|
|
self._nec_iq_error_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('presence-received', ged.CORE,
|
2010-12-19 10:39:15 +01:00
|
|
|
self._nec_presence_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('message-received', ged.CORE,
|
2010-12-19 21:22:29 +01:00
|
|
|
self._nec_message_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('mam-message-received', ged.CORE,
|
2017-04-16 17:16:41 +02:00
|
|
|
self._nec_message_received)
|
2017-11-11 21:46:34 +01:00
|
|
|
app.ged.register_event_handler('mam-gc-message-received', ged.CORE,
|
|
|
|
self._nec_message_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('decrypted-message-received', ged.CORE,
|
2010-12-19 21:22:29 +01:00
|
|
|
self._nec_decrypted_message_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('gc-message-received', ged.CORE,
|
2017-08-08 15:24:41 +02:00
|
|
|
self._nec_gc_message_received)
|
2010-09-08 19:55:19 +02:00
|
|
|
|
2011-01-06 16:50:38 +01:00
|
|
|
def cleanup(self):
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('iq-error-received', ged.CORE,
|
2011-01-06 16:50:38 +01:00
|
|
|
self._nec_iq_error_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('presence-received', ged.CORE,
|
2011-01-06 16:50:38 +01:00
|
|
|
self._nec_presence_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('message-received', ged.CORE,
|
2011-01-06 16:50:38 +01:00
|
|
|
self._nec_message_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('mam-message-received', ged.CORE,
|
2017-04-16 17:16:41 +02:00
|
|
|
self._nec_message_received)
|
2017-11-11 21:46:34 +01:00
|
|
|
app.ged.remove_event_handler('mam-gc-message-received', ged.CORE,
|
|
|
|
self._nec_message_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('decrypted-message-received', ged.CORE,
|
2011-01-06 16:50:38 +01:00
|
|
|
self._nec_decrypted_message_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('gc-message-received', ged.CORE,
|
2017-08-08 15:24:41 +02:00
|
|
|
self._nec_gc_message_received)
|
2011-01-06 16:50:38 +01:00
|
|
|
|
2010-10-04 13:51:42 +02:00
|
|
|
def _nec_iq_error_received(self, obj):
|
2010-09-08 19:55:19 +02:00
|
|
|
if obj.conn.name != self.name:
|
|
|
|
return
|
2010-03-10 21:58:14 +01:00
|
|
|
|
2010-12-19 10:39:15 +01:00
|
|
|
def _nec_presence_received(self, obj):
|
|
|
|
account = obj.conn.name
|
|
|
|
if account != self.name:
|
|
|
|
return
|
|
|
|
jid = obj.jid
|
|
|
|
resource = obj.resource or ''
|
|
|
|
|
|
|
|
statuss = ['offline', 'error', 'online', 'chat', 'away', 'xa', 'dnd',
|
|
|
|
'invisible']
|
|
|
|
obj.old_show = 0
|
|
|
|
obj.new_show = statuss.index(obj.show)
|
|
|
|
|
|
|
|
obj.contact_list = []
|
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
highest = app.contacts.get_contact_with_highest_priority(account, jid)
|
2010-12-19 10:39:15 +01:00
|
|
|
obj.was_highest = (highest and highest.resource == resource)
|
|
|
|
|
|
|
|
# Update contact
|
2017-08-13 13:18:56 +02:00
|
|
|
obj.contact_list = app.contacts.get_contacts(account, jid)
|
2010-12-19 10:39:15 +01:00
|
|
|
obj.contact = None
|
|
|
|
resources = []
|
|
|
|
for c in obj.contact_list:
|
|
|
|
resources.append(c.resource)
|
|
|
|
if c.resource == resource:
|
|
|
|
obj.contact = c
|
|
|
|
break
|
|
|
|
|
|
|
|
if obj.contact:
|
|
|
|
if obj.contact.show in statuss:
|
|
|
|
obj.old_show = statuss.index(obj.contact.show)
|
|
|
|
# nick changed
|
|
|
|
if obj.contact_nickname is not None and \
|
|
|
|
obj.contact.contact_name != obj.contact_nickname:
|
|
|
|
obj.contact.contact_name = obj.contact_nickname
|
|
|
|
obj.need_redraw = True
|
|
|
|
|
2018-03-26 23:47:43 +02:00
|
|
|
elif obj.old_show != obj.new_show or obj.contact.status != \
|
|
|
|
obj.status:
|
|
|
|
obj.need_redraw = True
|
2010-12-19 10:39:15 +01:00
|
|
|
else:
|
2017-08-13 13:18:56 +02:00
|
|
|
obj.contact = app.contacts.get_first_contact_from_jid(account,
|
2010-12-19 10:39:15 +01:00
|
|
|
jid)
|
|
|
|
if not obj.contact:
|
|
|
|
# Presence of another resource of our jid
|
|
|
|
# Create self contact and add to roster
|
|
|
|
if resource == obj.conn.server_resource:
|
|
|
|
return
|
|
|
|
# Ignore offline presence of unknown self resource
|
|
|
|
if obj.new_show < 2:
|
|
|
|
return
|
2017-08-13 13:18:56 +02:00
|
|
|
obj.contact = app.contacts.create_self_contact(jid=jid,
|
2010-12-19 10:39:15 +01:00
|
|
|
account=account, show=obj.show, status=obj.status,
|
|
|
|
priority=obj.prio, keyID=obj.keyID,
|
|
|
|
resource=obj.resource)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.contacts.add_contact(account, obj.contact)
|
2010-12-19 10:39:15 +01:00
|
|
|
obj.contact_list.append(obj.contact)
|
|
|
|
elif obj.contact.show in statuss:
|
|
|
|
obj.old_show = statuss.index(obj.contact.show)
|
|
|
|
if (resources != [''] and (len(obj.contact_list) != 1 or \
|
2012-01-21 16:32:52 +01:00
|
|
|
obj.contact_list[0].show not in ('not in roster', 'offline'))) and \
|
2017-08-13 13:18:56 +02:00
|
|
|
not app.jid_is_transport(jid):
|
2010-12-19 10:39:15 +01:00
|
|
|
# Another resource of an existing contact connected
|
|
|
|
obj.old_show = 0
|
2017-08-13 13:18:56 +02:00
|
|
|
obj.contact = app.contacts.copy_contact(obj.contact)
|
2010-12-19 10:39:15 +01:00
|
|
|
obj.contact_list.append(obj.contact)
|
|
|
|
obj.contact.resource = resource
|
|
|
|
|
|
|
|
obj.need_add_in_roster = True
|
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
if not app.jid_is_transport(jid) and len(obj.contact_list) == 1:
|
2010-12-19 10:39:15 +01:00
|
|
|
# It's not an agent
|
|
|
|
if obj.old_show == 0 and obj.new_show > 1:
|
2017-08-13 13:18:56 +02:00
|
|
|
if not jid in app.newly_added[account]:
|
|
|
|
app.newly_added[account].append(jid)
|
|
|
|
if jid in app.to_be_removed[account]:
|
|
|
|
app.to_be_removed[account].remove(jid)
|
2010-12-19 10:39:15 +01:00
|
|
|
elif obj.old_show > 1 and obj.new_show == 0 and \
|
|
|
|
obj.conn.connected > 1:
|
2017-08-13 13:18:56 +02:00
|
|
|
if not jid in app.to_be_removed[account]:
|
|
|
|
app.to_be_removed[account].append(jid)
|
|
|
|
if jid in app.newly_added[account]:
|
|
|
|
app.newly_added[account].remove(jid)
|
2010-12-19 10:39:15 +01:00
|
|
|
obj.need_redraw = True
|
|
|
|
|
|
|
|
obj.contact.show = obj.show
|
|
|
|
obj.contact.status = obj.status
|
|
|
|
obj.contact.priority = obj.prio
|
2017-08-13 13:18:56 +02:00
|
|
|
attached_keys = app.config.get_per('accounts', account,
|
2012-02-21 23:53:49 +01:00
|
|
|
'attached_gpg_keys').split()
|
|
|
|
if jid in attached_keys:
|
|
|
|
obj.contact.keyID = attached_keys[attached_keys.index(jid) + 1]
|
|
|
|
else:
|
|
|
|
# Do not override assigned key
|
|
|
|
obj.contact.keyID = obj.keyID
|
2010-12-19 10:39:15 +01:00
|
|
|
obj.contact.contact_nickname = obj.contact_nickname
|
2017-07-26 22:24:19 +02:00
|
|
|
obj.contact.idle_time = obj.idle_time
|
2010-12-19 10:39:15 +01:00
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
if app.jid_is_transport(jid):
|
2010-12-19 10:39:15 +01:00
|
|
|
return
|
|
|
|
|
|
|
|
# It isn't an agent
|
|
|
|
# reset chatstate if needed:
|
|
|
|
# (when contact signs out or has errors)
|
|
|
|
if obj.show in ('offline', 'error'):
|
2011-08-27 22:41:55 +02:00
|
|
|
obj.contact.our_chatstate = obj.contact.chatstate = None
|
2010-12-19 10:39:15 +01:00
|
|
|
|
|
|
|
# TODO: This causes problems when another
|
|
|
|
# resource signs off!
|
|
|
|
self.stop_all_active_file_transfers(obj.contact)
|
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
if app.config.get('log_contact_status_changes') and \
|
|
|
|
app.config.should_log(self.name, obj.jid):
|
|
|
|
show = app.logger.convert_show_values_to_db_api_values(obj.show)
|
2017-08-08 14:41:55 +02:00
|
|
|
if show is not None:
|
2017-11-17 21:42:44 +01:00
|
|
|
app.logger.insert_into_logs(self.name,
|
|
|
|
nbxmpp.JID(obj.jid).getStripped(),
|
2017-09-29 00:11:29 +02:00
|
|
|
time_time(),
|
|
|
|
KindConstant.STATUS,
|
|
|
|
message=obj.status,
|
|
|
|
show=show)
|
2010-12-19 10:39:15 +01:00
|
|
|
|
2010-12-19 21:22:29 +01:00
|
|
|
def _nec_message_received(self, obj):
|
|
|
|
if obj.conn.name != self.name:
|
|
|
|
return
|
2017-04-13 22:58:51 +02:00
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
app.plugin_manager.extension_point(
|
2017-04-13 22:58:51 +02:00
|
|
|
'decrypt', self, obj, self._on_message_received)
|
|
|
|
if not obj.encrypted:
|
2017-09-21 17:05:01 +02:00
|
|
|
# XEP-0380
|
|
|
|
enc_tag = obj.stanza.getTag('encryption', namespace=nbxmpp.NS_EME)
|
|
|
|
if enc_tag:
|
|
|
|
ns = enc_tag.getAttr('namespace')
|
|
|
|
if ns:
|
|
|
|
if ns == 'urn:xmpp:otr:0':
|
|
|
|
obj.msgtxt = _('This message was encrypted with OTR '
|
|
|
|
'and could not be decrypted.')
|
|
|
|
elif ns == 'jabber:x:encrypted':
|
|
|
|
obj.msgtxt = _('This message was encrypted with Legacy '
|
|
|
|
'OpenPGP and could not be decrypted. You can install '
|
|
|
|
'the PGP plugin to handle those messages.')
|
|
|
|
elif ns == 'urn:xmpp:openpgp:0':
|
|
|
|
obj.msgtxt = _('This message was encrypted with '
|
|
|
|
'OpenPGP for XMPP and could not be decrypted.')
|
|
|
|
else:
|
|
|
|
enc_name = enc_tag.getAttr('name')
|
|
|
|
if not enc_name:
|
|
|
|
enc_name = ns
|
|
|
|
obj.msgtxt = _('This message was encrypted with %s '
|
|
|
|
'and could not be decrypted.') % enc_name
|
2017-04-13 22:58:51 +02:00
|
|
|
self._on_message_received(obj)
|
|
|
|
|
|
|
|
def _on_message_received(self, obj):
|
|
|
|
if isinstance(obj, MessageReceivedEvent):
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(
|
2017-10-22 23:27:47 +02:00
|
|
|
DecryptedMessageReceivedEvent(
|
|
|
|
None, conn=self, msg_obj=obj, stanza_id=obj.unique_id))
|
2017-04-13 22:58:51 +02:00
|
|
|
else:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(
|
2017-07-27 20:39:21 +02:00
|
|
|
MamDecryptedMessageReceivedEvent(None, **vars(obj)))
|
2017-04-13 22:58:51 +02:00
|
|
|
|
2010-12-19 21:22:29 +01:00
|
|
|
def _nec_decrypted_message_received(self, obj):
|
|
|
|
if obj.conn.name != self.name:
|
|
|
|
return
|
|
|
|
|
|
|
|
# Receipt requested
|
|
|
|
# TODO: We shouldn't answer if we're invisible!
|
2017-08-13 13:18:56 +02:00
|
|
|
contact = app.contacts.get_contact(self.name, obj.jid)
|
2010-12-19 21:22:29 +01:00
|
|
|
nick = obj.resource
|
2017-08-13 13:18:56 +02:00
|
|
|
gc_contact = app.contacts.get_gc_contact(self.name, obj.jid, nick)
|
2016-03-05 15:23:48 +01:00
|
|
|
if obj.sent:
|
|
|
|
jid_to = obj.stanza.getFrom()
|
|
|
|
else:
|
|
|
|
jid_to = obj.stanza.getTo()
|
2016-02-20 20:04:47 +01:00
|
|
|
reply = False
|
|
|
|
if not jid_to:
|
|
|
|
reply = True
|
|
|
|
else:
|
2018-05-20 17:03:07 +02:00
|
|
|
fjid_to = str(jid_to)
|
|
|
|
if self.name != 'Local':
|
|
|
|
# Dont check precis for zeroconf
|
|
|
|
fjid_to = helpers.parse_jid(str(jid_to))
|
2017-08-13 13:18:56 +02:00
|
|
|
jid_to = app.get_jid_without_resource(fjid_to)
|
|
|
|
if jid_to == app.get_jid_from_account(self.name):
|
2016-02-20 20:04:47 +01:00
|
|
|
reply = True
|
2017-03-20 21:09:13 +01:00
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
if obj.jid != app.get_jid_from_account(self.name):
|
|
|
|
if obj.receipt_request_tag and app.config.get_per('accounts',
|
2017-03-20 21:09:13 +01:00
|
|
|
self.name, 'answer_receipts') and ((contact and contact.sub \
|
|
|
|
not in ('to', 'none')) or gc_contact) and obj.mtype != 'error' and \
|
|
|
|
reply:
|
|
|
|
receipt = nbxmpp.Message(to=obj.fjid, typ='chat')
|
|
|
|
receipt.setTag('received', namespace='urn:xmpp:receipts',
|
|
|
|
attrs={'id': obj.id_})
|
|
|
|
|
|
|
|
if obj.thread_id:
|
|
|
|
receipt.setThread(obj.thread_id)
|
|
|
|
self.connection.send(receipt)
|
2010-12-19 21:22:29 +01:00
|
|
|
|
|
|
|
# We got our message's receipt
|
2017-08-13 13:18:56 +02:00
|
|
|
if obj.receipt_received_tag and app.config.get_per('accounts',
|
2016-03-08 22:36:22 +01:00
|
|
|
self.name, 'request_receipt'):
|
|
|
|
ctrl = obj.session.control
|
|
|
|
if not ctrl:
|
2016-12-16 21:53:51 +01:00
|
|
|
# Received <message> doesn't have the <thread> element
|
|
|
|
# or control is not bound to session?
|
|
|
|
# --> search for it
|
2017-08-13 13:18:56 +02:00
|
|
|
ctrl = app.interface.msg_win_mgr.search_control(obj.jid,
|
2016-12-16 21:53:51 +01:00
|
|
|
obj.conn.name, obj.resource)
|
|
|
|
|
2016-03-08 22:36:22 +01:00
|
|
|
if ctrl:
|
|
|
|
id_ = obj.receipt_received_tag.getAttr('id')
|
|
|
|
if not id_:
|
|
|
|
# old XEP implementation
|
|
|
|
id_ = obj.id_
|
2017-05-01 19:42:57 +02:00
|
|
|
ctrl.conv_textview.show_xep0184_ack(id_)
|
2010-12-19 21:22:29 +01:00
|
|
|
|
|
|
|
if obj.mtype == 'error':
|
2011-03-05 13:17:32 +01:00
|
|
|
if not obj.msgtxt:
|
2014-09-14 14:23:31 +02:00
|
|
|
obj.msgtxt = _('message')
|
2010-12-19 21:22:29 +01:00
|
|
|
self.dispatch_error_message(obj.stanza, obj.msgtxt,
|
|
|
|
obj.session, obj.fjid, obj.timestamp)
|
|
|
|
return True
|
2012-08-24 12:54:27 +02:00
|
|
|
elif obj.mtype == 'groupchat':
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(GcMessageReceivedEvent(None,
|
2017-10-22 23:27:47 +02:00
|
|
|
conn=self, msg_obj=obj, stanza_id=obj.unique_id))
|
2012-08-24 12:54:27 +02:00
|
|
|
return True
|
2010-12-19 21:22:29 +01:00
|
|
|
|
2018-03-24 01:47:03 +01:00
|
|
|
def _check_for_mam_compliance(self, room_jid, stanza_id):
|
|
|
|
namespace = muc_caps_cache.get_mam_namespace(room_jid)
|
|
|
|
if stanza_id is None and namespace == nbxmpp.NS_MAM_2:
|
|
|
|
helpers.add_to_mam_blacklist(room_jid)
|
|
|
|
|
2017-08-08 15:24:41 +02:00
|
|
|
def _nec_gc_message_received(self, obj):
|
2017-09-07 16:42:51 +02:00
|
|
|
if obj.conn.name != self.name:
|
|
|
|
return
|
2018-03-24 01:47:03 +01:00
|
|
|
|
|
|
|
self._check_for_mam_compliance(obj.jid, obj.unique_id)
|
|
|
|
|
2017-10-22 00:39:56 +02:00
|
|
|
if (app.config.should_log(obj.conn.name, obj.jid) and
|
2017-10-22 23:27:47 +02:00
|
|
|
obj.msgtxt and obj.nick):
|
2017-08-08 15:24:41 +02:00
|
|
|
# if not obj.nick, it means message comes from room itself
|
|
|
|
# usually it hold description and can be send at each connection
|
|
|
|
# so don't store it in logs
|
2017-11-17 21:42:44 +01:00
|
|
|
app.logger.insert_into_logs(self.name,
|
|
|
|
obj.jid,
|
2017-09-29 00:11:29 +02:00
|
|
|
obj.timestamp,
|
|
|
|
KindConstant.GC_MSG,
|
|
|
|
message=obj.msgtxt,
|
|
|
|
contact_name=obj.nick,
|
2017-10-22 23:27:47 +02:00
|
|
|
additional_data=obj.additional_data,
|
|
|
|
stanza_id=obj.unique_id)
|
2017-10-22 00:39:56 +02:00
|
|
|
app.logger.set_room_last_message_time(obj.room_jid, obj.timestamp)
|
2017-08-08 15:24:41 +02:00
|
|
|
|
2010-12-19 21:22:29 +01:00
|
|
|
# process and dispatch an error message
|
|
|
|
def dispatch_error_message(self, msg, msgtxt, session, frm, tim):
|
|
|
|
error_msg = msg.getErrorMsg()
|
|
|
|
|
|
|
|
if not error_msg:
|
|
|
|
error_msg = msgtxt
|
|
|
|
msgtxt = None
|
|
|
|
|
|
|
|
subject = msg.getSubject()
|
|
|
|
|
|
|
|
if session.is_loggable():
|
2017-11-17 21:42:44 +01:00
|
|
|
app.logger.insert_into_logs(self.name,
|
|
|
|
nbxmpp.JID(frm).getStripped(),
|
2017-09-29 00:11:29 +02:00
|
|
|
tim,
|
|
|
|
KindConstant.ERROR,
|
|
|
|
message=error_msg,
|
|
|
|
subject=subject)
|
2017-08-08 14:41:55 +02:00
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(MessageErrorEvent(None, conn=self,
|
2010-12-19 21:22:29 +01:00
|
|
|
fjid=frm, error_code=msg.getErrorCode(), error_msg=error_msg,
|
2016-02-08 22:31:36 +01:00
|
|
|
msg=msgtxt, time_=tim, session=session, stanza=msg))
|
2010-12-19 21:22:29 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def get_sessions(self, jid):
|
|
|
|
"""
|
|
|
|
Get all sessions for the given full jid
|
|
|
|
"""
|
2017-08-13 13:18:56 +02:00
|
|
|
if not app.interface.is_pm_contact(jid, self.name):
|
|
|
|
jid = app.get_jid_without_resource(jid)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
try:
|
2013-01-02 17:53:42 +01:00
|
|
|
return list(self.sessions[jid].values())
|
2010-02-08 15:08:40 +01:00
|
|
|
except KeyError:
|
|
|
|
return []
|
|
|
|
|
|
|
|
def get_or_create_session(self, fjid, thread_id):
|
|
|
|
"""
|
|
|
|
Return an existing session between this connection and 'jid', returns a
|
|
|
|
new one if none exist
|
|
|
|
"""
|
|
|
|
pm = True
|
|
|
|
jid = fjid
|
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
if not app.interface.is_pm_contact(fjid, self.name):
|
2010-02-08 15:08:40 +01:00
|
|
|
pm = False
|
2017-08-13 13:18:56 +02:00
|
|
|
jid = app.get_jid_without_resource(fjid)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
session = self.find_session(jid, thread_id)
|
|
|
|
|
|
|
|
if session:
|
|
|
|
return session
|
|
|
|
|
|
|
|
if pm:
|
|
|
|
return self.make_new_session(fjid, thread_id, type_='pm')
|
|
|
|
else:
|
|
|
|
return self.make_new_session(fjid, thread_id)
|
|
|
|
|
|
|
|
def find_session(self, jid, thread_id):
|
|
|
|
try:
|
|
|
|
if not thread_id:
|
|
|
|
return self.find_null_session(jid)
|
|
|
|
else:
|
|
|
|
return self.sessions[jid][thread_id]
|
|
|
|
except KeyError:
|
|
|
|
return None
|
|
|
|
|
2018-05-27 01:01:35 +02:00
|
|
|
def terminate_sessions(self):
|
2010-02-08 15:08:40 +01:00
|
|
|
self.sessions = {}
|
|
|
|
|
|
|
|
def delete_session(self, jid, thread_id):
|
|
|
|
if not jid in self.sessions:
|
2017-08-13 13:18:56 +02:00
|
|
|
jid = app.get_jid_without_resource(jid)
|
2010-02-08 15:08:40 +01:00
|
|
|
if not jid in self.sessions:
|
|
|
|
return
|
|
|
|
|
|
|
|
del self.sessions[jid][thread_id]
|
|
|
|
|
|
|
|
if not self.sessions[jid]:
|
|
|
|
del self.sessions[jid]
|
|
|
|
|
|
|
|
def find_null_session(self, jid):
|
|
|
|
"""
|
|
|
|
Find all of the sessions between us and a remote jid in which we haven't
|
|
|
|
received a thread_id yet and returns the session that we last sent a
|
|
|
|
message to
|
|
|
|
"""
|
2013-01-02 17:53:42 +01:00
|
|
|
sessions = list(self.sessions[jid].values())
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
# sessions that we haven't received a thread ID in
|
|
|
|
idless = [s for s in sessions if not s.received_thread_id]
|
|
|
|
|
|
|
|
# filter out everything except the default session type
|
|
|
|
chat_sessions = [s for s in idless if isinstance(s,
|
2017-08-13 13:18:56 +02:00
|
|
|
app.default_session_type)]
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
if chat_sessions:
|
|
|
|
# return the session that we last sent a message in
|
2010-10-06 21:11:23 +02:00
|
|
|
return sorted(chat_sessions, key=operator.attrgetter('last_send'))[
|
|
|
|
-1]
|
2010-02-08 15:08:40 +01:00
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
2013-08-27 17:24:41 +02:00
|
|
|
def get_latest_session(self, jid):
|
|
|
|
"""
|
|
|
|
Get the session that we last sent a message to
|
|
|
|
"""
|
|
|
|
if jid not in self.sessions:
|
|
|
|
return None
|
|
|
|
sessions = self.sessions[jid].values()
|
|
|
|
if not sessions:
|
|
|
|
return None
|
|
|
|
return sorted(sessions, key=operator.attrgetter('last_send'))[-1]
|
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def find_controlless_session(self, jid, resource=None):
|
|
|
|
"""
|
|
|
|
Find an active session that doesn't have a control attached
|
|
|
|
"""
|
|
|
|
try:
|
2013-01-02 17:53:42 +01:00
|
|
|
sessions = list(self.sessions[jid].values())
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
# filter out everything except the default session type
|
|
|
|
chat_sessions = [s for s in sessions if isinstance(s,
|
2017-08-13 13:18:56 +02:00
|
|
|
app.default_session_type)]
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
orphaned = [s for s in chat_sessions if not s.control]
|
|
|
|
|
|
|
|
if resource:
|
|
|
|
orphaned = [s for s in orphaned if s.resource == resource]
|
|
|
|
|
|
|
|
return orphaned[0]
|
|
|
|
except (KeyError, IndexError):
|
|
|
|
return None
|
|
|
|
|
|
|
|
def make_new_session(self, jid, thread_id=None, type_='chat', cls=None):
|
|
|
|
"""
|
|
|
|
Create and register a new session
|
|
|
|
|
|
|
|
thread_id=None to generate one.
|
|
|
|
type_ should be 'chat' or 'pm'.
|
|
|
|
"""
|
|
|
|
if not cls:
|
2017-08-13 13:18:56 +02:00
|
|
|
cls = app.default_session_type
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2012-12-09 21:37:51 +01:00
|
|
|
sess = cls(self, nbxmpp.JID(jid), thread_id, type_)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
# determine if this session is a pm session
|
|
|
|
# if not, discard the resource so that all sessions are stored bare
|
|
|
|
if not type_ == 'pm':
|
2017-08-13 13:18:56 +02:00
|
|
|
jid = app.get_jid_without_resource(jid)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
if not jid in self.sessions:
|
|
|
|
self.sessions[jid] = {}
|
|
|
|
|
|
|
|
self.sessions[jid][sess.thread_id] = sess
|
|
|
|
|
|
|
|
return sess
|
2008-05-17 04:23:46 +02:00
|
|
|
|
2017-07-28 00:07:49 +02:00
|
|
|
class ConnectionHandlers(ConnectionArchive313,
|
2018-06-30 19:23:10 +02:00
|
|
|
ConnectionSocks5Bytestream, ConnectionDisco,
|
2018-07-05 20:20:22 +02:00
|
|
|
ConnectionCommands, ConnectionCaps,
|
2017-12-27 13:17:13 +01:00
|
|
|
ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream,
|
|
|
|
ConnectionHTTPUpload):
|
2010-02-08 15:08:40 +01:00
|
|
|
def __init__(self):
|
2014-11-11 15:28:24 +01:00
|
|
|
ConnectionArchive313.__init__(self)
|
2010-02-22 16:29:01 +01:00
|
|
|
ConnectionSocks5Bytestream.__init__(self)
|
2010-08-16 14:33:50 +02:00
|
|
|
ConnectionIBBytestream.__init__(self)
|
2010-02-08 15:08:40 +01:00
|
|
|
ConnectionCommands.__init__(self)
|
2018-01-24 17:05:41 +01:00
|
|
|
ConnectionHTTPUpload.__init__(self)
|
2010-11-24 09:19:38 +01:00
|
|
|
|
|
|
|
# Handle presences BEFORE caps
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.register_incoming_event(PresenceReceivedEvent)
|
2010-11-24 09:19:38 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
ConnectionCaps.__init__(self, account=self.name,
|
2013-04-06 12:24:26 +02:00
|
|
|
capscache=capscache.capscache,
|
2010-10-06 21:11:23 +02:00
|
|
|
client_caps_factory=capscache.create_suitable_client_caps)
|
2010-02-08 15:08:40 +01:00
|
|
|
ConnectionJingle.__init__(self)
|
|
|
|
ConnectionHandlersBase.__init__(self)
|
|
|
|
|
|
|
|
# keep the latest subscribed event for each jid to prevent loop when we
|
|
|
|
# acknowledge presences
|
|
|
|
self.subscribed_events = {}
|
2013-07-30 20:09:52 +02:00
|
|
|
# IDs of disco#items requests
|
|
|
|
self.disco_items_ids = []
|
|
|
|
# IDs of disco#info requests
|
|
|
|
self.disco_info_ids = []
|
2018-06-24 23:22:49 +02:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.continue_connect_info = None
|
|
|
|
|
2017-01-27 22:24:53 +01:00
|
|
|
self.privacy_default_list = None
|
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.register_incoming_event(StreamConflictReceivedEvent)
|
|
|
|
app.nec.register_incoming_event(StreamOtherHostReceivedEvent)
|
|
|
|
app.nec.register_incoming_event(MessageReceivedEvent)
|
|
|
|
app.nec.register_incoming_event(ArchivingErrorReceivedEvent)
|
|
|
|
app.nec.register_incoming_event(
|
2016-10-31 02:11:46 +01:00
|
|
|
Archiving313PreferencesChangedReceivedEvent)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.register_incoming_event(NotificationEvent)
|
2010-09-09 16:40:58 +02:00
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('roster-set-received',
|
2010-08-23 14:35:03 +02:00
|
|
|
ged.CORE, self._nec_roster_set_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('roster-received', ged.CORE,
|
2010-08-29 20:22:20 +02:00
|
|
|
self._nec_roster_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('iq-error-received', ged.CORE,
|
2010-10-04 13:51:42 +02:00
|
|
|
self._nec_iq_error_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('subscribe-presence-received',
|
2010-10-04 10:56:34 +02:00
|
|
|
ged.CORE, self._nec_subscribe_presence_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('subscribed-presence-received',
|
2010-10-04 10:56:34 +02:00
|
|
|
ged.CORE, self._nec_subscribed_presence_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('subscribed-presence-received',
|
2010-10-04 10:56:34 +02:00
|
|
|
ged.POSTGUI, self._nec_subscribed_presence_received_end)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('unsubscribed-presence-received',
|
2010-10-04 10:56:34 +02:00
|
|
|
ged.CORE, self._nec_unsubscribed_presence_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('unsubscribed-presence-received',
|
2010-10-04 10:56:34 +02:00
|
|
|
ged.POSTGUI, self._nec_unsubscribed_presence_received_end)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('agent-removed', ged.CORE,
|
2010-11-09 21:52:22 +01:00
|
|
|
self._nec_agent_removed)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('stream-other-host-received', ged.CORE,
|
2012-04-21 23:52:24 +02:00
|
|
|
self._nec_stream_other_host_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.register_event_handler('blocking', ged.CORE,
|
2014-08-13 22:46:18 +02:00
|
|
|
self._nec_blocking)
|
2010-07-20 10:35:38 +02:00
|
|
|
|
2011-01-06 16:50:38 +01:00
|
|
|
def cleanup(self):
|
|
|
|
ConnectionHandlersBase.cleanup(self)
|
|
|
|
ConnectionCaps.cleanup(self)
|
2014-12-29 19:13:12 +01:00
|
|
|
ConnectionArchive313.cleanup(self)
|
2017-12-27 13:17:13 +01:00
|
|
|
ConnectionHTTPUpload.cleanup(self)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('roster-set-received',
|
2011-01-06 16:50:38 +01:00
|
|
|
ged.CORE, self._nec_roster_set_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('roster-received', ged.CORE,
|
2011-01-06 16:50:38 +01:00
|
|
|
self._nec_roster_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('iq-error-received', ged.CORE,
|
2011-01-06 16:50:38 +01:00
|
|
|
self._nec_iq_error_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('subscribe-presence-received',
|
2011-01-06 16:50:38 +01:00
|
|
|
ged.CORE, self._nec_subscribe_presence_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('subscribed-presence-received',
|
2011-01-06 16:50:38 +01:00
|
|
|
ged.CORE, self._nec_subscribed_presence_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('subscribed-presence-received',
|
2011-01-06 16:50:38 +01:00
|
|
|
ged.POSTGUI, self._nec_subscribed_presence_received_end)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('unsubscribed-presence-received',
|
2011-01-06 16:50:38 +01:00
|
|
|
ged.CORE, self._nec_unsubscribed_presence_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('unsubscribed-presence-received',
|
2011-01-06 16:50:38 +01:00
|
|
|
ged.POSTGUI, self._nec_unsubscribed_presence_received_end)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('agent-removed', ged.CORE,
|
2011-01-06 16:50:38 +01:00
|
|
|
self._nec_agent_removed)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('stream-other-host-received', ged.CORE,
|
2012-04-21 23:52:24 +02:00
|
|
|
self._nec_stream_other_host_received)
|
2017-08-13 13:18:56 +02:00
|
|
|
app.ged.remove_event_handler('blocking', ged.CORE, self._nec_blocking)
|
2010-07-20 10:35:38 +02:00
|
|
|
|
2017-09-28 17:19:41 +02:00
|
|
|
def add_sha(self, p, send_caps=True):
|
2018-06-30 19:23:10 +02:00
|
|
|
p = self.get_module('VCardAvatars').add_update_node(p)
|
2017-09-28 17:19:41 +02:00
|
|
|
if send_caps:
|
|
|
|
return self._add_caps(p)
|
|
|
|
return p
|
|
|
|
|
|
|
|
def _add_caps(self, p):
|
|
|
|
''' advertise our capabilities in presence stanza (xep-0115)'''
|
|
|
|
c = p.setTag('c', namespace=nbxmpp.NS_CAPS)
|
|
|
|
c.setAttr('hash', 'sha-1')
|
|
|
|
c.setAttr('node', 'http://gajim.org')
|
|
|
|
c.setAttr('ver', app.caps_hash[self.name])
|
|
|
|
return p
|
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def _ErrorCB(self, con, iq_obj):
|
|
|
|
log.debug('ErrorCB')
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(IqErrorReceivedEvent(None, conn=self,
|
2010-10-18 22:05:41 +02:00
|
|
|
stanza=iq_obj))
|
2010-09-08 19:55:19 +02:00
|
|
|
|
2017-09-28 16:50:30 +02:00
|
|
|
def _IqCB(self, con, iq_obj):
|
|
|
|
id_ = iq_obj.getID()
|
|
|
|
|
|
|
|
app.nec.push_incoming_event(NetworkEvent('raw-iq-received',
|
|
|
|
conn=self, stanza=iq_obj))
|
|
|
|
|
|
|
|
# Check if we were waiting a timeout for this id
|
|
|
|
found_tim = None
|
|
|
|
for tim in self.awaiting_timeouts:
|
|
|
|
if id_ == self.awaiting_timeouts[tim][0]:
|
|
|
|
found_tim = tim
|
|
|
|
break
|
|
|
|
if found_tim:
|
|
|
|
del self.awaiting_timeouts[found_tim]
|
|
|
|
|
|
|
|
if id_ not in self.awaiting_answers:
|
|
|
|
return
|
|
|
|
|
|
|
|
if self.awaiting_answers[id_][0] == AGENT_REMOVED:
|
|
|
|
jid = self.awaiting_answers[id_][1]
|
|
|
|
app.nec.push_incoming_event(AgentRemovedEvent(None, conn=self,
|
|
|
|
agent=jid))
|
|
|
|
del self.awaiting_answers[id_]
|
|
|
|
elif self.awaiting_answers[id_][0] == METACONTACTS_ARRIVED:
|
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
if iq_obj.getType() == 'result':
|
|
|
|
app.nec.push_incoming_event(MetacontactsReceivedEvent(None,
|
|
|
|
conn=self, stanza=iq_obj))
|
|
|
|
else:
|
|
|
|
if iq_obj.getErrorCode() not in ('403', '406', '404'):
|
|
|
|
self.private_storage_supported = False
|
|
|
|
self.get_roster_delimiter()
|
|
|
|
del self.awaiting_answers[id_]
|
|
|
|
elif self.awaiting_answers[id_][0] == DELIMITER_ARRIVED:
|
|
|
|
del self.awaiting_answers[id_]
|
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
if iq_obj.getType() == 'result':
|
|
|
|
query = iq_obj.getTag('query')
|
|
|
|
if not query:
|
|
|
|
return
|
|
|
|
delimiter = query.getTagData('roster')
|
|
|
|
if delimiter:
|
|
|
|
self.nested_group_delimiter = delimiter
|
|
|
|
else:
|
|
|
|
self.set_roster_delimiter('::')
|
|
|
|
else:
|
|
|
|
self.private_storage_supported = False
|
|
|
|
|
|
|
|
# We can now continue connection by requesting the roster
|
|
|
|
self.request_roster()
|
|
|
|
elif self.awaiting_answers[id_][0] == ROSTER_ARRIVED:
|
|
|
|
if iq_obj.getType() == 'result':
|
|
|
|
if not iq_obj.getTag('query'):
|
2018-05-18 18:20:06 +02:00
|
|
|
self._init_roster_from_db()
|
2017-09-28 16:50:30 +02:00
|
|
|
self._getRoster()
|
|
|
|
elif iq_obj.getType() == 'error':
|
|
|
|
self.roster_supported = False
|
|
|
|
self.discoverItems(app.config.get_per('accounts', self.name,
|
|
|
|
'hostname'), id_prefix='Gajim_')
|
|
|
|
if app.config.get_per('accounts', self.name,
|
|
|
|
'use_ft_proxies'):
|
|
|
|
self.discover_ft_proxies()
|
|
|
|
app.nec.push_incoming_event(RosterReceivedEvent(None,
|
|
|
|
conn=self))
|
|
|
|
GLib.timeout_add_seconds(10, self.discover_servers)
|
|
|
|
del self.awaiting_answers[id_]
|
|
|
|
elif self.awaiting_answers[id_][0] == PRIVACY_ARRIVED:
|
|
|
|
del self.awaiting_answers[id_]
|
|
|
|
if iq_obj.getType() != 'error':
|
|
|
|
for list_ in iq_obj.getQueryPayload():
|
|
|
|
if list_.getName() == 'default':
|
|
|
|
self.privacy_default_list = list_.getAttr('name')
|
|
|
|
self.get_privacy_list(self.privacy_default_list)
|
|
|
|
break
|
|
|
|
# Ask metacontacts before roster
|
|
|
|
self.get_metacontacts()
|
|
|
|
else:
|
|
|
|
# That should never happen, but as it's blocking in the
|
|
|
|
# connection process, we don't take the risk
|
|
|
|
self.privacy_rules_supported = False
|
|
|
|
self._continue_connection_request_privacy()
|
|
|
|
elif self.awaiting_answers[id_][0] == PEP_CONFIG:
|
|
|
|
del self.awaiting_answers[id_]
|
|
|
|
if iq_obj.getType() == 'error':
|
|
|
|
return
|
|
|
|
if not iq_obj.getTag('pubsub'):
|
|
|
|
return
|
|
|
|
conf = iq_obj.getTag('pubsub').getTag('configure')
|
|
|
|
if not conf:
|
|
|
|
return
|
|
|
|
node = conf.getAttr('node')
|
|
|
|
form_tag = conf.getTag('x', namespace=nbxmpp.NS_DATA)
|
|
|
|
if form_tag:
|
|
|
|
form = dataforms.ExtendForm(node=form_tag)
|
|
|
|
app.nec.push_incoming_event(PEPConfigReceivedEvent(None,
|
|
|
|
conn=self, node=node, form=form))
|
|
|
|
|
2010-10-04 13:51:42 +02:00
|
|
|
def _nec_iq_error_received(self, obj):
|
2010-09-08 19:55:19 +02:00
|
|
|
if obj.conn.name != self.name:
|
2010-07-20 16:53:07 +02:00
|
|
|
return
|
2013-07-30 20:09:52 +02:00
|
|
|
if obj.id_ in self.disco_items_ids:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(AgentItemsErrorReceivedEvent(None,
|
2013-07-30 20:09:52 +02:00
|
|
|
conn=self, stanza=obj.stanza))
|
|
|
|
return True
|
|
|
|
if obj.id_ in self.disco_info_ids:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(AgentInfoErrorReceivedEvent(None,
|
2013-07-30 20:09:52 +02:00
|
|
|
conn=self, stanza=obj.stanza))
|
|
|
|
return True
|
2010-04-08 01:20:17 +02:00
|
|
|
|
2010-06-07 19:11:44 +02:00
|
|
|
def _SecLabelCB(self, con, iq_obj):
|
|
|
|
"""
|
|
|
|
Security Label callback, used for catalogues.
|
|
|
|
"""
|
|
|
|
log.debug('SecLabelCB')
|
|
|
|
query = iq_obj.getTag('catalog')
|
|
|
|
to = query.getAttr('to')
|
2011-10-07 17:57:24 +02:00
|
|
|
items = query.getTags('item')
|
2010-06-07 19:11:44 +02:00
|
|
|
labels = {}
|
|
|
|
ll = []
|
2011-10-13 18:04:43 +02:00
|
|
|
default = None
|
2010-06-07 19:11:44 +02:00
|
|
|
for item in items:
|
2011-10-07 17:57:24 +02:00
|
|
|
label = item.getAttr('selector')
|
|
|
|
labels[label] = item.getTag('securitylabel')
|
2010-06-07 19:11:44 +02:00
|
|
|
ll.append(label)
|
2011-10-13 18:04:43 +02:00
|
|
|
if item.getAttr('default') == 'true':
|
|
|
|
default = label
|
2010-06-07 19:11:44 +02:00
|
|
|
if to not in self.seclabel_catalogues:
|
2011-10-13 18:04:43 +02:00
|
|
|
self.seclabel_catalogues[to] = [[], None, None, None]
|
2010-06-07 19:11:44 +02:00
|
|
|
self.seclabel_catalogues[to][1] = labels
|
|
|
|
self.seclabel_catalogues[to][2] = ll
|
2011-10-13 18:04:43 +02:00
|
|
|
self.seclabel_catalogues[to][3] = default
|
2010-06-07 19:11:44 +02:00
|
|
|
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:
|
2015-03-01 15:07:14 +01:00
|
|
|
self.seclabel_catalogues[to] = [[], None, None, None]
|
2010-06-07 19:11:44 +02:00
|
|
|
self.seclabel_catalogues[to][0].append(callback)
|
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def _rosterSetCB(self, con, iq_obj):
|
|
|
|
log.debug('rosterSetCB')
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(RosterSetReceivedEvent(None, conn=self,
|
2010-10-18 22:05:41 +02:00
|
|
|
stanza=iq_obj))
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2010-08-23 14:35:03 +02:00
|
|
|
def _nec_roster_set_received(self, obj):
|
2010-08-24 08:26:17 +02:00
|
|
|
if obj.conn.name != self.name:
|
|
|
|
return
|
2010-08-23 14:35:03 +02:00
|
|
|
for jid in obj.items:
|
|
|
|
item = obj.items[jid]
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(RosterInfoEvent(None, conn=self,
|
2010-10-06 21:11:23 +02:00
|
|
|
jid=jid, nickname=item['name'], sub=item['sub'],
|
|
|
|
ask=item['ask'], groups=item['groups']))
|
2017-08-13 13:18:56 +02:00
|
|
|
account_jid = app.get_jid_from_account(self.name)
|
|
|
|
app.logger.add_or_update_contact(account_jid, jid, item['name'],
|
2010-08-23 14:35:03 +02:00
|
|
|
item['sub'], item['ask'], item['groups'])
|
|
|
|
if obj.version:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.config.set_per('accounts', self.name, 'roster_version',
|
2010-08-23 14:35:03 +02:00
|
|
|
obj.version)
|
|
|
|
|
2018-07-03 00:10:55 +02:00
|
|
|
def _messageCB(self, con, stanza):
|
2010-02-08 15:08:40 +01:00
|
|
|
"""
|
|
|
|
Called when we receive a message
|
|
|
|
"""
|
2018-07-05 21:09:55 +02:00
|
|
|
|
|
|
|
# Check if a child of the message contains any
|
|
|
|
# of these namespaces, so we dont execute the
|
|
|
|
# message handler for them.
|
|
|
|
# They have defined their own message handlers
|
|
|
|
# but nbxmpp executes less common handlers last
|
|
|
|
if self._message_namespaces & set(stanza.getProperties()):
|
2018-07-03 00:10:55 +02:00
|
|
|
return
|
2010-02-08 15:08:40 +01:00
|
|
|
log.debug('MessageCB')
|
2010-04-08 01:20:17 +02:00
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(NetworkEvent('raw-message-received',
|
2018-07-03 00:10:55 +02:00
|
|
|
conn=self, stanza=stanza, account=self.name))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2010-10-18 22:05:41 +02:00
|
|
|
def _dispatch_gc_msg_with_captcha(self, stanza, msg_obj):
|
|
|
|
msg_obj.stanza = stanza
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(GcMessageReceivedEvent(None,
|
2010-10-18 22:05:41 +02:00
|
|
|
conn=self, msg_obj=msg_obj))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2010-07-02 00:25:08 +02:00
|
|
|
def _on_bob_received(self, conn, result, cid):
|
|
|
|
"""
|
|
|
|
Called when we receive BoB data
|
|
|
|
"""
|
|
|
|
if cid not in self.awaiting_cids:
|
|
|
|
return
|
|
|
|
|
|
|
|
if result.getType() == 'result':
|
2017-08-23 20:15:32 +02:00
|
|
|
data = result.getTags('data', namespace=nbxmpp.NS_BOB)
|
2010-07-02 00:25:08 +02:00
|
|
|
if data.getAttr('cid') == cid:
|
|
|
|
for func in self.awaiting_cids[cid]:
|
|
|
|
cb = func[0]
|
|
|
|
args = func[1]
|
|
|
|
pos = func[2]
|
|
|
|
bob_data = data.getData()
|
|
|
|
def recurs(node, cid, data):
|
|
|
|
if node.getData() == 'cid:' + cid:
|
|
|
|
node.setData(data)
|
|
|
|
else:
|
|
|
|
for child in node.getChildren():
|
|
|
|
recurs(child, cid, data)
|
|
|
|
recurs(args[pos], cid, bob_data)
|
|
|
|
cb(*args)
|
|
|
|
del self.awaiting_cids[cid]
|
|
|
|
return
|
|
|
|
|
|
|
|
# An error occured, call callback without modifying data.
|
|
|
|
for func in self.awaiting_cids[cid]:
|
|
|
|
cb = func[0]
|
|
|
|
args = func[1]
|
|
|
|
cb(*args)
|
|
|
|
del self.awaiting_cids[cid]
|
|
|
|
|
|
|
|
def get_bob_data(self, cid, to, callback, args, position):
|
|
|
|
"""
|
|
|
|
Request for BoB (XEP-0231) and when data will arrive, call callback
|
|
|
|
with given args, after having replaced cid by it's data in
|
|
|
|
args[position]
|
|
|
|
"""
|
|
|
|
if cid in self.awaiting_cids:
|
|
|
|
self.awaiting_cids[cid].appends((callback, args, position))
|
|
|
|
else:
|
|
|
|
self.awaiting_cids[cid] = [(callback, args, position)]
|
2012-12-09 21:37:51 +01:00
|
|
|
iq = nbxmpp.Iq(to=to, typ='get')
|
2010-07-02 00:25:08 +02:00
|
|
|
data = iq.addChild(name='data', attrs={'cid': cid},
|
2012-12-09 21:37:51 +01:00
|
|
|
namespace=nbxmpp.NS_BOB)
|
2010-07-02 00:25:08 +02:00
|
|
|
self.connection.SendAndCallForResponse(iq, self._on_bob_received,
|
|
|
|
{'cid': cid})
|
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def _presenceCB(self, con, prs):
|
|
|
|
"""
|
|
|
|
Called when we receive a presence
|
|
|
|
"""
|
2010-09-17 12:41:30 +02:00
|
|
|
log.debug('PresenceCB')
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(NetworkEvent('raw-pres-received',
|
2010-10-18 22:05:41 +02:00
|
|
|
conn=self, stanza=prs))
|
2010-04-08 01:20:17 +02:00
|
|
|
|
2010-10-04 10:56:34 +02:00
|
|
|
def _nec_subscribe_presence_received(self, obj):
|
|
|
|
account = obj.conn.name
|
|
|
|
if account != self.name:
|
2010-02-08 15:08:40 +01:00
|
|
|
return
|
2017-08-13 13:18:56 +02:00
|
|
|
if app.jid_is_transport(obj.fjid) and obj.fjid in \
|
2010-10-04 10:56:34 +02:00
|
|
|
self.agent_registrations:
|
|
|
|
self.agent_registrations[obj.fjid]['sub_received'] = True
|
|
|
|
if not self.agent_registrations[obj.fjid]['roster_push']:
|
|
|
|
# We'll reply after roster push result
|
|
|
|
return True
|
2017-08-13 13:18:56 +02:00
|
|
|
if app.config.get_per('accounts', self.name, 'autoauth') or \
|
|
|
|
app.jid_is_transport(obj.fjid) or obj.jid in self.jids_for_auto_auth \
|
2010-10-04 10:56:34 +02:00
|
|
|
or obj.transport_auto_auth:
|
|
|
|
if self.connection:
|
2012-12-16 23:53:32 +01:00
|
|
|
p = nbxmpp.Presence(obj.fjid, 'subscribed')
|
2010-10-04 10:56:34 +02:00
|
|
|
p = self.add_sha(p)
|
|
|
|
self.connection.send(p)
|
2017-08-13 13:18:56 +02:00
|
|
|
if app.jid_is_transport(obj.fjid) or obj.transport_auto_auth:
|
2010-10-04 10:56:34 +02:00
|
|
|
#TODO!?!?
|
|
|
|
#self.show = 'offline'
|
|
|
|
#self.status = 'offline'
|
|
|
|
#emit NOTIFY
|
|
|
|
pass
|
|
|
|
if obj.transport_auto_auth:
|
|
|
|
self.automatically_added.append(obj.jid)
|
|
|
|
self.request_subscription(obj.jid, name=obj.user_nick)
|
|
|
|
return True
|
|
|
|
if not obj.status:
|
|
|
|
obj.status = _('I would like to add you to my roster.')
|
|
|
|
|
|
|
|
def _nec_subscribed_presence_received(self, obj):
|
|
|
|
account = obj.conn.name
|
|
|
|
if account != self.name:
|
2010-02-08 15:08:40 +01:00
|
|
|
return
|
2010-10-04 10:56:34 +02:00
|
|
|
# BE CAREFUL: no con.updateRosterItem() in a callback
|
|
|
|
if obj.jid in self.automatically_added:
|
|
|
|
self.automatically_added.remove(obj.jid)
|
|
|
|
return True
|
|
|
|
# detect a subscription loop
|
|
|
|
if obj.jid not in self.subscribed_events:
|
|
|
|
self.subscribed_events[obj.jid] = []
|
|
|
|
self.subscribed_events[obj.jid].append(time_time())
|
|
|
|
block = False
|
|
|
|
if len(self.subscribed_events[obj.jid]) > 5:
|
|
|
|
if time_time() - self.subscribed_events[obj.jid][0] < 5:
|
|
|
|
block = True
|
|
|
|
self.subscribed_events[obj.jid] = \
|
|
|
|
self.subscribed_events[obj.jid][1:]
|
|
|
|
if block:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.config.set_per('account', self.name, 'dont_ack_subscription',
|
2010-10-04 10:56:34 +02:00
|
|
|
True)
|
|
|
|
return True
|
|
|
|
|
|
|
|
def _nec_subscribed_presence_received_end(self, obj):
|
|
|
|
account = obj.conn.name
|
|
|
|
if account != self.name:
|
2010-02-08 15:08:40 +01:00
|
|
|
return
|
2017-08-13 13:18:56 +02:00
|
|
|
if not app.config.get_per('accounts', account,
|
2010-10-04 10:56:34 +02:00
|
|
|
'dont_ack_subscription'):
|
|
|
|
self.ack_subscribed(obj.jid)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2010-10-04 10:56:34 +02:00
|
|
|
def _nec_unsubscribed_presence_received(self, obj):
|
|
|
|
account = obj.conn.name
|
|
|
|
if account != self.name:
|
|
|
|
return
|
|
|
|
# detect a unsubscription loop
|
|
|
|
if obj.jid not in self.subscribed_events:
|
|
|
|
self.subscribed_events[obj.jid] = []
|
|
|
|
self.subscribed_events[obj.jid].append(time_time())
|
|
|
|
block = False
|
|
|
|
if len(self.subscribed_events[obj.jid]) > 5:
|
|
|
|
if time_time() - self.subscribed_events[obj.jid][0] < 5:
|
|
|
|
block = True
|
|
|
|
self.subscribed_events[obj.jid] = \
|
|
|
|
self.subscribed_events[obj.jid][1:]
|
|
|
|
if block:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.config.set_per('account', self.name, 'dont_ack_subscription',
|
2010-10-04 10:56:34 +02:00
|
|
|
True)
|
|
|
|
return True
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2010-10-04 10:56:34 +02:00
|
|
|
def _nec_unsubscribed_presence_received_end(self, obj):
|
|
|
|
account = obj.conn.name
|
|
|
|
if account != self.name:
|
|
|
|
return
|
2017-08-13 13:18:56 +02:00
|
|
|
if not app.config.get_per('accounts', account,
|
2010-10-04 10:56:34 +02:00
|
|
|
'dont_ack_subscription'):
|
|
|
|
self.ack_unsubscribed(obj.jid)
|
|
|
|
|
2010-11-09 21:52:22 +01:00
|
|
|
def _nec_agent_removed(self, obj):
|
|
|
|
if obj.conn.name != self.name:
|
|
|
|
return
|
|
|
|
for jid in obj.jid_list:
|
|
|
|
log.debug('Removing contact %s due to unregistered transport %s' % \
|
2010-12-22 11:21:57 +01:00
|
|
|
(jid, obj.agent))
|
2010-11-09 21:52:22 +01:00
|
|
|
self.unsubscribe(jid)
|
|
|
|
# Transport contacts can't have 2 resources
|
2017-08-13 13:18:56 +02:00
|
|
|
if jid in app.to_be_removed[self.name]:
|
2010-11-09 21:52:22 +01:00
|
|
|
# This way we'll really remove it
|
2017-08-13 13:18:56 +02:00
|
|
|
app.to_be_removed[self.name].remove(jid)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _MucOwnerCB(self, con, iq_obj):
|
|
|
|
log.debug('MucOwnerCB')
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(MucOwnerReceivedEvent(None, conn=self,
|
2010-10-18 22:05:41 +02:00
|
|
|
stanza=iq_obj))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _MucAdminCB(self, con, iq_obj):
|
|
|
|
log.debug('MucAdminCB')
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(MucAdminReceivedEvent(None, conn=self,
|
2010-10-18 22:05:41 +02:00
|
|
|
stanza=iq_obj))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _PrivacySetCB(self, con, iq_obj):
|
|
|
|
"""
|
|
|
|
Privacy lists (XEP 016)
|
|
|
|
|
|
|
|
A list has been set.
|
|
|
|
"""
|
|
|
|
log.debug('PrivacySetCB')
|
|
|
|
if not self.connection or self.connected < 2:
|
|
|
|
return
|
|
|
|
result = iq_obj.buildReply('result')
|
|
|
|
q = result.getTag('query')
|
|
|
|
if q:
|
|
|
|
result.delChild(q)
|
|
|
|
self.connection.send(result)
|
2017-01-27 23:48:27 +01:00
|
|
|
|
|
|
|
for list_ in iq_obj.getQueryPayload():
|
|
|
|
if list_.getName() == 'list':
|
|
|
|
self.get_privacy_list(list_.getAttr('name'))
|
|
|
|
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _getRoster(self):
|
|
|
|
log.debug('getRosterCB')
|
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
self.connection.getRoster(self._on_roster_set)
|
2017-08-13 13:18:56 +02:00
|
|
|
self.discoverItems(app.config.get_per('accounts', self.name,
|
2010-10-06 21:11:23 +02:00
|
|
|
'hostname'), id_prefix='Gajim_')
|
2017-08-13 13:18:56 +02:00
|
|
|
if app.config.get_per('accounts', self.name, 'use_ft_proxies'):
|
2010-02-08 15:08:40 +01:00
|
|
|
self.discover_ft_proxies()
|
|
|
|
|
|
|
|
def discover_ft_proxies(self):
|
2017-08-13 13:18:56 +02:00
|
|
|
cfg_proxies = app.config.get_per('accounts', self.name,
|
2010-10-06 21:11:23 +02:00
|
|
|
'file_transfer_proxies')
|
2017-08-13 13:18:56 +02:00
|
|
|
our_jid = helpers.parse_jid(app.get_jid_from_account(self.name) + \
|
2010-08-29 20:22:20 +02:00
|
|
|
'/' + self.server_resource)
|
2017-08-13 13:18:56 +02:00
|
|
|
testit = app.config.get_per('accounts', self.name,
|
2011-10-23 20:26:28 +02:00
|
|
|
'test_ft_proxies_on_startup')
|
2010-02-08 15:08:40 +01:00
|
|
|
if cfg_proxies:
|
|
|
|
proxies = [e.strip() for e in cfg_proxies.split(',')]
|
|
|
|
for proxy in proxies:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.proxy65_manager.resolve(proxy, self.connection, our_jid,
|
2011-10-23 20:26:28 +02:00
|
|
|
testit=testit)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2013-06-02 22:02:43 +02:00
|
|
|
def discover_servers(self):
|
|
|
|
if not self.connection:
|
|
|
|
return
|
|
|
|
servers = []
|
2017-08-13 13:18:56 +02:00
|
|
|
for c in app.contacts.iter_contacts(self.name):
|
|
|
|
s = app.get_server_from_jid(c.jid)
|
|
|
|
if s not in servers and s not in app.transport_type:
|
2013-06-02 22:02:43 +02:00
|
|
|
servers.append(s)
|
|
|
|
for s in servers:
|
|
|
|
self.discoverInfo(s)
|
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def _on_roster_set(self, roster):
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(RosterReceivedEvent(None, conn=self,
|
2010-08-29 20:22:20 +02:00
|
|
|
xmpp_roster=roster))
|
|
|
|
|
|
|
|
def _nec_roster_received(self, obj):
|
|
|
|
if obj.conn.name != self.name:
|
|
|
|
return
|
2017-08-13 13:18:56 +02:00
|
|
|
our_jid = app.get_jid_from_account(self.name)
|
2017-09-16 11:49:31 +02:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
if self.connected > 1 and self.continue_connect_info:
|
|
|
|
msg = self.continue_connect_info[1]
|
|
|
|
sign_msg = self.continue_connect_info[2]
|
|
|
|
signed = ''
|
|
|
|
send_first_presence = True
|
|
|
|
if sign_msg:
|
2010-10-06 21:11:23 +02:00
|
|
|
signed = self.get_signed_presence(msg,
|
|
|
|
self._send_first_presence)
|
2010-02-08 15:08:40 +01:00
|
|
|
if signed is None:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(GPGPasswordRequiredEvent(None,
|
2010-11-17 23:52:14 +01:00
|
|
|
conn=self, callback=self._send_first_presence))
|
2010-10-06 21:11:23 +02:00
|
|
|
# _send_first_presence will be called when user enter
|
|
|
|
# passphrase
|
2010-02-08 15:08:40 +01:00
|
|
|
send_first_presence = False
|
|
|
|
if send_first_presence:
|
|
|
|
self._send_first_presence(signed)
|
|
|
|
|
2010-08-29 20:22:20 +02:00
|
|
|
if obj.received_from_server:
|
2010-10-19 18:14:30 +02:00
|
|
|
for jid in obj.roster:
|
2017-08-13 13:18:56 +02:00
|
|
|
if jid != our_jid and app.jid_is_transport(jid) and \
|
|
|
|
not app.get_transport_name_from_jid(jid):
|
2010-10-19 18:14:30 +02:00
|
|
|
# we can't determine which iconset to use
|
|
|
|
self.discoverInfo(jid)
|
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
app.logger.replace_roster(self.name, obj.version, obj.roster)
|
2010-10-19 18:14:30 +02:00
|
|
|
|
2017-08-13 13:18:56 +02:00
|
|
|
for contact in app.contacts.iter_contacts(self.name):
|
2010-10-19 18:14:30 +02:00
|
|
|
if not contact.is_groupchat() and contact.jid not in obj.roster\
|
|
|
|
and contact.jid != our_jid:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(RosterInfoEvent(None,
|
2010-10-19 18:14:30 +02:00
|
|
|
conn=self, jid=contact.jid, nickname=None, sub=None,
|
|
|
|
ask=None, groups=()))
|
|
|
|
for jid, info in obj.roster.items():
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(RosterInfoEvent(None,
|
2010-10-19 18:14:30 +02:00
|
|
|
conn=self, jid=jid, nickname=info['name'],
|
|
|
|
sub=info['subscription'], ask=info['ask'],
|
2017-09-16 11:49:31 +02:00
|
|
|
groups=info['groups'], avatar_sha=info['avatar_sha']))
|
2010-04-08 01:20:17 +02:00
|
|
|
|
2010-10-06 21:11:23 +02:00
|
|
|
def _send_first_presence(self, signed=''):
|
2010-02-08 15:08:40 +01:00
|
|
|
show = self.continue_connect_info[0]
|
|
|
|
msg = self.continue_connect_info[1]
|
|
|
|
sign_msg = self.continue_connect_info[2]
|
|
|
|
if sign_msg and not signed:
|
|
|
|
signed = self.get_signed_presence(msg)
|
|
|
|
if signed is None:
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(BadGPGPassphraseEvent(None,
|
2010-11-15 16:50:54 +01:00
|
|
|
conn=self))
|
2010-02-08 15:08:40 +01:00
|
|
|
self.USE_GPG = False
|
|
|
|
signed = ''
|
2017-08-13 13:18:56 +02:00
|
|
|
self.connected = app.SHOW_LIST.index(show)
|
2010-02-08 15:08:40 +01:00
|
|
|
sshow = helpers.get_xmpp_show(show)
|
|
|
|
# send our presence
|
|
|
|
if show == 'invisible':
|
|
|
|
self.send_invisible_presence(msg, signed, True)
|
|
|
|
return
|
|
|
|
if show not in ['offline', 'online', 'chat', 'away', 'xa', 'dnd']:
|
|
|
|
return
|
2017-08-13 13:18:56 +02:00
|
|
|
priority = app.get_priority(self.name, sshow)
|
2012-12-09 21:37:51 +01:00
|
|
|
p = nbxmpp.Presence(typ=None, priority=priority, show=sshow)
|
2010-02-08 15:08:40 +01:00
|
|
|
if msg:
|
|
|
|
p.setStatus(msg)
|
|
|
|
if signed:
|
2012-12-09 21:37:51 +01:00
|
|
|
p.setTag(nbxmpp.NS_SIGNED + ' x').setData(signed)
|
2017-11-15 22:28:57 +01:00
|
|
|
p = self.add_sha(p)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
if self.connection:
|
|
|
|
self.connection.send(p)
|
|
|
|
self.priority = priority
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(OurShowEvent(None, conn=self,
|
2010-11-06 10:04:41 +01:00
|
|
|
show=show))
|
2010-02-08 15:08:40 +01:00
|
|
|
if self.vcard_supported:
|
|
|
|
# ask our VCard
|
2018-06-30 19:23:10 +02:00
|
|
|
self.get_module('VCardTemp').request_vcard()
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2018-07-01 02:16:33 +02:00
|
|
|
# Get bookmarks
|
|
|
|
self.get_module('Bookmarks').get_bookmarks()
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
# Get annotations from private namespace
|
2018-06-25 20:04:56 +02:00
|
|
|
self.get_module('Annotations').get_annotations()
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
# Inform GUI we just signed in
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(SignedInEvent(None, conn=self))
|
2018-07-03 00:10:55 +02:00
|
|
|
self.get_module('PEP').send_stored_publish()
|
2010-02-08 15:08:40 +01:00
|
|
|
self.continue_connect_info = None
|
|
|
|
|
2010-08-11 08:44:49 +02:00
|
|
|
def _PubkeyGetCB(self, con, iq_obj):
|
2010-08-08 10:42:30 +02:00
|
|
|
log.info('PubkeyGetCB')
|
2010-08-11 08:44:49 +02:00
|
|
|
jid_from = helpers.get_full_jid_from_iq(iq_obj)
|
|
|
|
sid = iq_obj.getAttr('id')
|
|
|
|
jingle_xtls.send_cert(con, jid_from, sid)
|
2012-12-09 21:37:51 +01:00
|
|
|
raise nbxmpp.NodeProcessed
|
2010-08-11 08:44:49 +02:00
|
|
|
|
|
|
|
def _PubkeyResultCB(self, con, iq_obj):
|
2010-08-08 10:42:30 +02:00
|
|
|
log.info('PubkeyResultCB')
|
2010-08-11 08:44:49 +02:00
|
|
|
jid_from = helpers.get_full_jid_from_iq(iq_obj)
|
|
|
|
jingle_xtls.handle_new_cert(con, iq_obj, jid_from)
|
2010-02-08 15:08:40 +01:00
|
|
|
|
2014-08-13 22:46:18 +02:00
|
|
|
def _BlockingSetCB(self, con, iq_obj):
|
|
|
|
log.debug('_BlockingSetCB')
|
2017-10-15 15:53:28 +02:00
|
|
|
app.nec.push_incoming_event(
|
|
|
|
BlockingEvent(None, conn=self, stanza=iq_obj))
|
|
|
|
reply = nbxmpp.Iq(typ='result', attrs={'id': iq_obj.getID()},
|
|
|
|
to=iq_obj.getFrom(), frm=iq_obj.getTo(), xmlns=None)
|
|
|
|
self.connection.send(reply)
|
2014-08-13 22:46:18 +02:00
|
|
|
raise nbxmpp.NodeProcessed
|
|
|
|
|
2017-10-15 18:03:41 +02:00
|
|
|
def _BlockingResultCB(self, con, iq_obj):
|
|
|
|
log.debug('_BlockingResultCB')
|
|
|
|
app.nec.push_incoming_event(
|
|
|
|
BlockingEvent(None, conn=self, stanza=iq_obj))
|
|
|
|
raise nbxmpp.NodeProcessed
|
|
|
|
|
2014-08-13 22:46:18 +02:00
|
|
|
def _nec_blocking(self, obj):
|
|
|
|
if obj.conn.name != self.name:
|
|
|
|
return
|
|
|
|
if obj.unblock_all:
|
|
|
|
self.blocked_contacts = []
|
2017-10-15 18:03:41 +02:00
|
|
|
elif obj.blocklist:
|
|
|
|
self.blocked_contacts = obj.blocklist
|
2014-08-13 22:46:18 +02:00
|
|
|
else:
|
|
|
|
for jid in obj.blocked_jids:
|
|
|
|
if jid not in self.blocked_contacts:
|
|
|
|
self.blocked_contacts.append(jid)
|
2017-10-15 21:32:16 +02:00
|
|
|
contact_list = app.contacts.get_contacts(self.name, jid)
|
|
|
|
for contact in contact_list:
|
|
|
|
contact.show = 'offline'
|
2014-08-13 22:46:18 +02:00
|
|
|
for jid in obj.unblocked_jids:
|
|
|
|
if jid in self.blocked_contacts:
|
|
|
|
self.blocked_contacts.remove(jid)
|
2017-10-15 20:22:25 +02:00
|
|
|
# Send a presence Probe to get the current Status
|
|
|
|
probe = nbxmpp.Presence(jid, 'probe', frm=self.get_own_jid())
|
|
|
|
self.connection.send(probe)
|
2014-08-13 22:46:18 +02:00
|
|
|
|
2012-04-21 23:52:24 +02:00
|
|
|
def _nec_stream_other_host_received(self, obj):
|
|
|
|
if obj.conn.name != self.name:
|
|
|
|
return
|
|
|
|
self.redirected = obj.redirected
|
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def _StreamCB(self, con, obj):
|
2012-04-21 23:52:24 +02:00
|
|
|
log.debug('StreamCB')
|
2017-08-13 13:18:56 +02:00
|
|
|
app.nec.push_incoming_event(StreamReceivedEvent(None,
|
2012-06-16 13:51:54 +02:00
|
|
|
conn=self, stanza=obj))
|
2010-02-08 15:08:40 +01:00
|
|
|
|
|
|
|
def _register_handlers(self, con, con_type):
|
|
|
|
# try to find another way to register handlers in each class
|
|
|
|
# that defines handlers
|
|
|
|
con.RegisterHandler('message', self._messageCB)
|
|
|
|
con.RegisterHandler('presence', self._presenceCB)
|
2012-12-09 21:37:51 +01:00
|
|
|
con.RegisterHandler('iq', self._rosterSetCB, 'set', nbxmpp.NS_ROSTER)
|
|
|
|
con.RegisterHandler('iq', self._siSetCB, 'set', nbxmpp.NS_SI)
|
|
|
|
con.RegisterHandler('iq', self._siErrorCB, 'error', nbxmpp.NS_SI)
|
|
|
|
con.RegisterHandler('iq', self._siResultCB, 'result', nbxmpp.NS_SI)
|
|
|
|
con.RegisterHandler('iq', self._discoGetCB, 'get', nbxmpp.NS_DISCO)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._bytestreamSetCB, 'set',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_BYTESTREAM)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._bytestreamResultCB, 'result',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_BYTESTREAM)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._bytestreamErrorCB, 'error',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_BYTESTREAM)
|
2010-08-17 15:42:34 +02:00
|
|
|
con.RegisterHandlerOnce('iq', self.IBBAllIqHandler)
|
2012-12-09 21:37:51 +01:00
|
|
|
con.RegisterHandler('iq', self.IBBIqHandler, ns=nbxmpp.NS_IBB)
|
|
|
|
con.RegisterHandler('message', self.IBBMessageHandler, ns=nbxmpp.NS_IBB)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._DiscoverItemsCB, 'result',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_DISCO_ITEMS)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._DiscoverItemsErrorCB, 'error',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_DISCO_ITEMS)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._DiscoverInfoCB, 'result',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_DISCO_INFO)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._DiscoverInfoErrorCB, 'error',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_DISCO_INFO)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._MucOwnerCB, 'result',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_MUC_OWNER)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._MucAdminCB, 'result',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_MUC_ADMIN)
|
2010-06-07 19:11:44 +02:00
|
|
|
con.RegisterHandler('iq', self._SecLabelCB, 'result',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_SECLABEL_CATALOG)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._CommandExecuteCB, 'set',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_COMMANDS)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._DiscoverInfoGetCB, 'get',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_DISCO_INFO)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._DiscoverItemsGetCB, 'get',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_DISCO_ITEMS)
|
|
|
|
con.RegisterHandler('iq', self._PrivacySetCB, 'set', nbxmpp.NS_PRIVACY)
|
2017-04-18 17:52:17 +02:00
|
|
|
con.RegisterHandler('iq', self._ArchiveCB, ns=nbxmpp.NS_MAM_1)
|
|
|
|
con.RegisterHandler('iq', self._ArchiveCB, ns=nbxmpp.NS_MAM_2)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._JingleCB, 'result')
|
|
|
|
con.RegisterHandler('iq', self._JingleCB, 'error')
|
2012-12-09 21:37:51 +01:00
|
|
|
con.RegisterHandler('iq', self._JingleCB, 'set', nbxmpp.NS_JINGLE)
|
2010-02-08 15:08:40 +01:00
|
|
|
con.RegisterHandler('iq', self._ErrorCB, 'error')
|
|
|
|
con.RegisterHandler('iq', self._IqCB)
|
|
|
|
con.RegisterHandler('iq', self._ResultCB, 'result')
|
2012-04-21 23:52:24 +02:00
|
|
|
con.RegisterHandler('unknown', self._StreamCB,
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_XMPP_STREAMS, xmlns=nbxmpp.NS_STREAMS)
|
2012-04-21 23:52:24 +02:00
|
|
|
con.RegisterHandler('iq', self._PubkeyGetCB, 'get',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_PUBKEY_PUBKEY)
|
2012-04-21 23:52:24 +02:00
|
|
|
con.RegisterHandler('iq', self._PubkeyResultCB, 'result',
|
2012-12-09 21:37:51 +01:00
|
|
|
nbxmpp.NS_PUBKEY_PUBKEY)
|
2014-08-13 22:46:18 +02:00
|
|
|
con.RegisterHandler('iq', self._BlockingSetCB, 'set',
|
|
|
|
nbxmpp.NS_BLOCKING)
|
2017-10-15 18:03:41 +02:00
|
|
|
con.RegisterHandler('iq', self._BlockingResultCB, 'result',
|
|
|
|
nbxmpp.NS_BLOCKING)
|
2018-06-24 17:00:13 +02:00
|
|
|
|
2018-07-03 00:10:55 +02:00
|
|
|
for handler in self.get_module_handlers():
|
|
|
|
con.RegisterHandler(*handler)
|