fix error namespace for ComponentXMPP

in SlixTest, if mode=="component", restore
jabber:client namespace afterwards

Fixes #3476
Fixes #3474
This commit is contained in:
nicoco 2023-02-26 22:32:21 +01:00
parent 4fa068da54
commit e16f72d32d
30 changed files with 31 additions and 86 deletions

View File

@ -9,13 +9,14 @@
import logging import logging
import hashlib import hashlib
from slixmpp import Message, Iq, Presence
from slixmpp.basexmpp import BaseXMPP from slixmpp.basexmpp import BaseXMPP
from slixmpp.stanza import Handshake from slixmpp.stanza import Handshake
from slixmpp.stanza.error import Error
from slixmpp.xmlstream import XMLStream from slixmpp.xmlstream import XMLStream
from slixmpp.xmlstream import ET
from slixmpp.xmlstream.matcher import MatchXPath from slixmpp.xmlstream.matcher import MatchXPath
from slixmpp.xmlstream.handler import Callback from slixmpp.xmlstream.handler import Callback
from slixmpp.xmlstream.stanzabase import register_stanza_plugin
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -39,9 +40,17 @@ class ComponentXMPP(BaseXMPP):
should be used instead of the standard should be used instead of the standard
``'jabber:component:accept'`` namespace. ``'jabber:component:accept'`` namespace.
Defaults to ``False``. Defaults to ``False``.
:param fix_error_ns: Fix the namespace of error stanzas.
If you use ``use_jc_ns`` namespace, you probably want that, but
it can be a problem if you use both a ClientXMPP and a ComponentXMPP
in the same interpreter. This is ``False`` by default for backwards
compatibility.
""" """
def __init__(self, jid, secret, host=None, port=None, plugin_config=None, plugin_whitelist=None, use_jc_ns=False): def __init__(self, jid, secret,
host=None, port=None, plugin_config=None,
plugin_whitelist=None, use_jc_ns=False,
fix_error_ns=False):
if not plugin_whitelist: if not plugin_whitelist:
plugin_whitelist = [] plugin_whitelist = []
@ -52,6 +61,8 @@ class ComponentXMPP(BaseXMPP):
default_ns = 'jabber:client' default_ns = 'jabber:client'
else: else:
default_ns = 'jabber:component:accept' default_ns = 'jabber:component:accept'
if fix_error_ns:
self._fix_error_ns()
BaseXMPP.__init__(self, jid, default_ns) BaseXMPP.__init__(self, jid, default_ns)
self.auto_authorize = None self.auto_authorize = None
@ -77,6 +88,11 @@ class ComponentXMPP(BaseXMPP):
self.add_event_handler('presence_probe', self.add_event_handler('presence_probe',
self._handle_probe) self._handle_probe)
def _fix_error_ns(self):
Error.namespace = self.default_ns
for st in Message, Iq, Presence:
register_stanza_plugin(st, Error)
def connect(self, host=None, port=None, use_ssl=False): def connect(self, host=None, port=None, use_ssl=False):
"""Connect to the server. """Connect to the server.

View File

