diff --git a/Pipfile b/Pipfile index 012b6da..89d3377 100644 --- a/Pipfile +++ b/Pipfile @@ -6,6 +6,6 @@ name = "pypi" [packages] hbmqtt = "*" aiohttp = "*" -black = "*" +tinydb = "*" [dev-packages] diff --git a/bumper.py b/bumper.py index c47426e..bf0fbae 100644 --- a/bumper.py +++ b/bumper.py @@ -54,17 +54,11 @@ def main(): conf_server = bumper.ConfServer( conf_address_443, usessl=True, - bumper_users=bumper.bumper_users_var, - bumper_bots=bumper.bumper_bots_var, - bumper_clients=bumper.bumper_clients_var, helperbot=mqtt_helperbot, ) conf_server_2 = bumper.ConfServer( conf_address_8007, usessl=False, - bumper_users=bumper.bumper_users_var, - bumper_bots=bumper.bumper_bots_var, - bumper_clients=bumper.bumper_clients_var, helperbot=mqtt_helperbot, ) @@ -95,17 +89,11 @@ def main(): while True: try: - time.sleep(0.25) - - # WIP: Remove clients that have disconnected - # remove_clients = bumper.bumper_removeclients_var.get() - # if len(remove_clients) > 0: - # for uid in remove_clients: - # if uid != "": - # xmpp_server.remove_client_byuid(uid) #Remove clients from xmpp server - # remove_clients.remove(uid) - - # bumper.bumper_removeclients_var.set(remove_clients) + time.sleep(30) + bumper.revoke_expired_tokens() + disconnected_clients = bumper.get_disconnected_xmpp_clients() + for client in disconnected_clients: + xmpp_server.remove_client_byuid(client['userid']) except KeyboardInterrupt: bumper.bumperlog.info("Bumper Exiting - Keyboard Interrupt") diff --git a/bumper/__init__.py b/bumper/__init__.py index 3ae2598..a803240 100644 --- a/bumper/__init__.py +++ b/bumper/__init__.py @@ -7,8 +7,12 @@ from .xmppserver import XMPPServer import asyncio import contextvars import time +from datetime import datetime, timedelta +import platform +import os import logging from base64 import b64decode, b64encode +from tinydb import TinyDB, Query bumper_users_var = contextvars.ContextVar("bumper_users", default=[]) bumper_clients_var = contextvars.ContextVar("bumper_clients", default=[]) @@ -19,6 +23,7 @@ server_cert = "./certs/cert.pem" server_key = "./certs/key.pem" use_auth = False +token_validity_seconds = 3600 #1 hour # Logs bumperlog = logging.getLogger("bumper") @@ -39,47 +44,145 @@ xmppserverlog = logging.getLogger("xmppserver") def get_milli_time(timetoconvert): return int(round(timetoconvert * 1000)) +def db_file(): + if platform.system() == 'Windows': + return os.path.join(os.getenv('APPDATA'), 'bumper.db') + else: + return os.path.expanduser('~/.config/bumper.db') + +def db_get(): + #Will create the database if it doesn't exist + db = TinyDB(db_file()) + + #Will create the tables if they don't exist + users_table = db.table('users') + clients_table = db.table('clients') + bots_table = db.table('bots') + + return db class BumperUser(object): def __init__(self, userid=""): self.userid = userid self.devices = [] - self.tokens = [] - self.authcodes = [] self.bots = [] - def add_device(self, devid): - if not devid in self.devices: - self.devices.append(devid) + def asdict(self): + return { + "userid": self.userid, + "devices": self.devices, + "bots": self.bots, + } - def remove_device(self, devid): - if devid in self.devices: - self.devices.remove(devid) +def user_add(userid): + newuser = BumperUser() + newuser.userid = userid + + user = user_get(userid) + if not user: + bumperlog.info("Adding new user with userid: {}".format(newuser.userid)) + user_full_upsert(newuser.asdict()) - def add_token(self, token): - if not token in self.tokens: - self.tokens.append(token) +def user_get(userid): + users = db_get().table('users') + User = Query() + return users.get(User.userid == userid) + +def user_by_deviceid(deviceid): + users = db_get().table('users') + User = Query() + return users.get(User.devices.any([deviceid])) - def revoke_token(self, token): - if token in self.tokens: - self.tokens.remove(token) +def user_full_upsert(user): + users = db_get().table('users') + User = Query() + users.upsert(user, User.did == user['userid']) - def add_authcode(self, authcode): - if not authcode in self.authcodes: - self.authcodes.append(authcode) +def user_add_device(userid, devid): + users = db_get().table('users') + User = Query() + user = users.get(User.userid == userid) + userdevices = list(user['devices']) + if not devid in userdevices: + userdevices.append(devid) + + users.upsert({'devices': userdevices}, User.userid == userid) - def revoke_authcode(self, authcode): - if authcode in self.authcodes: - self.authcodes.remove(authcode) +def user_remove_device(userid, devid): + users = db_get().table('users') + User = Query() + user = users.get(User.userid == userid) + userdevices = list(user['devices']) + if devid in userdevices: + userdevices.remove(devid) + + users.upsert({'devices': userdevices}, User.userid == userid) - def add_bot(self, botdid): - if not botdid in self.bots: - self.bots.append(botdid) +def user_add_bot(userid, did): + users = db_get().table('users') + User = Query() + user = users.get(User.userid == userid) + userbots = list(user['bots']) + if not did in userbots: + userbots.append(did) + + users.upsert({'bots': userbots}, User.userid == userid) - def remove_bot(self, botdid): - if botdid in self.bots: - self.bots.remove(botdid) +def user_remove_bot(userid, did): + users = db_get().table('users') + User = Query() + user = users.get(User.userid == userid) + userbots = list(user['bots']) + if did in userbots: + userbots.remove(did) + + users.upsert({'bots': userbots}, User.userid == userid) + +def user_get_tokens(userid): + tokens = db_get().table('tokens') + return tokens.search((Query().userid == userid)) +def user_get_token(userid, token): + tokens = db_get().table('tokens') + return tokens.get((Query().userid == userid) & (Query().token == token)) + +def user_add_token(userid, token): + tokens = db_get().table('tokens') + tmptoken = tokens.get((Query().userid == userid) & (Query().token == token)) + if not tmptoken: + tokens.insert({'userid':userid, 'token':token, 'expiration':"{}".format(datetime.now() + timedelta(seconds=token_validity_seconds))}) + +def user_revoke_all_tokens(userid): + tokens = db_get().table('tokens') + tsearch = tokens.search(Query().userid == userid) + for i in tsearch: + tokens.remove(doc_ids=[i.doc_id]) + +def user_revoke_expired_tokens(userid): + tokens = db_get().table('tokens') + tsearch = tokens.search(Query().userid == userid) + for i in tsearch: + if datetime.now() >= datetime.fromisoformat(i['expiration']): + bumperlog.debug("Removing token {} due to expiration".format(i['token'])) + tokens.remove(doc_ids=[i.doc_id]) + +def user_revoke_token(userid, token): + tokens = db_get().table('tokens') + tmptoken = tokens.get((Query().userid == userid) & (Query().token == token)) + if tmptoken: + tokens.remove(doc_ids=[tmptoken.doc_id]) + +def user_add_authcode(userid, token, authcode): + tokens = db_get().table('tokens') + tmptoken = tokens.get((Query().userid == userid) & (Query().token == token)) + if tmptoken: + tokens.upsert({'authcode': authcode}, ((Query().userid == userid) & (Query().token == token))) + +def user_revoke_authcode(userid, token, authcode): + tokens = db_get().table('tokens') + tmptoken = tokens.get((Query().userid == userid) & (Query().token == token)) + if tmptoken: + tokens.upsert({'authcode': ''}, ((Query().userid == userid) & (Query().token == token))) class VacBotDevice(object): def __init__( @@ -108,6 +211,8 @@ class VacBotDevice(object): "name": self.name, "nick": self.nick, "resource": self.resource, + "mqtt_connection": self.mqtt_connection, + "xmpp_connection": self.xmpp_connection } @@ -120,58 +225,125 @@ class VacBotClient(object): self.xmpp_connection = False def asdict(self): - return {"userid": self.userid, "realm": self.realm, "resource": self.resource} + return { + "userid": self.userid, + "realm": self.realm, + "resource": self.resource, + "mqtt_connection": self.mqtt_connection, + "xmpp_connection": self.xmpp_connection + } +def get_disconnected_xmpp_clients(): + clients = db_get().table('clients') + Client = Query() + return clients.search(Client.xmpp_connection == False) + def check_authcode(uid, authcode): - users = bumper_users_var.get() - for user in users: - if uid == "fuid_{}".format(user.userid) and authcode in user.authcodes: - return True + bumperlog.debug("Checking for authcode: {}".format(authcode)) + tokens = db_get().table('tokens') + tmpauth = tokens.get( + (Query().authcode == authcode) & #Match authcode + ((Query().userid == uid.replace("fuid_","")) | (Query().userid == "fuid_{}".format(uid))) #Userid with or without fuid_ + ) + if tmpauth: + return True + + return False - return False +def check_token(uid, token): + bumperlog.debug("Checking for token: {}".format(token)) + tokens = db_get().table('tokens') + tmpauth = tokens.get( + (Query().token == token) & #Match token + ((Query().userid == uid.replace("fuid_","")) | (Query().userid == "fuid_{}".format(uid))) #Userid with or without fuid_ + ) + if tmpauth: + return True + + return False + +def revoke_expired_tokens(): + tokens = db_get().table('tokens').all() + for i in tokens: + if datetime.now() >= datetime.fromisoformat(i['expiration']): + bumperlog.debug("Removing token {} due to expiration".format(i['token'])) + db_get().table('tokens').remove(doc_ids=[i.doc_id]) -def add_bot(sn, did, devclass, resource, company): - +def bot_add(sn, did, devclass, resource, company): newbot = VacBotDevice() newbot.did = did newbot.name = sn newbot.vac_bot_device_class = devclass newbot.resource = resource newbot.company = company + + bot = bot_get(did) + if not bot: + bumperlog.info("Adding new bot with SN: {} DID: {}".format(newbot.name, newbot.did)) + bot_full_upsert(newbot.asdict()) - bots = bumper_bots_var.get() - existingbot = False - for bot in bots: - if bot.did == newbot.did: - existingbot = True +def bot_remove(did): + bots = db_get().table('bots') + bot = bot_get(did) + bots.remove(doc_ids=[bot.doc_id]) + +def bot_get(did): + bots = db_get().table('bots') + Bot = Query() + return bots.get(Bot.did == did) - if existingbot == False: - bots.append(newbot) - bumperlog.info("new bot added SN: {} DID: {}".format(newbot.name, newbot.did)) - bumper_bots_var.set(bots) +def bot_full_upsert(vacbot): + bots = db_get().table('bots') + Bot = Query() + bots.upsert(vacbot, Bot.did == vacbot['did']) +def bot_set_nick(did, nick): + bots = db_get().table('bots') + Bot = Query() + bots.upsert({'nick': nick}, Bot.did == did) -def add_client(userid, realm, resource): +def bot_set_mqtt(did, mqtt): + bots = db_get().table('bots') + Bot = Query() + 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 newclient.realm = realm newclient.resource = resource - clients = bumper_clients_var.get() + client = client_get(resource) + if not client: + bumperlog.info("Adding new client with resource {}".format(newclient.resource)) + client_full_upsert(newclient.asdict()) - existingclient = False - for client in clients: - if client.userid == newclient.userid: - existingclient = True +def client_get(resource): + clients = db_get().table('clients') + Client = Query() + return clients.get(Client.resource == resource) - if existingclient == False: - clients.append(newclient) - bumperlog.info("new client added {}".format(newclient.userid)) - bumper_clients_var.set(clients) +def client_full_upsert(client): + clients = db_get().table('clients') + Client = Query() + clients.upsert(client, Client.resource == client['resource']) +def client_set_mqtt(resource, mqtt): + clients = db_get().table('clients') + 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) RETURN_API_SUCCESS = "0000" ERR_ACTIVATE_TOKEN_TIMEOUT = "1006" diff --git a/bumper/confserver.py b/bumper/confserver.py index 6cb58e4..bc327fa 100644 --- a/bumper/confserver.py +++ b/bumper/confserver.py @@ -37,21 +37,13 @@ logging.getLogger("aiohttp.access").addFilter(aiohttp_filter()) class ConfServer: - bumper_clients = contextvars.ContextVar - bumper_bots = contextvars.ContextVar def __init__( self, address, usessl=False, - bumper_users=contextvars.ContextVar, - bumper_bots=contextvars.ContextVar, - bumper_clients=contextvars.ContextVar, helperbot=None, ): - self.bumper_users = bumper_users - self.bumper_bots = bumper_bots - self.bumper_clients = bumper_clients self.helperbot = helperbot self.usessl = usessl self.address = address @@ -174,7 +166,7 @@ class ConfServer: async def handle_base(self, request): try: - + #TODO - API Options here for viewing clients, tokens, restarting the server, etc. text = "Bumper!" return web.json_response(text) @@ -193,60 +185,26 @@ class ConfServer: if ( not user_devid == "" ): # Performing basic "auth" using devid, super insecure - users = self.bumper_users.get() - for user in users: - if user_devid in user.devices: - tmpaccesstoken = "" - if "checkLogin" in request.path: - if request.query[ - "accessToken" - ] in user.tokens and request.query[ - "uid" - ] == "fuid_{}".format( - user.userid - ): - tmpaccesstoken = request.query["accessToken"] - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "accessToken": tmpaccesstoken, # Random chars 32 length - "country": countrycode, - "email": "null@null.com", - "uid": "fuid_{}".format(user.userid), - "username": "fusername_{}".format( - user.userid - ), - }, - "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), - } - else: - body = { - "code": bumper.ERR_TOKEN_INVALID, - "data": None, - "msg": "当前密码错误", - "time": bumper.get_milli_time(time.time()), - } - else: - if tmpaccesstoken == "": - tmpaccesstoken = uuid.uuid4().hex - user.add_token(tmpaccesstoken) - - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "accessToken": tmpaccesstoken, # Random chars 32 length - "country": countrycode, - "email": "null@null.com", - "uid": "fuid_{}".format(user.userid), - "username": "fusername_{}".format(user.userid), - }, - "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), - } - self.bumper_users.set(users) - - return web.json_response(body) + user = bumper.user_by_deviceid(user_devid) + if "checkLogin" in request.path: + self.check_token(countrycode, user, request.query["accessToken"]) + else: + #Deactivate old tokens and authcodes + bumper.user_revoke_expired_tokens(user['userid']) + + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "accessToken": self.generate_token(user), # generate a new token + "country": countrycode, + "email": "null@null.com", + "uid": "fuid_{}".format(user['userid']), + "username": "fusername_{}".format(user['userid']), + }, + "msg": "操作成功", + "time": bumper.get_milli_time(time.time()), + } + return web.json_response(body) body = { "code": bumper.ERR_USER_NOT_ACTIVATED, @@ -256,6 +214,7 @@ class ConfServer: } return web.json_response(body) + else: return web.json_response( self._auth_any(user_devid, countrycode, request) @@ -264,59 +223,86 @@ class ConfServer: except Exception as e: confserverlog.exception("{}".format(e)) + + def check_token(self, countrycode, user, token): + if ( + bumper.check_token(user['userid'], token) + ): + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "accessToken": token, + "country": countrycode, + "email": "null@null.com", + "uid": "fuid_{}".format(user['userid']), + "username": "fusername_{}".format( + user['userid'] + ), + }, + "msg": "操作成功", + "time": bumper.get_milli_time(time.time()), + } + return web.json_response(body) + + else: + body = { + "code": bumper.ERR_TOKEN_INVALID, + "data": None, + "msg": "当前密码错误", + "time": bumper.get_milli_time(time.time()), + } + return web.json_response(body) + + def generate_token(self, user): + tmpaccesstoken = uuid.uuid4().hex + bumper.user_add_token(user['userid'],tmpaccesstoken) + return tmpaccesstoken + + def generate_authcode(self, user, countrycode, token): + tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex) + bumper.user_add_authcode(user['userid'], token, tmpauthcode) + return tmpauthcode + + def _auth_any(self, devid, country, request): try: user_devid = devid countrycode = country - - tmpaccesstoken = "" - users = self.bumper_users.get() - bots = self.bumper_bots.get() - - if len(users) > 0: - tmpuser = users[0] - tmpuser.add_device(user_devid) + user = bumper.user_by_deviceid(user_devid) + bots = bumper.db_get().table('bots').all() + + if user: #Default to user 0 + tmpuser = user + bumper.user_add_device(tmpuser['userid'], user_devid) else: - tmpuser = bumper.BumperUser("tmpuser") - users.append(tmpuser) - tmpuser.add_device(user_devid) + bumper.user_add("tmpuser") #Add a new user + tmpuser = bumper.user_get("tmpuser") + bumper.user_add_device(tmpuser['userid'], user_devid) - for bot in bots: - tmpuser.add_bot(bot.did) + for bot in bots: #Add all bots to the user + bumper.user_add_bot(tmpuser['userid'], bot['did']) + + if "checkLogin" in request.path: #If request was to check a token do so + checkToken = self.check_token(countrycode, user, request.query["accessToken"]) + isGood = json.loads(checkToken.text) + if isGood['code'] == "0000": + return isGood + + #Deactivate old tokens and authcodes + bumper.user_revoke_expired_tokens(tmpuser['userid']) - if "checkLogin" in request.path: - tmpaccesstoken = request.query["accessToken"] - tmpuser.add_token(tmpaccesstoken) - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "accessToken": tmpaccesstoken, # Random chars 32 length - "country": countrycode, - "email": "null@null.com", - "uid": "fuid_{}".format(tmpuser.userid), - "username": "fusername_{}".format(tmpuser.userid), - }, - "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), - } - else: - if tmpaccesstoken == "": - tmpaccesstoken = uuid.uuid4().hex - tmpuser.add_token(tmpaccesstoken) - - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "accessToken": tmpaccesstoken, # Random chars 32 length - "country": countrycode, - "email": "null@null.com", - "uid": "fuid_{}".format(tmpuser.userid), - "username": "fusername_{}".format(tmpuser.userid), - }, - "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), - } - self.bumper_users.set(users) + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "accessToken": self.generate_token(tmpuser), # Generate a token + "country": countrycode, + "email": "null@null.com", + "uid": "fuid_{}".format(tmpuser['userid']), + "username": "fusername_{}".format(tmpuser['userid']), + }, + "msg": "操作成功", + "time": bumper.get_milli_time(time.time()), + } return body @@ -327,15 +313,13 @@ class ConfServer: try: user_devid = request.match_info.get("devid", "") if not user_devid == "": - users = self.bumper_users.get() - for user in users: - if user_devid in user.devices: - if ( - request.query["uid"] == "fuid_{}".format(user.userid) - and request.query["accessToken"] in user.tokens - ): - user.revoke_token(request.query["accessToken"]) - self.bumper_users.set(users) + user = bumper.user_by_deviceid(user_devid) + if user: + if ( + bumper.check_token(user['userid'], request.query["accessToken"]) + ): + #Deactivate old tokens and authcodes + bumper.user_revoke_token(user['userid'], request.query["accessToken"]) body = { "code": bumper.RETURN_API_SUCCESS, @@ -354,28 +338,26 @@ class ConfServer: user_devid = request.match_info.get("devid", "") if not user_devid == "": - users = self.bumper_users.get() - if len(users) > 0: - for user in users: - if ( - user_devid in user.devices - and request.query["accessToken"] in user.tokens - ): - countrycode = request.match_info.get("country", "us") - tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex) - user.add_authcode(tmpauthcode) - - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "authCode": tmpauthcode, - "ecovacsUid": request.query["uid"], - }, - "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), - } - self.bumper_users.set(users) - return web.json_response(body) + user = bumper.user_by_deviceid(user_devid) + if user: + token = bumper.user_get_token(user['userid'], request.query["accessToken"]) + if token: + authcode = "" + if not 'authcode' in token: + authcode = self.generate_authcode(user, request.match_info.get("country", "us"), request.query["accessToken"]) + else: + authcode = token['authcode'] + + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "authCode": authcode, + "ecovacsUid": request.query["uid"], + }, + "msg": "操作成功", + "time": bumper.get_milli_time(time.time()), + } + return web.json_response(body) body = { "code": bumper.ERR_TOKEN_INVALID, @@ -550,63 +532,44 @@ class ConfServer: } elif service == "EcoUpdate": body = {"result": "ok", "ip": "47.88.66.164", "port": 8005} + elif todo == "loginByItToken": - - users = self.bumper_users.get() - for user in users: - if ( - postbody["userId"] == "fuid_{}".format(user.userid) - and postbody["token"] in user.authcodes - ): - body = { - "resource": postbody["resource"], - "result": "ok", - "todo": "result", - "token": postbody["token"], - "userId": postbody["userId"], - } + if ( + bumper.check_authcode(postbody["userId"], postbody["token"]) + ): + body = { + "resource": postbody["resource"], + "result": "ok", + "todo": "result", + "token": postbody["token"], + "userId": postbody["userId"], + } elif todo == "GetDeviceList": - active_bots = self.bumper_bots.get() - bot_list = [] - for bot in active_bots: - bot_list.append(bot.asdict()) - body = {"devices": bot_list, "result": "ok", "todo": "result"} + body = {"devices": bumper.db_get().table('bots').all(), "result": "ok", "todo": "result"} elif todo == "SetDeviceNick": - bots = self.bumper_bots.get() - for bot in bots: - if postbody["did"] == bot.did: - bot.nick = postbody["nick"] - self.bumper_bots.set(bots) - body = {"result": "ok", "todo": "result"} + bumper.bot_set_nick(postbody["did"], postbody["nick"]) + body = {"result": "ok", "todo": "result"} elif todo == "AddOneDevice": - bots = self.bumper_bots.get() - for bot in bots: - if postbody["did"] == bot.did: - bot.nick = postbody["nick"] - self.bumper_bots.set(bots) - body = {"result": "ok", "todo": "result"} + bumper.bot_set_nick(postbody["did"], postbody["nick"]) + body = {"result": "ok", "todo": "result"} elif todo == "DeleteOneDevice": - bots = self.bumper_bots.get() - for bot in bots: - if postbody["did"] == bot.did: - #bots.remove(bot) - #self.bumper_bots.set(bots) - body = {"result": "ok", "todo": "result"} + bumper.bot_remove(postbody["did"]) + body = {"result": "ok", "todo": "result"} confserverlog.debug( "\r\n POST: {} \r\n Response: {}".format(postbody, body) ) - - + return web.json_response(body) except Exception as e: confserverlog.exception("{}".format(e)) + async def handle_lookup(self, request): try: @@ -651,26 +614,25 @@ class ConfServer: try: json_body = json.loads(await request.text()) randomid = "".join(random.sample(string.ascii_letters, 6)) - bots = self.bumper_bots.get() + if "toId" in json_body: #Its a command - for bot in bots: - if bot.company == 'eco-ng': - if bot.did == json_body["toId"] and bot.mqtt_connection == True: - retcmd = await self.helperbot.send_command(json_body, randomid) - body = retcmd - confserverlog.debug( - "\r\n POST: {} \r\n Response: {}".format(json_body, body) - ) - return web.json_response(body) - - #No response, send error back - confserverlog.error( - "No bots with DID: {} connected to MQTT".format( - json_body["toId"] + bot = bumper.bot_get(json_body["toId"]) + if bot['company'] == 'eco-ng' and bot['mqtt_connection'] == True: + retcmd = await self.helperbot.send_command(json_body, randomid) + body = retcmd + confserverlog.debug( + "\r\n POST: {} \r\n Response: {}".format(json_body, body) ) - ) - body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} - return web.json_response(body) + return web.json_response(body) + else: + #No response, send error back + confserverlog.error( + "No bots with DID: {} connected to MQTT".format( + json_body["toId"] + ) + ) + body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} + return web.json_response(body) else: if "td" in json_body: #Seen when doing initial wifi config if json_body["td"] == "PollSCResult": diff --git a/bumper/mqttserver.py b/bumper/mqttserver.py index 6dc3f10..7ee850c 100644 --- a/bumper/mqttserver.py +++ b/bumper/mqttserver.py @@ -332,7 +332,7 @@ class BumperMQTTServer_Plugin: or str(didsplit[0]).startswith("helper") ): tmpbotdetail = str(didsplit[1]).split("/") - bumper.add_bot( + bumper.bot_add( username, didsplit[0], tmpbotdetail[0], tmpbotdetail[1], "eco-ng" ) mqttserverlog.debug( @@ -358,7 +358,7 @@ class BumperMQTTServer_Plugin: auth = True if auth: - bumper.add_client(userid, realm, resource) + bumper.client_add(userid, realm, resource) mqttserverlog.debug( "client authenticated {}".format(userid) ) @@ -375,44 +375,36 @@ class BumperMQTTServer_Plugin: async def on_broker_client_connected(self, client_id): try: - bumper_users = self.bumper_config["bumper_users"].get() - bumper_bots = self.bumper_config["bumper_bots"].get() - bumper_clients = self.bumper_config["bumper_clients"].get() didsplit = str(client_id).split("@") - for bot in bumper_bots: - if didsplit[0] == bot.did: - bot.mqtt_connection = True - mqttserverlog.debug("bot connected {}".format(bot.did)) - self.bumper_config["bumper_bots"].set(bumper_bots) + bot = bumper.bot_get(didsplit[0]) + if bot: + bumper.bot_set_mqtt(bot['did'], True) + return - for client in bumper_clients: - if didsplit[0] == client.userid and client.userid != "helper1": - client.mqtt_connection = True - # mqttserverlog.info("client connected {}".format(client.userid)) - self.bumper_config["bumper_clients"].set(bumper_clients) + clientuserid = didsplit[0] + clientresource = didsplit[1].split("/")[1] + client = bumper.client_get(clientresource) + if client: + bumper.client_set_mqtt(client['resource'], True) + return except Exception as e: mqttserverlog.exception("{}".format(e)) async def on_broker_client_disconnected(self, client_id): try: - bumper_users = self.bumper_config["bumper_users"].get() - bumper_bots = self.bumper_config["bumper_bots"].get() - bumper_clients = self.bumper_config["bumper_clients"].get() didsplit = str(client_id).split("@") - for bot in bumper_bots: - if didsplit[0] == bot.did: - bot.mqtt_connection = False - mqttserverlog.debug("bot disconnected {}".format(bot.did)) - self.bumper_config["bumper_bots"].set(bumper_bots) + bot = bumper.bot_get(didsplit[0]) + if bot: + bumper.bot_set_mqtt(bot['did'], False) - for client in bumper_clients: - if didsplit[0] == client.userid and client.userid != "helper1": - client.mqtt_connection = False - # mqttserverlog.info("client disconnected {}".format(client.userid)) - self.bumper_config["bumper_clients"].set(bumper_clients) + clientuserid = didsplit[0] + clientresource = didsplit[1].split("/")[1] + client = bumper.client_get(clientresource) + if client: + bumper.client_set_mqtt(client['resource'], False) except Exception as e: mqttserverlog.exception("{}".format(e)) diff --git a/bumper/xmppserver.py b/bumper/xmppserver.py index 78cf78b..a9021ef 100644 --- a/bumper/xmppserver.py +++ b/bumper/xmppserver.py @@ -228,22 +228,15 @@ class Client(threading.Thread): def _disconnect(self): try: - bumper_bots = self.bumper_bots.get() - bumper_clients = self.bumper_clients.get() - for bot in bumper_bots: - if self.uid == bot.did: - bot.xmpp_connection = False - # xmppserverlog.info("bot disconnected {}".format(bot.did)) + + bot = bumper.bot_get(self.uid) + if bot: + bumper.bot_set_xmpp(bot['did'], False) - self.bumper_bots.set(bumper_bots) - - for client in bumper_clients: - if self.uid == client.userid and client.userid != "helper1": - client.xmpp_connection = False - # xmppserverlog.info("client disconnected {}".format(client.userid)) - - self.bumper_clients.set(bumper_clients) - # xmppserverlog.debug('client {} with resource {} disconnecting'.format(self.address, self.clientresource)) + client = bumper.client_get(self.clientresource) + if client: + bumper.client_set_xmpp(client['resource'], False) + self.connection.close() except Exception as e: @@ -545,7 +538,7 @@ class Client(threading.Thread): if not self.uid.startswith("fuid"): # Need sample data to see details here - bumper.add_bot("", self.uid, "", resource) + bumper.bot_add("", self.uid, "", resource) xmppserverlog.info("bot authenticated {}".format(self.uid)) # Client authenticated, move to next state @@ -562,7 +555,7 @@ class Client(threading.Thread): auth = True if auth: - bumper.add_client(self.uid, "bumper", self.clientresource) + bumper.client_add(self.uid, "bumper", self.clientresource) xmppserverlog.debug("client authenticated {}".format(self.uid)) # Client authenticated, move to next state @@ -617,7 +610,7 @@ class Client(threading.Thread): if not self.uid.startswith("fuid"): # Need sample data to see details here - bumper.add_bot(self.uid, self.uid, self.devclass, "atom","eco-legacy") + bumper.bot_add(self.uid, self.uid, self.devclass, "atom","eco-legacy") self.type = self.BOT xmppserverlog.info("bot authenticated {}".format(self.uid)) # Send response @@ -637,7 +630,7 @@ class Client(threading.Thread): if auth: self.type = self.CONTROLLER - bumper.add_client(self.uid, "bumper", self.clientresource) + bumper.client_add(self.uid, "bumper", self.clientresource) xmppserverlog.debug("client authenticated {}".format(self.uid)) # Client authenticated, move to next state @@ -661,18 +654,14 @@ class Client(threading.Thread): try: bumper_bots = self.bumper_bots.get() bumper_clients = self.bumper_clients.get() + + bot = bumper.bot_get(self.uid) + if bot: + bumper.bot_set_xmpp(bot['did'], True) - for bot in bumper_bots: - if self.uid == bot.did: - bot.xmpp_connection = True - # xmppserverlog.info("bot connected {}".format(bot.did)) - self.bumper_bots.set(bumper_bots) - - for client in bumper_clients: - if self.uid == client.userid: - client.xmpp_connection = True - # xmppserverlog.info("client connected {}".format(client.userid)) - self.bumper_clients.set(bumper_clients) + client = bumper.client_get(self.clientresource) + if client: + bumper.client_set_xmpp(client['resource'], True) clientbindxml = xml.getchildren() clientresourcexml = clientbindxml[0].getchildren() @@ -814,8 +803,7 @@ class Client(threading.Thread): if self.log_incoming_data: xmppserverlog.debug( "Unparsed Item - {}".format(str(ET.tostring(item, encoding="utf-8").decode("utf-8")).replace("ns0:","")) - ) - print("e") + ) except ET.ParseError as e: if (