def testNSPrefix(self): e = domish.Element((None, "foo"), attribs = {("testns2", "bar"): "baz"}) c = e.addElement(("testns2", "qux")) c[("testns2", "bar")] = "quux" self.assertEquals(e.toXml(), "<foo xmlns:xn0='testns2' xn0:bar='baz'><xn0:qux xn0:bar='quux'/></foo>")
def testTwoChilds(self): e = domish.Element(('', "foo")) child1 = e.addElement(("testns", "bar"), "testns2") child1.addElement(('testns2', 'quux')) child2 = e.addElement(("testns3", "baz"), "testns4") child2.addElement(('testns', 'quux')) self.assertEquals(e.toXml(), "<foo><xn0:bar xmlns:xn0='testns' xmlns='testns2'><quux/></xn0:bar><xn1:baz xmlns:xn1='testns3' xmlns='testns4'><xn0:quux xmlns:xn0='testns'/></xn1:baz></foo>")
def start(self): """ Start TLS negotiation. This checks if the receiving entity requires TLS, the SSL library is available and uses the C{required} and C{wanted} instance variables to determine what to do in the various different cases. For example, if the SSL library is not available, and wanted and required by the user, it raises an exception. However if it is not required by both parties, initialization silently succeeds, moving on to the next step. """ if self.wanted: if ssl is None: if self.required: return defer.fail(TLSNotSupported()) else: return defer.succeed(None) else: pass elif self.xmlstream.features[self.feature].required: return defer.fail(TLSRequired()) else: return defer.succeed(None) self._deferred = defer.Deferred() self.xmlstream.addOnetimeObserver("/proceed", self.onProceed) self.xmlstream.addOnetimeObserver("/failure", self.onFailure) self.xmlstream.send(domish.Element((NS_XMPP_TLS, "starttls"))) return self._deferred
def test_legacy(self): """ Test legacy operations of exceptionFromStanza. Given a realistic stanza with only legacy (pre-XMPP) error information, check if a sane exception is returned. Using this stanza:: <message type='error' to='[email protected]/Home' from='*****@*****.**'> <body>Are you there?</body> <error code='502'>Unable to resolve hostname.</error> </message> """ stanza = domish.Element((None, 'stanza')) p = stanza.addElement('body', content='Are you there?') e = stanza.addElement('error', content='Unable to resolve hostname.') e['code'] = '502' result = error.exceptionFromStanza(stanza) self.assert_(isinstance(result, error.StanzaError)) self.assertEquals('service-unavailable', result.condition) self.assertEquals('wait', result.type) self.assertEquals('Unable to resolve hostname.', result.text) self.assertEquals([p], result.children)
def toResponse(stanza, stanzaType=None): """ Create a response stanza from another stanza. This takes the addressing and id attributes from a stanza to create a (new, empty) response stanza. The addressing attributes are swapped and the id copied. Optionally, the stanza type of the response can be specified. @param stanza: the original stanza @type stanza: L{domish.Element} @param stanzaType: optional response stanza type @type stanzaType: C{str} @return: the response stanza. @rtype: L{domish.Element} """ toAddr = stanza.getAttribute('from') fromAddr = stanza.getAttribute('to') stanzaID = stanza.getAttribute('id') response = domish.Element((None, stanza.name)) if toAddr: response['to'] = toAddr if fromAddr: response['from'] = fromAddr if stanzaID: response['id'] = stanzaID if stanzaType: response['type'] = stanzaType return response
def sendHeader(self): """ Send stream header. """ # set up optional extra namespaces localPrefixes = {} for uri, prefix in self.prefixes.iteritems(): if uri != NS_STREAMS: localPrefixes[prefix] = uri rootElement = domish.Element((NS_STREAMS, 'stream'), self.namespace, localPrefixes=localPrefixes) if self.otherEntity: rootElement['to'] = self.otherEntity.userhost() if self.thisEntity: rootElement['from'] = self.thisEntity.userhost() if not self.initiating and self.sid: rootElement['id'] = self.sid if self.version >= (1, 0): rootElement['version'] = "%d.%d" % self.version self.send(rootElement.toXml(prefixes=self.prefixes, closeElement=0)) self._headerSent = True
def test_noType(self): """ Test that a proper response is generated without type attribute. """ stanza = domish.Element(('jabber:client', 'message')) response = xmlstream.toResponse(stanza) self.assertFalse(response.hasAttribute('type'))
def testAdvertized(self): """ Test that an advertized feature results in successful initialization. """ self.xmlstream.features = {self.init.feature: domish.Element(self.init.feature)} return self.init.initialize()
def testChildOps(self): e = domish.Element(("testns", "foo")) e.addContent("somecontent") b2 = e.addElement(("testns2", "bar2")) e["attrib1"] = "value1" e[("testns2", "attrib2")] = "value2" e.addElement("bar") e.addElement("bar") e.addContent("abc") e.addContent("123") # Check content merging self.assertEquals(e.children[-1], "abc123") # Check str()/content extraction self.assertEquals(str(e), "somecontent") # Check direct child accessor self.assertEquals(e.bar2, b2) e.bar2.addContent("subcontent") e.bar2["bar2value"] = "somevalue" # Check child ops self.assertEquals(e.children[1], e.bar2) self.assertEquals(e.children[2], e.bar) # Check attribute ops self.assertEquals(e["attrib1"], "value1") del e["attrib1"] self.assertEquals(e.hasAttribute("attrib1"), 0) self.assertEquals(e.hasAttribute("attrib2"), 0) self.assertEquals(e[("testns2", "attrib2")], "value2")
def testRawXMLSerialization(self): e = domish.Element((None, "foo")) e.addRawXml("<abc123>") # The testcase below should NOT generate valid XML -- that's # the whole point of using the raw XML call -- it's the callers # responsiblity to ensure that the data inserted is valid self.assertEquals(e.toXml(), "<foo><abc123></foo>")
def test_send(self): """ Test send with various types of objects. """ xs = self.xmlstream xs.send('<presence/>') self.assertEqual(xs.transport.value(), '<presence/>') xs.transport.clear() el = domish.Element(('testns', 'presence')) xs.send(el) self.assertEqual(xs.transport.value(), '<presence/>') xs.transport.clear() el = domish.Element(('http://etherx.jabber.org/streams', 'features')) xs.send(el) self.assertEqual(xs.transport.value(), '<stream:features/>')
def test_getElementAppCondition(self): """ Test getting an element for an error with an app specific condition. """ ac = domish.Element(('testns', 'myerror')) e = error.BaseError('feature-not-implemented', appCondition=ac) element = e.getElement() self.assertEquals(len(element.children), 2) self.assertEquals(element.myerror, ac)
def test_toResponseNoAddressing(self): """ Test that a response is generated from a stanza without any addressing. """ stanza = domish.Element(('jabber:client', 'message')) stanza['type'] = 'chat' response = xmlstream.toResponse(stanza) self.assertFalse(response.hasAttribute('to')) self.assertFalse(response.hasAttribute('from'))
def test_onChallengeIllegalCharacters(self): """ Test receiving a challenge message with illegal characters. """ d = self.init.start() challenge = domish.Element((NS_XMPP_SASL, 'challenge')) challenge.addContent('bXkg*Y2hhbGxlbmdl') self.init.onChallenge(challenge) self.assertFailure(d, sasl.SASLIncorrectEncodingError) return d
def test_toResponseNoTo(self): """ Test that a response is generated from a stanza without a to address. """ stanza = domish.Element(('jabber:client', 'iq')) stanza['type'] = 'get' stanza['from'] = '[email protected]/resource' response = xmlstream.toResponse(stanza) self.assertFalse(response.hasAttribute('from')) self.assertEqual(response['to'], '[email protected]/resource')
def test_onChallengeEmpty(self): """ Test receiving an empty challenge message. """ d = self.init.start() challenge = domish.Element((NS_XMPP_SASL, 'challenge')) self.init.onChallenge(challenge) self.assertEqual('', self.init.mechanism.challenge) self.init.onSuccess(None) return d
def test_onChallengeMalformed(self): """ Test receiving a malformed challenge message. """ d = self.init.start() challenge = domish.Element((NS_XMPP_SASL, 'challenge')) challenge.addContent('a') self.init.onChallenge(challenge) self.assertFailure(d, sasl.SASLIncorrectEncodingError) return d
def _setMechanism(self, name): """ Set up the XML Stream to have a SASL feature with the given mechanism. """ feature = domish.Element((NS_XMPP_SASL, 'mechanisms')) feature.addElement('mechanism', content=name) self.xmlstream.features[(feature.uri, feature.name)] = feature self.init.setMechanism() return self.init.mechanism.name
def initialize(self): xs = self.xmlstream hs = domish.Element((self.xmlstream.namespace, "handshake")) hs.addContent( xmlstream.hashPassword(xs.sid, unicode(xs.authenticator.password))) # Setup observer to watch for handshake result xs.addOnetimeObserver("/handshake", self._cbHandshake) xs.send(hs) self._deferred = defer.Deferred() return self._deferred
def test_onChallenge(self): """ Test receiving a challenge message. """ d = self.init.start() challenge = domish.Element((NS_XMPP_SASL, 'challenge')) challenge.addContent('bXkgY2hhbGxlbmdl') self.init.onChallenge(challenge) self.assertEqual('my challenge', self.init.mechanism.challenge) self.init.onSuccess(None) return d
def sendResponse(self, data=''): """ Send response to a challenge. @param data: client response. @type data: L{str}. """ response = domish.Element((NS_XMPP_SASL, 'response')) if data: response.addContent(b64encode(data)) self.xmlstream.send(response)
def testNotWantedNotRequired(self): """ Test start when TLS is not wanted, but required by the server. """ tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls')) self.xmlstream.features = {(tls.uri, tls.name): tls} self.init.wanted = False d = self.init.start() d.addCallback(self.assertEqual, None) self.assertEquals([], self.output) return d
def test_onFailure(self): """ Test that the SASL error condition is correctly extracted. """ failure = domish.Element( ('urn:ietf:params:xml:ns:xmpp-sasl', 'failure')) failure.addElement('not-authorized') self.init._deferred = defer.Deferred() self.init.onFailure(failure) self.assertFailure(self.init._deferred, sasl.SASLAuthError) self.init._deferred.addCallback( lambda e: self.assertEquals('not-authorized', e.condition)) return self.init._deferred
def test_onElement(self): """ We expect a handshake element with a hash. """ handshakes = [] xs = self.xmlstream xs.authenticator.onHandshake = handshakes.append handshake = domish.Element(('jabber:component:accept', 'handshake')) handshake.addContent('1234') xs.authenticator.onElement(handshake) self.assertEqual('1234', handshakes[-1])
def test_prefixesReuse(self): """ Test that prefixes passed to serialization are not modified. This test makes sure that passing a dictionary of prefixes repeatedly to C{toXml} of elements does not cause serialization errors. A previous implementation changed the passed in dictionary internally, causing havoc later on. """ prefixes = {'testns': 'foo'} # test passing of dictionary s = domish.SerializerClass(prefixes=prefixes) self.assertNotIdentical(prefixes, s.prefixes) # test proper serialization on prefixes reuse e = domish.Element(('testns2', 'foo'), localPrefixes={'quux': 'testns2'}) self.assertEquals("<quux:foo xmlns:quux='testns2'/>", e.toXml(prefixes=prefixes)) e = domish.Element(('testns2', 'foo')) self.assertEquals("<foo xmlns='testns2'/>", e.toXml(prefixes=prefixes))
def testNotWantedRequired(self): """ Test start when TLS is not wanted, but required by the server. """ tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls')) tls.addElement('required') self.xmlstream.features = {(tls.uri, tls.name): tls} self.init.wanted = False d = self.init.start() self.assertEquals([], self.output) self.assertFailure(d, xmlstream.TLSRequired) return d
def testElementInit(self): e = domish.Element((None, "foo")) self.assertEquals(e.name, "foo") self.assertEquals(e.uri, None) self.assertEquals(e.defaultUri, None) self.assertEquals(e.parent, None) e = domish.Element(("", "foo")) self.assertEquals(e.name, "foo") self.assertEquals(e.uri, "") self.assertEquals(e.defaultUri, "") self.assertEquals(e.parent, None) e = domish.Element(("testns", "foo")) self.assertEquals(e.name, "foo") self.assertEquals(e.uri, "testns") self.assertEquals(e.defaultUri, "testns") self.assertEquals(e.parent, None) e = domish.Element(("testns", "foo"), "test2ns") self.assertEquals(e.name, "foo") self.assertEquals(e.uri, "testns") self.assertEquals(e.defaultUri, "test2ns")
def test_toResponse(self): """ Test that a response stanza is generated with addressing swapped. """ stanza = domish.Element(('jabber:client', 'iq')) stanza['type'] = 'get' stanza['to'] = '*****@*****.**' stanza['from'] = '[email protected]/resource' stanza['id'] = 'stanza1' response = xmlstream.toResponse(stanza, 'result') self.assertNotIdentical(stanza, response) self.assertEqual(response['from'], '*****@*****.**') self.assertEqual(response['to'], '[email protected]/resource') self.assertEqual(response['type'], 'result') self.assertEqual(response['id'], 'stanza1')
def test_onElementNotHandshake(self): """ Reject elements that are not handshakes """ handshakes = [] streamErrors = [] xs = self.xmlstream xs.authenticator.onHandshake = handshakes.append xs.sendStreamError = streamErrors.append element = domish.Element(('jabber:component:accept', 'message')) xs.authenticator.onElement(element) self.assertFalse(handshakes) self.assertEquals('not-authorized', streamErrors[-1].condition)
def sendAuth(self, data=None): """ Initiate authentication protocol exchange. If an initial client response is given in C{data}, it will be sent along. @param data: initial client response. @type data: L{str} or L{None}. """ auth = domish.Element((NS_XMPP_SASL, 'auth')) auth['mechanism'] = self.mechanism.name if data is not None: auth.addContent(b64encode(data) or '=') self.xmlstream.send(auth)