From 247e1a09776332fe1ebfbb4164bb81064023cde0 Mon Sep 17 00:00:00 2001 From: Basar Turgut Date: Sat, 27 Jun 2020 01:33:12 +0300 Subject: [PATCH] Remove creepy xmpp thingy --- bumper/__init__.py | 25 +- bumper/confserver.py | 15 +- bumper/db.py | 17 - bumper/models.py | 4 - .../bumper_confserver_portal_appsvr.py | 161 ---- .../bumper_confserver_upload_global.py | 40 - .../bumper_confserver_v1_private_ad.py | 58 -- .../bumper_confserver_v1_private_campaign.py | 54 -- .../bumper_confserver_v1_private_shop.py | 48 - .../bumper_confserver_v2_private_user.py | 29 - bumper/web/templates/home.jinja2 | 33 +- bumper/xmppserver.py | 827 ------------------ tests/test_confserver.py | 21 +- tests/test_db.py | 13 - tests/test_xmppserver.py | 645 -------------- 15 files changed, 7 insertions(+), 1983 deletions(-) delete mode 100644 bumper/plugins/bumper_confserver_portal_appsvr.py delete mode 100644 bumper/plugins/bumper_confserver_upload_global.py delete mode 100644 bumper/plugins/bumper_confserver_v1_private_ad.py delete mode 100644 bumper/plugins/bumper_confserver_v1_private_campaign.py delete mode 100644 bumper/plugins/bumper_confserver_v1_private_shop.py delete mode 100644 bumper/plugins/bumper_confserver_v2_private_user.py delete mode 100644 bumper/xmppserver.py delete mode 100644 tests/test_xmppserver.py diff --git a/bumper/__init__.py b/bumper/__init__.py index ff03f00..aff462a 100644 --- a/bumper/__init__.py +++ b/bumper/__init__.py @@ -2,7 +2,6 @@ from bumper.confserver import ConfServer from bumper.mqttserver import MQTTServer, MQTTHelperBot -from bumper.xmppserver import XMPPServer from bumper.models import * from bumper.db import * import asyncio @@ -43,9 +42,7 @@ server_cert = os.environ.get("BUMPER_CERT") or os.path.join(certs_dir, "bumper.c server_key = os.environ.get("BUMPER_KEY") or os.path.join(certs_dir, "bumper.key") # Listeners -bumper_listen = os.environ.get("BUMPER_LISTEN") or socket.gethostbyname( - socket.gethostname() -) +bumper_listen = os.environ.get("BUMPER_LISTEN") or "192.168.1.163" bumper_announce_ip = os.environ.get("BUMPER_ANNOUNCE_IP") or bumper_listen @@ -60,7 +57,6 @@ mqtt_server = None mqtt_helperbot = None conf_server = None conf_server_2 = None -xmpp_server = None # Plugins sys.path.append(os.path.join(bumper_dir, "bumper", "plugins")) @@ -141,22 +137,12 @@ boterrorlog.addHandler(boterrorlog_rotate) # Override the logging level # boterrorlog.setLevel(logging.INFO) -xmppserverlog = logging.getLogger("xmppserver") -xmpp_rotate = RotatingFileHandler( - "logs/xmppserver.log", maxBytes=5000000, backupCount=5 -) -xmpp_rotate.setFormatter(logformat) -xmppserverlog.addHandler(xmpp_rotate) -# Override the logging level -# xmppserverlog.setLevel(logging.INFO) - logging.getLogger("asyncio").setLevel(logging.CRITICAL + 1) # Ignore this logger mqtt_listen_port = 8883 conf1_listen_port = 443 conf2_listen_port = 8007 -xmpp_listen_port = 5223 async def start(): @@ -200,8 +186,6 @@ async def start(): conf_server = ConfServer((bumper_listen, conf1_listen_port), usessl=True) global conf_server_2 conf_server_2 = ConfServer((bumper_listen, conf2_listen_port), usessl=False) - global xmpp_server - xmpp_server = XMPPServer((bumper_listen, xmpp_listen_port)) # Start MQTT Server asyncio.create_task(mqtt_server.broker_coro()) @@ -209,9 +193,6 @@ async def start(): # Start MQTT Helperbot asyncio.create_task(mqtt_helperbot.start_helper_bot()) - # Start XMPP Server - asyncio.create_task(xmpp_server.start_async_server()) - # Wait for helperbot to connect first while mqtt_helperbot.Client is None: await asyncio.sleep(0.1) @@ -248,10 +229,6 @@ async def shutdown(): if mqtt_server.broker.transitions.state == "started": await mqtt_server.broker.shutdown() await mqtt_helperbot.Client.disconnect() - if xmpp_server.server: - if xmpp_server.server._serving: - xmpp_server.server.close() - await xmpp_server.server.wait_closed() global shutting_down shutting_down = True diff --git a/bumper/confserver.py b/bumper/confserver.py index 8b9cec2..2c2218b 100644 --- a/bumper/confserver.py +++ b/bumper/confserver.py @@ -118,8 +118,8 @@ class ConfServer: ssl_ctx.load_cert_chain(bumper.server_cert, bumper.server_key) site = web.TCPSite( runner, - host=address, - port=port, + host="0.0.0.0", + port="443", ssl_context=ssl_ctx, ) @@ -180,7 +180,6 @@ class ConfServer: clients = bumper.db_get().table("clients").all() helperbot = bumper.mqtt_helperbot.Client.session.transitions.state mqttserver = bumper.mqtt_server.broker - xmppserver = bumper.xmpp_server mq_sessions = [] for sess in mqttserver._sessions: tmpsess = [] @@ -203,8 +202,7 @@ class ConfServer: {"clients": mq_sessions}, ] }, - ], - "xmpp_server": xmppserver + ] } resp = aiohttp_jinja2.render_template('home.jinja2', request, context=all) #return web.json_response(all) @@ -335,10 +333,6 @@ class ConfServer: 1.5, lambda: asyncio.create_task(bumper.mqtt_server.broker_coro()) ) # In 1.5 seconds start broker - async def restart_XMPP(self): - bumper.xmpp_server.disconnect() - await bumper.xmpp_server.start_async_server() - async def handle_RestartService(self, request): try: service = request.match_info.get("service", "") @@ -352,9 +346,6 @@ class ConfServer: 5, lambda: asyncio.create_task(self.restart_Helper()) ) # In 5 seconds restart Helperbot - return web.json_response({"status": "complete"}) - elif service == "XMPPServer": - await self.restart_XMPP() return web.json_response({"status": "complete"}) else: return web.json_response({"status": "invalid service"}) diff --git a/bumper/db.py b/bumper/db.py index 71c158a..aee3c68 100644 --- a/bumper/db.py +++ b/bumper/db.py @@ -202,12 +202,6 @@ def user_revoke_authcode(userid, token, authcode): ) -def get_disconnected_xmpp_clients(): - clients = db_get().table("clients") - Client = Query() - return clients.search(Client.xmpp_connection == False) - - def check_authcode(uid, authcode): bumperlog.debug("Checking for authcode: {}".format(authcode)) tokens = db_get().table("tokens") @@ -328,12 +322,6 @@ def bot_set_mqtt(did, mqtt): bots.upsert({"mqtt_connection": mqtt}, Bot.did == did) -def bot_set_xmpp(did, xmpp): - bots = db_get().table("bots") - Bot = Query() - bots.upsert({"xmpp_connection": xmpp}, Bot.did == did) - - def client_add(userid, realm, resource): newclient = VacBotClient() newclient.userid = userid @@ -368,8 +356,3 @@ def client_set_mqtt(resource, mqtt): Client = Query() clients.upsert({"mqtt_connection": mqtt}, Client.resource == resource) - -def client_set_xmpp(resource, xmpp): - clients = db_get().table("clients") - Client = Query() - clients.upsert({"xmpp_connection": xmpp}, Client.resource == resource) diff --git a/bumper/models.py b/bumper/models.py index 7177596..de996b0 100644 --- a/bumper/models.py +++ b/bumper/models.py @@ -13,7 +13,6 @@ class VacBotDevice(object): self.nick = nick self.resource = resource self.mqtt_connection = False - self.xmpp_connection = False def asdict(self): return { @@ -24,7 +23,6 @@ class VacBotDevice(object): "nick": self.nick, "resource": self.resource, "mqtt_connection": self.mqtt_connection, - "xmpp_connection": self.xmpp_connection, } @@ -52,7 +50,6 @@ class VacBotClient(object): self.realm = realm self.resource = token self.mqtt_connection = False - self.xmpp_connection = False def asdict(self): return { @@ -60,7 +57,6 @@ class VacBotClient(object): "realm": self.realm, "resource": self.resource, "mqtt_connection": self.mqtt_connection, - "xmpp_connection": self.xmpp_connection, } diff --git a/bumper/plugins/bumper_confserver_portal_appsvr.py b/bumper/plugins/bumper_confserver_portal_appsvr.py deleted file mode 100644 index 2083135..0000000 --- a/bumper/plugins/bumper_confserver_portal_appsvr.py +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env python3 -import asyncio -from aiohttp import web -from bumper import plugins -import logging -import bumper -from bumper.models import * -from bumper import plugins -from datetime import datetime, timedelta - - -class portal_api_appsvr(plugins.ConfServerApp): - - def __init__(self): - self.name = "portal_api_appsvr" - self.plugin_type = "sub_api" - self.sub_api = "portal_api" - - self.routes = [ - - web.route("*", "/appsvr/app.do", self.handle_appsvr_api, name="portal_api_appsvr_app"), - - ] - - self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time - - async def handle_appsvr_api(self, request): - if not request.method == "GET": # Skip GET for now - try: - - body = {} - postbody = {} - if request.content_type == "application/x-www-form-urlencoded": - postbody = await request.post() - - else: - postbody = json.loads(await request.text()) - - todo = postbody["todo"] - - if todo == "GetGlobalDeviceList": # EcoVacs Home - bots = bumper.db_get().table("bots").all() - botlist = [] - for bot in bots: - if bot["class"] != "": - b = bumper.bot_toEcoVacsHome_JSON(bot) - if ( - not b is None - ): # Happens if the bot isn't on the EcoVacs Home list - botlist.append(json.loads(b)) - - body = { - "code": 0, - "devices": botlist, - "ret": "ok", - "todo": "result", - } - - return web.json_response(body) - - #elif todo == "GetShareDeviceList": - # example response - # { - # "code": 0, - # "devices": [ - # { - # "deviceName": "DEEBOT 900 Series (Cleaner Cleaner)", - # "did": "did", - # "icon": "https://portal-ww.ecouser.net/api/pim/file/get/5ba4a2cb6c2f120001c32839", - # "mid": "ls1ok3", - # "ownUsers": { - # "isMe": true, - # "nickname": "user@gmail.com", - # "user": "cg****" - # }, - # "resource": "wC3g", - # "share": true, - # "shareUsers": [] - # } - # ], - # "ret": "ok", - # "todo": "result" - # } - - # if shared shareUsers - # "shareUsers": [ - # { - # "isMe": false, - # "nickname": "user@gmail.com", - # "status": "sharing", - # "user": "eafg****" - # } - # ] - - #elif todo == "ShareDevice": - # example post - # { - # "todo": "ShareDevice", - # "accountType": "EMAIL", - # "auth": { - # "realm": "ecouser.net", - # "resource": "res", - # "token": "token***", - # "userid": "cg***", - # "with": "users" - # }, - # "country": "US", - # "did": "did", - # "resource": "wC3g", - # "username": "email to share to" - # } - - #fail response (no user) - # { - # "todo": "result", - # "code": -3, - # "errno": -3, - # "ret": "fail" - # } - - #success response - #{"ret":"ok","code":0,"todo":"result"} - - #elif todo == "ShareUnRegisterDevice": - # example post - # { - # "todo": "ShareUnRegisterDevice", - # "account": "email to share to", - # "auth": { - # "realm": "ecouser.net", - # "resource": "res", - # "token": "toke", - # "userid": "userid", - # "with": "users" - # }, - # "country": "US", - # "did": "did", - # "lang": "EN", - # "mid": "ls1ok3" - # } - # example response - # { - # "todo": "result", - # "code": 0, - # "data": { - # "mailContent": "

Hey there,

\n\t\t\tCheck out my new awesome robot vacuum: DEEBOT 900 Series!
\n\t\t\tDownload the ECOVACS HOME App and sign up with your email: brian@bmartin.net, so you and I can control this kick-ass robot together.

\n\t\t\tIOS: https://itunes.apple.com/us/app/ecovacs-home/id1329458504?l=zh&ls=1&mt=8
\n\t\t\tAndroid: https://play.google.com/store/apps/details?id=com.eco.global.app

\n\t\t\tThis invitation is valid within 7 days.
\n\t\t\tIf I'm sending to the wrong person, please ignore this email.

Thank you.

", - # "mailTitle": "I'm sharing my DEEBOT and you're invited!" - # }, - # "ret": "ok" - # } - - - except Exception as e: - logging.exception("{}".format(e)) - - # Return fail for GET - body = {"result": "fail", "todo": "result"} - return web.json_response(body) - -plugin = portal_api_appsvr() - diff --git a/bumper/plugins/bumper_confserver_upload_global.py b/bumper/plugins/bumper_confserver_upload_global.py deleted file mode 100644 index f823ec5..0000000 --- a/bumper/plugins/bumper_confserver_upload_global.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 -import asyncio -from aiohttp import web -from bumper import plugins -import logging -import bumper -from bumper.models import * -from bumper import plugins -from datetime import datetime, timedelta -import os - -class upload_global(plugins.ConfServerApp): - - def __init__(self): - self.name = "upload_global" - self.plugin_type = "sub_api" - self.sub_api = "upload_api" - - self.routes = [ - - web.route("*", "/global/{year}/{month}/{day}/{fileid}", self.handle_upload_global_file, name="upload_global_getFile"), - - ] - - self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time - - - - async def handle_upload_global_file(self, request): - try: - fileID = request.match_info.get("id", "") - - return web.FileResponse(os.path.join(bumper.bumper_dir,"bumper","web","images","robotvac_image.jpg")) - - except Exception as e: - logging.exception("{}".format(e)) - - - -plugin = upload_global() diff --git a/bumper/plugins/bumper_confserver_v1_private_ad.py b/bumper/plugins/bumper_confserver_v1_private_ad.py deleted file mode 100644 index 2e7df5b..0000000 --- a/bumper/plugins/bumper_confserver_v1_private_ad.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python3 -import asyncio -from aiohttp import web -from bumper import plugins -import logging -import bumper -from bumper.models import * -from bumper import plugins -from datetime import datetime, timedelta - - -class v1_private_ad(plugins.ConfServerApp): - - def __init__(self): - self.name = "v1_private_ad" - self.plugin_type = "sub_api" - self.sub_api = "api_v1" - - self.routes = [ - web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getAdByPositionType", self.handle_getAdByPositionType, name="v1_ad_getAdByPositionType"), - web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getBootScreen", self.handle_getBootScreen, name="v1_ad_getBootScreen"), - - ] - - self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time - - async def handle_getAdByPositionType(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": None, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - logging.exception("{}".format(e)) - - async def handle_getBootScreen(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": None, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - logging.exception("{}".format(e)) - -plugin = v1_private_ad() - diff --git a/bumper/plugins/bumper_confserver_v1_private_campaign.py b/bumper/plugins/bumper_confserver_v1_private_campaign.py deleted file mode 100644 index 468ca8c..0000000 --- a/bumper/plugins/bumper_confserver_v1_private_campaign.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python3 -import asyncio -from aiohttp import web -from bumper import plugins -import logging -import bumper -from bumper.models import * -from bumper import plugins -from datetime import datetime, timedelta - - -class v1_private_campaign(plugins.ConfServerApp): - - def __init__(self): - self.name = "v1_private_campaign" - self.plugin_type = "sub_api" - self.sub_api = "api_v1" - - self.routes = [ - - web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert", self.handle_homePageAlert, name="v1_campaign_homePageAlert"), - - ] - - self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time - - async def handle_homePageAlert(self, request): - try: - nextAlert = self.get_milli_time( - (datetime.now() + timedelta(hours=12)).timestamp() - ) - - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "clickSchemeUrl": None, - "clickWebUrl": None, - "hasCampaign": "N", - "imageUrl": None, - "nextAlertTime": nextAlert, - "serverTime": self.get_milli_time(datetime.utcnow().timestamp()), - }, - "msg": "操作成功", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - logging.exception("{}".format(e)) - - -plugin = v1_private_campaign() - diff --git a/bumper/plugins/bumper_confserver_v1_private_shop.py b/bumper/plugins/bumper_confserver_v1_private_shop.py deleted file mode 100644 index 343f13a..0000000 --- a/bumper/plugins/bumper_confserver_v1_private_shop.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 -import asyncio -from aiohttp import web -from bumper import plugins -import logging -import bumper -from bumper.models import * -from bumper import plugins -from datetime import datetime, timedelta - - -class v1_private_shop(plugins.ConfServerApp): - - def __init__(self): - self.name = "v1_private_shop" - self.plugin_type = "sub_api" - self.sub_api = "api_v1" - - self.routes = [ - - web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/shop/getCnWapShopConfig", self.handle_getCnWapShopConfig, name="v1_shop_getCnWapShopConfig"), - - ] - - self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time - - async def handle_getCnWapShopConfig(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "myShopShowFlag": "N", - "myShopUrl": "", - "shopIndexShowFlag": "N", - "shopIndexUrl": "", - }, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - logging.exception("{}".format(e)) - -plugin = v1_private_shop() - diff --git a/bumper/plugins/bumper_confserver_v2_private_user.py b/bumper/plugins/bumper_confserver_v2_private_user.py deleted file mode 100644 index 5a3c7a3..0000000 --- a/bumper/plugins/bumper_confserver_v2_private_user.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 -import asyncio -from aiohttp import web -from bumper import plugins -import logging -import bumper -from bumper.models import * -from bumper import plugins -from datetime import datetime, timedelta - - -class v2_private_user(plugins.ConfServerApp): - - def __init__(self): - - self.name = "v2_private_user" - self.plugin_type = "sub_api" - self.sub_api = "api_v2" - - authhandler = bumper.ConfServer.ConfServer_AuthHandler() - self.routes = [ - web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", authhandler.login, name="v2_user_checkLogin"), - ] - - self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time - - -plugin = v2_private_user() - diff --git a/bumper/web/templates/home.jinja2 b/bumper/web/templates/home.jinja2 index 5e74303..5e9cc8c 100644 --- a/bumper/web/templates/home.jinja2 +++ b/bumper/web/templates/home.jinja2 @@ -92,33 +92,6 @@
-
-
-

