add type hints

This commit is contained in:
Robert Resch 2022-08-17 11:00:07 +02:00
parent b3fbf79290
commit 8afc17e23e
6 changed files with 114 additions and 106 deletions

View file

@ -109,7 +109,7 @@ async def start() -> None:
global web_server global web_server
web_server = WebServer(web_server_bindings) web_server = WebServer(web_server_bindings)
global xmpp_server global xmpp_server
xmpp_server = XMPPServer((bumper_listen, xmpp_listen_port)) xmpp_server = XMPPServer(bumper_listen, xmpp_listen_port)
# Start XMPP Server # Start XMPP Server
asyncio.create_task(xmpp_server.start_async_server()) asyncio.create_task(xmpp_server.start_async_server())
@ -151,7 +151,7 @@ async def shutdown() -> None:
if mqtt_server.state == "started": if mqtt_server.state == "started":
await mqtt_server.shutdown() await mqtt_server.shutdown()
if xmpp_server.server: if xmpp_server.server:
if xmpp_server.server._serving: if xmpp_server.server.is_serving:
xmpp_server.server.close() xmpp_server.server.close()
await xmpp_server.server.wait_closed() await xmpp_server.server.wait_closed()

View file

@ -275,6 +275,7 @@ def _auth_any(
checkToken = _check_token( checkToken = _check_token(
apptype, countrycode, tmpuser, request.query["accessToken"] apptype, countrycode, tmpuser, request.query["accessToken"]
) )
assert checkToken.text
isGood: dict[str, Any] = json.loads(checkToken.text) isGood: dict[str, Any] = json.loads(checkToken.text)
if isGood["code"] == "0000": if isGood["code"] == "0000":
return isGood return isGood

View file

@ -208,7 +208,9 @@ class WebServer:
response = await handler(request) response = await handler(request)
if response is None: if response is None:
confserverlog.warning("Response was null!") confserverlog.warning( # type:ignore[unreachable]
"Response was null!"
)
confserverlog.warning(json.dumps(to_log)) confserverlog.warning(json.dumps(to_log))
raise HTTPNoContent raise HTTPNoContent
@ -218,7 +220,9 @@ class WebServer:
if ( if (
"application/octet-stream" not in response.content_type "application/octet-stream" not in response.content_type
and isinstance(response, Response) and isinstance(response, Response)
and response.body
): ):
assert isinstance(response.body, bytes)
to_log["response"]["body"] = f"{json.loads(response.body)}" to_log["response"]["body"] = f"{json.loads(response.body)}"
confserverlog.debug(json.dumps(to_log)) confserverlog.debug(json.dumps(to_log))

View file

@ -4,6 +4,8 @@ import re
import ssl import ssl
import uuid import uuid
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from asyncio import transports
from typing import Optional
import bumper import bumper
from bumper.db import ( from bumper.db import (
@ -22,25 +24,24 @@ boterrorlog = bumper.get_logger("boterror")
class XMPPServer: class XMPPServer:
server_id = "ecouser.net" server_id = "ecouser.net"
clients = [] clients: list["XMPPAsyncClient"] = []
exit_flag = False exit_flag = False
server = None server = None
def __init__(self, address): def __init__(self, host: str, port: int):
# Initialize bot server # Initialize bot server
self.address = address self._host = host
self._port = port
self.xmpp_protocol = lambda: XMPPServer_Protocol() self.xmpp_protocol = lambda: XMPPServer_Protocol()
async def start_async_server(self) -> None: async def start_async_server(self) -> None:
try: try:
xmppserverlog.info( xmppserverlog.info(f"Starting XMPP Server at {self._host}:{self._port}")
f"Starting XMPP Server at {self.address[0]}:{self.address[1]}"
)
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
self.server = await loop.create_server( self.server = await loop.create_server(
self.xmpp_protocol, host=self.address[0], port=self.address[1] self.xmpp_protocol, host=self._host, port=self._port
) )
self.server_coro = loop.create_task(self.server.serve_forever()) self.server_coro = loop.create_task(self.server.serve_forever())
@ -63,32 +64,34 @@ class XMPPServer:
class XMPPServer_Protocol(asyncio.Protocol): class XMPPServer_Protocol(asyncio.Protocol):
client_id = None client_id = None
exit_flag = False exit_flag = False
aclient = None _client: Optional["XMPPAsyncClient"] = None
def connection_made(self, transport): def connection_made(self, transport: transports.BaseTransport) -> None:
if self.aclient: # Existing client... upgrading to TLS if self._client: # Existing client... upgrading to TLS
xmppserverlog.debug(f"Upgraded connection for {self.aclient.address}") xmppserverlog.debug(f"Upgraded connection for {self._client.address}")
self.aclient.transport = transport self._client.transport = transport
else: else:
aclient = XMPPAsyncClient(transport) client = XMPPAsyncClient(transport)
self.aclient = aclient self._client = client
XMPPServer.clients.append(aclient) XMPPServer.clients.append(client)
self.aclient.state = getattr(aclient, "CONNECT") self._client.state = getattr(client, "CONNECT")
xmppserverlog.debug(f"New Connection from {aclient.address}") xmppserverlog.debug(f"New Connection from {client.address}")
def connection_lost(self, error): def connection_lost(self, exc: Exception | None) -> None:
XMPPServer.clients.remove(self.aclient) if self._client:
self.aclient._set_state("DISCONNECT") XMPPServer.clients.remove(self._client)
self._client.set_state("DISCONNECT")
xmppserverlog.debug( xmppserverlog.debug(
"End Connection for ({}:{} | {})".format( "End Connection for ({}:{} | {})".format(
self.aclient.address[0], self._client.address[0],
self.aclient.address[1], self._client.address[1],
self.aclient.bumper_jid, self._client.bumper_jid,
) )
) )
def data_received(self, data): def data_received(self, data: bytes) -> None:
self.aclient._parse_data(data) if self._client:
self._client.parse_data(data)
class XMPPAsyncClient: class XMPPAsyncClient:
@ -103,7 +106,7 @@ class XMPPAsyncClient:
CONTROLLER = 2 CONTROLLER = 2
TLSUpgraded = False TLSUpgraded = False
def __init__(self, transport): def __init__(self, transport: transports.BaseTransport):
self.type = self.UNKNOWN self.type = self.UNKNOWN
self.state = self.IDLE self.state = self.IDLE
self.address = transport.get_extra_info("peername") self.address = transport.get_extra_info("peername")
@ -116,7 +119,7 @@ class XMPPAsyncClient:
self.log_incoming_data = True # Set to true to log sends self.log_incoming_data = True # Set to true to log sends
xmppserverlog.debug(f"new client with ip {self.address}") xmppserverlog.debug(f"new client with ip {self.address}")
def send(self, command): def send(self, command: str) -> None:
try: try:
if self.log_sent_message: if self.log_sent_message:
xmppserverlog.debug( xmppserverlog.debug(
@ -124,13 +127,13 @@ class XMPPAsyncClient:
self.address[0], self.address[1], self.bumper_jid, command self.address[0], self.address[1], self.bumper_jid, command
) )
) )
if isinstance(self.transport, transports.WriteTransport):
self.transport.write(command.encode()) self.transport.write(command.encode())
except Exception as e: except Exception as e:
xmppserverlog.exception(f"{e}") xmppserverlog.exception(f"{e}")
def _disconnect(self): def _disconnect(self) -> None:
try: try:
bot = bot_get(self.uid) bot = bot_get(self.uid)
@ -146,16 +149,15 @@ class XMPPAsyncClient:
except Exception as e: except Exception as e:
xmppserverlog.error(f"{e}") xmppserverlog.error(f"{e}")
def _tag_strip_uri(self, tag): def _tag_strip_uri(self, tag: str) -> str:
try: try:
if tag[0] == "{": if tag[0] == "{":
_, _, tag = tag[1:].partition("}") _, _, tag = tag[1:].partition("}")
return tag
except Exception as e: except Exception as e:
xmppserverlog.error(f"{e}") xmppserverlog.error(f"{e}")
return tag
def _set_state(self, state): def set_state(self, state: str) -> None:
try: try:
new_state = getattr(XMPPAsyncClient, state) new_state = getattr(XMPPAsyncClient, state)
if self.state > new_state: if self.state > new_state:
@ -179,7 +181,7 @@ class XMPPAsyncClient:
except Exception as e: except Exception as e:
xmppserverlog.error(f"{e}") xmppserverlog.error(f"{e}")
def _handle_ctl(self, xml, data): def _handle_ctl(self, xml: ET.Element, data: str) -> None:
try: try:
if "roster" in data: if "roster" in data:
@ -228,7 +230,7 @@ class XMPPAsyncClient:
xmppserverlog.debug( xmppserverlog.debug(
"admin username received from bot: {}".format(ctl.get("admin")) "admin username received from bot: {}".format(ctl.get("admin"))
) )
XMPPServer.client_id = ctl.get("admin") #XMPPServer.client_id = ctl.get("admin")
return return
# forward # forward
@ -247,7 +249,7 @@ class XMPPAsyncClient:
rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq") rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq")
rxmlstring = rxmlstring.replace("<query", '<query xmlns="com:ctl"') rxmlstring = rxmlstring.replace("<query", '<query xmlns="com:ctl"')
if client.type == self.BOT: if client.type == self.BOT and ctl_to:
if client.uid.lower() in ctl_to.lower(): if client.uid.lower() in ctl_to.lower():
xmppserverlog.debug(f"Sending ctl to bot: {rxmlstring}") xmppserverlog.debug(f"Sending ctl to bot: {rxmlstring}")
client.send(rxmlstring) client.send(rxmlstring)
@ -255,9 +257,10 @@ class XMPPAsyncClient:
except Exception as e: except Exception as e:
xmppserverlog.error(f"{e}") xmppserverlog.error(f"{e}")
def _handle_ping(self, xml, data): def _handle_ping(self, xml: ET.Element) -> None:
try: try:
if xml.get("to").find("@") == -1: # No to address pingto = xml.get("to")
if pingto and pingto.find("@") == -1: # No to address
# Ping to server - respond # Ping to server - respond
pingresp = '<iq type="result" id="{}" from="{}" />'.format( pingresp = '<iq type="result" id="{}" from="{}" />'.format(
xml.get("id"), xml.get("to") xml.get("id"), xml.get("to")
@ -266,7 +269,6 @@ class XMPPAsyncClient:
self.send(pingresp) self.send(pingresp)
else: else:
pingto = xml.get("to")
pingfrom = self.bumper_jid pingfrom = self.bumper_jid
if not "from" in xml.attrib: if not "from" in xml.attrib:
xml.attrib["from"] = f"{pingfrom}" xml.attrib["from"] = f"{pingfrom}"
@ -281,6 +283,7 @@ class XMPPAsyncClient:
if ( if (
client.bumper_jid != self.bumper_jid client.bumper_jid != self.bumper_jid
and client.state == client.READY and client.state == client.READY
and pingto
): ):
if client.uid.lower() in pingto.lower(): if client.uid.lower() in pingto.lower():
client.send(pingstring) client.send(pingstring)
@ -288,7 +291,7 @@ class XMPPAsyncClient:
except Exception as e: except Exception as e:
xmppserverlog.exception(f"{e}") xmppserverlog.exception(f"{e}")
async def schedule_ping(self, time): async def schedule_ping(self, time: int) -> None:
if not self.state == 5: # disconnected if not self.state == 5: # disconnected
pingstring = "<iq from='{}' to='{}' id='s2c1' type='get'><ping xmlns='urn:xmpp:ping'/></iq>".format( pingstring = "<iq from='{}' to='{}' id='s2c1' type='get'><ping xmlns='urn:xmpp:ping'/></iq>".format(
XMPPServer.server_id, self.bumper_jid XMPPServer.server_id, self.bumper_jid
@ -297,7 +300,7 @@ class XMPPAsyncClient:
await asyncio.sleep(time) await asyncio.sleep(time)
asyncio.Task(self.schedule_ping(time)) asyncio.Task(self.schedule_ping(time))
def _handle_result(self, xml, data): def _handle_result(self, xml: ET.Element, data: str) -> None:
try: try:
ctl_to = xml.get("to") ctl_to = xml.get("to")
if not "from" in xml.attrib: if not "from" in xml.attrib:
@ -321,7 +324,7 @@ class XMPPAsyncClient:
adminuser = adminuser.replace(" ", "") adminuser = adminuser.replace(" ", "")
elif "admin" in ctl[0].attrib: elif "admin" in ctl[0].attrib:
adminuser = ctl[0].attrib["admin"] adminuser = ctl[0].attrib["admin"]
if not ( if ctl_to and not (
adminuser.startswith("fuid_") adminuser.startswith("fuid_")
or adminuser.startswith("fusername_") or adminuser.startswith("fusername_")
or bumper.use_auth or bumper.use_auth
@ -367,9 +370,11 @@ class XMPPAsyncClient:
for client in XMPPServer.clients: for client in XMPPServer.clients:
client.send(rxmlstring) client.send(rxmlstring)
if xml.get("to").find("@") == -1: # No to address to = xml.get("to")
ctl_to = xml.get("to") if to and to.find("@") == -1: # No to address
ctl_to = to
else: else:
assert ctl_to
ctl_to = "{}@ecouser.net".format(ctl_to.split("@")[0]) ctl_to = "{}@ecouser.net".format(ctl_to.split("@")[0])
for client in XMPPServer.clients: for client in XMPPServer.clients:
@ -394,11 +399,11 @@ class XMPPAsyncClient:
except Exception as e: except Exception as e:
xmppserverlog.exception(f"{e}") xmppserverlog.exception(f"{e}")
def _handle_connect(self, data, xml=None): def _handle_connect(self, data: bytes, xml: None | ET.Element = None) -> None:
try: try:
if self.state == self.CONNECT: if self.state == self.CONNECT:
if xml == None: if xml is None:
# Client first connecting, send our features # Client first connecting, send our features
if data.decode("utf-8").find("jabber:client") > -1: if data.decode("utf-8").find("jabber:client") > -1:
sc = data.decode("utf-8").find("to=") sc = data.decode("utf-8").find("to=")
@ -414,7 +419,7 @@ class XMPPAsyncClient:
) )
# Send STARTTLS to client with auth mechanisms # Send STARTTLS to client with auth mechanisms
if self.TLSUpgraded == False: if not self.TLSUpgraded:
# With STARTTLS #https://xmpp.org/rfcs/rfc3920.html # With STARTTLS #https://xmpp.org/rfcs/rfc3920.html
self.send( self.send(
'<stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism></mechanisms></stream:features>' '<stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism></mechanisms></stream:features>'
@ -438,7 +443,7 @@ class XMPPAsyncClient:
xmppserverlog.error(f"Couldn't handle: {xml}") xmppserverlog.error(f"Couldn't handle: {xml}")
elif self.state == self.INIT: elif self.state == self.INIT:
if xml == None: if xml is None:
# Client getting session after authentication # Client getting session after authentication
if data.decode("utf-8").find("jabber:client") > -1: if data.decode("utf-8").find("jabber:client") > -1:
# ack jabbr:client # ack jabbr:client
@ -467,9 +472,9 @@ class XMPPAsyncClient:
except Exception as e: except Exception as e:
xmppserverlog.exception(f"{e}") xmppserverlog.exception(f"{e}")
async def _handle_starttls(self, data): async def _handle_starttls(self, _: bytes) -> None:
try: try:
if self.TLSUpgraded == False: if not self.TLSUpgraded:
self.TLSUpgraded = True # Set TLSUpgraded true to prevent further attempts to upgrade connection self.TLSUpgraded = True # Set TLSUpgraded true to prevent further attempts to upgrade connection
xmppserverlog.debug( xmppserverlog.debug(
"Upgrading connection with STARTTLS for {}:{}".format( "Upgrading connection with STARTTLS for {}:{}".format(
@ -497,9 +502,9 @@ class XMPPAsyncClient:
except Exception as e: except Exception as e:
xmppserverlog.exception(f"{e}") xmppserverlog.exception(f"{e}")
def _handle_sasl_auth(self, xml): def _handle_sasl_auth(self, xml: ET.Element) -> None:
try: try:
assert xml.text
saslauth = base64.b64decode(xml.text).decode("utf-8").split("/") saslauth = base64.b64decode(xml.text).decode("utf-8").split("/")
username = saslauth[0] username = saslauth[0]
username = saslauth[0].split("\x00")[1] username = saslauth[0].split("\x00")[1]
@ -525,7 +530,7 @@ class XMPPAsyncClient:
) # Success ) # Success
# Client authenticated, move to next state # Client authenticated, move to next state
self._set_state("INIT") self.set_state("INIT")
else: else:
auth = False auth = False
@ -540,7 +545,7 @@ class XMPPAsyncClient:
xmppserverlog.info(f"client authenticated {self.uid}") xmppserverlog.info(f"client authenticated {self.uid}")
# Client authenticated, move to next state # Client authenticated, move to next state
self._set_state("INIT") self.set_state("INIT")
# Send response # Send response
self.send( self.send(
@ -556,7 +561,7 @@ class XMPPAsyncClient:
except Exception as e: except Exception as e:
xmppserverlog.exception(f"{e}") xmppserverlog.exception(f"{e}")
def _handle_bind(self, xml): def _handle_bind(self, xml: ET.Element) -> None:
try: try:
bot = bot_get(self.uid) bot = bot_get(self.uid)
@ -583,6 +588,7 @@ class XMPPAsyncClient:
xml.get("id"), self.bumper_jid xml.get("id"), self.bumper_jid
) )
elif len(clientresourcexml) > 0: elif len(clientresourcexml) > 0:
assert clientresourcexml[0].text
self.clientresource = clientresourcexml[0].text self.clientresource = clientresourcexml[0].text
self.name = f"XMPP_Client_{self.clientresource}" self.name = f"XMPP_Client_{self.clientresource}"
self.bumper_jid = "{}@{}/{}".format( self.bumper_jid = "{}@{}/{}".format(
@ -608,19 +614,19 @@ class XMPPAsyncClient:
xml.get("id"), self.bumper_jid xml.get("id"), self.bumper_jid
) )
self._set_state("BIND") self.set_state("BIND")
self.send(res) self.send(res)
except Exception as e: except Exception as e:
xmppserverlog.exception(f"{e}") xmppserverlog.exception(f"{e}")
def _handle_session(self, xml): def _handle_session(self, xml: ET.Element) -> None:
res = '<iq type="result" id="{}" />'.format(xml.get("id")) res = '<iq type="result" id="{}" />'.format(xml.get("id"))
self._set_state("READY") self.set_state("READY")
self.send(res) self.send(res)
asyncio.Task(self.schedule_ping(30)) asyncio.Task(self.schedule_ping(30))
def _handle_presence(self, xml): def _handle_presence(self, xml: ET.Element) -> None:
if len(xml) and xml[0].tag == "status": if len(xml) and xml[0].tag == "status":
xmppserverlog.debug( xmppserverlog.debug(
@ -665,7 +671,7 @@ class XMPPAsyncClient:
) )
) )
self._set_state("DISCONNECT") self.set_state("DISCONNECT")
else: else:
# Sometimes the android app sends these # Sometimes the android app sends these
xmppserverlog.debug( xmppserverlog.debug(
@ -676,7 +682,7 @@ class XMPPAsyncClient:
# Send dummy return # Send dummy return
self.send(f'<presence to="{self.bumper_jid}"> dummy </presence>') self.send(f'<presence to="{self.bumper_jid}"> dummy </presence>')
def _parse_data(self, data): def parse_data(self, data: bytes) -> None:
if data.decode("utf-8").startswith( if data.decode("utf-8").startswith(
"<?xml" "<?xml"
@ -778,12 +784,12 @@ class XMPPAsyncClient:
xmppserverlog.error(f"xml parse error - {newdata} - {e}") xmppserverlog.error(f"xml parse error - {newdata} - {e}")
else: else:
self.send("</stream:stream>") # Close stream self.send("</stream:stream>") # Close stream
self._set_state("DISCONNECT") self.set_state("DISCONNECT")
except Exception as e: except Exception as e:
xmppserverlog.exception(f"{e}") xmppserverlog.exception(f"{e}")
def _handle_iq(self, xml, data): def _handle_iq(self, xml: ET.Element, data: str) -> None:
if len(xml): if len(xml):
child = self._tag_strip_uri(xml[0].tag) child = self._tag_strip_uri(xml[0].tag)
@ -796,7 +802,7 @@ class XMPPAsyncClient:
elif child == "session": elif child == "session":
self._handle_session(xml) self._handle_session(xml)
elif child == "ping": elif child == "ping":
self._handle_ping(xml, data) self._handle_ping(xml)
elif child == "query": elif child == "query":
if self.type == self.BOT: if self.type == self.BOT:
self._handle_result(xml, data) self._handle_result(xml, data)

View file

@ -17,8 +17,7 @@ def mock_transport_extra_info():
async def test_xmpp_server(): async def test_xmpp_server():
xmpp_address = ("127.0.0.1", 5223) xmpp_server = XMPPServer("127.0.0.1", 5223)
xmpp_server = XMPPServer(xmpp_address)
await xmpp_server.start_async_server() await xmpp_server.start_async_server()
with LogCapture("xmppserver") as l: with LogCapture("xmppserver") as l:
@ -63,7 +62,7 @@ async def test_client_connect_no_starttls():
# Send connect stream from "client" # Send connect stream from "client"
test_data = b"<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='ecouser.net'>" test_data = b"<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='ecouser.net'>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
# Expect 2 calls to send # Expect 2 calls to send
assert mock_send.call_count == 2 assert mock_send.call_count == 2
@ -83,7 +82,7 @@ async def test_client_connect_no_starttls():
# Client sendss auth - Ignoring the starttls, we don't force this with bumper # Client sendss auth - Ignoring the starttls, we don't force this with bumper
test_data = b'<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">AGZ1aWRfdG1wdXNlcgAwL0lPU0Y1M0QwN0JBL3VzXzg5ODgwMmZkYmM0NDQxYjBiYzgxNWIxZDFjNjgzMDJl</auth>' test_data = b'<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">AGZ1aWRfdG1wdXNlcgAwL0lPU0Y1M0QwN0JBL3VzXzg5ODgwMmZkYmM0NDQxYjBiYzgxNWIxZDFjNjgzMDJl</auth>'
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -102,7 +101,7 @@ async def test_client_end_stream():
# Send end stream from "client" # Send end stream from "client"
test_data = b"</stream:stream>" test_data = b"</stream:stream>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
# Expect 2 calls to send # Expect 2 calls to send
assert mock_send.call_count == 1 assert mock_send.call_count == 1
@ -114,14 +113,14 @@ async def test_client_end_stream():
# Send abnormal stream from "client" # Send abnormal stream from "client"
test_data = b"<badstr />" test_data = b"<badstr />"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
# Reset mock calls # Reset mock calls
mock_send.reset_mock() mock_send.reset_mock()
# Send blank from "client" # Send blank from "client"
test_data = b"" test_data = b""
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
async def test_client_connect_starttls_called(): async def test_client_connect_starttls_called():
@ -134,7 +133,7 @@ async def test_client_connect_starttls_called():
# Send connect stream from "client" # Send connect stream from "client"
test_data = b"<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='ecouser.net'>" test_data = b"<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='ecouser.net'>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
# Expect 2 calls to send # Expect 2 calls to send
assert mock_send.call_count == 2 assert mock_send.call_count == 2
@ -156,7 +155,7 @@ async def test_client_connect_starttls_called():
# Send start tls from "client" # Send start tls from "client"
test_data = b"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>" test_data = b"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
# After upgrading connection, server tells client to proceed with auth again # After upgrading connection, server tells client to proceed with auth again
assert mock_tls.called assert mock_tls.called
@ -165,7 +164,7 @@ async def test_client_connect_starttls_called():
# After TLS is upgraded, Client establishes session again and will auth this time # After TLS is upgraded, Client establishes session again and will auth this time
# Send connect stream from "client" # Send connect stream from "client"
test_data = b"<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='ecouser.net'>" test_data = b"<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='ecouser.net'>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
# Expect 2 calls to send # Expect 2 calls to send
assert mock_send.call_count == 2 assert mock_send.call_count == 2
@ -184,7 +183,7 @@ async def test_client_connect_starttls_called():
# Client sends auth # Client sends auth
test_data = b'<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">AGZ1aWRfdG1wdXNlcgAwL0lPU0Y1M0QwN0JBL3VzXzg5ODgwMmZkYmM0NDQxYjBiYzgxNWIxZDFjNjgzMDJl</auth>' test_data = b'<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">AGZ1aWRfdG1wdXNlcgAwL0lPU0Y1M0QwN0JBL3VzXzg5ODgwMmZkYmM0NDQxYjBiYzgxNWIxZDFjNjgzMDJl</auth>'
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -207,7 +206,7 @@ async def test_client_init():
# Send connect stream from "client" # Send connect stream from "client"
test_data = b"<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='ecouser.net'>" test_data = b"<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='ecouser.net'>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
# Expect 2 calls to send # Expect 2 calls to send
assert mock_send.call_count == 2 assert mock_send.call_count == 2
@ -227,7 +226,7 @@ async def test_client_init():
# Send bind from "client" # Send bind from "client"
test_data = b'<iq type="set" id="5E9872D5-547E-49AF-AE51-9EFAA282F952"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>IOSF53D07BA</resource></bind></iq>' test_data = b'<iq type="set" id="5E9872D5-547E-49AF-AE51-9EFAA282F952"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><resource>IOSF53D07BA</resource></bind></iq>'
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -240,7 +239,7 @@ async def test_client_init():
# Send set session from client # Send set session from client
test_data = b'<iq type="set" id="FA1041E7-AA27-43DD-BAA3-64DE2DE56AA3"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>' test_data = b'<iq type="set" id="FA1041E7-AA27-43DD-BAA3-64DE2DE56AA3"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>'
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert xmppclient.state == xmppclient.READY # client moved to READY state assert xmppclient.state == xmppclient.READY # client moved to READY state
assert ( assert (
@ -253,7 +252,7 @@ async def test_client_init():
# Send presence from client # Send presence from client
test_data = b'<presence type="available"/>' test_data = b'<presence type="available"/>'
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -271,7 +270,7 @@ async def test_bot_connect():
# Send connect stream from "bot" # Send connect stream from "bot"
test_data = b"<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='159.ecorobot.net' version='1.0'>" test_data = b"<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='159.ecorobot.net' version='1.0'>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
# Expect 2 calls to send # Expect 2 calls to send
assert mock_send.call_count == 2 assert mock_send.call_count == 2
@ -291,7 +290,7 @@ async def test_bot_connect():
# Send auth from "bot" # Send auth from "bot"
test_data = b"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>AEUwMDAwMDAwMDAwMDAwMDAxMjM0AGVuY3J5cHRlZF9wYXNz</auth>" test_data = b"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>AEUwMDAwMDAwMDAwMDAwMDAxMjM0AGVuY3J5cHRlZF9wYXNz</auth>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -314,7 +313,7 @@ async def test_bot_init():
# Send connect stream from "bot" # Send connect stream from "bot"
test_data = b"<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='159.ecorobot.net' version='1.0'>" test_data = b"<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='159.ecorobot.net' version='1.0'>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
# Expect 2 calls to send # Expect 2 calls to send
assert mock_send.call_count == 2 assert mock_send.call_count == 2
@ -334,7 +333,7 @@ async def test_bot_init():
# Send bind from "bot" # Send bind from "bot"
test_data = b"<iq type='set' id='2521'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>atom</resource></bind></iq>" test_data = b"<iq type='set' id='2521'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>atom</resource></bind></iq>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -347,7 +346,7 @@ async def test_bot_init():
# Send set session from bot # Send set session from bot
test_data = b"<iq type='set' id='2522'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>" test_data = b"<iq type='set' id='2522'><session xmlns='urn:ietf:params:xml:ns:xmpp-session'/></iq>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert xmppclient.state == xmppclient.READY # Bot moved to READY state assert xmppclient.state == xmppclient.READY # Bot moved to READY state
assert ( assert (
@ -359,7 +358,7 @@ async def test_bot_init():
# Send presence from bot # Send presence from bot
test_data = b"<presence><status>hello world</status></presence><iq type='result' from='E0000000000000001234@159.ecorobot.net/atom' to='ecouser.net' id='s2c1'/>" test_data = b"<presence><status>hello world</status></presence><iq type='result' from='E0000000000000001234@159.ecorobot.net/atom' to='ecouser.net' id='s2c1'/>"
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -379,7 +378,7 @@ async def test_ping_server():
# Ping from bot # Ping from bot
test_data = b'<iq xmlns:ns0="urn:xmpp:ping" from="E000BVTNX18700260382@159.ecorobot.net/atom" id="2542" to="159.ecorobot.net" type="get"><ping /></iq>' test_data = b'<iq xmlns:ns0="urn:xmpp:ping" from="E000BVTNX18700260382@159.ecorobot.net/atom" id="2542" to="159.ecorobot.net" type="get"><ping /></iq>'
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -410,7 +409,7 @@ async def test_ping_client_to_client():
# Ping from user to bot # Ping from user to bot
test_data = b'<iq id="104934615" to="fuid_tmpuser@ecouser.net/IOSF53D07BA" type="get"><ping xmlns="urn:xmpp:ping" /></iq>' test_data = b'<iq id="104934615" to="fuid_tmpuser@ecouser.net/IOSF53D07BA" type="get"><ping xmlns="urn:xmpp:ping" /></iq>'
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send2.mock_calls[0][1][0] mock_send2.mock_calls[0][1][0]
@ -419,7 +418,7 @@ async def test_ping_client_to_client():
# Ping response from bot to user # Ping response from bot to user
test_data = b"<iq type='result' to='E0000000000000001234@159.ecorobot.net/atom' id='104934615'/>" test_data = b"<iq type='result' to='E0000000000000001234@159.ecorobot.net/atom' id='104934615'/>"
xmppclient2._parse_data(test_data) xmppclient2.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -454,7 +453,7 @@ async def test_client_send_iq():
test_data = ( test_data = (
b'<iq id="EE0XQ-2" type="get"><query xmlns="jabber:iq:roster" ></query></iq>' b'<iq id="EE0XQ-2" type="get"><query xmlns="jabber:iq:roster" ></query></iq>'
) )
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -466,7 +465,7 @@ async def test_client_send_iq():
# Bot Command # Bot Command
test_data = b'<iq id="7" to="E0000000000000001234@159.ecorobot.net/atom" type="set"><query xmlns="com:ctl"><ctl id="72107787" td="GetCleanState" /></query></iq>' test_data = b'<iq id="7" to="E0000000000000001234@159.ecorobot.net/atom" type="set"><query xmlns="com:ctl"><ctl id="72107787" td="GetCleanState" /></query></iq>'
xmppclient._parse_data(test_data) xmppclient.parse_data(test_data)
assert ( assert (
mock_send2.mock_calls[0][1][0] mock_send2.mock_calls[0][1][0]
@ -478,7 +477,7 @@ async def test_client_send_iq():
# Bot response to query # Bot response to query
test_data = b'<iq xmlns:ns0="com:ctl" id="2679" to="fuid_tmpuser@ecouser.net/IOSF53D07BA" type="set"><query><ctl td="ChargeState"><charge h="0" r="a" type="Going" /></ctl></query></iq>' test_data = b'<iq xmlns:ns0="com:ctl" id="2679" to="fuid_tmpuser@ecouser.net/IOSF53D07BA" type="set"><query><ctl td="ChargeState"><charge h="0" r="a" type="Going" /></ctl></query></iq>'
xmppclient2._parse_data(test_data) xmppclient2.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -490,7 +489,7 @@ async def test_client_send_iq():
# Bot result # Bot result
test_data = b"<iq type='result' from='E0000000000000001234@159.ecorobot.net/atom' to='ecouser.net' id='s2c1'/>" test_data = b"<iq type='result' from='E0000000000000001234@159.ecorobot.net/atom' to='ecouser.net' id='s2c1'/>"
xmppclient2._parse_data(test_data) xmppclient2.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -502,7 +501,7 @@ async def test_client_send_iq():
# Bot iq set # Bot iq set
test_data = b"<iq to='fuid_tmpuser@ecouser.net/IOSF53D07BA' type='set' id='2700'><query xmlns='com:ctl'><ctl td='BatteryInfo'><battery power='100'/></ctl></query></iq>" test_data = b"<iq to='fuid_tmpuser@ecouser.net/IOSF53D07BA' type='set' id='2700'><query xmlns='com:ctl'><ctl td='BatteryInfo'><battery power='100'/></ctl></query></iq>"
xmppclient2._parse_data(test_data) xmppclient2.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -514,7 +513,7 @@ async def test_client_send_iq():
# Bot error report # Bot error report
test_data = b"<iq to='fuid_tmpuser@ecouser.net/IOSF53D07BA' type='set' id='631'><query xmlns='com:ctl'><ctl td='error' errs='102'/></query></iq>" test_data = b"<iq to='fuid_tmpuser@ecouser.net/IOSF53D07BA' type='set' id='631'><query xmlns='com:ctl'><ctl td='error' errs='102'/></query></iq>"
xmppclient2._parse_data(test_data) xmppclient2.parse_data(test_data)
assert ( assert (
mock_send.mock_calls[0][1][0] mock_send.mock_calls[0][1][0]
@ -526,7 +525,7 @@ async def test_client_send_iq():
# Bot "DorpError" to all # Bot "DorpError" to all
test_data = b"<iq to='rl.ecorobot.net' type='set' id='1234'><query xmlns='com:sf'><sf td='pub' t='log' ts='1559893796000' tp='p' k='DeviceAlert' v='DorpError' f='E0000000000000001234@159.ecorobot.net' g='fuid_tmpuser@ecouser.net'/></query></iq>" test_data = b"<iq to='rl.ecorobot.net' type='set' id='1234'><query xmlns='com:sf'><sf td='pub' t='log' ts='1559893796000' tp='p' k='DeviceAlert' v='DorpError' f='E0000000000000001234@159.ecorobot.net' g='fuid_tmpuser@ecouser.net'/></query></iq>"
xmppclient2._parse_data(test_data) xmppclient2.parse_data(test_data)
assert mock_send.mock_calls[0][1][0] == ( assert mock_send.mock_calls[0][1][0] == (
'<iq xmlns="com:sf" to="rl.ecorobot.net" type="set" id="1234" from="E0000000000000001234@159.ecorobot.net/atom"><query xmlns="com:ctl"><sf td="pub" t="log" ts="1559893796000" tp="p" k="DeviceAlert" v="DorpError" f="E0000000000000001234@159.ecorobot.net" g="fuid_tmpuser@ecouser.net" /></query></iq>' '<iq xmlns="com:sf" to="rl.ecorobot.net" type="set" id="1234" from="E0000000000000001234@159.ecorobot.net/atom"><query xmlns="com:ctl"><sf td="pub" t="log" ts="1559893796000" tp="p" k="DeviceAlert" v="DorpError" f="E0000000000000001234@159.ecorobot.net" g="fuid_tmpuser@ecouser.net" /></query></iq>'
) # result sent to ecouser.net ) # result sent to ecouser.net

View file

@ -41,8 +41,7 @@ async def test_base(webserver_client):
remove_existing_db() remove_existing_db()
# Start XMPP # Start XMPP
xmpp_address = (HOST, 5223) xmpp_server = XMPPServer(HOST, 5223)
xmpp_server = XMPPServer(xmpp_address)
bumper.xmpp_server = xmpp_server bumper.xmpp_server = xmpp_server
await xmpp_server.start_async_server() await xmpp_server.start_async_server()
@ -57,8 +56,7 @@ async def test_restartService(webserver_client):
remove_existing_db() remove_existing_db()
# Start XMPP # Start XMPP
xmpp_address = (HOST, 5223) xmpp_server = XMPPServer(HOST, 5223)
xmpp_server = XMPPServer(xmpp_address)
bumper.xmpp_server = xmpp_server bumper.xmpp_server = xmpp_server
await xmpp_server.start_async_server() await xmpp_server.start_async_server()