Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
8eb805d2 by Philipp Hörist at 2018-12-21T12:07:15Z
Add jid validation
- - - - -
9da76c1b by Philipp Hörist at 2018-12-21T12:21:51Z
Move code into setup.cfg
- - - - -
960a3ef0 by Philipp Hörist at 2018-12-21T12:24:22Z
Update README.md
- - - - -
ec4c203b by Philipp Hörist at 2018-12-21T12:29:09Z
Use GPL v3 on new code
- - - - -
9 changed files:
- README.md
- nbxmpp/misc.py
- nbxmpp/modules/eme.py
- nbxmpp/modules/http_auth.py
- nbxmpp/protocol.py
- nbxmpp/smacks.py
- nbxmpp/util.py
- setup.cfg
- setup.py
Changes:
=====================================
README.md
=====================================
@@ -5,7 +5,7 @@ python-nbxmpp is a Python library that provides a way for Python applications to
## Features
* Asynchronous
- * Supports ANONYMOUS, EXTERNAL, GSSAPI, SCRAM-SHA-1, DIGEST-MD5, PLAIN, and X-MESSENGER-OAUTH2 authentication mechanisms.
+ * Supports ANONYMOUS, EXTERNAL, GSSAPI, SCRAM-SHA-1(PLUS), SCRAM-SHA-256(PLUS) and PLAIN authentication mechanisms.
* Supports connection via proxies
* Suppors TLS
* Supports [BOSH (XEP-0124)](https://xmpp.org/extensions/xep-0124.html)
=====================================
nbxmpp/misc.py
=====================================
@@ -4,7 +4,7 @@
#
# This program 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; either version 2
+# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
=====================================
nbxmpp/modules/eme.py
=====================================
@@ -4,7 +4,7 @@
#
# This program 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; either version 2
+# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
=====================================
nbxmpp/modules/http_auth.py
=====================================
@@ -4,7 +4,7 @@
#
# This program 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; either version 2
+# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
=====================================
nbxmpp/protocol.py
=====================================
@@ -650,6 +650,9 @@ class XMLNotWellFormed(StreamError):
class InvalidStanza(Exception):
pass
+class InvalidJid(Exception):
+ pass
+
stream_exceptions = {'bad-format': BadFormat,
'bad-namespace-prefix': BadNamespacePrefix,
'conflict': Conflict,
=====================================
nbxmpp/smacks.py
=====================================
@@ -4,7 +4,7 @@
#
# This program 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; either version 2
+# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
=====================================
nbxmpp/util.py
=====================================
@@ -4,7 +4,7 @@
#
# This program 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; either version 2
+# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -15,9 +15,19 @@
# You should have received a copy of the GNU General Public License
# along with this program; If not, see <http://www.gnu.org/licenses/>.
+import logging
+import socket
import base64
from collections import namedtuple
+import precis_i18n.codec
+
+from nbxmpp.protocol import JID
+from nbxmpp.protocol import InvalidJid
+from nbxmpp.stringprepare import nameprep
+
+log = logging.getLogger('nbxmpp.util')
+
StanzaHandler = namedtuple('StanzaHandler', 'name callback typ ns xmlns system priority')
StanzaHandler.__new__.__defaults__ = ('', '', None, False, 50)
@@ -84,3 +94,74 @@ def get_property_dict(name):
if name == 'iq':
return IqPropertyDict()
return PropertyBase()
+
+
+def validate_jid(jid_string):
+ jid = JID(jid_string)
+ return prep(jid.getNode(),
+ jid.getDomain(),
+ jid.getResource())
+
+
+def prep(user, server, resource):
+ """
+ Perform stringprep on all JID fragments and return the full jid
+ """
+
+ ip_address = False
+
+ try:
+ socket.inet_aton(server)
+ ip_address = True
+ except socket.error:
+ pass
+
+ if not ip_address and hasattr(socket, 'inet_pton'):
+ try:
+ socket.inet_pton(socket.AF_INET6, server.strip('[]'))
+ server = '[%s]' % server.strip('[]')
+ ip_address = True
+ except (socket.error, ValueError):
+ pass
+
+ if not ip_address:
+ if server is not None:
+ if server.endswith('.'): # RFC7622, 3.2
+ server = server[:-1]
+ if not server or len(server.encode('utf-8')) > 1023:
+ raise InvalidJid('Server must be between 1 and 1023 bytes')
+ try:
+ server = nameprep.prepare(server)
+ except UnicodeError:
+ raise InvalidJid('Invalid character in hostname')
+ else:
+ raise InvalidJid('Server address required')
+
+ if user is not None:
+ if not user or len(user.encode('utf-8')) > 1023:
+ raise InvalidJid('Username must be between 1 and 1023 bytes')
+ try:
+ user = user.encode('UsernameCaseMapped').decode('utf-8')
+ except UnicodeError:
+ raise InvalidJid('Invalid character in username')
+ else:
+ user = None
+
+ if resource is not None:
+ if not resource or len(resource.encode('utf-8')) > 1023:
+ raise InvalidJid('Resource must be between 1 and 1023 bytes')
+ try:
+ resource = resource.encode('OpaqueString').decode('utf-8')
+ except UnicodeError:
+ raise InvalidJid('Invalid character in resource')
+ else:
+ resource = None
+
+ if user:
+ if resource:
+ return '%s@%s/%s' % (user, server, resource)
+ return '%s@%s' % (user, server)
+
+ if resource:
+ return '%s/%s' % (server, resource)
+ return server
=====================================
setup.cfg
=====================================
@@ -1,2 +1,21 @@
[metadata]
+name = nbxmpp
+version = attr: nbxmpp.__version__
+description = Non blocking Jabber/XMPP module
+author = Yann Leboulanger, Philipp Hoerist
+author_email = gajim-devel(a)gajim.org
+url = http://dev.gajim.org/gajim/python-nbxmpp
license_file = COPYING
+license = GPL v3
+classifiers =
+ Programming Language :: Python :: 3
+
+[options]
+python_requires = >=3.5
+packages = find:
+install_requires =
+ precis-i18n>=1.0.0
+
+[options.packages.find]
+exclude =
+ test*
=====================================
setup.py
=====================================
@@ -2,11 +2,4 @@
from setuptools import setup
-setup(name='nbxmpp',
- version='0.9.90.2',
- description='Non blocking Jabber/XMPP module',
- author='Yann Leboulanger',
- author_email='asterix(a)lagaule.org',
- url='http://dev.gajim.org/gajim/python-nbxmpp',
- packages=['nbxmpp', 'nbxmpp.modules'],
- )
+setup()
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/compare/5bea073ba9ef04f5fa58e440a…
--
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/compare/5bea073ba9ef04f5fa58e440a…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
5bea073b by Philipp Hörist at 2018-12-21T11:34:54Z
Fix test
- - - - -
1 changed file:
- test/unit/test_xmpp_dispatcher_nb.py
Changes:
=====================================
test/unit/test_xmpp_dispatcher_nb.py
=====================================
@@ -8,6 +8,8 @@ from test import lib
from nbxmpp import dispatcher_nb
from nbxmpp import protocol
+from nbxmpp.protocol import JID
+
class TestDispatcherNB(unittest.TestCase):
'''
@@ -19,6 +21,7 @@ class TestDispatcherNB(unittest.TestCase):
# Setup mock client
self.client = Mock()
+ self.client.get_bound_jid.return_value = JID('test(a)test.test')
self.client.defaultNamespace = protocol.NS_CLIENT
self.client.Connection = Mock() # mock transport
self.con = self.client.Connection
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/commit/5bea073ba9ef04f5fa58e440ae…
--
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/commit/5bea073ba9ef04f5fa58e440ae…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
6016d303 by Philipp Hörist at 2018-12-21T06:37:34Z
Add EME (XEP-0380) module
- - - - -
af28de82 by Philipp Hörist at 2018-12-21T11:09:12Z
Add HTTPAuth (XEP-0070) module
- - - - -
6 changed files:
- nbxmpp/dispatcher_nb.py
- + nbxmpp/modules/__init__.py
- + nbxmpp/modules/eme.py
- + nbxmpp/modules/http_auth.py
- nbxmpp/util.py
- setup.py
Changes:
=====================================
nbxmpp/dispatcher_nb.py
=====================================
@@ -41,8 +41,10 @@ from nbxmpp.protocol import Protocol
from nbxmpp.protocol import Node
from nbxmpp.protocol import Error
from nbxmpp.protocol import ERR_FEATURE_NOT_IMPLEMENTED
+from nbxmpp.modules.eme import EME
+from nbxmpp.modules.http_auth import HTTPAuth
from nbxmpp.misc import unwrap_carbon
-from nbxmpp.util import PropertyDict
+from nbxmpp.util import get_property_dict
log = logging.getLogger('nbxmpp.dispatcher_nb')
@@ -96,6 +98,7 @@ class XMPPDispatcher(PlugIn):
def __init__(self):
PlugIn.__init__(self)
self.handlers = {}
+ self._modules = {}
self._expected = {}
self._defaultHandler = None
self._pendingExceptions = []
@@ -144,6 +147,14 @@ class XMPPDispatcher(PlugIn):
"""
self.handlers = handlers
+ def _register_modules(self):
+ self._modules['EME'] = EME(self._owner)
+ self._modules['HTTPAuth'] = HTTPAuth(self._owner)
+
+ for instance in self._modules.values():
+ for handler in instance.handlers:
+ self.RegisterHandler(*handler)
+
def _init(self):
"""
Register default namespaces/protocols/handlers. Used internally
@@ -158,6 +169,7 @@ class XMPPDispatcher(PlugIn):
self.RegisterProtocol('message', Message)
self.RegisterDefaultHandler(self.returnStanzaHandler)
self.RegisterEventHandler(self._owner._caller._event_dispatcher)
+ self._register_modules()
self.on_responses = {}
def plugin(self, owner):
@@ -178,6 +190,7 @@ class XMPPDispatcher(PlugIn):
"""
Prepare instance to be destructed
"""
+ self._modules = {}
self.Stream.dispatch = None
self.Stream.features = None
self.Stream.destroy()
@@ -464,8 +477,8 @@ class XMPPDispatcher(PlugIn):
# Convert simplexml to Protocol object
stanza = self.handlers[xmlns][name]['type'](node=stanza)
- properties = PropertyDict()
- if stanza.getName() == 'message':
+ properties = get_property_dict(name)
+ if name == 'message':
# https://tools.ietf.org/html/rfc6120#section-8.1.1.1
# If the stanza does not include a 'to' address then the client MUST
# treat it as if the 'to' address were included with a value of the
=====================================
nbxmpp/modules/__init__.py
=====================================
=====================================
nbxmpp/modules/eme.py
=====================================
@@ -0,0 +1,50 @@
+# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
+#
+# This file is part of nbxmpp.
+#
+# This program 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; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 this program; If not, see <http://www.gnu.org/licenses/>.
+
+import logging
+
+from nbxmpp.protocol import NS_EME
+from nbxmpp.util import StanzaHandler
+
+log = logging.getLogger('nbxmpp.m.eme')
+
+
+class EME:
+ def __init__(self, client):
+ self._client = client
+ self.handlers = [
+ StanzaHandler(name='message',
+ callback=self._process_eme,
+ ns=NS_EME,
+ priority=40)
+ ]
+
+ @staticmethod
+ def _process_eme(_con, stanza, properties):
+ enc_tag = stanza.getTag('encryption', namespace=NS_EME)
+ if enc_tag is None:
+ return
+
+ ns = enc_tag.getAttr('namespace')
+ if ns is None:
+ log.warning('No namespace on message')
+ return
+
+ properties.eme = {}
+ properties.eme['namespace'] = ns
+ properties.eme['name'] = enc_tag.getAttr('name')
+ log.info('Found data: %s', properties.eme)
=====================================
nbxmpp/modules/http_auth.py
=====================================
@@ -0,0 +1,50 @@
+# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
+#
+# This file is part of nbxmpp.
+#
+# This program 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; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 this program; If not, see <http://www.gnu.org/licenses/>.
+
+import logging
+
+from nbxmpp.protocol import NS_HTTP_AUTH
+from nbxmpp.util import StanzaHandler
+
+log = logging.getLogger('nbxmpp.m.http_auth')
+
+
+class HTTPAuth:
+ def __init__(self, client):
+ self._client = client
+ self.handlers = [
+ StanzaHandler(name='message',
+ callback=self._process_http_auth,
+ ns=NS_HTTP_AUTH,
+ priority=40),
+ StanzaHandler(name='iq',
+ callback=self._process_http_auth,
+ typ='get',
+ ns=NS_HTTP_AUTH,
+ priority=40)
+ ]
+
+ @staticmethod
+ def _process_http_auth(_con, stanza, properties):
+ confirm = stanza.getTag('confirm', namespace=NS_HTTP_AUTH)
+ if confirm is None:
+ return
+
+ http_auth = confirm.getAttrs().copy()
+ http_auth['body'] = stanza.getTagData('body')
+ properties.http_auth = http_auth
+ log.info('Found data: %s', http_auth)
=====================================
nbxmpp/util.py
=====================================
@@ -16,6 +16,10 @@
# along with this program; If not, see <http://www.gnu.org/licenses/>.
import base64
+from collections import namedtuple
+
+StanzaHandler = namedtuple('StanzaHandler', 'name callback typ ns xmlns system priority')
+StanzaHandler.__new__.__defaults__ = ('', '', None, False, 50)
def b64decode(data, return_type=str):
@@ -36,15 +40,47 @@ def b64encode(data, return_type=str):
return result.decode()
-class PropertyDict:
+class PropertyBase:
def __init__(self):
- self.__data = {}
+ self._data = {}
def __getattr__(self, key):
- return self.__data[key]
+ return self._data[key]
def __setattr__(self, key, value):
- if '__' in key:
+ if '_data' in key:
super().__setattr__(key, value)
else:
- self.__data[key] = value
+ self._data[key] = value
+
+
+class MessagePropertyDict(PropertyBase):
+ def __init__(self):
+ self._data = {
+ 'carbon_type': None,
+ 'eme': None,
+ 'http_auth': None,
+ }
+
+ @property
+ def is_http_auth(self):
+ return self._data['http_auth'] is not None
+
+
+class IqPropertyDict(PropertyBase):
+ def __init__(self):
+ self._data = {
+ 'http_auth': None,
+ }
+
+ @property
+ def is_http_auth(self):
+ return self._data['http_auth'] is not None
+
+
+def get_property_dict(name):
+ if name == 'message':
+ return MessagePropertyDict()
+ if name == 'iq':
+ return IqPropertyDict()
+ return PropertyBase()
=====================================
setup.py
=====================================
@@ -8,5 +8,5 @@ setup(name='nbxmpp',
author='Yann Leboulanger',
author_email='asterix(a)lagaule.org',
url='http://dev.gajim.org/gajim/python-nbxmpp',
- packages=['nbxmpp'],
+ packages=['nbxmpp', 'nbxmpp.modules'],
)
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/compare/6b2a9da405c02434831465b9b…
--
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/compare/6b2a9da405c02434831465b9b…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
6b2a9da4 by Philipp Hörist at 2018-12-20T22:16:03Z
Add more message stanza processing logic
- Unwrap carbons before calling handlers
- Introduce PropertyDict which can be passed through the handler chain
- Add JID.getBare() as alias for getStripped() to make the purpose more evident
- - - - -
4 changed files:
- nbxmpp/dispatcher_nb.py
- + nbxmpp/misc.py
- nbxmpp/protocol.py
- nbxmpp/util.py
Changes:
=====================================
nbxmpp/dispatcher_nb.py
=====================================
@@ -25,6 +25,7 @@ import locale
import re
import uuid
import logging
+import inspect
from xml.parsers.expat import ExpatError
from nbxmpp.simplexml import NodeBuilder
@@ -32,6 +33,7 @@ from nbxmpp.plugin import PlugIn
from nbxmpp.protocol import NS_STREAMS
from nbxmpp.protocol import NS_HTTP_BIND
from nbxmpp.protocol import NodeProcessed
+from nbxmpp.protocol import InvalidFrom
from nbxmpp.protocol import Iq
from nbxmpp.protocol import Presence
from nbxmpp.protocol import Message
@@ -39,6 +41,8 @@ from nbxmpp.protocol import Protocol
from nbxmpp.protocol import Node
from nbxmpp.protocol import Error
from nbxmpp.protocol import ERR_FEATURE_NOT_IMPLEMENTED
+from nbxmpp.misc import unwrap_carbon
+from nbxmpp.util import PropertyDict
log = logging.getLogger('nbxmpp.dispatcher_nb')
@@ -430,8 +434,11 @@ class XMPPDispatcher(PlugIn):
if not session:
session = self
session.Stream._mini_dom = None
- name = stanza.getName()
+ # Count stanza
+ self._owner.Smacks.count_incoming(stanza.getName())
+
+ name = stanza.getName()
if name == 'features':
self._owner.got_features = True
session.Stream.features = stanza
@@ -449,43 +456,63 @@ class XMPPDispatcher(PlugIn):
if name not in ('features', 'stream'):
log.warning('Unknown stanza: %s', stanza)
else:
- log.debug('Got %s / %s stanza' % (xmlns, name))
+ log.debug('Got %s / %s stanza', xmlns, name)
name = 'unknown'
else:
- log.debug('Got %s / %s stanza' % (xmlns, name))
+ log.debug('Got %s / %s stanza', xmlns, name)
# Convert simplexml to Protocol object
stanza = self.handlers[xmlns][name]['type'](node=stanza)
+ properties = PropertyDict()
+ if stanza.getName() == 'message':
+ # https://tools.ietf.org/html/rfc6120#section-8.1.1.1
+ # If the stanza does not include a 'to' address then the client MUST
+ # treat it as if the 'to' address were included with a value of the
+ # client's full JID.
+
+ own_jid = self._owner.get_bound_jid()
+ to = stanza.getTo()
+ if to is None:
+ stanza.setTo(own_jid)
+ elif not to.bareMatch(own_jid):
+ log.warning('Message addressed to someone else: %s', stanza)
+ return
+
+ try:
+ stanza, properties.carbon_type = unwrap_carbon(stanza, own_jid)
+ except InvalidFrom as exc:
+ log.warning(exc)
+ return
+ except NodeProcessed as exc:
+ log.info(exc)
+ return
+
typ = stanza.getType()
if name == 'message' and not typ:
typ = 'normal'
elif not typ:
typ = ''
- stanza.props = stanza.getProperties()
- ID = stanza.getID()
+ stanza.props = stanza.getProperties()
log.debug('type: %s, properties: %s', typ, stanza.props)
- # If server supports stream management
- if hasattr(self._owner, 'Smacks'):
- self._owner.Smacks.count_incoming(stanza.getName())
-
+ _id = stanza.getID()
processed = False
- if ID in session._expected:
- if isinstance(session._expected[ID], tuple):
- cb, args = session._expected[ID]
+ if _id in session._expected:
+ if isinstance(session._expected[_id], tuple):
+ cb, args = session._expected[_id]
log.debug('Expected stanza arrived. Callback %s(%s) found',
cb, args)
try:
- cb(session,stanza,**args)
+ cb(session, stanza, **args)
except NodeProcessed:
pass
except Exception:
raise
else:
log.debug('Expected stanza arrived')
- session._expected[ID] = stanza
+ session._expected[_id] = stanza
processed = True
# Gather specifics depending on stanza properties
@@ -511,7 +538,13 @@ class XMPPDispatcher(PlugIn):
if not processed or handler['system']:
try:
log.info('Call handler: %s', handler['func'].__qualname__)
- handler['func'](session, stanza)
+ # Backwards compatibility until all handlers support
+ # properties
+ signature = inspect.signature(handler['func'])
+ if 'properties' in signature.parameters:
+ handler['func'](session, stanza, properties)
+ else:
+ handler['func'](session, stanza)
except NodeProcessed:
processed = True
except Exception:
=====================================
nbxmpp/misc.py
=====================================
@@ -0,0 +1,65 @@
+# Copyright (C) 2018 Philipp Hörist <philipp AT hoerist.com>
+#
+# This file is part of nbxmpp.
+#
+# This program 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; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program 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 this program; If not, see <http://www.gnu.org/licenses/>.
+
+import logging
+
+from nbxmpp.protocol import NS_CARBONS
+from nbxmpp.protocol import NS_FORWARD
+from nbxmpp.protocol import NS_MUC_USER
+from nbxmpp.protocol import NodeProcessed
+from nbxmpp.protocol import InvalidFrom
+from nbxmpp.protocol import Message
+
+log = logging.getLogger('nbxmpp.misc')
+
+
+def unwrap_carbon(stanza, own_jid):
+ carbon = stanza.getTag('received', namespace=NS_CARBONS)
+ if carbon is None:
+ carbon = stanza.getTag('sent', namespace=NS_CARBONS)
+ if carbon is None:
+ return stanza, None
+
+ # Carbon must be from our bare jid
+ if not stanza.getFrom() == own_jid.getBare():
+ raise InvalidFrom('Invalid from: %s' % stanza.getAttr('from'))
+
+ forwarded = carbon.getTag('forwarded', namespace=NS_FORWARD)
+ message = Message(node=forwarded.getTag('message'))
+
+ type_ = carbon.getName()
+ to = message.getTo()
+ if to is None:
+ message.setTo(own_jid.getBare())
+
+ frm = message.getFrom()
+ if frm is None:
+ message.setFrom(own_jid.getBare())
+
+ if type_ == 'received':
+ 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
+ raise NodeProcessed('Drop "received"-Carbon from ourself')
+
+ if message.getTag('x', namespace=NS_MUC_USER) is not None:
+ # A MUC broadcasts messages sent to us to all resources
+ # there is no need to process the received carbon
+ raise NodeProcessed('Drop MUC-PM "received"-Carbon')
+
+ return message, type_
=====================================
nbxmpp/protocol.py
=====================================
@@ -647,6 +647,9 @@ class UnsupportedVersion(StreamError):
class XMLNotWellFormed(StreamError):
pass
+class InvalidStanza(Exception):
+ pass
+
stream_exceptions = {'bad-format': BadFormat,
'bad-namespace-prefix': BadNamespacePrefix,
'conflict': Conflict,
@@ -747,6 +750,12 @@ class JID:
"""
return self.__str__(0)
+ def getBare(self):
+ """
+ Return the bare representation of JID. I.e. string value w/o resource
+ """
+ return self.__str__(0)
+
def __eq__(self, other):
"""
Compare the JID to another instance or to string for equality
=====================================
nbxmpp/util.py
=====================================
@@ -17,6 +17,7 @@
import base64
+
def b64decode(data, return_type=str):
if isinstance(data, str):
data = data.encode()
@@ -25,6 +26,7 @@ def b64decode(data, return_type=str):
return result
return result.decode()
+
def b64encode(data, return_type=str):
if isinstance(data, str):
data = data.encode()
@@ -32,3 +34,17 @@ def b64encode(data, return_type=str):
if return_type == bytes:
return result
return result.decode()
+
+
+class PropertyDict:
+ def __init__(self):
+ self.__data = {}
+
+ def __getattr__(self, key):
+ return self.__data[key]
+
+ def __setattr__(self, key, value):
+ if '__' in key:
+ super().__setattr__(key, value)
+ else:
+ self.__data[key] = value
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/commit/6b2a9da405c02434831465b9b7…
--
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/commit/6b2a9da405c02434831465b9b7…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
42c1909d by Philipp Hörist at 2018-12-20T22:18:23Z
Remove carbon processing
nbxmpp does that now for us
- - - - -
2 changed files:
- gajim/common/modules/carbons.py
- gajim/common/modules/message.py
Changes:
=====================================
gajim/common/modules/carbons.py
=====================================
@@ -49,61 +49,5 @@ class Carbons:
log.warning('Carbons deactivated (user setting)')
-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', type_, 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
-
-
def get_instance(*args, **kwargs):
return Carbons(*args, **kwargs), 'Carbons'
=====================================
gajim/common/modules/message.py
=====================================
@@ -27,7 +27,6 @@ from gajim.common.nec import NetworkEvent
from gajim.common.helpers import AdditionalDataDict
from gajim.common.modules.security_labels import parse_securitylabel
from gajim.common.modules.user_nickname import parse_nickname
-from gajim.common.modules.carbons import parse_carbon
from gajim.common.modules.misc import parse_delay
from gajim.common.modules.misc import parse_eme
from gajim.common.modules.misc import parse_correction
@@ -60,24 +59,7 @@ class Message:
nbxmpp.NS_IBB,
nbxmpp.NS_CAPTCHA,])
- def _message_received(self, _con, stanza):
- # https://tools.ietf.org/html/rfc6120#section-8.1.1.1
- # If the stanza does not include a 'to' address then the client MUST
- # treat it as if the 'to' address were included with a value of the
- # client's full JID.
- #
- # Implementation Note: However, if the client does
- # check the 'to' address then it is suggested to check at most the
- # bare JID portion (not the full JID)
-
- own_jid = self._con.get_own_jid().getStripped()
- to = stanza.getTo()
- if to is None:
- stanza.setTo(own_jid)
- elif not to.bareMatch(own_jid):
- log.warning('Message addressed to someone else: %s', stanza)
- raise nbxmpp.NodeProcessed
-
+ def _message_received(self, _con, stanza, properties):
# Check if a child of the message contains any
# namespaces that we handle in other modules.
# nbxmpp executes less common handlers last
@@ -98,20 +80,19 @@ class Message:
stanza=stanza,
account=self._account))
- if stanza.getFrom() == self._con.get_own_jid(warn=True):
- # Drop messages sent from our own full jid
- # It can happen that when we sent message to our own bare jid
- # that the server routes that message back to us
- log.info('Received message from self: %s, message is dropped',
- stanza.getFrom())
- return
-
- stanza, sent, forwarded = parse_carbon(self._con, stanza)
+ forwarded = properties.carbon_type is not None
+ sent = properties.carbon_type == 'sent'
+ if sent:
+ # Ugly, we treat the from attr as the remote jid,
+ # to make that work with sent carbons we have to do this.
+ # TODO: Check where in Gajim and plugins we depend on that behavior
+ stanza.setFrom(stanza.getTo().getBare())
from_ = stanza.getFrom()
type_ = stanza.getType()
if type_ is None:
type_ = 'normal'
+
self_message = is_self_message(stanza, type_ == 'groupchat')
muc_pm = is_muc_pm(stanza, from_, type_ == 'groupchat')
@@ -138,7 +119,7 @@ class Message:
if type_ == 'groupchat':
archive_jid = stanza.getFrom().getStripped()
else:
- archive_jid = own_jid
+ archive_jid = self._con.get_own_jid().getStripped()
if app.logger.find_stanza_id(self._account,
archive_jid,
stanza_id,
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/42c1909d3b5899f43cf19d65d7b115b1ec…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/42c1909d3b5899f43cf19d65d7b115b1ec…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
730a1520 by Philipp Hörist at 2018-12-19T14:37:55Z
Allow registering handlers for type normal
- - - - -
1 changed file:
- nbxmpp/dispatcher_nb.py
Changes:
=====================================
nbxmpp/dispatcher_nb.py
=====================================
@@ -448,7 +448,9 @@ class XMPPDispatcher(PlugIn):
stanza = self.handlers[xmlns][name][type](node=stanza)
typ = stanza.getType()
- if not typ:
+ if name == 'message' and not typ:
+ typ = 'normal'
+ elif not typ:
typ = ''
stanza.props = stanza.getProperties()
ID = stanza.getID()
@@ -472,6 +474,7 @@ class XMPPDispatcher(PlugIn):
for key in list_:
if key:
chain = chain + self.handlers[xmlns][name][key]
+ log.debug('Chain: %s', [key for key in list_ if key])
if ID in session._expected:
user = 0
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/commit/730a1520220270f68cb38f17e4…
--
View it on GitLab: https://dev.gajim.org/gajim/python-nbxmpp/commit/730a1520220270f68cb38f17e4…
You're receiving this email because of your account on dev.gajim.org.