diff --git a/bumper.py b/bumper.py index 11aba3b..0f86cbc 100644 --- a/bumper.py +++ b/bumper.py @@ -31,7 +31,7 @@ def main(): mqtt_address = (listen_host, 8883) xmpp_server = bumper.XMPPServer(xmpp_address, bumper_users=bumper.bumper_users_var, bumper_bots=bumper.bumper_bots_var,bumper_clients=bumper.bumper_clients_var) - mqtt_server = bumper.MQTTServer(mqtt_address, bumper_bots=bumper.bumper_bots_var,bumper_clients=bumper.bumper_clients_var) + mqtt_server = bumper.MQTTServer(mqtt_address,bumper_users=bumper.bumper_users_var, bumper_bots=bumper.bumper_bots_var,bumper_clients=bumper.bumper_clients_var) mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address, bumper_bots=bumper.bumper_bots_var,bumper_clients=bumper.bumper_clients_var) 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) @@ -39,8 +39,8 @@ def main(): #add user users = bumper.bumper_users_var.get() user1 = bumper.BumperUser('user1') - user1.add_device('user_phone') - user1.add_bot('bot_id') + user1.add_device('devid') + user1.add_bot('bot_did') users.append(user1) bumper.bumper_users_var.set(users) diff --git a/bumper/__init__.py b/bumper/__init__.py index b39671c..c986fb1 100644 --- a/bumper/__init__.py +++ b/bumper/__init__.py @@ -99,3 +99,11 @@ class VacBotClient(object): def asdict(self): return {"userid": self.userid,"realm": self.realm,"resource": self.resource} + +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 + + return False \ No newline at end of file diff --git a/bumper/confserver.py b/bumper/confserver.py index ebebe5c..3ee906b 100644 --- a/bumper/confserver.py +++ b/bumper/confserver.py @@ -140,7 +140,7 @@ class ConfServer(): user_devid = request.match_info.get('devid', "") countrycode = request.match_info.get('country', "us") if not user_devid == "": #Performing basic "auth" using devid, super insecure - users = bumper.bumper_users_var.get() + users = self.bumper_users.get() for user in users: if user_devid in user.devices: tmpaccesstoken = '' @@ -163,8 +163,8 @@ class ConfServer(): }, "msg": "操作成功", "time": bumper.get_milli_time(time.time()) - } - bumper.bumper_users_var.set(users) + } + self.bumper_users.set(users) return web.json_response(body) body = { @@ -185,12 +185,12 @@ class ConfServer(): try: user_devid = request.match_info.get('devid', "") if not user_devid == "": - users = bumper.bumper_users_var.get() + 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']) - bumper.bumper_users_var.set(users) + self.bumper_users.set(users) body = {"code": "0000","data": None,"msg": "操作成功", "time": bumper.get_milli_time(time.time())} @@ -204,7 +204,7 @@ class ConfServer(): user_devid = request.match_info.get('devid', "") if not user_devid == "": - users = bumper.bumper_users_var.get() + users = self.bumper_users.get() for user in users: if user_devid in user.devices and request.query['accessToken'] in user.tokens: countrycode = request.match_info.get('country', "us") @@ -220,7 +220,7 @@ class ConfServer(): "msg": "操作成功", "time": bumper.get_milli_time(time.time()) } - bumper.bumper_users_var.set(users) + self.bumper_users.set(users) return web.json_response(body) body = { @@ -323,7 +323,7 @@ class ConfServer(): body = {"result":"ok","ip":"47.88.66.164","port":8005} elif todo == 'loginByItToken': - users = bumper.bumper_users_var.get() + users = self.bumper_users.get() for user in users: if postbody['userId'] == "fuid_{}".format(user.userid) and postbody['token'] in user.authcodes: body = { @@ -342,6 +342,17 @@ class ConfServer(): "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", + } + confserverlog.debug("\r\n POST: {} \r\n Response: {}".format(postbody,body)) return web.json_response(body) diff --git a/bumper/mqttserver.py b/bumper/mqttserver.py index e7ee992..b5213e9 100644 --- a/bumper/mqttserver.py +++ b/bumper/mqttserver.py @@ -148,9 +148,11 @@ class MQTTHelperBot(): class MQTTServer(): default_config = {} + bumper_users = [] bumper_clients = [] bumper_bots = [] + async def broker_coro(self): try: broker = hbmqtt.broker.Broker(config=self.default_config) @@ -174,9 +176,9 @@ class MQTTServer(): except Exception as e: mqttserverlog.exception('{}'.format(e)) - def __init__(self, address, bumper_bots=contextvars.ContextVar, bumper_clients=contextvars.ContextVar): + def __init__(self, address,bumper_users=contextvars.ContextVar, bumper_bots=contextvars.ContextVar, bumper_clients=contextvars.ContextVar): try: - + self.bumper_users = bumper_users self.bumper_bots = bumper_bots self.bumper_clients = bumper_clients self.mqttserverthread = None @@ -203,18 +205,19 @@ class MQTTServer(): }, 'sys_interval': 10, 'auth': { - 'allow-anonymous': True, + 'allow-anonymous': False, 'password-file': os.path.join(os.path.dirname(os.path.realpath(__file__)), "passwd"), 'plugins': [ - '' #No plugins == no auth + 'bumper' #No plugins == no auth ] }, 'topic-check': { 'enabled': False }, - 'clients':{ - 'connected_bots': self.bumper_bots, - 'connected_clients': self.bumper_clients, + 'bumper':{ + 'bumper_users' : self.bumper_users, + 'bumper_bots': self.bumper_bots, + 'bumper_clients': self.bumper_clients, }, } @@ -251,18 +254,79 @@ class BumperMQTTServer_Plugin: def __init__(self, context): self.context = context try: - self.clients = self.context.config['clients'] + self.bumper_config = self.context.config['bumper'] + self.auth_config = self.context.config['auth'] except KeyError: - self.context.logger.warning("'clients' section not found in context configuration") + self.context.logger.warning("'bumper' section not found in context configuration") except Exception as e: mqttserverlog.exception('{}'.format(e)) + + async def authenticate(self, *args, **kwargs): + if not self.auth_config: + # auth config section not found + self.context.logger.warning("'auth' section not found in context configuration") + return False + + allow_anonymous = self.auth_config.get('allow-anonymous', True) # allow anonymous by default + if allow_anonymous: + authenticated = True + self.context.logger.debug("Authentication success: config allows anonymous") + else: + 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() + session = kwargs.get('session', None) + username = session.username + password = session.password + client_id = session.client_id + + didsplit = str(client_id).split("@") + #If this isn't a fake user (fuid) then add as a bot + if not (str(didsplit[0]).startswith("fuid") or str(didsplit[0]).startswith("helper")): + tmpbotdetail = str(didsplit[1]).split("/") + newbot = bumper.VacBotDevice() + newbot.did = didsplit[0] + newbot.name = username + newbot.vac_bot_device_class = tmpbotdetail[0] + newbot.resource = tmpbotdetail[1] + bumper_bots.append(newbot.asdict()) + mqttserverlog.info("new bot authenticated {}".format(newbot.asdict())) + self.bumper_config['bumper_bots'].set(bumper_bots) + authenticated = True + + else: + if didsplit[0] == "helper1": + authenticated = True + + elif bumper.check_authcode(didsplit[0], password): + tmpclientdetail = str(didsplit[1]).split("/") + newclient = bumper.VacBotClient() + newclient.userid = didsplit[0] + newclient.realm = tmpclientdetail[0] + newclient.resource = tmpclientdetail[1] + bumper_clients.append(newclient.asdict()) + mqttserverlog.info("new client authenticated {}".format(newclient.asdict())) + self.bumper_config['bumper_clients'].set(bumper_clients) + authenticated = True + + else: + authenticated = False + + except KeyError: + self.context.logger.warning("Session informations not available") + authenticated = False + return authenticated + + async def on_broker_client_connected(self, client_id): try: #mqttserverlog.debug('%s connected' % client_id) - connected_bots = self.clients['connected_bots'].get() - connected_clients = self.clients['connected_clients'].get() + 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("@") #If this isn't a fake user (fuid) then add as a bot if not (str(didsplit[0]).startswith("fuid") or str(didsplit[0]).startswith("helper")): @@ -271,33 +335,34 @@ class BumperMQTTServer_Plugin: newbot.did = didsplit[0] newbot.vac_bot_device_class = tmpbotdetail[0] newbot.resource = tmpbotdetail[1] - botactive = False - for bot in connected_bots: - if bot['did'] == newbot.did: - botactive = True + #botactive = False + #for bot in bumper_bots: + # if bot['did'] == newbot.did: + # botactive = True - if botactive == False: - connected_bots.append(newbot.asdict()) - mqttserverlog.info("new bot {}".format(newbot.did)) + #if botactive == False: + # bumper_bots.append(newbot.asdict()) + mqttserverlog.debug("bot connected {}".format(newbot.did)) - self.clients['connected_bots'].set(connected_bots) + #self.bumper_config['bumper_bots'].set(bumper_bots) + else: - tmpuserdetail = str(didsplit[1]).split("/") - newuser = bumper.VacBotClient() - newuser.userid = didsplit[0] - newuser.realm = tmpuserdetail[0] - newuser.resource = tmpuserdetail[1] + tmpclientdetail = str(didsplit[1]).split("/") + newclient = bumper.VacBotClient() + newclient.userid = didsplit[0] + newclient.realm = tmpclientdetail[0] + newclient.resource = tmpclientdetail[1] + + #clientactive = False + #for client in bumper_clients: + # if client['userid'] == newuser.userid: + # clientactive = True - clientactive = False - for client in connected_clients: - if client['userid'] == newuser.userid: - clientactive = True + #if clientactive == False and newuser.userid != 'helper1': + #bumper_clients.append(newuser.asdict()) + mqttserverlog.debug("client connected {}".format(newclient.userid)) - if clientactive == False and newuser.userid != 'helper1': - connected_clients.append(newuser.asdict()) - mqttserverlog.info("new client {}".format(newuser.userid)) - - self.clients['connected_clients'].set(connected_clients) + #self.bumper['bumper_clients'].set(bumper_clients) #mqttserverlog.debug('Connected Bots: %s' %self.clients['connected_bots'].get()) #mqttserverlog.debug('Connected Clients: %s' %self.clients['connected_clients'].get()) @@ -306,28 +371,28 @@ class BumperMQTTServer_Plugin: mqttserverlog.exception('{}'.format(e)) - async def on_broker_client_disconnected(self, client_id): try: #mqttserverlog.debug('%s disconnected' % client_id) - connected_bots = self.clients['connected_bots'].get() - connected_clients = self.clients['connected_clients'].get() + bumper_users = self.bumper_config['bumper_users'].get() + bumper_bots = self.bumper_config['bumper_bots'].get() + bumper_clients = self.bumper_config['bumper_clients'].get() #remove_clients = self.clients['remove_clients'].get() didsplit = str(client_id).split("@") #If the did is in the list, remove it - for bot in connected_bots: + for bot in bumper_bots: if didsplit[0] == bot['did']: mqttserverlog.info("bot disconnected {}".format(bot['did'])) - connected_bots.remove(bot) + #bumper_bots.remove(bot) #remove_clients.append(bot['did']) - self.clients['connected_bots'].set(connected_bots) + #self.clients['bumper_bots'].set(bumper_bots) - for client in connected_clients: + for client in bumper_clients: if didsplit[0] == client['userid'] and client['userid'] != 'helper1': mqttserverlog.info("client disconnected {}".format(client['userid'])) - connected_clients.remove(client) + #bumper_clients.remove(client) #remove_clients.append(client['userid']) - self.clients['connected_clients'].set(connected_clients) + #self.bumper_config['bumper_clients'].set(bumper_clients) #self.clients['remove_clients'].set(remove_clients) diff --git a/bumper/xmppserver.py b/bumper/xmppserver.py index 4c1f800..3740c20 100644 --- a/bumper/xmppserver.py +++ b/bumper/xmppserver.py @@ -342,7 +342,7 @@ class Client(threading.Thread): elif 'resource' in aitem.tag: self.clientresource = aitem.text - if self.check_authcode(self.uid, password): + if bumper.check_authcode(self.uid, password): #Client authenticated, move to next state self._set_state('INIT') @@ -366,14 +366,6 @@ class Client(threading.Thread): except Exception as e: xmppserverlog.exception('{}'.format(e)) - def check_authcode(self, uid, authcode): - users = bumper.bumper_users_var.get() - for user in users: - if uid == "fuid_{}".format(user.userid) and authcode in user.authcodes: - return True - - return False - def _handle_sasl_auth(self, data): try: xml = ET.fromstring(data.decode('utf-8')) @@ -385,7 +377,7 @@ class Client(threading.Thread): self.clientresource = resource authcode = saslauth[2] - if self.check_authcode(self.uid, authcode): + if bumper.check_authcode(self.uid, authcode): #Send response self.send('') #Success