Changeset 7:0fbac5c2e97d in ralphm-patches


Ignore:
Timestamp:
Apr 7, 2009, 11:53:45 AM (11 years ago)
Author:
Ralph Meijer <ralphm@…>
Branch:
default
Message:

Save current state.

Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • compat-pre-twisted-8.0.0.patch

    r5 r7  
    1 diff -r 6fa0283e522b wokkel/compat.py
    2 --- a/wokkel/compat.py  Wed Mar 25 18:14:08 2009 +0100
    3 +++ b/wokkel/compat.py  Wed Mar 25 18:15:15 2009 +0100
     1diff -r 84ffc75012b4 wokkel/compat.py
     2--- a/wokkel/compat.py  Tue Apr 07 11:14:44 2009 +0200
     3+++ b/wokkel/compat.py  Tue Apr 07 11:15:52 2009 +0200
    44@@ -7,40 +7,6 @@
    55 from twisted.words.protocols.jabber import xmlstream
     
    4343     """
    4444     XmlStream factory mixin to install bootstrap event observers.
    45 diff -r 6fa0283e522b wokkel/subprotocols.py
    46 --- a/wokkel/subprotocols.py    Wed Mar 25 18:14:08 2009 +0100
    47 +++ b/wokkel/subprotocols.py    Wed Mar 25 18:15:15 2009 +0100
     45diff -r 84ffc75012b4 wokkel/subprotocols.py
     46--- a/wokkel/subprotocols.py    Tue Apr 07 11:14:44 2009 +0200
     47+++ b/wokkel/subprotocols.py    Tue Apr 07 11:15:52 2009 +0200
    4848@@ -1,6 +1,6 @@
    4949 # -*- test-case-name: wokkel.test.test_subprotocols -*-
     
    7070 
    7171 class XMPPHandler(object):
    72 diff -r 6fa0283e522b wokkel/test/test_compat.py
    73 --- a/wokkel/test/test_compat.py        Wed Mar 25 18:14:08 2009 +0100
    74 +++ b/wokkel/test/test_compat.py        Wed Mar 25 18:15:15 2009 +0100
     72diff -r 84ffc75012b4 wokkel/test/test_compat.py
     73--- a/wokkel/test/test_compat.py        Tue Apr 07 11:14:44 2009 +0200
     74+++ b/wokkel/test/test_compat.py        Tue Apr 07 11:15:52 2009 +0200
    7575@@ -1,5 +1,5 @@
    7676-# Copyright (c) 2001-2007 Twisted Matrix Laboratories.
     
    166166     """
    167167     Tests for L{XmlStreamServerFactory}.
    168 diff -r 6fa0283e522b wokkel/test/test_disco.py
    169 --- a/wokkel/test/test_disco.py Wed Mar 25 18:14:08 2009 +0100
    170 +++ b/wokkel/test/test_disco.py Wed Mar 25 18:15:15 2009 +0100
     168diff -r 84ffc75012b4 wokkel/test/test_disco.py
     169--- a/wokkel/test/test_disco.py Tue Apr 07 11:14:44 2009 +0200
     170+++ b/wokkel/test/test_disco.py Tue Apr 07 11:15:52 2009 +0200
    171171@@ -10,6 +10,7 @@
    172172 from twisted.internet import defer
     
    189189 NS_DISCO_ITEMS = 'http://jabber.org/protocol/disco#items'
    190190 
    191 diff -r 6fa0283e522b wokkel/test/test_pubsub.py
    192 --- a/wokkel/test/test_pubsub.py        Wed Mar 25 18:14:08 2009 +0100
    193 +++ b/wokkel/test/test_pubsub.py        Wed Mar 25 18:15:15 2009 +0100
     191diff -r 84ffc75012b4 wokkel/test/test_pubsub.py
     192--- a/wokkel/test/test_pubsub.py        Tue Apr 07 11:14:44 2009 +0200
     193+++ b/wokkel/test/test_pubsub.py        Tue Apr 07 11:15:52 2009 +0200
    194194@@ -1,4 +1,4 @@
    195195-# Copyright (c) 2003-2008 Ralph Meijer
     
    198198 
    199199 """
    200 @@ -12,16 +12,12 @@
     200@@ -12,15 +12,11 @@
    201201 from twisted.words.xish import domish
    202202 from twisted.words.protocols.jabber import error
     
    205205 
    206206 from wokkel import data_form, disco, iwokkel, pubsub, shim
    207  from wokkel.generic import parseXml
    208207 from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub
    209208 
  • pubsub_request.patch

    r6 r7  
    1111that is passed to the corresponding handler methods.
    1212
    13 diff -r 0bfc0b2a633c wokkel/generic.py
    14 --- a/wokkel/generic.py Wed Apr 01 17:25:11 2009 +0200
    15 +++ b/wokkel/generic.py Wed Apr 01 17:26:46 2009 +0200
     13diff -r 556fc011f965 wokkel/generic.py
     14--- a/wokkel/generic.py Tue Apr 07 11:16:01 2009 +0200
     15+++ b/wokkel/generic.py Tue Apr 07 11:17:21 2009 +0200
    1616@@ -10,7 +10,7 @@
    1717 from zope.interface import implements
     
    6161     protocol = xmlstream.XmlStream
    6262 
    63 diff -r 0bfc0b2a633c wokkel/iwokkel.py
    64 --- a/wokkel/iwokkel.py Wed Apr 01 17:25:11 2009 +0200
    65 +++ b/wokkel/iwokkel.py Wed Apr 01 17:26:46 2009 +0200
     63diff -r 556fc011f965 wokkel/iwokkel.py
     64--- a/wokkel/iwokkel.py Tue Apr 07 11:16:01 2009 +0200
     65+++ b/wokkel/iwokkel.py Tue Apr 07 11:17:21 2009 +0200
    6666@@ -278,6 +278,7 @@
    6767                              C{list} of L{domish.Element})
     
    343343+        @rtype: L{defer.Deferred}
    344344         """
    345 diff -r 0bfc0b2a633c wokkel/pubsub.py
    346 --- a/wokkel/pubsub.py  Wed Apr 01 17:25:11 2009 +0200
    347 +++ b/wokkel/pubsub.py  Wed Apr 01 17:26:46 2009 +0200
     345diff -r 556fc011f965 wokkel/pubsub.py
     346--- a/wokkel/pubsub.py  Tue Apr 07 11:16:01 2009 +0200
     347+++ b/wokkel/pubsub.py  Tue Apr 07 11:17:21 2009 +0200
    348348@@ -16,7 +16,7 @@
    349349 from twisted.words.protocols.jabber import jid, error, xmlstream
     
    14151415+    def delete(self, request):
    14161416         raise Unsupported('delete-nodes')
    1417 diff -r 0bfc0b2a633c wokkel/test/test_pubsub.py
    1418 --- a/wokkel/test/test_pubsub.py        Wed Apr 01 17:25:11 2009 +0200
    1419 +++ b/wokkel/test/test_pubsub.py        Wed Apr 01 17:26:46 2009 +0200
    1420 @@ -14,6 +14,7 @@
    1421  from twisted.words.protocols.jabber.jid import JID
    1422  
    1423  from wokkel import data_form, iwokkel, pubsub, shim
     1417diff -r 556fc011f965 wokkel/test/test_pubsub.py
     1418--- a/wokkel/test/test_pubsub.py        Tue Apr 07 11:16:01 2009 +0200
     1419+++ b/wokkel/test/test_pubsub.py        Tue Apr 07 11:17:21 2009 +0200
     1420@@ -15,6 +15,7 @@
     1421 from twisted.words.protocols.jabber.xmlstream import toResponse
     1422 
     1423 from wokkel import data_form, disco, iwokkel, pubsub, shim
    14241424+from wokkel.generic import parseXml
    14251425 from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub
    14261426 
    1427  try:
    1428 @@ -490,6 +491,630 @@
     1427 NS_PUBSUB = 'http://jabber.org/protocol/pubsub'
     1428@@ -487,6 +488,630 @@
    14291429 
    14301430 
     
    20572057     """
    20582058     Tests for L{pubsub.PubSubService}.
    2059 @@ -507,6 +1132,29 @@
     2059@@ -504,6 +1129,29 @@
    20602060         verify.verifyObject(iwokkel.IPubSubService, self.service)
    20612061 
     
    20872087         """
    20882088         Test getDiscoInfo calls getNodeInfo and returns some minimal info.
    2089 @@ -524,28 +1172,6 @@
     2089@@ -569,28 +1217,6 @@
    20902090         return d
    20912091 
     
    21162116         """
    21172117         A publish request should result in L{PubSubService.publish} being
    2118 @@ -561,27 +1187,147 @@
     2118@@ -606,27 +1232,147 @@
    21192119         </iq>
    21202120         """
     
    22712271         </iq>
    22722272         """
    2273 @@ -627,14 +1373,141 @@
     2273@@ -672,14 +1418,141 @@
    22742274             self.assertEqual('subscribed', subscription['subscription'])
    22752275 
     
    24162416         d.addCallback(cb)
    24172417         return d
    2418 @@ -665,10 +1538,7 @@
     2418@@ -710,10 +1583,7 @@
    24192419                      "label": "Deliver payloads with event notifications"}
    24202420                 }
     
    24282428 
    24292429         def cb(element):
    2430 @@ -686,6 +1556,85 @@
     2430@@ -731,6 +1601,85 @@
    24312431         return d
    24322432 
     
    25142514         """
    25152515         On a node configuration get request L{PubSubService.getConfiguration}
    2516 @@ -714,14 +1663,11 @@
     2516@@ -759,14 +1708,11 @@
    25172517                      "label": "Owner of the node"}
    25182518                 }
     
    25322532         def cb(element):
    25332533             self.assertEqual('pubsub', element.name)
    2534 @@ -749,8 +1695,12 @@
     2534@@ -794,8 +1740,12 @@
    25352535             field.typeCheck()
    25362536             self.assertEqual(JID('user@example.org'), field.value)
     
    25452545         d.addCallback(cb)
    25462546         return d
    2547 @@ -789,16 +1739,14 @@
     2547@@ -834,16 +1784,14 @@
    25482548                      "label": "Deliver payloads with event notifications"}
    25492549                 }
     
    25652565 
    25662566 
    2567 @@ -823,10 +1771,11 @@
     2567@@ -868,10 +1816,11 @@
    25682568         </iq>
    25692569         """
     
    25782578 
    25792579 
    2580 @@ -862,14 +1811,47 @@
     2580@@ -907,14 +1856,47 @@
    25812581                      "label": "Deliver payloads with event notifications"}
    25822582                 }
     
    26282628         """
    26292629         On a items request, return all items for the given node.
    2630 @@ -883,12 +1865,7 @@
     2630@@ -928,12 +1910,7 @@
    26312631         </iq>
    26322632         """
     
    26422642 
    26432643         def cb(element):
    2644 @@ -925,11 +1902,7 @@
     2644@@ -970,11 +1947,7 @@
    26452645         </iq>
    26462646         """
     
    26552655 
    26562656         self.service.retract = retract
    2657 @@ -951,10 +1924,7 @@
     2657@@ -996,10 +1969,7 @@
    26582658         </iq>
    26592659         """
     
    26672667 
    26682668         self.service.purge = purge
    2669 @@ -976,10 +1946,7 @@
     2669@@ -1021,10 +1991,7 @@
    26702670         </iq>
    26712671         """
     
    26792679 
    26802680         self.service.delete = delete
    2681 @@ -1031,3 +1998,461 @@
     2681@@ -1076,3 +2043,461 @@
    26822682         self.assertEqual(NS_PUBSUB_EVENT, message.event.delete.redirect.uri)
    26832683         self.assertTrue(message.event.delete.redirect.hasAttribute('uri'))
  • pubsub_resource.patch

    r5 r7  
    1 diff -r 2ea6196efcdc wokkel/iwokkel.py
    2 --- a/wokkel/iwokkel.py Wed Mar 25 18:14:07 2009 +0100
    3 +++ b/wokkel/iwokkel.py Mon Mar 30 08:35:05 2009 +0200
     1diff -r cf770fa6bcb7 wokkel/iwokkel.py
     2--- a/wokkel/iwokkel.py Tue Apr 07 11:17:23 2009 +0200
     3+++ b/wokkel/iwokkel.py Tue Apr 07 11:25:27 2009 +0200
    44@@ -297,75 +297,46 @@
    55         """
     
    208208         Called when a node configuration change request has been received.
    209209 
    210 diff -r 2ea6196efcdc wokkel/pubsub.py
    211 --- a/wokkel/pubsub.py  Wed Mar 25 18:14:07 2009 +0100
    212 +++ b/wokkel/pubsub.py  Mon Mar 30 08:35:05 2009 +0200
     210diff -r cf770fa6bcb7 wokkel/pubsub.py
     211--- a/wokkel/pubsub.py  Tue Apr 07 11:17:23 2009 +0200
     212+++ b/wokkel/pubsub.py  Tue Apr 07 11:25:27 2009 +0200
    213213@@ -13,12 +13,13 @@
    214214 from zope.interface import implements
     
    296296@@ -852,17 +845,33 @@
    297297 
    298                  info.append(form.toElement())
     298                 info.append(form)
    299299 
    300300-        d = self.getNodeInfo(requestor, target, nodeIdentifier or '')
     
    765765+    def subscriptionsSet(self, request):
    766766+        return defer.fail(Unsupported('manage-subscriptions'))
    767 diff -r 2ea6196efcdc wokkel/test/test_pubsub.py
    768 --- a/wokkel/test/test_pubsub.py        Wed Mar 25 18:14:07 2009 +0100
    769 +++ b/wokkel/test/test_pubsub.py        Mon Mar 30 08:35:05 2009 +0200
    770 @@ -13,7 +13,7 @@
    771  from twisted.words.protocols.jabber import error
    772  from twisted.words.protocols.jabber.jid import JID
    773  
    774 -from wokkel import data_form, iwokkel, pubsub, shim
    775 +from wokkel import data_form, disco, iwokkel, pubsub, shim
    776  from wokkel.generic import parseXml
    777  from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub
    778  
    779 @@ -1225,7 +1225,8 @@
     767diff -r cf770fa6bcb7 wokkel/test/test_pubsub.py
     768--- a/wokkel/test/test_pubsub.py        Tue Apr 07 11:17:23 2009 +0200
     769+++ b/wokkel/test/test_pubsub.py        Tue Apr 07 11:25:27 2009 +0200
     770@@ -1222,7 +1222,8 @@
    780771 
    781772     def setUp(self):
     
    787778 
    788779     def test_interface(self):
    789 @@ -1263,19 +1264,120 @@
     780@@ -1260,12 +1261,12 @@
    790781         Test getDiscoInfo calls getNodeInfo and returns some minimal info.
    791782         """
     
    805796                                       JID('pubsub.example.org'), '')
    806797         d.addCallback(cb)
     798@@ -1282,11 +1283,11 @@
     799                 discoInfo.append(item)
     800             self.assertIn(('pubsub', 'collection'), discoInfo.identities)
     801 
     802-        def getNodeInfo(requestor, target, nodeIdentifier):
     803+        def getInfo(requestor, target, nodeIdentifier):
     804             return defer.succeed({'type': 'collection',
     805                                   'meta-data': {}})
     806 
     807-        self.service.getNodeInfo = getNodeInfo
     808+        self.resource.getInfo = getInfo
     809         d = self.service.getDiscoInfo(JID('user@example.org/home'),
     810                                       JID('pubsub.example.org'), '')
     811         d.addCallback(cb)
     812@@ -1307,20 +1308,100 @@
     813             form = discoInfo.extensions[NS_PUBSUB_META_DATA]
     814             self.assertIn('pubsub#node_type', form.fields)
     815 
     816-        def getNodeInfo(requestor, target, nodeIdentifier):
     817+        def getInfo(requestor, target, nodeIdentifier):
     818             metaData = [{'var': 'pubsub#persist_items',
     819                          'label': 'Persist items to storage',
     820                          'value': True}]
     821             return defer.succeed({'type': 'leaf', 'meta-data': metaData})
     822 
     823-        self.service.getNodeInfo = getNodeInfo
     824+        self.resource.getInfo = getInfo
     825         d = self.service.getDiscoInfo(JID('user@example.org/home'),
     826                                       JID('pubsub.example.org'), '')
     827         d.addCallback(cb)
    807828         return d
    808829 
    809830 
    810831-    def test_onPublish(self):
    811 +    def test_getDiscoInfoNodeType(self):
    812 +        """
    813 +        Test getDiscoInfo calls getNodeInfo and returns some minimal info.
    814 +        """
    815 +        def cb(info):
    816 +            discoInfo = disco.DiscoInfo()
    817 +            for item in info:
    818 +                discoInfo.append(item)
    819 +            self.assertIn(('pubsub', 'collection'), discoInfo.identities)
    820 +
    821 +        def getInfo(requestor, target, nodeIdentifier):
    822 +            return defer.succeed({'type': 'collection',
    823 +                                  'meta-data': {}})
    824 +
    825 +        self.resource.getInfo = getInfo
    826 +        d = self.service.getDiscoInfo(JID('user@example.org/home'),
    827 +                                      JID('pubsub.example.org'), '')
    828 +        d.addCallback(cb)
    829 +        return d
    830 +
    831 +
    832832+    def test_getDiscoInfoResourceFeatures(self):
    833833+        """
    834 +        Test getDiscoInfo calls getNodeInfo and returns some minimal info.
     834+        Test getDiscoInfo with the resource features.
    835835+        """
    836836+        def cb(info):
     
    914914         A publish request should result in L{PubSubService.publish} being
    915915         called.
    916 @@ -1293,12 +1395,12 @@
     916@@ -1338,12 +1419,12 @@
    917917         def publish(request):
    918918             return defer.succeed(None)
     
    930930         A successful subscription should return the current subscription.
    931931         """
    932 @@ -1326,14 +1428,14 @@
     932@@ -1371,14 +1452,14 @@
    933933             self.assertEqual('user@example.org/Home', subscription['jid'])
    934934             self.assertEqual('subscribed', subscription['subscription'])
     
    948948         A successful subscription on root node should return no node attribute.
    949949         """
    950 @@ -1355,14 +1457,14 @@
     950@@ -1400,14 +1481,14 @@
    951951         def cb(element):
    952952             self.assertFalse(element.subscription.hasAttribute('node'))
     
    966966         A successful unsubscription should return an empty response.
    967967         """
    968 @@ -1382,14 +1484,14 @@
     968@@ -1427,14 +1508,14 @@
    969969         def cb(element):
    970970             self.assertIdentical(None, element)
     
    984984         Getting subscription options is not supported.
    985985         """
    986 @@ -1414,7 +1516,7 @@
     986@@ -1459,7 +1540,7 @@
    987987         return d
    988988 
     
    993993         Setting subscription options is not supported.
    994994         """
    995 @@ -1446,7 +1548,7 @@
     995@@ -1491,7 +1572,7 @@
    996996         return d
    997997 
     
    10021002         A subscriptions request should result in
    10031003         L{PubSubService.subscriptions} being called and the result prepared
    1004 @@ -1462,6 +1564,11 @@
     1004@@ -1507,6 +1588,11 @@
    10051005         </iq>
    10061006         """
     
    10141014             self.assertEqual('pubsub', element.name)
    10151015             self.assertEqual(NS_PUBSUB, element.uri)
    1016 @@ -1475,20 +1582,14 @@
     1016@@ -1520,20 +1606,14 @@
    10171017             self.assertEqual('test', subscription['node'])
    10181018             self.assertEqual('subscribed', subscription['subscription'])
     
    10381038         A subscriptions request should result in
    10391039         L{PubSubService.affiliations} being called and the result prepared
    1040 @@ -1504,6 +1605,10 @@
     1040@@ -1549,6 +1629,10 @@
    10411041         </iq>
    10421042         """
     
    10491049             self.assertEqual('pubsub', element.name)
    10501050             self.assertEqual(NS_PUBSUB, element.uri)
    1051 @@ -1516,19 +1621,14 @@
     1051@@ -1561,19 +1645,14 @@
    10521052             self.assertEqual('test', affiliation['node'])
    10531053             self.assertEqual('owner', affiliation['affiliation'])
     
    10721072         Replies to create node requests don't return the created node.
    10731073         """
    1074 @@ -1548,14 +1648,14 @@
     1074@@ -1593,14 +1672,14 @@
    10751075         def cb(element):
    10761076             self.assertIdentical(None, element)
     
    10901090         Replies to create node requests return the created node if changed.
    10911091         """
    1092 @@ -1579,14 +1679,14 @@
     1092@@ -1624,14 +1703,14 @@
    10931093             self.assertEqual(u'myrenamednode',
    10941094                              element.create.getAttribute('node'))
     
    11081108         Replies to create instant node requests return the created node.
    11091109         """
    1110 @@ -1609,14 +1709,14 @@
     1110@@ -1654,14 +1733,14 @@
    11111111             self.assertEqual(NS_PUBSUB, element.create.uri)
    11121112             self.assertEqual(u'random', element.create.getAttribute('node'))
     
    11261126         A default request should result in
    11271127         L{PubSubService.getDefaultConfiguration} being called.
    1128 @@ -1641,7 +1741,7 @@
     1128@@ -1686,7 +1765,7 @@
    11291129                      "label": "Deliver payloads with event notifications"}
    11301130                 }
     
    11351135 
    11361136         def cb(element):
    1137 @@ -1651,15 +1751,15 @@
     1137@@ -1696,15 +1775,15 @@
    11381138             form = data_form.Form.fromElement(element.default.x)
    11391139             self.assertEqual(NS_PUBSUB_CONFIG, form.formNamespace)
     
    11551155         Responses to default requests should depend on passed node type.
    11561156         """
    1157 @@ -1690,19 +1790,19 @@
     1157@@ -1735,19 +1814,19 @@
    11581158                      "label": "Deliver payloads with event notifications"}
    11591159                 }
     
    11811181 
    11821182         xml = """
    1183 @@ -1724,24 +1824,25 @@
     1183@@ -1769,24 +1848,25 @@
    11841184         </iq>
    11851185         """
     
    12131213 
    12141214         xml = """
    1215 @@ -1766,7 +1867,7 @@
     1215@@ -1811,7 +1891,7 @@
    12161216                      "label": "Owner of the node"}
    12171217                 }
     
    12221222                                   'pubsub#persist_items': '1',
    12231223                                   'pubsub#owner': JID('user@example.org'),
    1224 @@ -1800,19 +1901,18 @@
     1224@@ -1845,19 +1925,18 @@
    12251225 
    12261226             self.assertNotIn('x-myfield', fields)
     
    12471247 
    12481248         xml = """
    1249 @@ -1842,21 +1942,21 @@
     1249@@ -1887,21 +1966,21 @@
    12501250                      "label": "Deliver payloads with event notifications"}
    12511251                 }
     
    12761276 
    12771277         xml = """
    1278 @@ -1874,15 +1974,15 @@
     1278@@ -1919,15 +1998,15 @@
    12791279         </iq>
    12801280         """
     
    12961296         On a node configuration set request unknown fields should be ignored.
    12971297         """
    1298 @@ -1914,17 +2014,17 @@
     1298@@ -1959,17 +2038,17 @@
    12991299                      "label": "Deliver payloads with event notifications"}
    13001300                 }
     
    13191319         On a node configuration set request unknown fields should be ignored.
    13201320         """
    1321 @@ -1955,7 +2055,7 @@
     1321@@ -2000,7 +2079,7 @@
    13221322         return d
    13231323 
     
    13281328         On a items request, return all items for the given node.
    13291329         """
    1330 @@ -1981,16 +2081,17 @@
     1330@@ -2026,16 +2105,17 @@
    13311331             self.assertEqual(NS_PUBSUB, item.uri)
    13321332             self.assertEqual('current', item['id'])
     
    13501350 
    13511351         xml = """
    1352 @@ -2008,13 +2109,14 @@
     1352@@ -2053,13 +2133,14 @@
    13531353         def retract(request):
    13541354             return defer.succeed(None)
     
    13681368         """
    13691369 
    1370 @@ -2030,13 +2132,14 @@
     1370@@ -2075,13 +2156,14 @@
    13711371         def purge(request):
    13721372             return defer.succeed(None)
     
    13861386         """
    13871387 
    1388 @@ -2052,7 +2155,8 @@
     1388@@ -2097,7 +2179,8 @@
    13891389         def delete(request):
    13901390             return defer.succeed(None)
     
    13961396 
    13971397 
    1398 @@ -2103,7 +2207,7 @@
     1398@@ -2148,7 +2231,7 @@
    13991399         self.assertEqual(redirectURI, message.event.delete.redirect['uri'])
    14001400 
     
    14051405         Getting subscription options is not supported.
    14061406         """
    1407 @@ -2130,7 +2234,7 @@
     1407@@ -2175,7 +2258,7 @@
    14081408         return d
    14091409 
     
    14141414         Setting subscription options is not supported.
    14151415         """
    1416 @@ -2157,7 +2261,7 @@
     1416@@ -2202,7 +2285,7 @@
    14171417         return d
    14181418 
     
    14231423         Getting subscription options is not supported.
    14241424         """
    1425 @@ -2184,7 +2288,7 @@
     1425@@ -2229,7 +2312,7 @@
    14261426         return d
    14271427 
     
    14321432         Setting subscription options is not supported.
    14331433         """
    1434 @@ -2211,18 +2315,38 @@
     1434@@ -2256,18 +2339,38 @@
    14351435         return d
    14361436 
     
    14811481 
    14821482         def cb(result):
    1483 @@ -2231,7 +2355,7 @@
     1483@@ -2276,7 +2379,7 @@
    14841484             self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    14851485             self.assertEquals('publish', result.appCondition['feature'])
     
    14901490         d.addCallback(cb)
    14911491         return d
    1492 @@ -2239,16 +2363,7 @@
     1492@@ -2284,16 +2387,7 @@
    14931493 
    14941494     def test_subscribe(self):
     
    15081508 
    15091509         def cb(result):
    1510 @@ -2257,7 +2372,7 @@
     1510@@ -2302,7 +2396,7 @@
    15111511             self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    15121512             self.assertEquals('subscribe', result.appCondition['feature'])
     
    15171517         d.addCallback(cb)
    15181518         return d
    1519 @@ -2265,16 +2380,7 @@
     1519@@ -2310,16 +2404,7 @@
    15201520 
    15211521     def test_unsubscribe(self):
     
    15351535 
    15361536         def cb(result):
    1537 @@ -2283,7 +2389,7 @@
     1537@@ -2328,7 +2413,7 @@
    15381538             self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    15391539             self.assertEquals('subscribe', result.appCondition['feature'])
     
    15441544         d.addCallback(cb)
    15451545         return d
    1546 @@ -2291,16 +2397,7 @@
     1546@@ -2336,16 +2421,7 @@
    15471547 
    15481548     def test_subscriptions(self):
     
    15621562 
    15631563         def cb(result):
    1564 @@ -2310,7 +2407,7 @@
     1564@@ -2355,7 +2431,7 @@
    15651565             self.assertEquals('retrieve-subscriptions',
    15661566                               result.appCondition['feature'])
     
    15711571         d.addCallback(cb)
    15721572         return d
    1573 @@ -2318,16 +2415,7 @@
     1573@@ -2363,16 +2439,7 @@
    15741574 
    15751575     def test_affiliations(self):
     
    15891589 
    15901590         def cb(result):
    1591 @@ -2337,7 +2425,7 @@
     1591@@ -2382,7 +2449,7 @@
    15921592             self.assertEquals('retrieve-affiliations',
    15931593                               result.appCondition['feature'])
     
    15981598         d.addCallback(cb)
    15991599         return d
    1600 @@ -2345,16 +2433,7 @@
     1600@@ -2390,16 +2457,7 @@
    16011601 
    16021602     def test_create(self):
     
    16161616 
    16171617         def cb(result):
    1618 @@ -2363,87 +2442,51 @@
     1618@@ -2408,87 +2466,51 @@
    16191619             self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    16201620             self.assertEquals('create-nodes', result.appCondition['feature'])
     
    17151715 
    17161716         def cb(result):
    1717 @@ -2452,7 +2495,7 @@
     1717@@ -2497,7 +2519,7 @@
    17181718             self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    17191719             self.assertEquals('config-node', result.appCondition['feature'])
     
    17241724         d.addCallback(cb)
    17251725         return d
    1726 @@ -2460,15 +2503,7 @@
     1726@@ -2505,15 +2527,7 @@
    17271727 
    17281728     def test_items(self):
     
    17411741 
    17421742         def cb(result):
    1743 @@ -2477,7 +2512,7 @@
     1743@@ -2522,7 +2536,7 @@
    17441744             self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    17451745             self.assertEquals('retrieve-items', result.appCondition['feature'])
     
    17501750         d.addCallback(cb)
    17511751         return d
    1752 @@ -2485,18 +2520,7 @@
     1752@@ -2530,18 +2544,7 @@
    17531753 
    17541754     def test_retract(self):
     
    17701770 
    17711771         def cb(result):
    1772 @@ -2505,7 +2529,7 @@
     1772@@ -2550,7 +2553,7 @@
    17731773             self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    17741774             self.assertEquals('retract-items', result.appCondition['feature'])
     
    17791779         d.addCallback(cb)
    17801780         return d
    1781 @@ -2513,15 +2537,7 @@
     1781@@ -2558,15 +2561,7 @@
    17821782 
    17831783     def test_purge(self):
     
    17961796 
    17971797         def cb(result):
    1798 @@ -2530,7 +2546,7 @@
     1798@@ -2575,7 +2570,7 @@
    17991799             self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    18001800             self.assertEquals('purge-nodes', result.appCondition['feature'])
     
    18051805         d.addCallback(cb)
    18061806         return d
    1807 @@ -2538,15 +2554,7 @@
     1807@@ -2583,15 +2578,7 @@
    18081808 
    18091809     def test_delete(self):
     
    18221822 
    18231823         def cb(result):
    1824 @@ -2555,7 +2563,7 @@
     1824@@ -2600,7 +2587,7 @@
    18251825             self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri)
    18261826             self.assertEquals('delete-nodes', result.appCondition['feature'])
  • release-0.5.patch

    r1 r7  
    1 diff -r 64319a254f83 LICENSE
    2 --- a/LICENSE   Wed Feb 04 14:42:34 2009 +0100
    3 +++ b/LICENSE   Wed Feb 04 15:30:11 2009 +0100
     1diff -r a3563a451736 LICENSE
     2--- a/LICENSE   Tue Apr 07 09:22:25 2009 +0200
     3+++ b/LICENSE   Tue Apr 07 09:24:47 2009 +0200
    44@@ -1,4 +1,4 @@
    55-Copyright (c) 2003-2008 Ralph Meijer
     
    88 Permission is hereby granted, free of charge, to any person obtaining
    99 a copy of this software and associated documentation files (the
    10 diff -r 64319a254f83 NEWS
    11 --- a/NEWS      Wed Feb 04 14:42:34 2009 +0100
    12 +++ b/NEWS      Wed Feb 04 15:30:11 2009 +0100
     10diff -r a3563a451736 NEWS
     11--- a/NEWS      Tue Apr 07 09:22:25 2009 +0200
     12+++ b/NEWS      Tue Apr 07 09:24:47 2009 +0200
    1313@@ -1,3 +1,37 @@
    14 +0.5.0 (2009-02-04)
     14+0.5.0 (2009-04-07)
    1515+==================
    1616+
     
    3636+-----
    3737+
    38 + - Publish-Subscribe subscriptions requests work again (#22, Mike Malone).
     38+ - Publish-Subscribe subscriptions requests work again (#22).
    3939+ - Publish-Subscribe delete node requests now have the correct namespace (#27).
    4040+ - NodeIDs in Service Discovery requests are now returned in responses (#7).
     
    4949 ==================
    5050 
    51 diff -r 64319a254f83 README
    52 --- a/README    Wed Feb 04 14:42:34 2009 +0100
    53 +++ b/README    Wed Feb 04 15:30:11 2009 +0100
     51diff -r a3563a451736 README
     52--- a/README    Tue Apr 07 09:22:25 2009 +0200
     53+++ b/README    Tue Apr 07 09:24:47 2009 +0200
    5454@@ -1,30 +1,53 @@
    5555-Wokkel 0.4.0
     
    117117 Ralph Meijer
    118118 <xmpp:ralphm@ik.nu>
    119 diff -r 64319a254f83 setup.py
    120 --- a/setup.py  Wed Feb 04 14:42:34 2009 +0100
    121 +++ b/setup.py  Wed Feb 04 15:30:11 2009 +0100
     119diff -r a3563a451736 setup.py
     120--- a/setup.py  Tue Apr 07 09:22:25 2009 +0200
     121+++ b/setup.py  Tue Apr 07 09:24:47 2009 +0200
    122122@@ -1,12 +1,12 @@
    123123 #!/usr/bin/env python
  • s2s.patch

    r6 r7  
    1 diff -r c52801c0d6c2 wokkel/server.py
     1diff -r 842c0a2f8fa1 wokkel/server.py
    22--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
    3 +++ b/wokkel/server.py  Wed Apr 01 17:23:43 2009 +0200
    4 @@ -0,0 +1,566 @@
     3+++ b/wokkel/server.py  Tue Apr 07 09:17:35 2009 +0200
     4@@ -0,0 +1,684 @@
    55+# -*- test-case-name: wokkel.test.test_server -*-
    66+#
     
    225225+
    226226+class XMPPServerConnectAuthenticator(xmlstream.ConnectAuthenticator):
     227+    """
     228+    Authenticator for an outgoing XMPP server-to-server connection.
     229+
     230+    This authenticator connects to C{otherHost} (the Receiving Server) and then
     231+    initiates dialback as C{thisHost} (the Originating Server) using
     232+    L{OriginatingDialbackInitializer}.
     233+
     234+    @ivar thisHost: The domain this server connects from (the Originating
     235+                    Server) .
     236+    @ivar otherHost: The domain of the server this server connects to (the
     237+                     Receiving Server).
     238+    @ivar secret: The shared secret that is used for verifying the validity
     239+                  of this new connection.
     240+    """
    227241+    namespace = 'jabber:server'
    228242+
     
    250264+
    251265+class XMPPServerVerifyAuthenticator(xmlstream.ConnectAuthenticator):
     266+    """
     267+    Authenticator for an outgoing connection to verify an incoming connection.
     268+
     269+    This authenticator connects to C{otherHost} (the Authoritative Server) and
     270+    then initiates dialback as C{thisHost} (the Receiving Server) using
     271+    L{ReceivingDialbackInitializer}.
     272+
     273+    @ivar thisHost: The domain this server connects from (the Receiving
     274+                    Server) .
     275+    @ivar otherHost: The domain of the server this server connects to (the
     276+                     Authoritative Server).
     277+    @ivar originalStreamID: The stream ID of the incoming connection that is
     278+                            being verified.
     279+    @ivar key: The key provided by the Receving Server to be verified.
     280+    """
    252281+    namespace = 'jabber:server'
    253282+
     
    276305+
    277306+class XMPPServerListenAuthenticator(xmlstream.ListenAuthenticator):
     307+    """
     308+    Authenticator for an incoming XMPP server-to-server connection.
     309+
     310+    This authenticator handles two types of incoming connections. Regular
     311+    server-to-server connections are from the Originating Server to the
     312+    Receiving Server, where this server is the Receiving Server. These
     313+    connections start out by receiving a dialback key, verifying the
     314+    key with the Authoritative Server, and then accept normal XMPP stanzas.
     315+
     316+    The other type of connections is from a Receiving Server to an
     317+    Authoritative Server, where this server acts as the Authoritative Server.
     318+    These connections are used to verify the validity of an outgoing connection
     319+    from this server. In this case, this server receives a verification
     320+    request, checks the key and then returns the result.
     321+
     322+    @ivar service: The service that keeps the list of domains we accept
     323+                   connections for.
     324+    """
    278325+    namespace = 'jabber:server'
    279 +    connectorClass = XMPPServerConnector
    280 +
    281 +    def __init__(self, domain, secret):
     326+
     327+    def __init__(self, service):
    282328+        xmlstream.ListenAuthenticator.__init__(self)
    283 +        self.domain = domain
    284 +        self.secret = secret
     329+        self.service = service
    285330+
    286331+
     
    293338+            self.xmlstream.sid = randbytes.secureRandom(8).encode('hex')
    294339+
    295 +        def prepareStream():
     340+        if self.xmlstream.thisEntity:
     341+            targetDomain = self.xmlstream.thisEntity.host
     342+        else:
     343+            targetDomain = self.service.defaultDomain
     344+
     345+        def prepareStream(domain):
    296346+            self.xmlstream.namespace = self.namespace
    297347+            self.xmlstream.prefixes = {xmlstream.NS_STREAMS: 'stream',
    298348+                                       NS_DIALBACK: 'db'}
    299 +            self.xmlstream.thisEntity = jid.internJID(self.domain)
     349+            self.xmlstream.thisEntity = jid.internJID(domain)
    300350+
    301351+        try:
     
    305355+                raise error.StreamError('invalid-namespace')
    306356+
    307 +            if self.xmlstream.thisEntity.full() != self.domain:
     357+            if targetDomain not in self.service.domains:
    308358+                raise error.StreamError('host-unknown')
    309359+        except error.StreamError, exc:
    310 +            prepareStream()
     360+            prepareStream(self.service.defaultDomain)
    311361+            self.xmlstream.sendStreamError(exc)
    312362+            return
     
    318368+                                   self.onResult)
    319369+
    320 +        prepareStream()
     370+        prepareStream(targetDomain)
    321371+        self.xmlstream.sendHeader()
    322372+
     
    326376+
    327377+
    328 +
    329378+    def onVerify(self, verify):
    330379+        try:
    331 +            receivingServer = jid.JID(verify['from'])
    332 +            originatingServer = jid.JID(verify['to'])
     380+            receivingServer = jid.JID(verify['from']).host
     381+            originatingServer = jid.JID(verify['to']).host
    333382+        except (KeyError, jid.InvalidFormat):
    334383+            raise error.StreamError('improper-addressing')
    335384+
    336 +        if originatingServer != self.domain:
     385+        if originatingServer not in self.service.domains:
    337386+            raise error.StreamError('host-unknown')
    338387+
    339 +        if receivingServer != self.xmlstream.thisEntity:
     388+        if (self.xmlstream.otherEntity and
     389+            receivingServer != self.xmlstream.otherEntity.host):
    340390+            raise error.StreamError('invalid-from')
    341391+
     
    343393+        key = unicode(verify)
    344394+
    345 +        calculatedKey = generateKey(self.secret, receivingServer,
     395+        calculatedKey = generateKey(self.service.secret, receivingServer,
    346396+                                    originatingServer, streamID)
    347397+        validity = (key == calculatedKey) and 'valid' or 'invalid'
     
    356406+
    357407+    def onResult(self, result):
    358 +        def connected(xs):
    359 +            self.verifyStream = xs
    360 +
    361 +            def logDataIn(buf):
    362 +                log.msg("RECV!: %r" % buf)
    363 +
    364 +            def logDataOut(buf):
    365 +                log.msg("SEND!: %r" % buf)
    366 +
    367 +            xs.rawDataInFn = logDataIn
    368 +            xs.rawDataOutFn = logDataOut
    369 +
    370408+        def reply(validity):
    371 +            factory.stopTrying()
    372 +            self.verifyStream.transport.loseConnection()
    373 +            self.verifyStream = None
    374 +
    375409+            reply = domish.Element((NS_DIALBACK, 'result'))
    376410+            reply['from'] = result['to']
     
    386420+
    387421+        def invalid(failure):
     422+            log.err(failure)
    388423+            reply('invalid')
    389424+
     425+        receivingServer = result['to']
    390426+        originatingServer = result['from']
    391 +
    392 +        authenticator = XMPPServerVerifyAuthenticator(self.domain,
    393 +                                                      originatingServer,
    394 +                                                      self.xmlstream.sid,
    395 +                                                      unicode(result))
    396 +        factory = xmlstream.XmlStreamFactory(authenticator)
    397 +        factory.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT, connected)
    398 +        factory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, valid)
    399 +        factory.addBootstrap(xmlstream.INIT_FAILED_EVENT, invalid)
    400 +        connector = self.connectorClass(reactor,
    401 +                                        originatingServer,
    402 +                                        factory)
    403 +        connector.connect()
     427+        key = unicode(result)
     428+
     429+        d = self.service.validateConnection(receivingServer, originatingServer,
     430+                                            self.xmlstream.sid, key)
     431+        d.addCallbacks(valid, invalid)
     432+        return d
    404433+
    405434+
     
    414443+    """
    415444+
    416 +    def __init__(self, domain, otherHost, secret):
    417 +        authenticator = XMPPServerConnectAuthenticator(domain,
    418 +                                                            otherHost,
    419 +                                                            secret)
     445+    def __init__(self, authenticator):
    420446+        DeferredXmlStreamFactory.__init__(self, authenticator)
     447+
     448+        self.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT,
     449+                          self.onConnectionMade)
     450+
     451+        self.serial = 0
     452+
     453+
     454+    def onConnectionMade(self, xs):
     455+        xs.serial = self.serial
     456+        self.serial += 1
     457+
     458+        def logDataIn(buf):
     459+            log.msg("RECV (%d): %r" % (xs.serial, buf))
     460+
     461+        def logDataOut(buf):
     462+            log.msg("SEND (%d): %r" % (xs.serial, buf))
     463+
     464+        if self.logTraffic:
     465+            xs.rawDataInFn = logDataIn
     466+            xs.rawDataOutFn = logDataOut
    421467+
    422468+
     
    430476+
    431477+
    432 +class ServerService(service.Service):
     478+class XMPPS2SServerFactory(XmlStreamServerFactory):
     479+    """
     480+    XMPP Server-to-Server Server factory.
     481+
     482+    This factory accepts XMPP server-to-server connections.
     483+    """
     484+
     485+    logTraffic = False
     486+
     487+    def __init__(self, service):
     488+        self.service = service
     489+
     490+        def authenticatorFactory():
     491+            return XMPPServerListenAuthenticator(service)
     492+
     493+        XmlStreamServerFactory.__init__(self, authenticatorFactory)
     494+        self.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT,
     495+                          self.onConnectionMade)
     496+        self.addBootstrap(xmlstream.STREAM_AUTHD_EVENT,
     497+                          self.onAuthenticated)
     498+
     499+        self.serial = 0
     500+
     501+
     502+    def onConnectionMade(self, xs):
     503+        """
     504+        Called when a server-to-server connection was made.
     505+
     506+        This enables traffic debugging on incoming streams.
     507+        """
     508+        xs.serial = self.serial
     509+        self.serial += 1
     510+
     511+        def logDataIn(buf):
     512+            log.msg("RECV (%d): %r" % (xs.serial, buf))
     513+
     514+        def logDataOut(buf):
     515+            log.msg("SEND (%d): %r" % (xs.serial, buf))
     516+
     517+        if self.logTraffic:
     518+            xs.rawDataInFn = logDataIn
     519+            xs.rawDataOutFn = logDataOut
     520+
     521+        xs.addObserver(xmlstream.STREAM_ERROR_EVENT, self.onError)
     522+
     523+
     524+    def onAuthenticated(self, xs):
     525+        thisHost = xs.thisEntity.host
     526+        otherHost = xs.otherEntity.host
     527+
     528+        log.msg("Incoming connection %d from %r to %r established" %
     529+                (xs.serial, otherHost, thisHost))
     530+
     531+        xs.addObserver(xmlstream.STREAM_END_EVENT, self.onConnectionLost,
     532+                                                   0, xs)
     533+        xs.addObserver('/*', self.onElement, 0, xs)
     534+
     535+
     536+    def onConnectionLost(self, xs, reason):
     537+        thisHost = xs.thisEntity.host
     538+        otherHost = xs.otherEntity.host
     539+
     540+        log.msg("Incoming connection %d from %r to %r disconnected" %
     541+                (xs.serial, otherHost, thisHost))
     542+
     543+
     544+    def onError(self, reason):
     545+        log.err(reason, "Stream Error")
     546+
     547+
     548+    def onElement(self, element, xs):
     549+        """
     550+        Called when an element was received from one of the connected streams.
     551+
     552+        """
     553+        if element.handled:
     554+            return
     555+
     556+        if jid.internJID(element["from"]).host != xs.otherEntity.host:
     557+            xs.sendStreamError(error.StreamError('invalid-from'))
     558+        else:
     559+            self.service.dispatch(element)
     560+
     561+
     562+
     563+class ServerService(object):
    433564+    """
    434565+    Service for managing XMPP server to server connections.
     
    437568+    logTraffic = False
    438569+
    439 +    def __init__(self, router, domain, port=5222):
     570+    def __init__(self, router, secret, domain):
    440571+        self.router = router
    441 +        self.domain = domain
    442 +        self.port = port
    443 +        self.secret = 'woei!'
    444 +
    445 +        def authenticatorFactory():
    446 +            return XMPPServerListenAuthenticator(self.domain, self.secret)
    447 +        self.factory = XmlStreamServerFactory(authenticatorFactory)
    448 +        self.factory.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT,
    449 +                                  self.makeConnection)
    450 +        self.factory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT,
    451 +                                  self.incomingInitialized)
    452 +
    453 +        self.incomingStreams = {}
    454 +        self.outgoingStreams = {}
    455 +        self.outgoingQueues = {}
    456 +        self.outgoingConnecting = set()
     572+        self.secret = secret
     573+        self.defaultDomain = domain
     574+        self.domains = set([domain])
     575+
     576+        self._outgoingStreams = {}
     577+        self._outgoingQueues = {}
     578+        self._outgoingConnecting = set()
    457579+        self.serial = 0
    458580+
    459 +
    460 +    def startService(self):
    461581+        pipe = XmlPipe()
    462582+        self.xmlstream = pipe.source
     
    464584+        self.xmlstream.addObserver('/*', self.send)
    465585+
    466 +        service.Service.startService(self)
    467 +        reactor.listenTCP(self.port, self.factory)
    468 +
    469 +
    470 +    def makeConnection(self, xs):
    471 +        xs.serial = self.serial
    472 +        self.serial += 1
    473 +
    474 +        def logDataIn(buf):
    475 +            log.msg("RECV (%d): %r" % (xs.serial, buf))
    476 +
    477 +        def logDataOut(buf):
    478 +            log.msg("SEND (%d): %r" % (xs.serial, buf))
    479 +
    480 +        if self.logTraffic:
    481 +            xs.rawDataInFn = logDataIn
    482 +            xs.rawDataOutFn = logDataOut
    483 +
    484 +
    485 +    def incomingInitialized(self, xs):
    486 +        self.incomingStreams[xs.otherEntity.host] = xs
    487 +        xs.addObserver(xmlstream.STREAM_END_EVENT,
    488 +                       lambda _: self.incomingDisconnected(xs))
    489 +        xs.addObserver('/*', lambda element: self.onElement(element, xs))
    490 +
    491 +
    492 +    def incomingDisconnected(self, xs):
    493 +        del self.incomingStreams[xs.otherEntity.host]
    494 +
    495586+
    496587+    def outgoingInitialized(self, xs):
    497 +        self.outgoingStreams[xs.otherEntity.host] = xs
     588+        thisHost = xs.thisEntity.host
     589+        otherHost = xs.otherEntity.host
     590+
     591+        log.msg("Outgoing connection %d from %r to %r established" %
     592+                (xs.serial, thisHost, otherHost))
     593+
     594+        self._outgoingStreams[thisHost, otherHost] = xs
    498595+        xs.addObserver(xmlstream.STREAM_END_EVENT,
    499596+                       lambda _: self.outgoingDisconnected(xs))
    500597+
    501 +        if xs.otherEntity.host in self.outgoingQueues:
    502 +            print "Hier!"
    503 +            for element in self.outgoingQueues[xs.otherEntity.host]:
     598+        if (thisHost, otherHost) in self._outgoingQueues:
     599+            for element in self._outgoingQueues[thisHost, otherHost]:
    504600+                xs.send(element)
    505 +            del self.outgoingQueues[xs.otherEntity.host]
     601+            del self._outgoingQueues[thisHost, otherHost]
    506602+
    507603+
    508604+    def outgoingDisconnected(self, xs):
    509 +        del self.outgoingStreams[xs.otherEntity.host]
    510 +
    511 +
    512 +    def initiateOutgoingStream(self, otherHost):
    513 +        if otherHost in self.outgoingConnecting:
     605+        thisHost = xs.thisEntity.host
     606+        otherHost = xs.otherEntity.host
     607+
     608+        log.msg("Outgoing connection %d from %r to %r disconnected" %
     609+                (xs.serial, thisHost, otherHost))
     610+
     611+        del self._outgoingStreams[thisHost, otherHost]
     612+
     613+
     614+    def initiateOutgoingStream(self, thisHost, otherHost):
     615+        """
     616+        Initiate an outgoing XMPP server-to-server connection.
     617+        """
     618+
     619+        def resetConnecting(_):
     620+            self._outgoingConnecting.remove((thisHost, otherHost))
     621+
     622+        if (thisHost, otherHost) in self._outgoingConnecting:
    514623+            return
    515624+
    516 +        factory = DeferredS2SClientFactory(self.domain,
    517 +                                           otherHost,
    518 +                                           self.secret)
    519 +        factory.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT,
    520 +                             self.makeConnection)
     625+        authenticator = XMPPServerConnectAuthenticator(thisHost,
     626+                                                       otherHost,
     627+                                                       self.secret)
     628+        factory = DeferredS2SClientFactory(authenticator)
    521629+        factory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT,
    522630+                             self.outgoingInitialized)
    523631+
    524 +        def resetConnecting(_):
    525 +            self.outgoingConnecting.remove(otherHost)
     632+        self._outgoingConnecting.add((thisHost, otherHost))
    526633+
    527634+        d = initiateS2S(factory)
    528 +        def debug(result):
    529 +            print result
    530 +            return result
    531 +        d.addBoth(debug)
    532635+        d.addBoth(resetConnecting)
    533 +        self.outgoingConnecting.add(otherHost)
    534 +
    535 +
    536 +    def onElement(self, element, xs):
    537 +        """
    538 +        Called when an element was received from one of the connected streams.
    539 +
    540 +        """
    541 +        if element.handled:
    542 +            return
    543 +
    544 +        if jid.internJID(element["from"]).host != xs.otherEntity.host:
    545 +            xs.sendStreamError(error.StreamError('invalid-from'))
    546 +        else:
    547 +            self.xmlstream.send(element)
     636+        return d
     637+
     638+
     639+    def validateConnection(self, thisHost, otherHost, sid, key):
     640+        """
     641+        Validate an incoming XMPP server-to-server connection.
     642+        """
     643+
     644+        def connected(xs):
     645+            # Set up stream for immediate disconnection.
     646+            def disconnect(_):
     647+                xs.transport.loseConnection()
     648+            xs.addObserver(xmlstream.STREAM_AUTHD_EVENT, disconnect)
     649+            xs.addObserver(xmlstream.INIT_FAILED_EVENT, disconnect)
     650+
     651+        authenticator = XMPPServerVerifyAuthenticator(thisHost, otherHost,
     652+                                                      sid, key)
     653+        factory = DeferredS2SClientFactory(authenticator)
     654+        factory.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT, connected)
     655+
     656+        d = initiateS2S(factory)
     657+        return d
    548658+
    549659+
     
    556666+        """
    557667+
    558 +        destination = jid.internJID(stanza["to"]).host
    559 +
    560 +        if destination not in self.outgoingStreams:
     668+        otherHost = jid.internJID(stanza["to"]).host
     669+        thisHost = jid.internJID(stanza["from"]).host
     670+
     671+        if (thisHost, otherHost) not in self._outgoingStreams:
    561672+            # There is no connection with the destination (yet). Cache the
    562673+            # outgoing stanza until the connection has been established.
    563674+            # XXX: If the connection cannot be established, the queue should
    564675+            #      be emptied at some point.
    565 +            if destination not in self.outgoingQueues:
    566 +                self.outgoingQueues[destination] = []
    567 +            self.outgoingQueues[destination].append(stanza)
    568 +            self.initiateOutgoingStream(destination)
     676+            if (thisHost, otherHost) not in self._outgoingQueues:
     677+                self._outgoingQueues[(thisHost, otherHost)] = []
     678+            self._outgoingQueues[(thisHost, otherHost)].append(stanza)
     679+            self.initiateOutgoingStream(thisHost, otherHost)
    569680+        else:
    570 +            self.outgoingStreams[destination].send(stanza)
    571 diff -r c52801c0d6c2 wokkel/test/test_server.py
     681+            self._outgoingStreams[(thisHost, otherHost)].send(stanza)
     682+
     683+
     684+    def dispatch(self, element):
     685+        """
     686+        Send on element to be routed within the server.
     687+        """
     688+        self.xmlstream.send(element)
     689diff -r 842c0a2f8fa1 wokkel/test/test_server.py
    572690--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
    573 +++ b/wokkel/test/test_server.py        Wed Apr 01 17:23:43 2009 +0200
    574 @@ -0,0 +1,227 @@
     691+++ b/wokkel/test/test_server.py        Tue Apr 07 09:17:35 2009 +0200
     692@@ -0,0 +1,412 @@
    575693+# Copyright (c) 2003-2008 Ralph Meijer
    576694+# See LICENSE for details.
     
    580698+"""
    581699+
     700+from twisted.internet import defer
     701+from twisted.python import failure
     702+from twisted.test.proto_helpers import StringTransport
    582703+from twisted.trial import unittest
    583 +from twisted.words.protocols.jabber import error, xmlstream
    584 +from twisted.test.proto_helpers import StringTransport
    585 +
    586 +from wokkel import server
     704+from twisted.words.protocols.jabber import error, jid, xmlstream
     705+from twisted.words.xish import domish
     706+
     707+from wokkel import component, server
    587708+
    588709+NS_STREAMS = 'http://etherx.jabber.org/streams'
    589 +DIALBACK_NS = "jabber:server:dialback"
     710+NS_DIALBACK = "jabber:server:dialback"
    590711+
    591712+class GenerateKeyTest(unittest.TestCase):
     
    595716+
    596717+    def testBasic(self):
     718+        originating = "example.org"
     719+        receiving = "xmpp.example.com"
     720+        sid = "D60000229F"
    597721+        secret = "s3cr3tf0rd14lb4ck"
    598 +        receiving = "example.net"
    599 +        originating = "example.com"
    600 +        id = "D60000229F"
    601 +
    602 +        key = server.generateKey(secret, receiving, originating, id)
     722+
     723+        key = server.generateKey(secret, receiving, originating, sid)
    603724+
    604725+        self.assertEqual(key,
    605 +            '008c689ff366b50c63d69a3e2d2c0e0e1f8404b0118eb688a0102c87cb691bdc')
     726+            '37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643')
    606727+
    607728+
     
    612733+    """
    613734+
    614 +    receiving = "example.org"
    615 +    originating = "example.net"
    616 +    id_ = "2093845023948"
    617 +    secret = "not-telling"
     735+    secret = "s3cr3tf0rd14lb4ck"
     736+    originating = "example.org"
     737+    receiving = "xmpp.example.com"
     738+    sid = "D60000229F"
     739+    key = '37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643'
    618740+
    619741+    def setUp(self):
    620742+        self.output = []
    621 +        self.authenticator = server.XMPPServerListenAuthenticator(
    622 +                        self.receiving, self.secret)
     743+
     744+        class MyService(object):
     745+            pass
     746+
     747+        self.service = MyService()
     748+        self.service.defaultDomain = self.receiving
     749+        self.service.domains = [self.receiving, 'pubsub.'+self.receiving]
     750+        self.service.secret = self.secret
     751+
     752+        self.authenticator = server.XMPPServerListenAuthenticator(self.service)
    623753+        self.xmlstream = xmlstream.XmlStream(self.authenticator)
    624754+        self.xmlstream.send = self.output.append
     
    630760+        Test attributes of authenticator and stream objects.
    631761+        """
    632 +        self.assertEquals(self.secret, self.authenticator.secret)
    633 +        self.assertEquals(self.receiving, self.authenticator.domain)
    634 +        self.assertEquals(self.xmlstream.initiating, False)
     762+        self.assertEqual(self.service, self.authenticator.service)
     763+        self.assertEqual(self.xmlstream.initiating, False)
    635764+
    636765+
     
    644773+                           "xmlns:db='jabber:server:dialback' "
    645774+                           "xmlns='jabber:server' "
    646 +                           "to='example.org'>")
     775+                           "to='xmpp.example.com'>")
    647776+        self.assertEqual((0, 0), self.xmlstream.version)
    648777+
     
    657786+                           "xmlns:db='jabber:server:dialback' "
    658787+                           "xmlns='jabber:server' "
    659 +                           "to='example.org' "
     788+                           "to='xmpp.example.com' "
    660789+                           "version='1.0'>")
    661790+        self.assertEqual((1, 0), self.xmlstream.version)
     
    673802+                           "xmlns:db='jabber:server:dialback' "
    674803+                           "xmlns='jabber:server' "
    675 +                           "to='example.org' "
     804+                           "to='xmpp.example.com' "
    676805+                           "version='1.0'>")
    677806+        self.assertNotIdentical(None, self.xmlstream.sid)
     
    689818+                           "xmlns:db='jabber:server:dialback' "
    690819+                           "xmlns='jabber:server' "
    691 +                           "to='example.org'>")
     820+                           "to='xmpp.example.com'>")
    692821+        self.assertTrue(self.xmlstream._headerSent)
    693822+
     
    702831+                           "xmlns:db='jabber:server:dialback' "
    703832+                           "xmlns='jabber:server' "
    704 +                           "to='example.org'>")
     833+                           "to='xmpp.example.com'>")
    705834+        self.assertEqual(1, len(self.output))
    706835+
     
    715844+                           "xmlns:db='jabber:server:dialback' "
    716845+                           "xmlns='jabber:server' "
    717 +                           "to='example.org' "
     846+                           "to='xmpp.example.com' "
    718847+                           "version='1.0'>")
    719848+        self.assertEqual(2, len(self.output))
     
    732861+                           "xmlns:db='jabber:server:dialback' "
    733862+                           "xmlns='jabber:server' "
    734 +                           "to='example.org'>")
    735 +
    736 +        self.assertEquals(3, len(self.output))
     863+                           "to='xmpp.example.com'>")
     864+
     865+        self.assertEqual(3, len(self.output))
    737866+        exc = error.exceptionFromStreamError(self.output[1])
    738 +        self.assertEquals('invalid-namespace', exc.condition)
     867+        self.assertEqual('invalid-namespace', exc.condition)
    739868+
    740869+
     
    748877+                           "xmlns:db='jabber:server:dialback' "
    749878+                           "xmlns='badns' "
    750 +                           "to='example.org'>")
    751 +
    752 +        self.assertEquals(3, len(self.output))
     879+                           "to='xmpp.example.com'>")
     880+
     881+        self.assertEqual(3, len(self.output))
    753882+        exc = error.exceptionFromStreamError(self.output[1])
    754 +        self.assertEquals('invalid-namespace', exc.condition)
     883+        self.assertEqual('invalid-namespace', exc.condition)
    755884+
    756885+
     
    763892+            "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
    764893+                           "xmlns='jabber:server' "
    765 +                           "to='example.org'>")
    766 +
    767 +        self.assertEquals(3, len(self.output))
     894+                           "to='xmpp.example.com'>")
     895+
     896+        self.assertEqual(3, len(self.output))
    768897+        exc = error.exceptionFromStreamError(self.output[1])
    769 +        self.assertEquals('invalid-namespace', exc.condition)
     898+        self.assertEqual('invalid-namespace', exc.condition)
    770899+
    771900+
     
    779908+                           "xmlns:db='badns' "
    780909+                           "xmlns='jabber:server' "
    781 +                           "to='example.org'>")
    782 +
    783 +        self.assertEquals(3, len(self.output))
     910+                           "to='xmpp.example.com'>")
     911+
     912+        self.assertEqual(3, len(self.output))
    784913+        exc = error.exceptionFromStreamError(self.output[1])
    785 +        self.assertEquals('invalid-namespace', exc.condition)
     914+        self.assertEqual('invalid-namespace', exc.condition)
    786915+
    787916+
     
    797926+                           "to='badhost'>")
    798927+
    799 +        self.assertEquals(3, len(self.output))
     928+        self.assertEqual(3, len(self.output))
    800929+        exc = error.exceptionFromStreamError(self.output[1])
    801 +        self.assertEquals('host-unknown', exc.condition)
     930+        self.assertEqual('host-unknown', exc.condition)
     931+
     932+
     933+    def test_streamToOtherLocalHost(self):
     934+        """
     935+        The authenticator supports XMPP 1.0 streams.
     936+        """
     937+        self.xmlstream.connectionMade()
     938+        self.xmlstream.dataReceived(
     939+            "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
     940+                           "xmlns:db='jabber:server:dialback' "
     941+                           "xmlns='jabber:server' "
     942+                           "to='pubsub.xmpp.example.com' "
     943+                           "version='1.0'>")
     944+
     945+        self.assertEqual(2, len(self.output))
     946+        self.assertEqual(jid.JID('pubsub.xmpp.example.com'),
     947+                         self.xmlstream.thisEntity)
     948+
     949+    def test_onResult(self):
     950+        def cb(result):
     951+            self.assertEqual(1, len(self.output))
     952+            reply = self.output[0]
     953+            self.assertEqual(self.originating, reply['to'])
     954+            self.assertEqual(self.receiving, reply['from'])
     955+            self.assertEqual('valid', reply['type'])
     956+
     957+        def validateConnection(thisHost, otherHost, sid, key):
     958+            self.assertEqual(thisHost, self.receiving)
     959+            self.assertEqual(otherHost, self.originating)
     960+            self.assertEqual(sid, self.sid)
     961+            self.assertEqual(key, self.key)
     962+            return defer.succeed(None)
     963+
     964+        self.xmlstream.sid = self.sid
     965+        self.service.validateConnection = validateConnection
     966+
     967+        result = domish.Element((NS_DIALBACK, 'result'))
     968+        result['to'] = self.receiving
     969+        result['from'] = self.originating
     970+        result.addContent(self.key)
     971+
     972+        d = self.authenticator.onResult(result)
     973+        d.addCallback(cb)
     974+        return d
     975+
     976+
     977+    def test_onResultFailure(self):
     978+        class TestError(Exception):
     979+            pass
     980+
     981+        def cb(result):
     982+            reply = self.output[0]
     983+            self.assertEqual('invalid', reply['type'])
     984+            self.assertEqual(1, len(self.flushLoggedErrors(TestError)))
     985+
     986+
     987+        def validateConnection(thisHost, otherHost, sid, key):
     988+            return defer.fail(TestError())
     989+
     990+        self.xmlstream.sid = self.sid
     991+        self.service.validateConnection = validateConnection
     992+
     993+        result = domish.Element((NS_DIALBACK, 'result'))
     994+        result['to'] = self.receiving
     995+        result['from'] = self.originating
     996+        result.addContent(self.key)
     997+
     998+        d = self.authenticator.onResult(result)
     999+        d.addCallback(cb)
     1000+        return d
     1001+
     1002+
     1003+
     1004+class FakeService(object):
     1005+    domains = set(['example.org', 'pubsub.example.org'])
     1006+    defaultDomain = 'example.org'
     1007+    secret = 'mysecret'
     1008+
     1009+    def __init__(self):
     1010+        self.dispatched = []
     1011+
     1012+    def dispatch(self, element):
     1013+        self.dispatch.append(element)
     1014+
     1015+
     1016+
     1017+class XMPPS2SServerFactoryTest(unittest.TestCase):
     1018+    """
     1019+    Tests for L{component.XMPPS2SServerFactory}.
     1020+    """
     1021+
     1022+    def setUp(self):
     1023+        self.service = FakeService
     1024+        self.factory = server.XMPPS2SServerFactory(self.service)
     1025+        self.xmlstream = self.factory.buildProtocol(None)
     1026+        self.xmlstream.thisEntity = jid.JID('example.org')
     1027+        self.xmlstream.otherEntity = jid.JID('example.com')
     1028+
     1029+
     1030+    def test_makeConnection(self):
     1031+        """
     1032+        A new connection increases the stream serial count. No logs by default.
     1033+        """
     1034+        self.xmlstream.dispatch(self.xmlstream,
     1035+                                xmlstream.STREAM_CONNECTED_EVENT)
     1036+        self.assertEqual(0, self.xmlstream.serial)
     1037+        self.assertEqual(1, self.factory.serial)
     1038+        self.assertIdentical(None, self.xmlstream.rawDataInFn)
     1039+        self.assertIdentical(None, self.xmlstream.rawDataOutFn)
     1040+
     1041+
     1042+    def test_makeConnectionLogTraffic(self):
     1043+        """
     1044+        Setting logTraffic should set up raw data loggers.
     1045+        """
     1046+        self.factory.logTraffic = True
     1047+        self.xmlstream.dispatch(self.xmlstream,
     1048+                                xmlstream.STREAM_CONNECTED_EVENT)
     1049+        self.assertNotIdentical(None, self.xmlstream.rawDataInFn)
     1050+        self.assertNotIdentical(None, self.xmlstream.rawDataOutFn)
     1051+
     1052+
     1053+    def test_onError(self):
     1054+        """
     1055+        An observer for stream errors should trigger onError to log it.
     1056+        """
     1057+        self.xmlstream.dispatch(self.xmlstream,
     1058+                                xmlstream.STREAM_CONNECTED_EVENT)
     1059+
     1060+        class TestError(Exception):
     1061+            pass
     1062+
     1063+        reason = failure.Failure(TestError())
     1064+        self.xmlstream.dispatch(reason, xmlstream.STREAM_ERROR_EVENT)
     1065+        self.assertEqual(1, len(self.flushLoggedErrors(TestError)))
     1066+
     1067+
     1068+    def test_connectionInitialized(self):
     1069+        """
     1070+        """
     1071+        self.xmlstream.dispatch(self.xmlstream,
     1072+                                xmlstream.STREAM_CONNECTED_EVENT)
     1073+        self.xmlstream.dispatch(self.xmlstream, xmlstream.STREAM_AUTHD_EVENT)
     1074+
     1075+
     1076+    def test_connectionLost(self):
     1077+        """
     1078+        """
     1079+        self.xmlstream.dispatch(self.xmlstream,
     1080+                                xmlstream.STREAM_CONNECTED_EVENT)
     1081+        self.xmlstream.dispatch(self.xmlstream, xmlstream.STREAM_AUTHD_EVENT)
     1082+        self.xmlstream.dispatch(None, xmlstream.STREAM_END_EVENT)
     1083+
     1084+
     1085+    def test_ElementNotAuthenticated(self):
     1086+        self.xmlstream.dispatch(self.xmlstream,
     1087+                                xmlstream.STREAM_CONNECTED_EVENT)
     1088+        self.xmlstream.dataReceived("<presence/>")
     1089+
     1090+
     1091+class ServerServiceTest(unittest.TestCase):
     1092+
     1093+    def setUp(self):
     1094+        self.router = component.Router()
     1095+        self.service = server.ServerService(self.router,
     1096+                                            secret='mysecret',
     1097+                                            domain='example.org')
     1098+
     1099+
     1100+    def test_defaultDomainInDomains(self):
     1101+        """
     1102+        The default domain is part of the domains considered local.
     1103+        """
     1104+        self.assertIn(self.service.defaultDomain, self.service.domains)
  • series

    r6 r7  
     1pubsub-disco-info-42.patch
     2compat-pre-twisted-8.0.0.patch
     3release-0.5.patch
    14component_multiple.patch
    25deferred_xmlstream_factory.patch
     
    69pubsub_client_sender.patch
    710pubsub_resource.patch
    8 compat-pre-twisted-8.0.0.patch
    9 release-0.5.patch
Note: See TracChangeset for help on using the changeset viewer.