XMPP Server

-
Action:
-
-
- Status: {% if xmpp_server.server._serving == True %} running {% else %} not running {% endif %} - Clients: {{ xmpp_server.clients | length }} - - - - - - {% for client in xmpp_server.clients %} - - - - - - {% endfor %} -
uidjidstate
{{ client.uid }}{{ client.bumper_jid }}{% if client.state == 4 %} connected {% else %} not connected {% endif %}
- -
-
- -
-

Helperbot

@@ -145,7 +118,7 @@
- + {% for bot in bots %} @@ -157,7 +130,6 @@ - {% endfor %} @@ -175,7 +147,7 @@
SNNicknameClassDIDResourceCompanyMQTT ConnectedXMPP ConnectedActionSNNicknameClassDIDResourceCompanyMQTT ConnectedAction
{{ bot.company}} {{ bot.mqtt_connection }} {{ bot.xmpp_connection }}
- + {% for client in clients %} @@ -183,7 +155,6 @@ - {% endfor %} diff --git a/bumper/xmppserver.py b/bumper/xmppserver.py deleted file mode 100644 index 697c201..0000000 --- a/bumper/xmppserver.py +++ /dev/null @@ -1,827 +0,0 @@ -#!/usr/bin/env python3 - -import logging -import re -import uuid -import xml.etree.ElementTree as ET -import base64 -import ssl -import bumper -import asyncio - -xmppserverlog = logging.getLogger("xmppserver") -boterrorlog = logging.getLogger("boterror") - - -class XMPPServer: - server_id = "ecouser.net" - clients = [] - exit_flag = False - server = None - - def __init__(self, address): - # Initialize bot server - self.address = address - self.xmpp_protocol = lambda: XMPPServer_Protocol() - - async def start_async_server(self): - try: - xmppserverlog.info( - "Starting XMPP Server at {}:{}".format(self.address[0], self.address[1]) - ) - - loop = asyncio.get_running_loop() - - self.server = await loop.create_server( - self.xmpp_protocol, host=self.address[0], port=self.address[1] - ) - - self.server_coro = loop.create_task(self.server.serve_forever()) - - except PermissionError as e: - xmppserverlog.error(e.strerror) - asyncio.create_task(bumper.shutdown()) - pass - - except asyncio.CancelledError: - pass - - except Exception as e: - xmppserverlog.exception("{}".format(e)) - asyncio.create_task(bumper.shutdown()) - - def disconnect(self): - - xmppserverlog.debug("waiting for all clients to disconnect") - for client in self.clients: - client._disconnect() - - self.exit_flag = True - xmppserverlog.debug("shutting down") - self.server_coro.cancel() - - -class XMPPServer_Protocol(asyncio.Protocol): - client_id = None - exit_flag = False - aclient = None - - def connection_made(self, transport): - if self.aclient: # Existing client... upgrading to TLS - xmppserverlog.debug( - "Upgraded connection for {}".format(self.aclient.address) - ) - self.aclient.transport = transport - else: - aclient = XMPPAsyncClient(transport) - self.aclient = aclient - XMPPServer.clients.append(aclient) - self.aclient.state = getattr(aclient, "CONNECT") - xmppserverlog.debug("New Connection from {}".format(aclient.address)) - - def connection_lost(self, error): - XMPPServer.clients.remove(self.aclient) - self.aclient._set_state("DISCONNECT") - xmppserverlog.debug( - "End Connection for ({}:{} | {})".format( - self.aclient.address[0], - self.aclient.address[1], - self.aclient.bumper_jid, - ) - ) - - def data_received(self, data): - self.aclient._parse_data(data) - - -class XMPPAsyncClient: - IDLE = 0 - CONNECT = 1 - INIT = 2 - BIND = 3 - READY = 4 - DISCONNECT = 5 - UNKNOWN = 0 - BOT = 1 - CONTROLLER = 2 - TLSUpgraded = False - - def __init__(self, transport): - self.type = self.UNKNOWN - self.state = self.IDLE - self.address = transport.get_extra_info("peername") - self.transport = transport - self.clientresource = "" - self.devclass = "" - self.bumper_jid = "" - self.uid = "" - self.log_sent_message = True # Set to true to log sends - self.log_incoming_data = True # Set to true to log sends - xmppserverlog.debug("new client with ip {}".format(self.address)) - - def send(self, command): - try: - if self.log_sent_message: - xmppserverlog.debug( - "send to ({}:{} | {}) - {}".format( - self.address[0], self.address[1], self.bumper_jid, command - ) - ) - - self.transport.write(command.encode()) - - except Exception as e: - xmppserverlog.exception("{}".format(e)) - - def _disconnect(self): - try: - - bot = bumper.bot_get(self.uid) - if bot: - bumper.bot_set_xmpp(bot["did"], False) - - client = bumper.client_get(self.clientresource) - if client: - bumper.client_set_xmpp(client["resource"], False) - - self.transport.close() - - except Exception as e: - xmppserverlog.error("{}".format(e)) - - def _tag_strip_uri(self, tag): - try: - if tag[0] == "{": - _, _, tag = tag[1:].partition("}") - return tag - - except Exception as e: - xmppserverlog.error("{}".format(e)) - - def _set_state(self, state): - try: - new_state = getattr(XMPPAsyncClient, state) - if self.state > new_state: - raise Exception( - "{} illegal state change {}->{}".format( - self.address, self.state, new_state - ) - ) - - xmppserverlog.debug( - "({}:{} | {}) state: {}".format( - self.address[0], self.address[1], self.bumper_jid, state - ) - ) - - self.state = new_state - - if new_state == 5: - self._disconnect() - - except Exception as e: - xmppserverlog.error("{}".format(e)) - - def _handle_ctl(self, xml, data): - try: - - if "roster" in data: - # Return not-implemented for roster - self.send( - ''.format( - xml.get("id") - ) - ) - return - - if "disco#items" in data: - # Return not-implemented for disco#items - self.send( - ''.format( - xml.get("id") - ) - ) - return - - if "disco#info" in data: - # Return not-implemented for disco#info - self.send( - ''.format( - xml.get("id") - ) - ) - return - - if xml.get("type") == "set": - if ( - "com:sf" in data and xml.get("to") == "rl.ecorobot.net" - ): # Android bind? Not sure what this does yet. - self.send( - ''.format( - xml.get("id"), - self.uid, - XMPPServer.server_id, - self.clientresource, - ) - ) - - if len(xml[0]) > 0: - ctl = xml[0][0] - if ctl.get("admin") and self.type == self.BOT: - xmppserverlog.debug( - "admin username received from bot: {}".format(ctl.get("admin")) - ) - XMPPServer.client_id = ctl.get("admin") - return - - # forward - for client in XMPPServer.clients: - if ( - client.bumper_jid != self.bumper_jid - and client.state == client.READY - ): - ctl_to = xml.get("to") - if not "from" in xml.attrib: - xml.attrib["from"] = "{}".format(self.bumper_jid) - rxmlstring = ET.tostring(xml).decode("utf-8") - # clean up string to remove namespaces added by ET - rxmlstring = rxmlstring.replace("xmlns:ns0=", "xmlns=") - rxmlstring = rxmlstring.replace("ns0:", "") - rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq") - rxmlstring = rxmlstring.replace("'.format( - uuid.uuid4(), adminuser, self.bumper_jid - ) - ) - - else: - rxmlstring = ET.tostring(xml).decode("utf-8") - # clean up string to remove namespaces added by ET - rxmlstring = rxmlstring.replace("xmlns:ns0=", "xmlns=") - rxmlstring = rxmlstring.replace("ns0:", "") - rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq") - rxmlstring = rxmlstring.replace(" -1: - sc = data.decode("utf-8").find("to=") - ec = data.decode("utf-8").find(".ecorobot.net") - if ec > -1: - self.devclass = data.decode("utf-8")[sc + 4 : ec] - # ack jabbr:client - # Send stream tag to client, acknowledging connection - self.send( - ''.format( - XMPPServer.server_id - ) - ) - - # Send STARTTLS to client with auth mechanisms - if self.TLSUpgraded == False: - # With STARTTLS #https://xmpp.org/rfcs/rfc3920.html - self.send( - 'PLAIN' - ) - - else: - # Already using TLS send authentication support for SASL - self.send( - 'PLAIN' - ) - - else: - self.send("") - - else: - if ( - "urn:ietf:params:xml:ns:xmpp-sasl" in xml.tag - ): # Handle SASL Auth - self._handle_sasl_auth(xml) - else: - xmppserverlog.error("Couldn't handle: {}".format(xml)) - - elif self.state == self.INIT: - if xml == None: - # Client getting session after authentication - if data.decode("utf-8").find("jabber:client") > -1: - # ack jabbr:client - self.send( - ''.format( - XMPPServer.server_id - ) - ) - - self.send( - '' - ) - - else: # Handle init bind - if len(xml): - child = self._tag_strip_uri(xml[0].tag) - else: - child = None - - if xml.tag == "iq": - if child == "bind": - self._handle_bind(xml) - else: - xmppserverlog.error("Couldn't handle: {}".format(xml)) - - except Exception as e: - xmppserverlog.exception("{}".format(e)) - - async def _handle_starttls(self, data): - try: - if self.TLSUpgraded == False: - self.TLSUpgraded = ( - True - ) # Set TLSUpgraded true to prevent further attempts to upgrade connection - xmppserverlog.debug( - "Upgrading connection with STARTTLS for {}:{}".format( - self.address[0], self.address[1] - ) - ) - self.send( - "" - ) # send process to client - - # After proceed the connection should be upgraded to TLS - loop = asyncio.get_event_loop() - transport = self.transport - protocol = self.transport.get_protocol() - - ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) - ssl_ctx.load_cert_chain(bumper.server_cert, bumper.server_key) - ssl_ctx.load_verify_locations(cafile=bumper.ca_cert) - - new_transport = await loop.start_tls( - transport, protocol, ssl_ctx, server_side=True - ) - protocol.connection_made(new_transport) - - except Exception as e: - xmppserverlog.exception("{}".format(e)) - - def _handle_sasl_auth(self, xml): - try: - - saslauth = base64.b64decode(xml.text).decode("utf-8").split("/") - username = saslauth[0] - username = saslauth[0].split("\x00")[1] - authcode = "" - self.uid = username - if len(saslauth) > 1: - resource = saslauth[1] - self.clientresource = resource - elif len(saslauth[0].split("\x00")) > 2: - resource = saslauth[0].split("\x00")[2] - self.clientresource = resource - - if len(saslauth) > 2: - authcode = saslauth[2] - - if self.devclass: # if there is a devclass it is a bot - bumper.bot_add(self.uid, self.uid, self.devclass, "atom", "eco-legacy") - self.type = self.BOT - xmppserverlog.info("bot authenticated SN: {}".format(self.uid)) - # Send response - self.send( - '' - ) # Success - - # Client authenticated, move to next state - self._set_state("INIT") - - else: - auth = False - if bumper.check_authcode(self.uid, authcode): - auth = True - elif bumper.use_auth == False: - auth = True - - if auth: - self.type = self.CONTROLLER - bumper.client_add(self.uid, "bumper", self.clientresource) - xmppserverlog.info("client authenticated {}".format(self.uid)) - - # Client authenticated, move to next state - self._set_state("INIT") - - # Send response - self.send( - '' - ) # Success - - else: - # Failed to authenticate - self.send( - '' - ) # Fail - - except Exception as e: - xmppserverlog.exception("{}".format(e)) - - def _handle_bind(self, xml): - try: - - bot = bumper.bot_get(self.uid) - if bot: - bumper.bot_set_xmpp(bot["did"], True) - - client = bumper.client_get(self.clientresource) - if client: - bumper.client_set_xmpp(client["resource"], True) - - clientbindxml = xml.getchildren() - clientresourcexml = clientbindxml[0].getchildren() - if self.devclass: # its a bot - self.name = "XMPP_Client_{}_{}".format(self.uid, self.devclass) - self.bumper_jid = "{}@{}.ecorobot.net/atom".format( - self.uid, self.devclass - ) - xmppserverlog.debug( - "new bot ({}:{} | {})".format( - self.address[0], self.address[1], self.bumper_jid - ) - ) - res = '{}'.format( - xml.get("id"), self.bumper_jid - ) - elif len(clientresourcexml) > 0: - self.clientresource = clientresourcexml[0].text - self.name = "XMPP_Client_{}".format(self.clientresource) - self.bumper_jid = "{}@{}/{}".format( - self.uid, XMPPServer.server_id, self.clientresource - ) - xmppserverlog.debug( - "new client ({}:{} | {})".format( - self.address[0], self.address[1], self.bumper_jid - ) - ) - res = '{}'.format( - xml.get("id"), self.bumper_jid - ) - else: - self.name = "XMPP_Client_{}_{}".format(self.uid, self.address) - self.bumper_jid = "{}@{}".format(self.uid, XMPPServer.server_id) - xmppserverlog.debug( - "new client ({}:{} | {})".format( - self.address[0], self.address[1], self.bumper_jid - ) - ) - res = '{}'.format( - xml.get("id"), self.bumper_jid - ) - - self._set_state("BIND") - self.send(res) - - except Exception as e: - xmppserverlog.exception("{}".format(e)) - - def _handle_session(self, xml): - res = ''.format(xml.get("id")) - self._set_state("READY") - self.send(res) - asyncio.Task(self.schedule_ping(30)) - - def _handle_presence(self, xml): - - if len(xml) and xml[0].tag == "status": - xmppserverlog.debug( - "bot presence {} ".format( - ET.tostring(xml, encoding="utf-8").decode("utf-8") - ) - ) - # Most likely a bot, possibly hello world in text - - # Send dummy return - self.send(' dummy '.format(self.bumper_jid)) - - # If it is a BOT, send extras - if self.type == self.BOT: - # get device info - self.send( - ''.format( - self.bumper_jid, XMPPServer.server_id - ) - ) - - else: - xmppserverlog.debug( - "client presence - {} ".format( - ET.tostring(xml, encoding="utf-8").decode("utf-8") - ) - ) - - if xml.get("type") == "available": - xmppserverlog.debug( - "client presence available - {} ".format( - ET.tostring(xml, encoding="utf-8").decode("utf-8") - ) - ) - - # Send dummy return - self.send( - ' dummy '.format(self.bumper_jid) - ) - elif xml.get("type") == "unavailable": - xmppserverlog.debug( - "client presence unavailable (DISCONNECT) - {} ".format( - ET.tostring(xml, encoding="utf-8").decode("utf-8") - ) - ) - - self._set_state("DISCONNECT") - else: - # Sometimes the android app sends these - xmppserverlog.debug( - "client presence (UNKNOWN) - {} ".format( - ET.tostring(xml, encoding="utf-8") - ) - ) - # Send dummy return - self.send( - ' dummy '.format(self.bumper_jid) - ) - - def _parse_data(self, data): - - if data.decode("utf-8").startswith( - "]+\?>)", r"", data.decode("utf-8")) + "" - ) - - else: - newdata = "{}".format( - data.decode("utf-8") - ) # Add artificial root - - try: - root = ET.fromstring(newdata) - for item in root.iter(): - if item.tag != "root": - if item.tag == "iq": - if self.log_incoming_data: - xmppserverlog.debug( - "from ({}:{} | {}) - {}".format( - self.address[0], - self.address[1], - self.bumper_jid, - str( - ET.tostring(item, encoding="utf-8").decode( - "utf-8" - ) - ).replace("ns0:", ""), - ) - ) - if ( - 'td="error"' in newdata - or "errs=" in newdata - or 'k="DeviceAlert' in newdata - ): - boterrorlog.error( - "Received Error from ({}:{} | {}) - {}".format( - self.address[0], - self.address[1], - self.bumper_jid, - newdata, - ) - ) - self._handle_iq(item, newdata) - item.clear() - - elif "auth" in item.tag: - if "urn:ietf:params:xml:ns:xmpp-sasl" in item.tag: # SASL Auth - self._handle_sasl_auth(item) - item.clear() - - elif "-tls" in item.tag: - if not self.TLSUpgraded: - asyncio.Task(self._handle_starttls(newdata.encode("utf-8"))) - - elif "presence" in item.tag: - self._handle_presence(item) - item.clear() - - else: - if self.log_incoming_data: - xmppserverlog.debug( - "Unparsed Item - {}".format( - str( - ET.tostring(item, encoding="utf-8").decode( - "utf-8" - ) - ).replace("ns0:", "") - ) - ) - - except ET.ParseError as e: - if ( - "no element found" in e.msg - ): # Element not closed or not all bytes received - # Happens wth connect stream often - if " - client is signalling end of session/disconnect - if not "" in newdata: - xmppserverlog.error("xml parse error - {} - {}".format(newdata, e)) - else: - self.send("") # Close stream - - else: - if "" in newdata: - xmppserverlog.error( - "xml parse error - {} - {}".format(newdata, e) - ) - else: - self.send("") # Close stream - self._set_state("DISCONNECT") - - except Exception as e: - xmppserverlog.exception("{}".format(e)) - - def _handle_iq(self, xml, data): - - if len(xml): - child = self._tag_strip_uri(xml[0].tag) - else: - child = None - - if xml.tag == "iq": - if child == "bind": - self._handle_bind(xml) - elif child == "session": - self._handle_session(xml) - elif child == "ping": - self._handle_ping(xml, data) - elif child == "query": - if self.type == self.BOT: - self._handle_result(xml, data) - else: - self._handle_ctl(xml, data) - elif xml.get("type") == "result": - if self.type == self.BOT: - self._handle_result(xml, data) - else: - self._handle_result(xml, data) - elif xml.get("type") == "set": - if self.type == self.BOT: - self._handle_result(xml, data) - else: - self._handle_result(xml, data) diff --git a/tests/test_confserver.py b/tests/test_confserver.py index 2149673..6b5d04d 100644 --- a/tests/test_confserver.py +++ b/tests/test_confserver.py @@ -93,12 +93,6 @@ async def test_base(aiohttp_client): mqtt_server = bumper.MQTTServer(mqtt_address, password_file="tests/passwd") bumper.mqtt_server = mqtt_server await mqtt_server.broker_coro() - - # Start XMPP - xmpp_address = ("127.0.0.1", 5223) - xmpp_server = bumper.XMPPServer(xmpp_address) - bumper.xmpp_server = xmpp_server - await xmpp_server.start_async_server() # Start Helperbot mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address) @@ -113,8 +107,6 @@ async def test_base(aiohttp_client): await mqtt_server.broker.shutdown() - bumper.xmpp_server.disconnect() - async def test_restartService(aiohttp_client): remove_existing_db() @@ -125,12 +117,6 @@ async def test_restartService(aiohttp_client): mqtt_server = bumper.MQTTServer(mqtt_address, password_file="tests/passwd") bumper.mqtt_server = mqtt_server await mqtt_server.broker_coro() - - # Start XMPP - xmpp_address = ("127.0.0.1", 5223) - xmpp_server = bumper.XMPPServer(xmpp_address) - bumper.xmpp_server = xmpp_server - await xmpp_server.start_async_server() # Start Helperbot mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address) @@ -143,16 +129,11 @@ async def test_restartService(aiohttp_client): assert resp.status == 200 resp = await client.get("/restart_MQTTServer") - assert resp.status == 200 - - resp = await client.get("/restart_XMPPServer") - assert resp.status == 200 + assert resp.status == 200 mqtt_helperbot.Client.disconnect() await mqtt_server.broker.shutdown() - xmpp_server.disconnect() - async def test_RemoveBot(aiohttp_client): client = await aiohttp_client(create_app) resp = await client.get("/bot/remove/test_did") diff --git a/tests/test_db.py b/tests/test_db.py index a23b368..7dc838d 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -117,11 +117,6 @@ def test_bot_db(): "mqtt_connection" ] # Test that mqtt was set True for bot - bumper.bot_set_xmpp("did_123", True) - assert bumper.bot_get("did_123")[ - "xmpp_connection" - ] # Test that xmpp was set True for bot - bumper.bot_remove("did_123") assert bumper.bot_get("did_123") == None # Test that bot is no longer in db @@ -136,13 +131,5 @@ def test_client_db(): "mqtt_connection" ] # Test that mqtt was set True for client - bumper.client_set_xmpp("resource_123", False) - assert ( - bumper.client_get("resource_123")["xmpp_connection"] == False - ) # Test that xmpp was set False for client - assert ( - len(bumper.get_disconnected_xmpp_clients()) > 0 - ) # Test len of connected xmpp clients is 1 - bumper.client_remove("resource_123") assert bumper.client_get("resource_123") == None diff --git a/tests/test_xmppserver.py b/tests/test_xmppserver.py deleted file mode 100644 index ef48025..0000000 --- a/tests/test_xmppserver.py +++ /dev/null @@ -1,645 +0,0 @@ -import mock -import bumper -import asyncio -import pytest -import os -import json -import tinydb -import pytest_asyncio -import xml.etree.ElementTree as ET -import socket -from testfixtures import LogCapture -import ssl - - -def return_send_data(data, *args, **kwargs): - return data - - -def mock_transport_extra_info(*args, **kwargs): - return ("127.0.0.1", 5223) - - -async def test_xmpp_server(): - xmpp_address = ("127.0.0.1", 5223) - xmpp_server = bumper.XMPPServer(xmpp_address) - await xmpp_server.start_async_server() - - with LogCapture("xmppserver") as l: - - reader, writer = await asyncio.open_connection("127.0.0.1", 5223) - - writer.write(b"") # Start stream - await writer.drain() - - await asyncio.sleep(0.1) - - assert len(xmpp_server.clients) == 1 # Client count increased - assert ( - xmpp_server.clients[0].address[1] - == writer.transport.get_extra_info("sockname")[1] - ) - - writer.close() # Close connection - await writer.wait_closed() - - await asyncio.sleep(0.1) - - assert len(xmpp_server.clients) == 0 # Client count decreased - - reader, writer = await asyncio.open_connection("127.0.0.1", 5223) - - writer.write(b"") # Start stream - await writer.drain() - - await asyncio.sleep(0.1) - - xmpp_server.disconnect() - - -async def test_client_connect_no_starttls(*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 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 available features - assert ( - mock_send.mock_calls[1].args[0] - == 'PLAIN' - ) - - # Reset mock calls - mock_send.reset_mock() - - # Client sendss auth - Ignoring the starttls, we don't force this with bumper - test_data = 'AGZ1aWRfdG1wdXNlcgAwL0lPU0Y1M0QwN0JBL3VzXzg5ODgwMmZkYmM0NDQxYjBiYzgxNWIxZDFjNjgzMDJl'.encode( - "utf-8" - ) - xmppclient._parse_data(test_data) - - assert ( - mock_send.mock_calls[0].args[0] - == '' - ) # Client successfully authenticated - 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()) - 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 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 available features - assert ( - mock_send.mock_calls[1].args[0] - == 'PLAIN' - ) - - # Reset mock calls - mock_send.reset_mock() - - mock_tls = xmppclient._handle_starttls = mock.Mock() - - # Send start tls from "client" - test_data = "".encode("utf-8") - xmppclient._parse_data(test_data) - - # After upgrading connection, server tells client to proceed with auth again - assert mock_tls.called - xmppclient.TLSUpgraded = True - - # After TLS is upgraded, Client establishes session again and will auth this time - # 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 available features (without STARTTLS) - assert ( - mock_send.mock_calls[1].args[0] - == 'PLAIN' - ) - # Reset mock calls - mock_send.reset_mock() - - # Client sends auth - test_data = 'AGZ1aWRfdG1wdXNlcgAwL0lPU0Y1M0QwN0JBL3VzXzg5ODgwMmZkYmM0NDQxYjBiYzgxNWIxZDFjNjgzMDJl'.encode( - "utf-8" - ) - xmppclient._parse_data(test_data) - - assert ( - mock_send.mock_calls[0].args[0] - == '' - ) # Client successfully authenticated - assert xmppclient.state == xmppclient.INIT # Client moved to INIT state - - -async def test_xmpp_server_client_tls(): - - xmpp_address = ("127.0.0.1", 5223) - xmpp_server = bumper.XMPPServer(xmpp_address) - await xmpp_server.start_async_server() - - with LogCapture("xmppserver") as l: - - async def do_stuff_after_start_tls( - ssl_reader, ssl_writer - ): # Used after starttls - - writer.write( - b"" - ) # New Stream - - await writer.drain() - - writer.write( - b'AGZ1aWRfdG1wdXNlcgAwL0lPU0Y1M0QwN0JBL3VzXzg5ODgwMmZkYmM0NDQxYjBiYzgxNWIxZDFjNjgzMDJl' - ) # Send Auth - - await writer.drain() - - reader, writer = await asyncio.open_connection("127.0.0.1", 5223) - - writer.write( - b"" - ) # Start stream - await writer.drain() - - await asyncio.sleep(0.1) - - writer.write( - b"" - ) # Send StartTLS - await writer.drain() - - await asyncio.sleep(0.1) - - # Below will upgrade connection to TLS then callback to "do_stuff_after_start_tls" - ssl_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) - ssl_context.check_hostname = False - ssl_context.load_verify_locations(cafile=bumper.ca_cert) - loop = asyncio.get_event_loop() - transport = writer.transport - protocol = writer.transport.get_protocol() - new_transport = await loop.start_tls( - transport, protocol, ssl_context, server_side=False - ) - protocol._stream_reader = asyncio.StreamReader(loop=loop) - protocol._client_connected_cb = do_stuff_after_start_tls - protocol.connection_made(new_transport) - - print(l) - - -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()) - 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 connect stream from "bot" - 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 available features - assert ( - mock_send.mock_calls[1].args[0] - == 'PLAIN' - ) - - # Reset mock calls - mock_send.reset_mock() - - # Send auth from "bot" - test_data = "AEUwMDAwMDAwMDAwMDAwMDAxMjM0AGVuY3J5cHRlZF9wYXNz".encode( - "utf-8" - ) - xmppclient._parse_data(test_data) - - assert ( - mock_send.mock_calls[0].args[0] - == '' - ) # Bot successfully authenticated - assert xmppclient.state == xmppclient.INIT # Bot moved to INIT state - assert xmppclient.type == xmppclient.BOT # Client type is now bot - - -async def test_bot_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 = "E0000000000000001234" - xmppclient.devclass = "159" - xmppclient.type = xmppclient.BOT - mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) - - # Send connect stream from "bot" - 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 "bot" - test_data = "atom".encode( - "utf-8" - ) - xmppclient._parse_data(test_data) - - assert ( - mock_send.mock_calls[0].args[0] - == 'E0000000000000001234@159.ecorobot.net/atom' - ) # Bot successfully binded - assert xmppclient.state == xmppclient.BIND # Bot moved to BIND state - - # Reset mock calls - mock_send.reset_mock() - - # Send set session from bot - test_data = "".encode( - "utf-8" - ) - xmppclient._parse_data(test_data) - - assert xmppclient.state == xmppclient.READY # Bot moved to READY state - assert ( - mock_send.mock_calls[0].args[0] == '' - ) # Bot ready - - # Reset mock calls - mock_send.reset_mock() - - # Send presense from bot - test_data = "hello world".encode( - "utf-8" - ) - xmppclient._parse_data(test_data) - - assert ( - mock_send.mock_calls[0].args[0] - == ' dummy ' - ) # bot presence - dummy response - - -async def test_ping_server(*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.READY # Set client state to READY - xmppclient.uid = "E0000000000000001234" - xmppclient.devclass = "159" - mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) - - # Ping from bot - test_data = ''.encode( - "utf-8" - ) - xmppclient._parse_data(test_data) - - assert ( - mock_send.mock_calls[0].args[0] - == '' - ) # ping response - - -async def test_ping_client_to_client(*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.READY # Set client state to READY - xmppclient.uid = "E0000000000000001234" - xmppclient.devclass = "159" - xmppclient.bumper_jid = "E0000000000000001234@159.ecorobot.net/atom" - mock_send = xmppclient.send = mock.Mock(side_effect=return_send_data) - - xmppclient2 = bumper.xmppserver.XMPPAsyncClient(test_transport) - xmppclient2.state = xmppclient.READY # Set client state to READY - xmppclient2.uid = "fuid_tmpuser" - xmppclient2.resource = "IOSF53D07BA" - xmppclient2.bumper_jid = "fuid_tmpuser@ecouser.net/IOSF53D07BA" - mock_send2 = xmppclient2.send = mock.Mock(side_effect=return_send_data) - - bumper.xmppserver.XMPPServer.clients.append(xmppclient) - bumper.xmppserver.XMPPServer.clients.append(xmppclient2) - - # Ping from user to bot - test_data = ''.encode( - "utf-8" - ) - 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() - 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.READY # Set client state to READY - 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) - bumper.xmppserver.XMPPServer.clients.append(xmppclient) - - xmppclient2 = bumper.xmppserver.XMPPAsyncClient(test_transport) - xmppclient2.state = xmppclient.READY # Set client state to READY - xmppclient2.uid = "E0000000000000001234" - xmppclient2.devclass = "159" - xmppclient2.bumper_jid = "E0000000000000001234@159.ecorobot.net/atom" - xmppclient2.type = xmppclient2.BOT - mock_send2 = xmppclient2.send = mock.Mock(side_effect=return_send_data) - - bumper.xmppserver.XMPPServer.clients.append(xmppclient2) - - # Roster IQ - Only seen from Android app so far - test_data = ''.encode( - "utf-8" - ) - xmppclient._parse_data(test_data) - - assert ( - mock_send.mock_calls[0].args[0] - == '' - ) # feature not implemented response - - # Reset mock calls - mock_send.reset_mock() - - # Bot Command - test_data = ''.encode( - "utf-8" - ) - xmppclient._parse_data(test_data) - - assert ( - mock_send2.mock_calls[0].args[0] - == '' - ) # command was sent to bot - - # Reset mock calls - mock_send.reset_mock() - - # Bot response to query - test_data = ''.encode( - "utf-8" - ) - xmppclient2._parse_data(test_data) - - assert ( - mock_send.mock_calls[0].args[0] - == '' - ) # result sent to client - - # 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() - - # Bot error report - 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 "DorpError" to all - 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() -
User IDRealmResourceMQTT ConnectedXMPP ConnectedActionUser IDRealmResourceMQTT ConnectedAction
{{ client.realm }} {{ client.resource }} {{ client.mqtt_connection }} {{ client.xmpp_connection }}