From eff3330e754cfbb496d6ba761d0a821375f575c8 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 12 Dec 2011 22:17:07 -0800 Subject: Add support for incoming/outgoing filters. A filter accepts and returns a stanza, but potentially modified. To prevent sending/receiving a stanza, a filter may return None. Incoming: self.add_filter('in', in_filter) Outgoing: self.add_filter('out', out_filter) Filters are applied in the order thay are added. However, you may add an order parameter, which is the place in the list to insert the filter: self.add_filter('in', in_filter, order=0) --- sleekxmpp/xmlstream/stanzabase.py | 2 +- sleekxmpp/xmlstream/xmlstream.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'sleekxmpp/xmlstream') diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py index 389fe20c..2f864300 100644 --- a/sleekxmpp/xmlstream/stanzabase.py +++ b/sleekxmpp/xmlstream/stanzabase.py @@ -1251,7 +1251,7 @@ class StanzaBase(ElementBase): stanza sent immediately. Useful for stream initialization. Defaults to ``False``. """ - self.stream.send_raw(self.__str__(), now=now) + self.stream.send(self, now=now) def __copy__(self): """Return a copy of the stanza object that does not share the diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py index 3e569082..b690103c 100644 --- a/sleekxmpp/xmlstream/xmlstream.py +++ b/sleekxmpp/xmlstream/xmlstream.py @@ -35,7 +35,7 @@ except ImportError: import sleekxmpp from sleekxmpp.thirdparty.statemachine import StateMachine from sleekxmpp.xmlstream import Scheduler, tostring -from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET +from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET, ElementBase from sleekxmpp.xmlstream.handler import Waiter, XMLCallback from sleekxmpp.xmlstream.matcher import MatchXMLMask @@ -268,6 +268,7 @@ class XMLStream(object): self.__handlers = [] self.__event_handlers = {} self.__event_handlers_lock = threading.Lock() + self.__filters = {'in': [], 'out': []} self._id = 0 self._id_lock = threading.Lock() @@ -743,6 +744,18 @@ class XMLStream(object): """ del self.__root_stanza[stanza_class] + def add_filter(self, mode, handler, order=None): + """Add a filter for incoming or outgoing stanzas. + + These filters are applied before incoming stanzas are + passed to any handlers, and before outgoing stanzas + are put in the send queue. + """ + if order: + self.__filters[mode].insert(order, handler) + else: + self.__filters[mode].append(handler) + def add_handler(self, mask, pointer, name=None, disposable=False, threaded=False, filter=False, instream=False): """A shortcut method for registering a handler using XML masks. @@ -994,6 +1007,14 @@ class XMLStream(object): timeout = self.response_timeout if hasattr(mask, 'xml'): mask = mask.xml + + if isinstance(data, ElementBase): + for filter in self.__filters['out']: + if data is not None: + data = filter(data) + if data is None: + return + data = str(data) if mask is not None: log.warning("Use of send mask waiters is deprecated.") @@ -1254,6 +1275,12 @@ class XMLStream(object): # stanza type applies, a generic StanzaBase stanza will be used. stanza = self._build_stanza(xml) + for filter in self.__filters['in']: + if stanza is not None: + stanza = filter(stanza) + if stanza is None: + return + # Match the stanza against registered handlers. Handlers marked # to run "in stream" will be executed immediately; the rest will # be queued. -- cgit v1.2.3 From cb635dcd5ab94a1cbc104788b33abefea12d0040 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 12 Dec 2011 22:37:19 -0800 Subject: Add parameter docs for add_filter. --- sleekxmpp/xmlstream/xmlstream.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sleekxmpp/xmlstream') diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py index b690103c..8f662e88 100644 --- a/sleekxmpp/xmlstream/xmlstream.py +++ b/sleekxmpp/xmlstream/xmlstream.py @@ -750,6 +750,16 @@ class XMLStream(object): These filters are applied before incoming stanzas are passed to any handlers, and before outgoing stanzas are put in the send queue. + + Each filter must accept a single stanza, and return + either a stanza or ``None``. If the filter returns + ``None``, then the stanza will be dropped from being + processed for events or from being sent. + + :param mode: One of ``'in'`` or ``'out'``. + :param handler: The filter function. + :param int order: The position to insert the filter in + the list of active filters. """ if order: self.__filters[mode].insert(order, handler) -- cgit v1.2.3 From f6e30edbc4a717b34bbf01d3d0a9fe884c6b37da Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Wed, 14 Dec 2011 21:14:27 -0800 Subject: Log received data AFTER filtering. This allows applications to filter out sensitive information, such as passwords, so that it won't appear in the logs. It does mean that the debug logs will not show the actual received data, and there will be no indication of tampering, unless the filter author explicitly logs and notes that a change was made. --- sleekxmpp/xmlstream/xmlstream.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sleekxmpp/xmlstream') diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py index 8f662e88..66dd657a 100644 --- a/sleekxmpp/xmlstream/xmlstream.py +++ b/sleekxmpp/xmlstream/xmlstream.py @@ -1276,8 +1276,6 @@ class XMLStream(object): :param xml: The :class:`~sleekxmpp.xmlstream.stanzabase.ElementBase` stanza to analyze. """ - log.debug("RECV: %s", tostring(xml, xmlns=self.default_ns, - stream=self)) # Apply any preprocessing filters. xml = self.incoming_filter(xml) @@ -1291,6 +1289,9 @@ class XMLStream(object): if stanza is None: return + log.debug("RECV: %s", tostring(xml, xmlns=self.default_ns, + stream=self)) + # Match the stanza against registered handlers. Handlers marked # to run "in stream" will be executed immediately; the rest will # be queued. -- cgit v1.2.3 From 1a61bdb302e48d29888ab9b9cc23421bbb3fbead Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Wed, 28 Dec 2011 09:53:22 -0500 Subject: Ensure that stanza plugins work as expected if the XML is appended. --- sleekxmpp/xmlstream/stanzabase.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sleekxmpp/xmlstream') diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py index 2f864300..8678ca14 100644 --- a/sleekxmpp/xmlstream/stanzabase.py +++ b/sleekxmpp/xmlstream/stanzabase.py @@ -345,7 +345,8 @@ class ElementBase(object): """ if attrib not in self.plugins: plugin_class = self.plugin_attrib_map[attrib] - plugin = plugin_class(parent=self) + existing_xml = self.xml.find(plugin_class.tag_name()) + plugin = plugin_class(parent=self, xml=existing_xml) self.plugins[attrib] = plugin if plugin_class in self.plugin_iterables: self.iterables.append(plugin) -- cgit v1.2.3