diff --git a/bumper/xmppserver.py b/bumper/xmppserver.py
index f012f6f..0dabdc9 100644
--- a/bumper/xmppserver.py
+++ b/bumper/xmppserver.py
@@ -402,22 +402,20 @@ class XMPPAsyncClient:
if self.TLSUpgraded == False:
# With STARTTLS #https://xmpp.org/rfcs/rfc3920.html
self.send(
- 'PLAIN'
+ 'PLAIN'
)
else:
- # Already using TLS send authentication support for iq-auth (fallback) and SASL
+ # Already using TLS send authentication support for SASL
self.send(
- 'PLAIN'
+ 'PLAIN'
)
else:
self.send("")
else:
- if "jabber:iq:auth" in xml.tag: # Handle iq-auth
- self._handle_iq_auth(xml)
- elif (
+ if (
"urn:ietf:params:xml:ns:xmpp-sasl" in xml.tag
): # Handle SASL Auth
self._handle_sasl_auth(xml)
@@ -486,98 +484,6 @@ class XMPPAsyncClient:
except Exception as e:
xmppserverlog.exception("{}".format(e))
- def _handle_iq_auth(self, data):
- try:
- xml = ET.fromstring(data.decode("utf-8"))
- ctl = xml[0][0]
- xmppserverlog.info("IQ AUTH XML: {}".format(xml))
- # Received username and auth tag, send username/password requirement
- if (
- xml.get("type") == "get"
- and "auth}username" in ctl.tag
- and self.type == self.UNKNOWN
- ):
- self.send(
- ''.format(
- xml.get("id")
- )
- )
-
- # Received username, password, resource - Handle auth here and return pass or fail
- if (
- xml.get("type") == "set"
- and "auth}username" in ctl.tag
- and self.type == self.UNKNOWN
- ):
- xmlauth = xml[0].getchildren()
- # uid = ""
- password = ""
- authcode = ""
- resource = ""
- for aitem in xmlauth:
- if "username" in aitem.tag:
- self.uid = aitem.text
-
- elif "password" in aitem.tag:
- password = aitem.text.split("/")[2]
- authcode = password
-
- elif "resource" in aitem.tag:
- self.clientresource = aitem.text
- resource = self.clientresource
-
- if self.devclass: # if there is a devclass it is a bot
- bumper.bot_add("", self.uid, "", resource, "eco-legacy")
- xmppserverlog.debug("bot authenticated {}".format(self.uid))
-
- # Client authenticated, move to next state
- self._set_state("INIT")
-
- # Successful auth
- self.send(''.format(xml.get("id")))
-
- else:
- auth = False
- if bumper.check_authcode(self.uid, authcode):
- auth = True
- elif bumper.use_auth == False:
- auth = True
-
- if auth:
- bumper.client_add(self.uid, "bumper", self.clientresource)
- xmppserverlog.debug("client authenticated {}".format(self.uid))
-
- # Client authenticated, move to next state
- self._set_state("INIT")
-
- # Successful auth
- self.send(''.format(xml.get("id")))
-
- else:
- # Failed auth
- self.send(
- ''.format(
- xml.get("id")
- )
- )
-
- except ET.ParseError as e:
- if "no element found" in e.msg:
- xmppserverlog.debug(
- "xml parse error - {} - {}".format(data.decode("utf-8"), e)
- )
- elif "not well-formed (invalid token)" in e.msg:
- xmppserverlog.debug(
- "xml parse error - {} - {}".format(data.decode("utf-8"), e)
- )
- else:
- xmppserverlog.debug(
- "xml parse error - {} - {}".format(data.decode("utf-8"), e)
- )
-
- except Exception as e:
- xmppserverlog.exception("{}".format(e))
-
def _handle_sasl_auth(self, xml):
try:
diff --git a/tests/test_xmppserver.py b/tests/test_xmppserver.py
index 95fa8e1..e56fdcf 100644
--- a/tests/test_xmppserver.py
+++ b/tests/test_xmppserver.py
@@ -41,7 +41,7 @@ async def test_client_connect_no_starttls(*args, **kwargs):
# Server tells client available features
assert (
mock_send.mock_calls[1].args[0]
- == 'PLAIN'
+ == 'PLAIN'
)
# Reset mock calls
@@ -60,6 +60,38 @@ async def test_client_connect_no_starttls(*args, **kwargs):
assert xmppclient.state == xmppclient.INIT # Client moved to INIT state
+async def test_client_end_stream(*args, **kwargs):
+ test_transport = asyncio.Transport()
+ test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info())
+ test_transport.write = mock.Mock(return_value=return_send_data)
+ xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport)
+ xmppclient.state = xmppclient.CONNECT # Set client state to CONNECT
+ mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data)
+
+ # Send end stream from "client"
+ test_data = "".encode("utf-8")
+ xmppclient._parse_data(test_data)
+
+ # Expect 2 calls to send
+ assert mock_send.call_count == 1
+ # Server opens stream
+ assert mock_send.mock_calls[0].args[0] == ""
+
+ # Reset mock calls
+ mock_send.reset_mock()
+
+ # Send abnormal stream from "client"
+ test_data = "".encode("utf-8")
+ xmppclient._parse_data(test_data)
+
+ # Reset mock calls
+ mock_send.reset_mock()
+
+ # Send blank from "client"
+ test_data = "".encode("utf-8")
+ xmppclient._parse_data(test_data)
+
+
async def test_client_connect_starttls_called(*args, **kwargs):
test_transport = asyncio.Transport()
test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info())
@@ -84,7 +116,7 @@ async def test_client_connect_starttls_called(*args, **kwargs):
# Server tells client available features
assert (
mock_send.mock_calls[1].args[0]
- == 'PLAIN'
+ == 'PLAIN'
)
# Reset mock calls
@@ -117,7 +149,7 @@ async def test_client_connect_starttls_called(*args, **kwargs):
# Server tells client available features (without STARTTLS)
assert (
mock_send.mock_calls[1].args[0]
- == 'PLAIN'
+ == 'PLAIN'
)
# Reset mock calls
mock_send.reset_mock()
@@ -135,6 +167,80 @@ async def test_client_connect_starttls_called(*args, **kwargs):
assert xmppclient.state == xmppclient.INIT # Client moved to INIT state
+async def test_client_init(*args, **kwargs):
+ test_transport = asyncio.Transport()
+ test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info())
+ test_transport.write = mock.Mock(return_value=return_send_data)
+ xmppclient = bumper.xmppserver.XMPPAsyncClient(test_transport)
+ xmppclient.state = xmppclient.INIT # Set client state to INIT
+ xmppclient.uid = "fuid_tmpuser"
+ xmppclient.resource = "IOSF53D07BA"
+ xmppclient.bumper_jid = "fuid_tmpuser@ecouser.net/IOSF53D07BA"
+ xmppclient.type = xmppclient.CONTROLLER
+ mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data)
+
+ # Send connect stream from "client"
+ test_data = "".encode(
+ "utf-8"
+ )
+ xmppclient._parse_data(test_data)
+
+ # Expect 2 calls to send
+ assert mock_send.call_count == 2
+ # Server opens stream
+ assert (
+ mock_send.mock_calls[0].args[0]
+ == ''
+ )
+ # Server tells client binds
+ assert (
+ mock_send.mock_calls[1].args[0]
+ == ''
+ )
+
+ # Reset mock calls
+ mock_send.reset_mock()
+
+ # Send bind from "client"
+ test_data = 'IOSF53D07BA'.encode(
+ "utf-8"
+ )
+ xmppclient._parse_data(test_data)
+
+ assert (
+ mock_send.mock_calls[0].args[0]
+ == 'fuid_tmpuser@ecouser.net/IOSF53D07BA'
+ ) # client successfully binded
+ assert xmppclient.state == xmppclient.BIND # client moved to BIND state
+
+ # Reset mock calls
+ mock_send.reset_mock()
+
+ # Send set session from client
+ test_data = ''.encode(
+ "utf-8"
+ )
+ xmppclient._parse_data(test_data)
+
+ assert xmppclient.state == xmppclient.READY # client moved to READY state
+ assert (
+ mock_send.mock_calls[0].args[0]
+ == ''
+ ) # client ready
+
+ # Reset mock calls
+ mock_send.reset_mock()
+
+ # Send presense from client
+ test_data = ''.encode("utf-8")
+ xmppclient._parse_data(test_data)
+
+ assert (
+ mock_send.mock_calls[0].args[0]
+ == ' dummy '
+ ) # client presence - dummy response
+
+
async def test_bot_connect(*args, **kwargs):
test_transport = asyncio.Transport()
test_transport.get_extra_info = mock.Mock(return_value=mock_transport_extra_info())
@@ -159,7 +265,7 @@ async def test_bot_connect(*args, **kwargs):
# Server tells client available features
assert (
mock_send.mock_calls[1].args[0]
- == 'PLAIN'
+ == 'PLAIN'
)
# Reset mock calls
@@ -187,6 +293,7 @@ async def test_bot_init(*args, **kwargs):
xmppclient.state = xmppclient.INIT # Set client state to INIT
xmppclient.uid = "E0000000000000001234"
xmppclient.devclass = "159"
+ xmppclient.type = xmppclient.BOT
mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data)
# Send connect stream from "bot"
@@ -302,12 +409,22 @@ async def test_ping_client_to_client(*args, **kwargs):
)
xmppclient._parse_data(test_data)
+ assert (
+ mock_send2.mock_calls[0].args[0]
+ == ''
+ ) # ping response
+
# Ping response from bot to user
test_data = "".encode(
"utf-8"
)
xmppclient2._parse_data(test_data)
+ assert (
+ mock_send.mock_calls[0].args[0]
+ == ''
+ ) # ping response
+
async def test_client_send_iq(*args, **kwargs):
test_transport = asyncio.Transport()
@@ -341,7 +458,7 @@ async def test_client_send_iq(*args, **kwargs):
assert (
mock_send.mock_calls[0].args[0]
== ''
- ) # ping response
+ ) # feature not implemented response
# Reset mock calls
mock_send.reset_mock()
@@ -373,3 +490,32 @@ async def test_client_send_iq(*args, **kwargs):
# Reset mock calls
mock_send.reset_mock()
+
+ # Bot result
+ test_data = "".encode(
+ "utf-8"
+ )
+ xmppclient2._parse_data(test_data)
+
+ assert (
+ mock_send.mock_calls[0].args[0]
+ == ''
+ ) # result sent to ecouser.net
+
+ # Reset mock calls
+ mock_send.reset_mock()
+
+ # Bot iq set
+ test_data = "".encode(
+ "utf-8"
+ )
+ xmppclient2._parse_data(test_data)
+
+ assert (
+ mock_send.mock_calls[0].args[0]
+ == ''
+ ) # result sent to ecouser.net
+
+ # Reset mock calls
+ mock_send.reset_mock()
+