@ -10,11 +10,13 @@ from xml.parsers.expat import ExpatError
from slixmpp.test import TestTransport from slixmpp.test import TestTransport
from slixmpp import ClientXMPP, ComponentXMPP from slixmpp import ClientXMPP, ComponentXMPP
from slixmpp.stanza import Message, Iq, Presence from slixmpp.stanza import Message, Iq, Presence
from slixmpp.stanza.error import Error
from slixmpp.xmlstream import ET from slixmpp.xmlstream import ET
from slixmpp.xmlstream import ElementBase from slixmpp.xmlstream import ElementBase
from slixmpp.xmlstream.tostring import tostring, highlight from slixmpp.xmlstream.tostring import tostring, highlight
from slixmpp.xmlstream.matcher import StanzaPath, MatcherId, MatchIDSender from slixmpp.xmlstream.matcher import StanzaPath, MatcherId, MatchIDSender
from slixmpp.xmlstream.matcher import MatchXMLMask, MatchXPath from slixmpp.xmlstream.matcher import MatchXMLMask, MatchXPath
from slixmpp.xmlstream.stanzabase import register_stanza_plugin
import asyncio import asyncio
@ -322,6 +324,7 @@ class SlixTest(unittest.TestCase):
if not plugin_config: if not plugin_config:
plugin_config = {} plugin_config = {}
self.mode = mode
if mode == 'client': if mode == 'client':
self.xmpp = ClientXMPP(jid, password, self.xmpp = ClientXMPP(jid, password,
sasl_mech=sasl_mech, sasl_mech=sasl_mech,
@ -740,3 +743,10 @@ class SlixTest(unittest.TestCase):
# Everything matches # Everything matches
return True return True
def tearDown(self):
self.stream_close()
if getattr(self, "mode", None) == "component":
Error.namespace = 'jabber:client'
for st in Message, Iq, Presence:
register_stanza_plugin(st, Error)

View File

@ -8,9 +8,6 @@ class TestLiveStream(SlixTest):
Test that we can test a live stanza stream. Test that we can test a live stanza stream.
""" """
def tearDown(self):
self.stream_close()
def testClientConnection(self): def testClientConnection(self):
"""Test that we can interact with a live ClientXMPP instance.""" """Test that we can interact with a live ClientXMPP instance."""
self.stream_start(mode='client', self.stream_start(mode='client',

View File

@ -8,9 +8,6 @@ class TestEvents(SlixTest):
def setUp(self): def setUp(self):
self.stream_start() self.stream_start()
def tearDown(self):
self.stream_close()
def testEventHappening(self): def testEventHappening(self):
"""Test handler working""" """Test handler working"""
happened = [] happened = []

View File

@ -5,10 +5,6 @@ from slixmpp.xmlstream.stanzabase import ET
class TestIqStanzas(SlixTest): class TestIqStanzas(SlixTest):
def tearDown(self):
"""Shutdown the XML stream after testing."""
self.stream_close()
def testSetup(self): def testSetup(self):
"""Test initializing default Iq values.""" """Test initializing default Iq values."""
iq = self.Iq() iq = self.Iq()

View File

@ -8,9 +8,6 @@ class TestStreamTester(SlixTest):
Test that we can simulate and test a stanza stream. Test that we can simulate and test a stanza stream.
""" """
def tearDown(self):
self.stream_close()
def testClientEcho(self): def testClientEcho(self):
"""Test that we can interact with a ClientXMPP instance.""" """Test that we can interact with a ClientXMPP instance."""
self.stream_start(mode='client') self.stream_start(mode='client')

View File

@ -10,9 +10,6 @@ class TestStreamExceptions(SlixTest):
Test handling roster updates. Test handling roster updates.
""" """
def tearDown(self):
self.stream_close()
def testExceptionContinueWorking(self): def testExceptionContinueWorking(self):
"""Test that Slixmpp continues to respond after an XMPPError is raised.""" """Test that Slixmpp continues to respond after an XMPPError is raised."""

View File

@ -14,9 +14,6 @@ class TestFilters(SlixTest):
def setUp(self): def setUp(self):
self.stream_start() self.stream_start()
def tearDown(self):
self.stream_close()
def testIncoming(self): def testIncoming(self):
data = [] data = []

View File

@ -15,9 +15,6 @@ class TestHandlers(SlixTest):
def setUp(self): def setUp(self):
self.stream_start() self.stream_start()
def tearDown(self):
self.stream_close()
def testCallback(self): def testCallback(self):
"""Test using stream callback handlers.""" """Test using stream callback handlers."""

View File

@ -11,9 +11,6 @@ class TestStreamPresence(SlixTest):
def setUp(self): def setUp(self):
self.stream_start(jid='tester@localhost', plugins=[]) self.stream_start(jid='tester@localhost', plugins=[])
def tearDown(self):
self.stream_close()
def testInitialUnavailablePresences(self): def testInitialUnavailablePresences(self):
""" """
Test receiving unavailable presences from JIDs that Test receiving unavailable presences from JIDs that

View File

@ -13,9 +13,6 @@ class TestStreamRoster(SlixTest):
Test handling roster updates. Test handling roster updates.
""" """
def tearDown(self):
self.stream_close()
def testGetRoster(self): def testGetRoster(self):
"""Test handling roster requests.""" """Test handling roster requests."""
self.stream_start(mode='client', jid='tester@localhost') self.stream_start(mode='client', jid='tester@localhost')

View File

@ -11,9 +11,6 @@ class TestStreamDisco(SlixTest):
Test using the XEP-0030 plugin. Test using the XEP-0030 plugin.
""" """
def tearDown(self):
self.stream_close()
def testInfoEmptyDefaultNode(self): def testInfoEmptyDefaultNode(self):
""" """
Info query result from an entity MUST have at least one identity Info query result from an entity MUST have at least one identity

View File

@ -11,9 +11,6 @@ class TestInBandByteStreams(SlixTest):
def setUp(self): def setUp(self):
self.stream_start(plugins=['xep_0047', 'xep_0030']) self.stream_start(plugins=['xep_0047', 'xep_0030'])
def tearDown(self):
self.stream_close()
def testOpenStream(self): def testOpenStream(self):
"""Test requesting a stream, successfully""" """Test requesting a stream, successfully"""

View File

@ -16,9 +16,6 @@ class TestAdHocCommands(SlixTest):
# a dummy value. # a dummy value.
self.xmpp['xep_0050'].new_session = lambda: '_sessionid_' self.xmpp['xep_0050'].new_session = lambda: '_sessionid_'
def tearDown(self):
self.stream_close()
def testInitialPayloadCommand(self): def testInitialPayloadCommand(self):
"""Test a command with an initial payload.""" """Test a command with an initial payload."""

View File

@ -19,9 +19,6 @@ class TestJabberSearch(SlixTest):
self.xmpp["xep_0055"].api.register(get_results, "search_query") self.xmpp["xep_0055"].api.register(get_results, "search_query")
self.xmpp["xep_0055"].api.register(get_results, "search_query") self.xmpp["xep_0055"].api.register(get_results, "search_query")
def tearDown(self):
self.stream_close()
def testRequestingSearchFields(self): def testRequestingSearchFields(self):
self.recv( self.recv(
""" """

View File

@ -15,9 +15,6 @@ class TestStreamPubsub(SlixTest):
def setUp(self): def setUp(self):
self.stream_start() self.stream_start()
def tearDown(self):
self.stream_close()
def testCreateInstantNode(self): def testCreateInstantNode(self):
"""Test creating an instant node""" """Test creating an instant node"""
self.xmpp['xep_0060'].create_node('pubsub.example.com', None) self.xmpp['xep_0060'].create_node('pubsub.example.com', None)

View File

@ -6,9 +6,6 @@ from slixmpp.test import SlixTest
class TestOOB(SlixTest): class TestOOB(SlixTest):
def tearDown(self):
self.stream_close()
def testSendOOB(self): def testSendOOB(self):
"""Test sending an OOB transfer request.""" """Test sending an OOB transfer request."""
self.stream_start(plugins=['xep_0066', 'xep_0030']) self.stream_start(plugins=['xep_0066', 'xep_0030'])

View File

@ -6,9 +6,6 @@ from slixmpp.test import SlixTest
class TestStreamChatStates(SlixTest): class TestStreamChatStates(SlixTest):
def tearDown(self):
self.stream_close()
def testChatStates(self): def testChatStates(self):
self.stream_start(mode='client', plugins=['xep_0030', 'xep_0085']) self.stream_start(mode='client', plugins=['xep_0030', 'xep_0085'])

View File

@ -6,9 +6,6 @@ from slixmpp.test import SlixTest
class TestStreamSet(SlixTest): class TestStreamSet(SlixTest):
def tearDown(self):
self.stream_close()
def testHandleSoftwareVersionRequest(self): def testHandleSoftwareVersionRequest(self):
self.stream_start(mode='client', plugins=['xep_0030', 'xep_0092']) self.stream_start(mode='client', plugins=['xep_0030', 'xep_0092'])

View File

@ -19,6 +19,7 @@ class TestStreamGateway(SlixTest):
"xep_0100": {"component_name": "AIM Gateway", "type": "aim"} "xep_0100": {"component_name": "AIM Gateway", "type": "aim"}
}, },
) )
self.xmpp._fix_error_ns()
def next_sent(self): def next_sent(self):
self.wait_for_send_queue() self.wait_for_send_queue()
@ -160,7 +161,6 @@ class TestStreamGateway(SlixTest):
</iq> </iq>
""" """
) )
# xmlns="jabber:client" in error substanza, bug in XEP-0077 plugin or OK?
self.send( self.send(
""" """
<iq type='error' <iq type='error'
@ -171,7 +171,7 @@ class TestStreamGateway(SlixTest):
<username>RomeoMyRomeo</username> <username>RomeoMyRomeo</username>
<password>ILoveJuliet</password> <password>ILoveJuliet</password>
</query> </query>
<error code='406' type='modify' xmlns="jabber:client"> <error code='406' type='modify'>
<not-acceptable <not-acceptable
xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Not good</text> <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">Not good</text>

View File

@ -8,9 +8,6 @@ class TestStreamExtendedDisco(SlixTest):
Test using the XEP-0128 plugin. Test using the XEP-0128 plugin.
""" """
def tearDown(self):
self.stream_close()
def testUsingExtendedInfo(self): def testUsingExtendedInfo(self):
self.stream_start(mode='client', self.stream_start(mode='client',
jid='tester@localhost', jid='tester@localhost',

View File

@ -10,9 +10,6 @@ class TestStreamDirectInvite(SlixTest):
Test using the XEP-0249 plugin. Test using the XEP-0249 plugin.
""" """
def tearDown(self):
self.stream_close()
def testReceiveInvite(self): def testReceiveInvite(self):
self.stream_start(mode='client', self.stream_start(mode='client',
plugins=['xep_0030', plugins=['xep_0030',

View File

@ -9,9 +9,6 @@ class TestMAM(SlixTest):
def setUp(self): def setUp(self):
self.stream_start(plugins=['xep_0313']) self.stream_start(plugins=['xep_0313'])
def tearDown(self):
self.stream_close()
def testRetrieveSimple(self): def testRetrieveSimple(self):
"""Test requesting MAM messages without RSM""" """Test requesting MAM messages without RSM"""

View File

@ -24,9 +24,6 @@ class TestStreamSensorData(SlixTest):
def _time_now(self): def _time_now(self):
return datetime.datetime.now().replace(microsecond=0).isoformat() return datetime.datetime.now().replace(microsecond=0).isoformat()
def tearDown(self):
self.stream_close()
def testRequestAccept(self): def testRequestAccept(self):
self.stream_start(mode='component', self.stream_start(mode='component',
plugins=['xep_0030', plugins=['xep_0030',

View File

@ -30,9 +30,6 @@ class TestStreamControl(SlixTest):
def _time_now(self): def _time_now(self):
return datetime.datetime.now().replace(microsecond=0).isoformat() return datetime.datetime.now().replace(microsecond=0).isoformat()
def tearDown(self):
self.stream_close()
def testRequestSetOk(self): def testRequestSetOk(self):
self.stream_start(mode='component', self.stream_start(mode='component',
plugins=['xep_0030', plugins=['xep_0030',

View File

@ -14,9 +14,6 @@ class TestSIMS(SlixTest):
mode="component", jid="whatevs.shakespeare.lit", plugins={"xep_0385"} mode="component", jid="whatevs.shakespeare.lit", plugins={"xep_0385"}
) )
def tearDown(self):
self.stream_close()
def test_set_file(self): def test_set_file(self):
with NamedTemporaryFile("wb+") as f: with NamedTemporaryFile("wb+") as f:
n = 10 n = 10

View File

@ -8,9 +8,6 @@ class TestMIXPAM(SlixTest):
def setUp(self): def setUp(self):
self.stream_start(plugins=['xep_0405']) self.stream_start(plugins=['xep_0405'])
def tearDown(self):
self.stream_close()
def testGetRosterEmpty(self): def testGetRosterEmpty(self):
"""Test requesting an empty annotated roster""" """Test requesting an empty annotated roster"""

View File

@ -15,8 +15,6 @@ class TestStatelessFileSharing(SlixTest):
mode="component", jid="whatevs.shakespeare.lit", plugins={"xep_0447"} mode="component", jid="whatevs.shakespeare.lit", plugins={"xep_0447"}
) )
def tearDown(self):
self.stream_close()
def test_set_file(self): def test_set_file(self):
with NamedTemporaryFile("wb+") as f: with NamedTemporaryFile("wb+") as f:

View File

@ -7,9 +7,6 @@ class TestReply(SlixTest):
def setUp(self): def setUp(self):
self.stream_start(plugins=["xep_0461"]) self.stream_start(plugins=["xep_0461"])
def tearDown(self):
self.stream_close()
def testFallBackBody(self): def testFallBackBody(self):
async def on_reply(msg): async def on_reply(msg):
start = msg["feature_fallback"]["fallback_body"]["start"] start = msg["feature_fallback"]["fallback_body"]["start"]

View File

@ -10,9 +10,6 @@ class TestToString(SlixTest):
Test the implementation of slixmpp.xmlstream.tostring Test the implementation of slixmpp.xmlstream.tostring
""" """
def tearDown(self):
self.stream_close()
def tryTostring(self, original='', expected=None, message='', **kwargs): def tryTostring(self, original='', expected=None, message='', **kwargs):
""" """
Compare the result of calling tostring against an Compare the result of calling tostring against an