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@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/6b2a9da405c02434831465b9b7...