diff --git a/gajim/common/connection_handlers_events.py b/gajim/common/connection_handlers_events.py index 008caa048..0c2ea00a0 100644 --- a/gajim/common/connection_handlers_events.py +++ b/gajim/common/connection_handlers_events.py @@ -42,7 +42,6 @@ from gajim.common.const import KindConstant, SSLError from gajim.common.pep import SUPPORTED_PERSONAL_USER_EVENTS from gajim.common.jingle_transport import JingleTransportSocks5 from gajim.common.file_props import FilesProp -from gajim.common.nec import NetworkEvent log = logging.getLogger('gajim.c.connection_handlers_events') @@ -643,9 +642,6 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): def generate(self): self.conn = self.base_event.conn self.stanza = self.base_event.stanza - self.get_id() - self.forwarded = False - self.sent = False self.encrypted = False self.self_message = None self.muc_pm = None @@ -659,6 +655,11 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): self.stanza.getFrom()) return + from gajim.common.modules.carbons import parse_carbon + self.stanza, self.sent, self.forwarded = parse_carbon(self.conn, + self.stanza) + + self.get_id() try: self.get_jid_resource() except helpers.InvalidFormat: @@ -696,47 +697,6 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): return self.jid = app.get_jid_without_resource(self.fjid) - carbon_marker = self.stanza.getTag('sent', namespace=nbxmpp.NS_CARBONS) - if not carbon_marker: - carbon_marker = self.stanza.getTag('received', - namespace=nbxmpp.NS_CARBONS) - # Be sure it comes from one of our resource, else ignore forward element - if carbon_marker and self.jid == app.get_jid_from_account(account): - forward_tag = carbon_marker.getTag('forwarded', - namespace=nbxmpp.NS_FORWARD) - if forward_tag: - msg = forward_tag.getTag('message') - self.stanza = nbxmpp.Message(node=msg) - self.get_id() - if carbon_marker.getName() == 'sent': - to = self.stanza.getTo() - frm = self.stanza.getFrom() - if not frm: - frm = app.get_jid_from_account(account) - self.stanza.setTo(frm) - if not to: - to = app.get_jid_from_account(account) - self.stanza.setFrom(to) - self.sent = True - elif carbon_marker.getName() == 'received': - full_frm = str(self.stanza.getFrom()) - frm = app.get_jid_without_resource(full_frm) - if frm == app.get_jid_from_account(account): - # Drop 'received' Carbons from ourself, we already - # got the message with the 'sent' Carbon or via the - # message itself - log.info( - 'Drop "received"-Carbon from ourself: %s' - % full_frm) - return - try: - self.get_jid_resource() - except helpers.InvalidFormat: - log.warning('Invalid JID: %s, ignoring it', - self.stanza.getFrom()) - return - self.forwarded = True - # Mediated invitation? muc_user = self.stanza.getTag('x', namespace=nbxmpp.NS_MUC_USER) if muc_user: diff --git a/gajim/common/modules/carbons.py b/gajim/common/modules/carbons.py new file mode 100644 index 000000000..99d576406 --- /dev/null +++ b/gajim/common/modules/carbons.py @@ -0,0 +1,77 @@ +# 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-0280: Message Carbons + +import logging + +import nbxmpp + +log = logging.getLogger('gajim.c.m.carbons') + + +def parse_carbon(con, stanza): + carbon = stanza.getTag( + 'received', namespace=nbxmpp.NS_CARBONS, protocol=True) + if carbon is None: + carbon = stanza.getTag( + 'sent', namespace=nbxmpp.NS_CARBONS, protocol=True) + if carbon is None: + return stanza, False, False + + # Carbon must be from our bare jid + own_jid = con.get_own_jid() + if not stanza.getFrom().bareMatch(own_jid): + log.warning('Ignore message because from is invalid %s', + stanza.getFrom()) + raise nbxmpp.NodeProcessed + + forwarded = carbon.getTag('forwarded', + namespace=nbxmpp.NS_FORWARD, + protocol=True) + message = forwarded.getTag('message', protocol=True) + + type_ = carbon.getName() + to = message.getTo() + frm = message.getFrom() + log.info('Received type: %s, from: %s, to: %s', type_, to, frm) + + if type_ == 'received': + sent = False + if message.getFrom().bareMatch(own_jid): + # Drop 'received' Carbons from ourself, we already + # got the message with the 'sent' Carbon or via the + # message itself + log.info('Drop "received"-Carbon from ourself: %s') + raise nbxmpp.NodeProcessed + if message.getTag('x', namespace=nbxmpp.NS_MUC_USER) is not None: + # A MUC broadcasts messages sent to us to all resources + # there is no need to process carbons for these messages + log.info('Drop MUC-PM "received"-Carbon') + raise nbxmpp.NodeProcessed + + elif type_ == 'sent': + if frm is None: + frm = own_jid.getStripped() + message.setTo(frm) + if to is None: + to = own_jid.getStripped() + message.setFrom(to) + sent = True + + else: + log.warning('Ignore invalid carbon: %s', stanza) + raise nbxmpp.NodeProcessed + + return message, sent, True