reformat files with black
reformat files with black
This commit is contained in:
parent
028399c496
commit
af3e4ab1ce
5 changed files with 475 additions and 387 deletions
10
bumper.py
10
bumper.py
|
|
@ -52,14 +52,10 @@ def main():
|
||||||
bumper_clients=bumper.bumper_clients_var,
|
bumper_clients=bumper.bumper_clients_var,
|
||||||
)
|
)
|
||||||
conf_server = bumper.ConfServer(
|
conf_server = bumper.ConfServer(
|
||||||
conf_address_443,
|
conf_address_443, usessl=True, helperbot=mqtt_helperbot
|
||||||
usessl=True,
|
|
||||||
helperbot=mqtt_helperbot,
|
|
||||||
)
|
)
|
||||||
conf_server_2 = bumper.ConfServer(
|
conf_server_2 = bumper.ConfServer(
|
||||||
conf_address_8007,
|
conf_address_8007, usessl=False, helperbot=mqtt_helperbot
|
||||||
usessl=False,
|
|
||||||
helperbot=mqtt_helperbot,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# add user
|
# add user
|
||||||
|
|
@ -93,7 +89,7 @@ def main():
|
||||||
bumper.revoke_expired_tokens()
|
bumper.revoke_expired_tokens()
|
||||||
disconnected_clients = bumper.get_disconnected_xmpp_clients()
|
disconnected_clients = bumper.get_disconnected_xmpp_clients()
|
||||||
for client in disconnected_clients:
|
for client in disconnected_clients:
|
||||||
xmpp_server.remove_client_byuid(client['userid'])
|
xmpp_server.remove_client_byuid(client["userid"])
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
bumper.bumperlog.info("Bumper Exiting - Keyboard Interrupt")
|
bumper.bumperlog.info("Bumper Exiting - Keyboard Interrupt")
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ server_cert = "./certs/cert.pem"
|
||||||
server_key = "./certs/key.pem"
|
server_key = "./certs/key.pem"
|
||||||
|
|
||||||
use_auth = False
|
use_auth = False
|
||||||
token_validity_seconds = 3600 #1 hour
|
token_validity_seconds = 3600 # 1 hour
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
bumperlog = logging.getLogger("bumper")
|
bumperlog = logging.getLogger("bumper")
|
||||||
|
|
@ -44,23 +44,26 @@ xmppserverlog = logging.getLogger("xmppserver")
|
||||||
def get_milli_time(timetoconvert):
|
def get_milli_time(timetoconvert):
|
||||||
return int(round(timetoconvert * 1000))
|
return int(round(timetoconvert * 1000))
|
||||||
|
|
||||||
|
|
||||||
def db_file():
|
def db_file():
|
||||||
if platform.system() == 'Windows':
|
if platform.system() == "Windows":
|
||||||
return os.path.join(os.getenv('APPDATA'), 'bumper.db')
|
return os.path.join(os.getenv("APPDATA"), "bumper.db")
|
||||||
else:
|
else:
|
||||||
return os.path.expanduser('~/.config/bumper.db')
|
return os.path.expanduser("~/.config/bumper.db")
|
||||||
|
|
||||||
|
|
||||||
def db_get():
|
def db_get():
|
||||||
#Will create the database if it doesn't exist
|
# Will create the database if it doesn't exist
|
||||||
db = TinyDB(db_file())
|
db = TinyDB(db_file())
|
||||||
|
|
||||||
#Will create the tables if they don't exist
|
# Will create the tables if they don't exist
|
||||||
users_table = db.table('users')
|
users_table = db.table("users")
|
||||||
clients_table = db.table('clients')
|
clients_table = db.table("clients")
|
||||||
bots_table = db.table('bots')
|
bots_table = db.table("bots")
|
||||||
|
|
||||||
return db
|
return db
|
||||||
|
|
||||||
|
|
||||||
class BumperUser(object):
|
class BumperUser(object):
|
||||||
def __init__(self, userid=""):
|
def __init__(self, userid=""):
|
||||||
self.userid = userid
|
self.userid = userid
|
||||||
|
|
@ -68,131 +71,151 @@ class BumperUser(object):
|
||||||
self.bots = []
|
self.bots = []
|
||||||
|
|
||||||
def asdict(self):
|
def asdict(self):
|
||||||
return {
|
return {"userid": self.userid, "devices": self.devices, "bots": self.bots}
|
||||||
"userid": self.userid,
|
|
||||||
"devices": self.devices,
|
|
||||||
"bots": self.bots,
|
|
||||||
}
|
|
||||||
|
|
||||||
def user_add(userid):
|
def user_add(userid):
|
||||||
newuser = BumperUser()
|
newuser = BumperUser()
|
||||||
newuser.userid = userid
|
newuser.userid = userid
|
||||||
|
|
||||||
user = user_get(userid)
|
user = user_get(userid)
|
||||||
if not user:
|
if not user:
|
||||||
bumperlog.info("Adding new user with userid: {}".format(newuser.userid))
|
bumperlog.info("Adding new user with userid: {}".format(newuser.userid))
|
||||||
user_full_upsert(newuser.asdict())
|
user_full_upsert(newuser.asdict())
|
||||||
|
|
||||||
|
|
||||||
def user_get(userid):
|
def user_get(userid):
|
||||||
users = db_get().table('users')
|
users = db_get().table("users")
|
||||||
User = Query()
|
User = Query()
|
||||||
return users.get(User.userid == userid)
|
return users.get(User.userid == userid)
|
||||||
|
|
||||||
|
|
||||||
def user_by_deviceid(deviceid):
|
def user_by_deviceid(deviceid):
|
||||||
users = db_get().table('users')
|
users = db_get().table("users")
|
||||||
User = Query()
|
User = Query()
|
||||||
return users.get(User.devices.any([deviceid]))
|
return users.get(User.devices.any([deviceid]))
|
||||||
|
|
||||||
|
|
||||||
def user_full_upsert(user):
|
def user_full_upsert(user):
|
||||||
users = db_get().table('users')
|
users = db_get().table("users")
|
||||||
User = Query()
|
User = Query()
|
||||||
users.upsert(user, User.did == user['userid'])
|
users.upsert(user, User.did == user["userid"])
|
||||||
|
|
||||||
|
|
||||||
def user_add_device(userid, devid):
|
def user_add_device(userid, devid):
|
||||||
users = db_get().table('users')
|
users = db_get().table("users")
|
||||||
User = Query()
|
User = Query()
|
||||||
user = users.get(User.userid == userid)
|
user = users.get(User.userid == userid)
|
||||||
userdevices = list(user['devices'])
|
userdevices = list(user["devices"])
|
||||||
if not devid in userdevices:
|
if not devid in userdevices:
|
||||||
userdevices.append(devid)
|
userdevices.append(devid)
|
||||||
|
|
||||||
users.upsert({'devices': userdevices}, User.userid == userid)
|
users.upsert({"devices": userdevices}, User.userid == userid)
|
||||||
|
|
||||||
|
|
||||||
def user_remove_device(userid, devid):
|
def user_remove_device(userid, devid):
|
||||||
users = db_get().table('users')
|
users = db_get().table("users")
|
||||||
User = Query()
|
User = Query()
|
||||||
user = users.get(User.userid == userid)
|
user = users.get(User.userid == userid)
|
||||||
userdevices = list(user['devices'])
|
userdevices = list(user["devices"])
|
||||||
if devid in userdevices:
|
if devid in userdevices:
|
||||||
userdevices.remove(devid)
|
userdevices.remove(devid)
|
||||||
|
|
||||||
users.upsert({'devices': userdevices}, User.userid == userid)
|
users.upsert({"devices": userdevices}, User.userid == userid)
|
||||||
|
|
||||||
|
|
||||||
def user_add_bot(userid, did):
|
def user_add_bot(userid, did):
|
||||||
users = db_get().table('users')
|
users = db_get().table("users")
|
||||||
User = Query()
|
User = Query()
|
||||||
user = users.get(User.userid == userid)
|
user = users.get(User.userid == userid)
|
||||||
userbots = list(user['bots'])
|
userbots = list(user["bots"])
|
||||||
if not did in userbots:
|
if not did in userbots:
|
||||||
userbots.append(did)
|
userbots.append(did)
|
||||||
|
|
||||||
users.upsert({'bots': userbots}, User.userid == userid)
|
users.upsert({"bots": userbots}, User.userid == userid)
|
||||||
|
|
||||||
|
|
||||||
def user_remove_bot(userid, did):
|
def user_remove_bot(userid, did):
|
||||||
users = db_get().table('users')
|
users = db_get().table("users")
|
||||||
User = Query()
|
User = Query()
|
||||||
user = users.get(User.userid == userid)
|
user = users.get(User.userid == userid)
|
||||||
userbots = list(user['bots'])
|
userbots = list(user["bots"])
|
||||||
if did in userbots:
|
if did in userbots:
|
||||||
userbots.remove(did)
|
userbots.remove(did)
|
||||||
|
|
||||||
users.upsert({'bots': userbots}, User.userid == userid)
|
users.upsert({"bots": userbots}, User.userid == userid)
|
||||||
|
|
||||||
|
|
||||||
def user_get_tokens(userid):
|
def user_get_tokens(userid):
|
||||||
tokens = db_get().table('tokens')
|
tokens = db_get().table("tokens")
|
||||||
return tokens.search((Query().userid == userid))
|
return tokens.search((Query().userid == userid))
|
||||||
|
|
||||||
|
|
||||||
def user_get_token(userid, token):
|
def user_get_token(userid, token):
|
||||||
tokens = db_get().table('tokens')
|
tokens = db_get().table("tokens")
|
||||||
return tokens.get((Query().userid == userid) & (Query().token == token))
|
return tokens.get((Query().userid == userid) & (Query().token == token))
|
||||||
|
|
||||||
|
|
||||||
def user_add_token(userid, token):
|
def user_add_token(userid, token):
|
||||||
tokens = db_get().table('tokens')
|
tokens = db_get().table("tokens")
|
||||||
tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
|
tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
|
||||||
if not tmptoken:
|
if not tmptoken:
|
||||||
tokens.insert({'userid':userid, 'token':token, 'expiration':"{}".format(datetime.now() + timedelta(seconds=token_validity_seconds))})
|
tokens.insert(
|
||||||
|
{
|
||||||
|
"userid": userid,
|
||||||
|
"token": token,
|
||||||
|
"expiration": "{}".format(
|
||||||
|
datetime.now() + timedelta(seconds=token_validity_seconds)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def user_revoke_all_tokens(userid):
|
def user_revoke_all_tokens(userid):
|
||||||
tokens = db_get().table('tokens')
|
tokens = db_get().table("tokens")
|
||||||
tsearch = tokens.search(Query().userid == userid)
|
tsearch = tokens.search(Query().userid == userid)
|
||||||
for i in tsearch:
|
for i in tsearch:
|
||||||
tokens.remove(doc_ids=[i.doc_id])
|
tokens.remove(doc_ids=[i.doc_id])
|
||||||
|
|
||||||
|
|
||||||
def user_revoke_expired_tokens(userid):
|
def user_revoke_expired_tokens(userid):
|
||||||
tokens = db_get().table('tokens')
|
tokens = db_get().table("tokens")
|
||||||
tsearch = tokens.search(Query().userid == userid)
|
tsearch = tokens.search(Query().userid == userid)
|
||||||
for i in tsearch:
|
for i in tsearch:
|
||||||
if datetime.now() >= datetime.fromisoformat(i['expiration']):
|
if datetime.now() >= datetime.fromisoformat(i["expiration"]):
|
||||||
bumperlog.debug("Removing token {} due to expiration".format(i['token']))
|
bumperlog.debug("Removing token {} due to expiration".format(i["token"]))
|
||||||
tokens.remove(doc_ids=[i.doc_id])
|
tokens.remove(doc_ids=[i.doc_id])
|
||||||
|
|
||||||
|
|
||||||
def user_revoke_token(userid, token):
|
def user_revoke_token(userid, token):
|
||||||
tokens = db_get().table('tokens')
|
tokens = db_get().table("tokens")
|
||||||
tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
|
tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
|
||||||
if tmptoken:
|
if tmptoken:
|
||||||
tokens.remove(doc_ids=[tmptoken.doc_id])
|
tokens.remove(doc_ids=[tmptoken.doc_id])
|
||||||
|
|
||||||
|
|
||||||
def user_add_authcode(userid, token, authcode):
|
def user_add_authcode(userid, token, authcode):
|
||||||
tokens = db_get().table('tokens')
|
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))
|
tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
|
||||||
if tmptoken:
|
if tmptoken:
|
||||||
tokens.upsert({'authcode': ''}, ((Query().userid == userid) & (Query().token == token)))
|
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):
|
class VacBotDevice(object):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self, did="", vac_bot_device_class="", resource="", name="", nick="", company=""
|
||||||
did="",
|
|
||||||
vac_bot_device_class="",
|
|
||||||
resource="",
|
|
||||||
name="",
|
|
||||||
nick="",
|
|
||||||
company="",
|
|
||||||
):
|
):
|
||||||
self.vac_bot_device_class = vac_bot_device_class
|
self.vac_bot_device_class = vac_bot_device_class
|
||||||
self.company = company
|
self.company = company
|
||||||
|
|
@ -212,7 +235,7 @@ class VacBotDevice(object):
|
||||||
"nick": self.nick,
|
"nick": self.nick,
|
||||||
"resource": self.resource,
|
"resource": self.resource,
|
||||||
"mqtt_connection": self.mqtt_connection,
|
"mqtt_connection": self.mqtt_connection,
|
||||||
"xmpp_connection": self.xmpp_connection
|
"xmpp_connection": self.xmpp_connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -230,45 +253,54 @@ class VacBotClient(object):
|
||||||
"realm": self.realm,
|
"realm": self.realm,
|
||||||
"resource": self.resource,
|
"resource": self.resource,
|
||||||
"mqtt_connection": self.mqtt_connection,
|
"mqtt_connection": self.mqtt_connection,
|
||||||
"xmpp_connection": self.xmpp_connection
|
"xmpp_connection": self.xmpp_connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_disconnected_xmpp_clients():
|
def get_disconnected_xmpp_clients():
|
||||||
clients = db_get().table('clients')
|
clients = db_get().table("clients")
|
||||||
Client = Query()
|
Client = Query()
|
||||||
return clients.search(Client.xmpp_connection == False)
|
return clients.search(Client.xmpp_connection == False)
|
||||||
|
|
||||||
|
|
||||||
def check_authcode(uid, authcode):
|
def check_authcode(uid, authcode):
|
||||||
bumperlog.debug("Checking for authcode: {}".format(authcode))
|
bumperlog.debug("Checking for authcode: {}".format(authcode))
|
||||||
tokens = db_get().table('tokens')
|
tokens = db_get().table("tokens")
|
||||||
tmpauth = tokens.get(
|
tmpauth = tokens.get(
|
||||||
(Query().authcode == authcode) & #Match authcode
|
(Query().authcode == authcode)
|
||||||
((Query().userid == uid.replace("fuid_","")) | (Query().userid == "fuid_{}".format(uid))) #Userid with or without fuid_
|
& ( # Match authcode
|
||||||
)
|
(Query().userid == uid.replace("fuid_", ""))
|
||||||
|
| (Query().userid == "fuid_{}".format(uid))
|
||||||
|
) # Userid with or without fuid_
|
||||||
|
)
|
||||||
if tmpauth:
|
if tmpauth:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def check_token(uid, token):
|
def check_token(uid, token):
|
||||||
bumperlog.debug("Checking for token: {}".format(token))
|
bumperlog.debug("Checking for token: {}".format(token))
|
||||||
tokens = db_get().table('tokens')
|
tokens = db_get().table("tokens")
|
||||||
tmpauth = tokens.get(
|
tmpauth = tokens.get(
|
||||||
(Query().token == token) & #Match token
|
(Query().token == token)
|
||||||
((Query().userid == uid.replace("fuid_","")) | (Query().userid == "fuid_{}".format(uid))) #Userid with or without fuid_
|
& ( # Match token
|
||||||
)
|
(Query().userid == uid.replace("fuid_", ""))
|
||||||
|
| (Query().userid == "fuid_{}".format(uid))
|
||||||
|
) # Userid with or without fuid_
|
||||||
|
)
|
||||||
if tmpauth:
|
if tmpauth:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def revoke_expired_tokens():
|
def revoke_expired_tokens():
|
||||||
tokens = db_get().table('tokens').all()
|
tokens = db_get().table("tokens").all()
|
||||||
for i in tokens:
|
for i in tokens:
|
||||||
if datetime.now() >= datetime.fromisoformat(i['expiration']):
|
if datetime.now() >= datetime.fromisoformat(i["expiration"]):
|
||||||
bumperlog.debug("Removing token {} due to expiration".format(i['token']))
|
bumperlog.debug("Removing token {} due to expiration".format(i["token"]))
|
||||||
db_get().table('tokens').remove(doc_ids=[i.doc_id])
|
db_get().table("tokens").remove(doc_ids=[i.doc_id])
|
||||||
|
|
||||||
|
|
||||||
def bot_add(sn, did, devclass, resource, company):
|
def bot_add(sn, did, devclass, resource, company):
|
||||||
|
|
@ -278,41 +310,50 @@ def bot_add(sn, did, devclass, resource, company):
|
||||||
newbot.vac_bot_device_class = devclass
|
newbot.vac_bot_device_class = devclass
|
||||||
newbot.resource = resource
|
newbot.resource = resource
|
||||||
newbot.company = company
|
newbot.company = company
|
||||||
|
|
||||||
bot = bot_get(did)
|
bot = bot_get(did)
|
||||||
if not bot:
|
if not bot:
|
||||||
bumperlog.info("Adding new bot with SN: {} DID: {}".format(newbot.name, newbot.did))
|
bumperlog.info(
|
||||||
|
"Adding new bot with SN: {} DID: {}".format(newbot.name, newbot.did)
|
||||||
|
)
|
||||||
bot_full_upsert(newbot.asdict())
|
bot_full_upsert(newbot.asdict())
|
||||||
|
|
||||||
|
|
||||||
def bot_remove(did):
|
def bot_remove(did):
|
||||||
bots = db_get().table('bots')
|
bots = db_get().table("bots")
|
||||||
bot = bot_get(did)
|
bot = bot_get(did)
|
||||||
bots.remove(doc_ids=[bot.doc_id])
|
bots.remove(doc_ids=[bot.doc_id])
|
||||||
|
|
||||||
|
|
||||||
def bot_get(did):
|
def bot_get(did):
|
||||||
bots = db_get().table('bots')
|
bots = db_get().table("bots")
|
||||||
Bot = Query()
|
Bot = Query()
|
||||||
return bots.get(Bot.did == did)
|
return bots.get(Bot.did == did)
|
||||||
|
|
||||||
|
|
||||||
def bot_full_upsert(vacbot):
|
def bot_full_upsert(vacbot):
|
||||||
bots = db_get().table('bots')
|
bots = db_get().table("bots")
|
||||||
Bot = Query()
|
Bot = Query()
|
||||||
bots.upsert(vacbot, Bot.did == vacbot['did'])
|
bots.upsert(vacbot, Bot.did == vacbot["did"])
|
||||||
|
|
||||||
|
|
||||||
def bot_set_nick(did, nick):
|
def bot_set_nick(did, nick):
|
||||||
bots = db_get().table('bots')
|
bots = db_get().table("bots")
|
||||||
Bot = Query()
|
Bot = Query()
|
||||||
bots.upsert({'nick': nick}, Bot.did == did)
|
bots.upsert({"nick": nick}, Bot.did == did)
|
||||||
|
|
||||||
|
|
||||||
def bot_set_mqtt(did, mqtt):
|
def bot_set_mqtt(did, mqtt):
|
||||||
bots = db_get().table('bots')
|
bots = db_get().table("bots")
|
||||||
Bot = Query()
|
Bot = Query()
|
||||||
bots.upsert({'mqtt_connection': mqtt}, Bot.did == did)
|
bots.upsert({"mqtt_connection": mqtt}, Bot.did == did)
|
||||||
|
|
||||||
|
|
||||||
def bot_set_xmpp(did, xmpp):
|
def bot_set_xmpp(did, xmpp):
|
||||||
bots = db_get().table('bots')
|
bots = db_get().table("bots")
|
||||||
Bot = Query()
|
Bot = Query()
|
||||||
bots.upsert({'xmpp_connection': xmpp}, Bot.did == did)
|
bots.upsert({"xmpp_connection": xmpp}, Bot.did == did)
|
||||||
|
|
||||||
|
|
||||||
def client_add(userid, realm, resource):
|
def client_add(userid, realm, resource):
|
||||||
newclient = VacBotClient()
|
newclient = VacBotClient()
|
||||||
|
|
@ -325,25 +366,30 @@ def client_add(userid, realm, resource):
|
||||||
bumperlog.info("Adding new client with resource {}".format(newclient.resource))
|
bumperlog.info("Adding new client with resource {}".format(newclient.resource))
|
||||||
client_full_upsert(newclient.asdict())
|
client_full_upsert(newclient.asdict())
|
||||||
|
|
||||||
|
|
||||||
def client_get(resource):
|
def client_get(resource):
|
||||||
clients = db_get().table('clients')
|
clients = db_get().table("clients")
|
||||||
Client = Query()
|
Client = Query()
|
||||||
return clients.get(Client.resource == resource)
|
return clients.get(Client.resource == resource)
|
||||||
|
|
||||||
|
|
||||||
def client_full_upsert(client):
|
def client_full_upsert(client):
|
||||||
clients = db_get().table('clients')
|
clients = db_get().table("clients")
|
||||||
Client = Query()
|
Client = Query()
|
||||||
clients.upsert(client, Client.resource == client['resource'])
|
clients.upsert(client, Client.resource == client["resource"])
|
||||||
|
|
||||||
|
|
||||||
def client_set_mqtt(resource, mqtt):
|
def client_set_mqtt(resource, mqtt):
|
||||||
clients = db_get().table('clients')
|
clients = db_get().table("clients")
|
||||||
Client = Query()
|
Client = Query()
|
||||||
clients.upsert({'mqtt_connection': mqtt}, Client.resource == resource)
|
clients.upsert({"mqtt_connection": mqtt}, Client.resource == resource)
|
||||||
|
|
||||||
|
|
||||||
def client_set_xmpp(resource, xmpp):
|
def client_set_xmpp(resource, xmpp):
|
||||||
clients = db_get().table('clients')
|
clients = db_get().table("clients")
|
||||||
Client = Query()
|
Client = Query()
|
||||||
clients.upsert({'xmpp_connection': xmpp}, Client.resource == resource)
|
clients.upsert({"xmpp_connection": xmpp}, Client.resource == resource)
|
||||||
|
|
||||||
|
|
||||||
RETURN_API_SUCCESS = "0000"
|
RETURN_API_SUCCESS = "0000"
|
||||||
ERR_ACTIVATE_TOKEN_TIMEOUT = "1006"
|
ERR_ACTIVATE_TOKEN_TIMEOUT = "1006"
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,7 @@ logging.getLogger("aiohttp.access").addFilter(aiohttp_filter())
|
||||||
|
|
||||||
|
|
||||||
class ConfServer:
|
class ConfServer:
|
||||||
|
def __init__(self, address, usessl=False, helperbot=None):
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
address,
|
|
||||||
usessl=False,
|
|
||||||
helperbot=None,
|
|
||||||
):
|
|
||||||
self.helperbot = helperbot
|
self.helperbot = helperbot
|
||||||
self.usessl = usessl
|
self.usessl = usessl
|
||||||
self.address = address
|
self.address = address
|
||||||
|
|
@ -166,7 +160,7 @@ class ConfServer:
|
||||||
|
|
||||||
async def handle_base(self, request):
|
async def handle_base(self, request):
|
||||||
try:
|
try:
|
||||||
#TODO - API Options here for viewing clients, tokens, restarting the server, etc.
|
# TODO - API Options here for viewing clients, tokens, restarting the server, etc.
|
||||||
text = "Bumper!"
|
text = "Bumper!"
|
||||||
|
|
||||||
return web.json_response(text)
|
return web.json_response(text)
|
||||||
|
|
@ -186,25 +180,29 @@ class ConfServer:
|
||||||
not user_devid == ""
|
not user_devid == ""
|
||||||
): # Performing basic "auth" using devid, super insecure
|
): # Performing basic "auth" using devid, super insecure
|
||||||
user = bumper.user_by_deviceid(user_devid)
|
user = bumper.user_by_deviceid(user_devid)
|
||||||
if "checkLogin" in request.path:
|
if "checkLogin" in request.path:
|
||||||
self.check_token(countrycode, user, request.query["accessToken"])
|
self.check_token(
|
||||||
else:
|
countrycode, user, request.query["accessToken"]
|
||||||
#Deactivate old tokens and authcodes
|
)
|
||||||
bumper.user_revoke_expired_tokens(user['userid'])
|
else:
|
||||||
|
# Deactivate old tokens and authcodes
|
||||||
|
bumper.user_revoke_expired_tokens(user["userid"])
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
"code": bumper.RETURN_API_SUCCESS,
|
"code": bumper.RETURN_API_SUCCESS,
|
||||||
"data": {
|
"data": {
|
||||||
"accessToken": self.generate_token(user), # generate a new token
|
"accessToken": self.generate_token(
|
||||||
|
user
|
||||||
|
), # generate a new token
|
||||||
"country": countrycode,
|
"country": countrycode,
|
||||||
"email": "null@null.com",
|
"email": "null@null.com",
|
||||||
"uid": "fuid_{}".format(user['userid']),
|
"uid": "fuid_{}".format(user["userid"]),
|
||||||
"username": "fusername_{}".format(user['userid']),
|
"username": "fusername_{}".format(user["userid"]),
|
||||||
},
|
},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"time": bumper.get_milli_time(time.time()),
|
"time": bumper.get_milli_time(time.time()),
|
||||||
}
|
}
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
"code": bumper.ERR_USER_NOT_ACTIVATED,
|
"code": bumper.ERR_USER_NOT_ACTIVATED,
|
||||||
|
|
@ -214,7 +212,7 @@ class ConfServer:
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return web.json_response(
|
return web.json_response(
|
||||||
self._auth_any(user_devid, countrycode, request)
|
self._auth_any(user_devid, countrycode, request)
|
||||||
|
|
@ -223,27 +221,22 @@ class ConfServer:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception("{}".format(e))
|
confserverlog.exception("{}".format(e))
|
||||||
|
|
||||||
|
|
||||||
def check_token(self, countrycode, user, token):
|
def check_token(self, countrycode, user, token):
|
||||||
if (
|
if bumper.check_token(user["userid"], token):
|
||||||
bumper.check_token(user['userid'], token)
|
|
||||||
):
|
|
||||||
body = {
|
body = {
|
||||||
"code": bumper.RETURN_API_SUCCESS,
|
"code": bumper.RETURN_API_SUCCESS,
|
||||||
"data": {
|
"data": {
|
||||||
"accessToken": token,
|
"accessToken": token,
|
||||||
"country": countrycode,
|
"country": countrycode,
|
||||||
"email": "null@null.com",
|
"email": "null@null.com",
|
||||||
"uid": "fuid_{}".format(user['userid']),
|
"uid": "fuid_{}".format(user["userid"]),
|
||||||
"username": "fusername_{}".format(
|
"username": "fusername_{}".format(user["userid"]),
|
||||||
user['userid']
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"time": bumper.get_milli_time(time.time()),
|
"time": bumper.get_milli_time(time.time()),
|
||||||
}
|
}
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
body = {
|
body = {
|
||||||
"code": bumper.ERR_TOKEN_INVALID,
|
"code": bumper.ERR_TOKEN_INVALID,
|
||||||
|
|
@ -251,45 +244,46 @@ class ConfServer:
|
||||||
"msg": "当前密码错误",
|
"msg": "当前密码错误",
|
||||||
"time": bumper.get_milli_time(time.time()),
|
"time": bumper.get_milli_time(time.time()),
|
||||||
}
|
}
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
def generate_token(self, user):
|
def generate_token(self, user):
|
||||||
tmpaccesstoken = uuid.uuid4().hex
|
tmpaccesstoken = uuid.uuid4().hex
|
||||||
bumper.user_add_token(user['userid'],tmpaccesstoken)
|
bumper.user_add_token(user["userid"], tmpaccesstoken)
|
||||||
return tmpaccesstoken
|
return tmpaccesstoken
|
||||||
|
|
||||||
def generate_authcode(self, user, countrycode, token):
|
def generate_authcode(self, user, countrycode, token):
|
||||||
tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex)
|
tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex)
|
||||||
bumper.user_add_authcode(user['userid'], token, tmpauthcode)
|
bumper.user_add_authcode(user["userid"], token, tmpauthcode)
|
||||||
return tmpauthcode
|
return tmpauthcode
|
||||||
|
|
||||||
|
|
||||||
def _auth_any(self, devid, country, request):
|
def _auth_any(self, devid, country, request):
|
||||||
try:
|
try:
|
||||||
user_devid = devid
|
user_devid = devid
|
||||||
countrycode = country
|
countrycode = country
|
||||||
user = bumper.user_by_deviceid(user_devid)
|
user = bumper.user_by_deviceid(user_devid)
|
||||||
bots = bumper.db_get().table('bots').all()
|
bots = bumper.db_get().table("bots").all()
|
||||||
|
|
||||||
if user: #Default to user 0
|
|
||||||
tmpuser = user
|
|
||||||
bumper.user_add_device(tmpuser['userid'], user_devid)
|
|
||||||
else:
|
|
||||||
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: #Add all bots to the user
|
if user: # Default to user 0
|
||||||
bumper.user_add_bot(tmpuser['userid'], bot['did'])
|
tmpuser = user
|
||||||
|
bumper.user_add_device(tmpuser["userid"], user_devid)
|
||||||
if "checkLogin" in request.path: #If request was to check a token do so
|
else:
|
||||||
checkToken = self.check_token(countrycode, user, request.query["accessToken"])
|
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: # 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)
|
isGood = json.loads(checkToken.text)
|
||||||
if isGood['code'] == "0000":
|
if isGood["code"] == "0000":
|
||||||
return isGood
|
return isGood
|
||||||
|
|
||||||
#Deactivate old tokens and authcodes
|
# Deactivate old tokens and authcodes
|
||||||
bumper.user_revoke_expired_tokens(tmpuser['userid'])
|
bumper.user_revoke_expired_tokens(tmpuser["userid"])
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
"code": bumper.RETURN_API_SUCCESS,
|
"code": bumper.RETURN_API_SUCCESS,
|
||||||
|
|
@ -297,8 +291,8 @@ class ConfServer:
|
||||||
"accessToken": self.generate_token(tmpuser), # Generate a token
|
"accessToken": self.generate_token(tmpuser), # Generate a token
|
||||||
"country": countrycode,
|
"country": countrycode,
|
||||||
"email": "null@null.com",
|
"email": "null@null.com",
|
||||||
"uid": "fuid_{}".format(tmpuser['userid']),
|
"uid": "fuid_{}".format(tmpuser["userid"]),
|
||||||
"username": "fusername_{}".format(tmpuser['userid']),
|
"username": "fusername_{}".format(tmpuser["userid"]),
|
||||||
},
|
},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"time": bumper.get_milli_time(time.time()),
|
"time": bumper.get_milli_time(time.time()),
|
||||||
|
|
@ -314,12 +308,12 @@ class ConfServer:
|
||||||
user_devid = request.match_info.get("devid", "")
|
user_devid = request.match_info.get("devid", "")
|
||||||
if not user_devid == "":
|
if not user_devid == "":
|
||||||
user = bumper.user_by_deviceid(user_devid)
|
user = bumper.user_by_deviceid(user_devid)
|
||||||
if user:
|
if user:
|
||||||
if (
|
if bumper.check_token(user["userid"], request.query["accessToken"]):
|
||||||
bumper.check_token(user['userid'], request.query["accessToken"])
|
# Deactivate old tokens and authcodes
|
||||||
):
|
bumper.user_revoke_token(
|
||||||
#Deactivate old tokens and authcodes
|
user["userid"], request.query["accessToken"]
|
||||||
bumper.user_revoke_token(user['userid'], request.query["accessToken"])
|
)
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
"code": bumper.RETURN_API_SUCCESS,
|
"code": bumper.RETURN_API_SUCCESS,
|
||||||
|
|
@ -338,16 +332,22 @@ class ConfServer:
|
||||||
|
|
||||||
user_devid = request.match_info.get("devid", "")
|
user_devid = request.match_info.get("devid", "")
|
||||||
if not user_devid == "":
|
if not user_devid == "":
|
||||||
user = bumper.user_by_deviceid(user_devid)
|
user = bumper.user_by_deviceid(user_devid)
|
||||||
if user:
|
if user:
|
||||||
token = bumper.user_get_token(user['userid'], request.query["accessToken"])
|
token = bumper.user_get_token(
|
||||||
|
user["userid"], request.query["accessToken"]
|
||||||
|
)
|
||||||
if token:
|
if token:
|
||||||
authcode = ""
|
authcode = ""
|
||||||
if not 'authcode' in token:
|
if not "authcode" in token:
|
||||||
authcode = self.generate_authcode(user, request.match_info.get("country", "us"), request.query["accessToken"])
|
authcode = self.generate_authcode(
|
||||||
|
user,
|
||||||
|
request.match_info.get("country", "us"),
|
||||||
|
request.query["accessToken"],
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
authcode = token['authcode']
|
authcode = token["authcode"]
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
"code": bumper.RETURN_API_SUCCESS,
|
"code": bumper.RETURN_API_SUCCESS,
|
||||||
"data": {
|
"data": {
|
||||||
|
|
@ -532,11 +532,9 @@ class ConfServer:
|
||||||
}
|
}
|
||||||
elif service == "EcoUpdate":
|
elif service == "EcoUpdate":
|
||||||
body = {"result": "ok", "ip": "47.88.66.164", "port": 8005}
|
body = {"result": "ok", "ip": "47.88.66.164", "port": 8005}
|
||||||
|
|
||||||
elif todo == "loginByItToken":
|
elif todo == "loginByItToken":
|
||||||
if (
|
if bumper.check_authcode(postbody["userId"], postbody["token"]):
|
||||||
bumper.check_authcode(postbody["userId"], postbody["token"])
|
|
||||||
):
|
|
||||||
body = {
|
body = {
|
||||||
"resource": postbody["resource"],
|
"resource": postbody["resource"],
|
||||||
"result": "ok",
|
"result": "ok",
|
||||||
|
|
@ -546,30 +544,32 @@ class ConfServer:
|
||||||
}
|
}
|
||||||
|
|
||||||
elif todo == "GetDeviceList":
|
elif todo == "GetDeviceList":
|
||||||
body = {"devices": bumper.db_get().table('bots').all(), "result": "ok", "todo": "result"}
|
body = {
|
||||||
|
"devices": bumper.db_get().table("bots").all(),
|
||||||
|
"result": "ok",
|
||||||
|
"todo": "result",
|
||||||
|
}
|
||||||
|
|
||||||
elif todo == "SetDeviceNick":
|
elif todo == "SetDeviceNick":
|
||||||
bumper.bot_set_nick(postbody["did"], postbody["nick"])
|
bumper.bot_set_nick(postbody["did"], postbody["nick"])
|
||||||
body = {"result": "ok", "todo": "result"}
|
body = {"result": "ok", "todo": "result"}
|
||||||
|
|
||||||
|
|
||||||
elif todo == "AddOneDevice":
|
elif todo == "AddOneDevice":
|
||||||
bumper.bot_set_nick(postbody["did"], postbody["nick"])
|
bumper.bot_set_nick(postbody["did"], postbody["nick"])
|
||||||
body = {"result": "ok", "todo": "result"}
|
body = {"result": "ok", "todo": "result"}
|
||||||
|
|
||||||
elif todo == "DeleteOneDevice":
|
elif todo == "DeleteOneDevice":
|
||||||
bumper.bot_remove(postbody["did"])
|
bumper.bot_remove(postbody["did"])
|
||||||
body = {"result": "ok", "todo": "result"}
|
body = {"result": "ok", "todo": "result"}
|
||||||
|
|
||||||
confserverlog.debug(
|
confserverlog.debug(
|
||||||
"\r\n POST: {} \r\n Response: {}".format(postbody, body)
|
"\r\n POST: {} \r\n Response: {}".format(postbody, body)
|
||||||
)
|
)
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception("{}".format(e))
|
confserverlog.exception("{}".format(e))
|
||||||
|
|
||||||
|
|
||||||
async def handle_lookup(self, request):
|
async def handle_lookup(self, request):
|
||||||
try:
|
try:
|
||||||
|
|
@ -588,24 +588,26 @@ class ConfServer:
|
||||||
if todo == "FindBest":
|
if todo == "FindBest":
|
||||||
service = postbody["service"]
|
service = postbody["service"]
|
||||||
if service == "EcoMsgNew":
|
if service == "EcoMsgNew":
|
||||||
|
|
||||||
srvip = socket.gethostbyname(socket.gethostname())
|
srvip = socket.gethostbyname(socket.gethostname())
|
||||||
msgserver = {"ip":srvip,"port":5223,"result":"ok"}
|
msgserver = {"ip": srvip, "port": 5223, "result": "ok"}
|
||||||
msgserver = json.dumps(msgserver)
|
msgserver = json.dumps(msgserver)
|
||||||
msgserver = msgserver.replace(" ","") #bot seems to be very picky about having no spaces, only way was with text
|
msgserver = msgserver.replace(
|
||||||
|
" ", ""
|
||||||
|
) # bot seems to be very picky about having no spaces, only way was with text
|
||||||
|
|
||||||
confserverlog.debug(
|
confserverlog.debug(
|
||||||
"\r\n POST: {} \r\n Response: {}".format(postbody, msgserver)
|
"\r\n POST: {} \r\n Response: {}".format(postbody, msgserver)
|
||||||
)
|
)
|
||||||
return web.json_response(text=msgserver)
|
return web.json_response(text=msgserver)
|
||||||
|
|
||||||
elif service == "EcoUpdate":
|
elif service == "EcoUpdate":
|
||||||
body = {"result": "ok", "ip": "47.88.66.164", "port": 8005}
|
body = {"result": "ok", "ip": "47.88.66.164", "port": 8005}
|
||||||
|
|
||||||
confserverlog.debug(
|
confserverlog.debug(
|
||||||
"\r\n POST: {} \r\n Response: {}".format(postbody, body)
|
"\r\n POST: {} \r\n Response: {}".format(postbody, body)
|
||||||
)
|
)
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception("{}".format(e))
|
confserverlog.exception("{}".format(e))
|
||||||
|
|
@ -614,18 +616,18 @@ class ConfServer:
|
||||||
try:
|
try:
|
||||||
json_body = json.loads(await request.text())
|
json_body = json.loads(await request.text())
|
||||||
randomid = "".join(random.sample(string.ascii_letters, 6))
|
randomid = "".join(random.sample(string.ascii_letters, 6))
|
||||||
|
|
||||||
if "toId" in json_body: #Its a command
|
if "toId" in json_body: # Its a command
|
||||||
bot = bumper.bot_get(json_body["toId"])
|
bot = bumper.bot_get(json_body["toId"])
|
||||||
if bot['company'] == 'eco-ng' and bot['mqtt_connection'] == True:
|
if bot["company"] == "eco-ng" and bot["mqtt_connection"] == True:
|
||||||
retcmd = await self.helperbot.send_command(json_body, randomid)
|
retcmd = await self.helperbot.send_command(json_body, randomid)
|
||||||
body = retcmd
|
body = retcmd
|
||||||
confserverlog.debug(
|
confserverlog.debug(
|
||||||
"\r\n POST: {} \r\n Response: {}".format(json_body, body)
|
"\r\n POST: {} \r\n Response: {}".format(json_body, body)
|
||||||
)
|
)
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
else:
|
else:
|
||||||
#No response, send error back
|
# No response, send error back
|
||||||
confserverlog.error(
|
confserverlog.error(
|
||||||
"No bots with DID: {} connected to MQTT".format(
|
"No bots with DID: {} connected to MQTT".format(
|
||||||
json_body["toId"]
|
json_body["toId"]
|
||||||
|
|
@ -634,11 +636,9 @@ class ConfServer:
|
||||||
body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"}
|
body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"}
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
else:
|
else:
|
||||||
if "td" in json_body: #Seen when doing initial wifi config
|
if "td" in json_body: # Seen when doing initial wifi config
|
||||||
if json_body["td"] == "PollSCResult":
|
if json_body["td"] == "PollSCResult":
|
||||||
body = {
|
body = {"ret": "ok"}
|
||||||
"ret": "ok"
|
|
||||||
}
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,11 @@ class BumperMQTTServer_Plugin:
|
||||||
):
|
):
|
||||||
tmpbotdetail = str(didsplit[1]).split("/")
|
tmpbotdetail = str(didsplit[1]).split("/")
|
||||||
bumper.bot_add(
|
bumper.bot_add(
|
||||||
username, didsplit[0], tmpbotdetail[0], tmpbotdetail[1], "eco-ng"
|
username,
|
||||||
|
didsplit[0],
|
||||||
|
tmpbotdetail[0],
|
||||||
|
tmpbotdetail[1],
|
||||||
|
"eco-ng",
|
||||||
)
|
)
|
||||||
mqttserverlog.debug(
|
mqttserverlog.debug(
|
||||||
"new bot authenticated SN: {} DID: {}".format(
|
"new bot authenticated SN: {} DID: {}".format(
|
||||||
|
|
@ -379,14 +383,14 @@ class BumperMQTTServer_Plugin:
|
||||||
|
|
||||||
bot = bumper.bot_get(didsplit[0])
|
bot = bumper.bot_get(didsplit[0])
|
||||||
if bot:
|
if bot:
|
||||||
bumper.bot_set_mqtt(bot['did'], True)
|
bumper.bot_set_mqtt(bot["did"], True)
|
||||||
return
|
return
|
||||||
|
|
||||||
clientuserid = didsplit[0]
|
clientuserid = didsplit[0]
|
||||||
clientresource = didsplit[1].split("/")[1]
|
clientresource = didsplit[1].split("/")[1]
|
||||||
client = bumper.client_get(clientresource)
|
client = bumper.client_get(clientresource)
|
||||||
if client:
|
if client:
|
||||||
bumper.client_set_mqtt(client['resource'], True)
|
bumper.client_set_mqtt(client["resource"], True)
|
||||||
return
|
return
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -398,13 +402,13 @@ class BumperMQTTServer_Plugin:
|
||||||
|
|
||||||
bot = bumper.bot_get(didsplit[0])
|
bot = bumper.bot_get(didsplit[0])
|
||||||
if bot:
|
if bot:
|
||||||
bumper.bot_set_mqtt(bot['did'], False)
|
bumper.bot_set_mqtt(bot["did"], False)
|
||||||
|
|
||||||
clientuserid = didsplit[0]
|
clientuserid = didsplit[0]
|
||||||
clientresource = didsplit[1].split("/")[1]
|
clientresource = didsplit[1].split("/")[1]
|
||||||
client = bumper.client_get(clientresource)
|
client = bumper.client_get(clientresource)
|
||||||
if client:
|
if client:
|
||||||
bumper.client_set_mqtt(client['resource'], False)
|
bumper.client_set_mqtt(client["resource"], False)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
mqttserverlog.exception("{}".format(e))
|
mqttserverlog.exception("{}".format(e))
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ class Client(threading.Thread):
|
||||||
|
|
||||||
except BrokenPipeError as e:
|
except BrokenPipeError as e:
|
||||||
xmppserverlog.error("{}".format(e))
|
xmppserverlog.error("{}".format(e))
|
||||||
self._set_state('DISCONNECT')
|
self._set_state("DISCONNECT")
|
||||||
|
|
||||||
except ConnectionResetError as e:
|
except ConnectionResetError as e:
|
||||||
xmppserverlog.error("{}".format(e))
|
xmppserverlog.error("{}".format(e))
|
||||||
|
|
@ -228,15 +228,15 @@ class Client(threading.Thread):
|
||||||
|
|
||||||
def _disconnect(self):
|
def _disconnect(self):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
bot = bumper.bot_get(self.uid)
|
bot = bumper.bot_get(self.uid)
|
||||||
if bot:
|
if bot:
|
||||||
bumper.bot_set_xmpp(bot['did'], False)
|
bumper.bot_set_xmpp(bot["did"], False)
|
||||||
|
|
||||||
client = bumper.client_get(self.clientresource)
|
client = bumper.client_get(self.clientresource)
|
||||||
if client:
|
if client:
|
||||||
bumper.client_set_xmpp(client['resource'], False)
|
bumper.client_set_xmpp(client["resource"], False)
|
||||||
|
|
||||||
self.connection.close()
|
self.connection.close()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -285,8 +285,7 @@ class Client(threading.Thread):
|
||||||
|
|
||||||
if xml.get("type") == "set":
|
if xml.get("type") == "set":
|
||||||
if (
|
if (
|
||||||
"com:sf" in data
|
"com:sf" in data and xml.get("to") == "rl.ecorobot.net"
|
||||||
and xml.get("to") == "rl.ecorobot.net"
|
|
||||||
): # Android bind? Not sure what this does yet.
|
): # Android bind? Not sure what this does yet.
|
||||||
self.send(
|
self.send(
|
||||||
'<iq id="{}" to="{}@{}/{}" from="rl.ecorobot.net" type="result"/>'.format(
|
'<iq id="{}" to="{}@{}/{}" from="rl.ecorobot.net" type="result"/>'.format(
|
||||||
|
|
@ -308,55 +307,64 @@ class Client(threading.Thread):
|
||||||
|
|
||||||
# forward
|
# forward
|
||||||
for client in XMPPServer.clients:
|
for client in XMPPServer.clients:
|
||||||
if client.bumper_jid != self.bumper_jid and client.state == client.READY:
|
if (
|
||||||
ctl_to = xml.get("to")
|
client.bumper_jid != self.bumper_jid
|
||||||
|
and client.state == client.READY
|
||||||
|
):
|
||||||
|
ctl_to = xml.get("to")
|
||||||
xml.attrib["from"] = "{}".format(self.bumper_jid)
|
xml.attrib["from"] = "{}".format(self.bumper_jid)
|
||||||
rxmlstring = ET.tostring(xml).decode("utf-8")
|
rxmlstring = ET.tostring(xml).decode("utf-8")
|
||||||
#clean up string to remove namespaces added by ET
|
# clean up string to remove namespaces added by ET
|
||||||
rxmlstring = rxmlstring.replace("xmlns:ns0=", "xmlns=")
|
rxmlstring = rxmlstring.replace("xmlns:ns0=", "xmlns=")
|
||||||
rxmlstring = rxmlstring.replace("ns0:", "")
|
rxmlstring = rxmlstring.replace("ns0:", "")
|
||||||
rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq")
|
rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq")
|
||||||
rxmlstring = rxmlstring.replace('<query','<query xmlns="com:ctl"')
|
rxmlstring = rxmlstring.replace("<query", '<query xmlns="com:ctl"')
|
||||||
|
|
||||||
if client.type == self.BOT:
|
if client.type == self.BOT:
|
||||||
if client.uid.lower() in ctl_to.lower():
|
if client.uid.lower() in ctl_to.lower():
|
||||||
xmppserverlog.info("Sending ctl to bot: {}".format(rxmlstring))
|
xmppserverlog.info(
|
||||||
|
"Sending ctl to bot: {}".format(rxmlstring)
|
||||||
|
)
|
||||||
client.send(rxmlstring)
|
client.send(rxmlstring)
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
xmppserverlog.exception("{}".format(e))
|
xmppserverlog.exception("{}".format(e))
|
||||||
|
|
||||||
def _handle_ping(self, xml, data):
|
def _handle_ping(self, xml, data):
|
||||||
try:
|
try:
|
||||||
if xml.get("to").find("@") == -1: #No to address
|
if xml.get("to").find("@") == -1: # No to address
|
||||||
# Ping to server - respond
|
# Ping to server - respond
|
||||||
pingresp = '<iq type="result" id="{}" from="{}" />'.format(
|
pingresp = '<iq type="result" id="{}" from="{}" />'.format(
|
||||||
xml.get("id"), xml.get("to")
|
xml.get("id"), xml.get("to")
|
||||||
)
|
)
|
||||||
#xmppserverlog.debug("Server Ping resp: {}".format(pingresp))
|
# xmppserverlog.debug("Server Ping resp: {}".format(pingresp))
|
||||||
self.send(pingresp)
|
self.send(pingresp)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pingto = xml.get("to")
|
pingto = xml.get("to")
|
||||||
pingfrom = self.bumper_jid
|
pingfrom = self.bumper_jid
|
||||||
|
|
||||||
xml.attrib["from"] = pingfrom
|
xml.attrib["from"] = pingfrom
|
||||||
pingstring = ET.tostring(xml).decode("utf-8")
|
pingstring = ET.tostring(xml).decode("utf-8")
|
||||||
#clean up string to remove namespaces added by ET
|
# clean up string to remove namespaces added by ET
|
||||||
pingstring = pingstring.replace("xmlns:ns0=", "xmlns=")
|
pingstring = pingstring.replace("xmlns:ns0=", "xmlns=")
|
||||||
pingstring = pingstring.replace("ns0:", "")
|
pingstring = pingstring.replace("ns0:", "")
|
||||||
pingstring = pingstring.replace('iq xmlns="com:ctl"', "iq")
|
pingstring = pingstring.replace('iq xmlns="com:ctl"', "iq")
|
||||||
pingstring = pingstring.replace('<query','<query xmlns="com:ctl"')
|
pingstring = pingstring.replace("<query", '<query xmlns="com:ctl"')
|
||||||
|
|
||||||
for client in XMPPServer.clients:
|
for client in XMPPServer.clients:
|
||||||
if client.bumper_jid != self.bumper_jid and client.state == client.READY:
|
if (
|
||||||
if pingto.lower() in client.bumper_jid.lower():
|
client.bumper_jid != self.bumper_jid
|
||||||
|
and client.state == client.READY
|
||||||
|
):
|
||||||
|
if pingto.lower() in client.bumper_jid.lower():
|
||||||
pingsend = '<iq type="result" id="{}" from="{}" to="{}" />'.format(
|
pingsend = '<iq type="result" id="{}" from="{}" to="{}" />'.format(
|
||||||
xml.get("id"), pingfrom, pingto
|
xml.get("id"), pingfrom, pingto
|
||||||
)
|
)
|
||||||
xmppserverlog.debug("ping from {} to {}".format(pingfrom, pingto))
|
xmppserverlog.debug(
|
||||||
client.send(pingstring)
|
"ping from {} to {}".format(pingfrom, pingto)
|
||||||
|
)
|
||||||
|
client.send(pingstring)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
xmppserverlog.exception("{}".format(e))
|
xmppserverlog.exception("{}".format(e))
|
||||||
|
|
@ -365,62 +373,82 @@ class Client(threading.Thread):
|
||||||
try:
|
try:
|
||||||
ctl_to = xml.get("to")
|
ctl_to = xml.get("to")
|
||||||
xml.attrib["from"] = self.bumper_jid
|
xml.attrib["from"] = self.bumper_jid
|
||||||
if "errno='103' error='permission denied," in data: #No permissions, usually if bot was last on Ecovac network
|
if (
|
||||||
if self.type == self.BOT:
|
"errno='103' error='permission denied," in data
|
||||||
|
): # No permissions, usually if bot was last on Ecovac network
|
||||||
|
if self.type == self.BOT:
|
||||||
xquery = xml.getchildren()
|
xquery = xml.getchildren()
|
||||||
ctl = xquery[0].getchildren()
|
ctl = xquery[0].getchildren()
|
||||||
ctlerr = ctl[0].attrib["error"]
|
ctlerr = ctl[0].attrib["error"]
|
||||||
adminuser = ctlerr.replace("permission denied, please contact ","")
|
adminuser = ctlerr.replace("permission denied, please contact ", "")
|
||||||
adminuser = adminuser.replace(" ","")
|
adminuser = adminuser.replace(" ", "")
|
||||||
if not (adminuser.startswith("fuid_") or bumper.use_auth): #if not fuid_ then its ecovacs OR ignore bumper auth
|
if not (
|
||||||
#TODO: Implement auth later, should this user have access to bot?
|
adminuser.startswith("fuid_") or bumper.use_auth
|
||||||
|
): # if not fuid_ then its ecovacs OR ignore bumper auth
|
||||||
#Add user jid to bot
|
# TODO: Implement auth later, should this user have access to bot?
|
||||||
|
|
||||||
|
# Add user jid to bot
|
||||||
newuser = ctl_to.split("/")[0]
|
newuser = ctl_to.split("/")[0]
|
||||||
adduser = '<iq type="set" id="{}" from="{}" to="{}"><query xmlns="com:ctl"><ctl td="AddUser" id="0000" jid="{}" /></query></iq>'.format(
|
adduser = '<iq type="set" id="{}" from="{}" to="{}"><query xmlns="com:ctl"><ctl td="AddUser" id="0000" jid="{}" /></query></iq>'.format(
|
||||||
uuid.uuid4(), adminuser, self.bumper_jid, newuser)
|
uuid.uuid4(), adminuser, self.bumper_jid, newuser
|
||||||
|
)
|
||||||
xmppserverlog.debug("Add User: {}".format(adduser))
|
xmppserverlog.debug("Add User: {}".format(adduser))
|
||||||
self.send(adduser)
|
self.send(adduser)
|
||||||
|
|
||||||
#Add user ACs - Manage users, settings, and clean (full access)
|
# Add user ACs - Manage users, settings, and clean (full access)
|
||||||
adduseracs = '<iq type="set" id="{}" from="{}" to="{}"><query xmlns="com:ctl"><ctl td="SetAC" id="1111" jid="{}"><acs><ac name="userman" allow="1"/><ac name="setting" allow="1"/><ac name="clean" allow="1"/></acs></ctl></query></iq>'.format(
|
adduseracs = '<iq type="set" id="{}" from="{}" to="{}"><query xmlns="com:ctl"><ctl td="SetAC" id="1111" jid="{}"><acs><ac name="userman" allow="1"/><ac name="setting" allow="1"/><ac name="clean" allow="1"/></acs></ctl></query></iq>'.format(
|
||||||
uuid.uuid4(), adminuser, self.bumper_jid, newuser)
|
uuid.uuid4(), adminuser, self.bumper_jid, newuser
|
||||||
|
)
|
||||||
xmppserverlog.debug("Add User ACs: {}".format(adduseracs))
|
xmppserverlog.debug("Add User ACs: {}".format(adduseracs))
|
||||||
self.send(adduseracs)
|
self.send(adduseracs)
|
||||||
|
|
||||||
#GetUserInfo - Just to confirm it set correctly
|
# GetUserInfo - Just to confirm it set correctly
|
||||||
self.send(
|
self.send(
|
||||||
'<iq type="set" id="{}" from="{}" to="{}"><query xmlns="com:ctl"><ctl td="GetUserInfo" id="4444" /><UserInfos/></query></iq>'.format(
|
'<iq type="set" id="{}" from="{}" to="{}"><query xmlns="com:ctl"><ctl td="GetUserInfo" id="4444" /><UserInfos/></query></iq>'.format(
|
||||||
uuid.uuid4(), adminuser, self.bumper_jid)
|
uuid.uuid4(), adminuser, self.bumper_jid
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
rxmlstring = ET.tostring(xml).decode("utf-8")
|
rxmlstring = ET.tostring(xml).decode("utf-8")
|
||||||
#clean up string to remove namespaces added by ET
|
# clean up string to remove namespaces added by ET
|
||||||
rxmlstring = rxmlstring.replace("xmlns:ns0=", "xmlns=")
|
rxmlstring = rxmlstring.replace("xmlns:ns0=", "xmlns=")
|
||||||
rxmlstring = rxmlstring.replace("ns0:", "")
|
rxmlstring = rxmlstring.replace("ns0:", "")
|
||||||
rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq")
|
rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq")
|
||||||
rxmlstring = rxmlstring.replace('<query','<query xmlns="com:ctl"')
|
rxmlstring = rxmlstring.replace("<query", '<query xmlns="com:ctl"')
|
||||||
if self.type == self.BOT:
|
if self.type == self.BOT:
|
||||||
if ctl_to == "de.ecorobot.net": #Send to all clients
|
if ctl_to == "de.ecorobot.net": # Send to all clients
|
||||||
xmppserverlog.debug("Sending to all clients because of de: {}".format(rxmlstring))
|
xmppserverlog.debug(
|
||||||
|
"Sending to all clients because of de: {}".format(
|
||||||
|
rxmlstring
|
||||||
|
)
|
||||||
|
)
|
||||||
for client in XMPPServer.clients:
|
for client in XMPPServer.clients:
|
||||||
client.send(rxmlstring)
|
client.send(rxmlstring)
|
||||||
|
|
||||||
if xml.get("to").find("@") == -1: #No to address
|
if xml.get("to").find("@") == -1: # No to address
|
||||||
ctl_to = xml.get("to")
|
ctl_to = xml.get("to")
|
||||||
else:
|
else:
|
||||||
ctl_to = "{}@ecouser.net".format(ctl_to.split("@")[0])
|
ctl_to = "{}@ecouser.net".format(ctl_to.split("@")[0])
|
||||||
|
|
||||||
for client in XMPPServer.clients:
|
|
||||||
if client.bumper_jid != self.bumper_jid and client.state == client.READY:
|
|
||||||
if not "@" in ctl_to: #No user@, send to all clients?
|
|
||||||
#TODO: Revisit later, this may be wrong
|
|
||||||
client.send(rxmlstring)
|
|
||||||
|
|
||||||
elif client.uid.lower() in ctl_to.lower(): #If client matches TO=
|
for client in XMPPServer.clients:
|
||||||
xmppserverlog.debug("Sending from {} to client {}: {}".format(self.uid, client.uid, rxmlstring))
|
if (
|
||||||
client.send(rxmlstring)
|
client.bumper_jid != self.bumper_jid
|
||||||
|
and client.state == client.READY
|
||||||
|
):
|
||||||
|
if not "@" in ctl_to: # No user@, send to all clients?
|
||||||
|
# TODO: Revisit later, this may be wrong
|
||||||
|
client.send(rxmlstring)
|
||||||
|
|
||||||
|
elif (
|
||||||
|
client.uid.lower() in ctl_to.lower()
|
||||||
|
): # If client matches TO=
|
||||||
|
xmppserverlog.debug(
|
||||||
|
"Sending from {} to client {}: {}".format(
|
||||||
|
self.uid, client.uid, rxmlstring
|
||||||
|
)
|
||||||
|
)
|
||||||
|
client.send(rxmlstring)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
xmppserverlog.exception("{}".format(e))
|
xmppserverlog.exception("{}".format(e))
|
||||||
|
|
@ -434,8 +462,8 @@ class Client(threading.Thread):
|
||||||
if data.decode("utf-8").find("jabber:client") > -1:
|
if data.decode("utf-8").find("jabber:client") > -1:
|
||||||
sc = data.decode("utf-8").find("to=")
|
sc = data.decode("utf-8").find("to=")
|
||||||
ec = data.decode("utf-8").find(".ecorobot.net")
|
ec = data.decode("utf-8").find(".ecorobot.net")
|
||||||
if ec > -1:
|
if ec > -1:
|
||||||
self.devclass = data.decode("utf-8")[sc+4:ec]
|
self.devclass = data.decode("utf-8")[sc + 4 : ec]
|
||||||
# ack jabbr:client
|
# ack jabbr:client
|
||||||
# no STARTTLS
|
# no STARTTLS
|
||||||
self.send(
|
self.send(
|
||||||
|
|
@ -454,12 +482,14 @@ class Client(threading.Thread):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.send("</stream>")
|
self.send("</stream>")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if "jabber:iq:auth" in xml.tag: # Handle iq-auth
|
if "jabber:iq:auth" in xml.tag: # Handle iq-auth
|
||||||
self._handle_iq_auth(xml)
|
self._handle_iq_auth(xml)
|
||||||
elif "urn:ietf:params:xml:ns:xmpp-sasl" in xml.tag: #Handle SASL Auth
|
elif (
|
||||||
self._handle_sasl_auth(xml)
|
"urn:ietf:params:xml:ns:xmpp-sasl" in xml.tag
|
||||||
|
): # Handle SASL Auth
|
||||||
|
self._handle_sasl_auth(xml)
|
||||||
else:
|
else:
|
||||||
xmppserverlog.error("Couldn't handle: {}".format(xml))
|
xmppserverlog.error("Couldn't handle: {}".format(xml))
|
||||||
|
|
||||||
|
|
@ -479,19 +509,17 @@ class Client(threading.Thread):
|
||||||
'<stream:features><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></stream:features>'
|
'<stream:features><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></stream:features>'
|
||||||
)
|
)
|
||||||
|
|
||||||
else: # Handle init bind
|
else: # Handle init bind
|
||||||
if len(xml):
|
if len(xml):
|
||||||
child = self._tag_strip_uri(xml[0].tag)
|
child = self._tag_strip_uri(xml[0].tag)
|
||||||
else:
|
else:
|
||||||
child = None
|
child = None
|
||||||
|
|
||||||
if xml.tag == "iq":
|
if xml.tag == "iq":
|
||||||
if child == "bind":
|
if child == "bind":
|
||||||
self._handle_bind(xml)
|
self._handle_bind(xml)
|
||||||
else:
|
else:
|
||||||
xmppserverlog.error("Couldn't handle: {}".format(xml))
|
xmppserverlog.error("Couldn't handle: {}".format(xml))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
xmppserverlog.exception("{}".format(e))
|
xmppserverlog.exception("{}".format(e))
|
||||||
|
|
@ -575,9 +603,7 @@ class Client(threading.Thread):
|
||||||
except ET.ParseError as e:
|
except ET.ParseError as e:
|
||||||
if "no element found" in e.msg:
|
if "no element found" in e.msg:
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
"xml parse error - {} - {}".format(
|
"xml parse error - {} - {}".format(data.decode("utf-8"), e)
|
||||||
data.decode("utf-8"), e
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
elif "not well-formed (invalid token)" in e.msg:
|
elif "not well-formed (invalid token)" in e.msg:
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
|
|
@ -592,9 +618,9 @@ class Client(threading.Thread):
|
||||||
xmppserverlog.exception("{}".format(e))
|
xmppserverlog.exception("{}".format(e))
|
||||||
|
|
||||||
def _handle_sasl_auth(self, xml):
|
def _handle_sasl_auth(self, xml):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
saslauth = base64.b64decode(xml.text).decode("utf-8").split("/")
|
saslauth = base64.b64decode(xml.text).decode("utf-8").split("/")
|
||||||
username = saslauth[0]
|
username = saslauth[0]
|
||||||
username = saslauth[0].split("\x00")[1]
|
username = saslauth[0].split("\x00")[1]
|
||||||
self.uid = username
|
self.uid = username
|
||||||
|
|
@ -604,13 +630,13 @@ class Client(threading.Thread):
|
||||||
elif len(saslauth[0].split("\x00")) > 2:
|
elif len(saslauth[0].split("\x00")) > 2:
|
||||||
resource = saslauth[0].split("\x00")[2]
|
resource = saslauth[0].split("\x00")[2]
|
||||||
self.clientresource = resource
|
self.clientresource = resource
|
||||||
|
|
||||||
if len(saslauth) > 2:
|
if len(saslauth) > 2:
|
||||||
authcode = saslauth[2]
|
authcode = saslauth[2]
|
||||||
|
|
||||||
if not self.uid.startswith("fuid"):
|
if not self.uid.startswith("fuid"):
|
||||||
# Need sample data to see details here
|
# Need sample data to see details here
|
||||||
bumper.bot_add(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
|
self.type = self.BOT
|
||||||
xmppserverlog.info("bot authenticated {}".format(self.uid))
|
xmppserverlog.info("bot authenticated {}".format(self.uid))
|
||||||
# Send response
|
# Send response
|
||||||
|
|
@ -654,20 +680,22 @@ class Client(threading.Thread):
|
||||||
try:
|
try:
|
||||||
bumper_bots = self.bumper_bots.get()
|
bumper_bots = self.bumper_bots.get()
|
||||||
bumper_clients = self.bumper_clients.get()
|
bumper_clients = self.bumper_clients.get()
|
||||||
|
|
||||||
bot = bumper.bot_get(self.uid)
|
bot = bumper.bot_get(self.uid)
|
||||||
if bot:
|
if bot:
|
||||||
bumper.bot_set_xmpp(bot['did'], True)
|
bumper.bot_set_xmpp(bot["did"], True)
|
||||||
|
|
||||||
client = bumper.client_get(self.clientresource)
|
client = bumper.client_get(self.clientresource)
|
||||||
if client:
|
if client:
|
||||||
bumper.client_set_xmpp(client['resource'], True)
|
bumper.client_set_xmpp(client["resource"], True)
|
||||||
|
|
||||||
clientbindxml = xml.getchildren()
|
clientbindxml = xml.getchildren()
|
||||||
clientresourcexml = clientbindxml[0].getchildren()
|
clientresourcexml = clientbindxml[0].getchildren()
|
||||||
if self.devclass: #its a bot
|
if self.devclass: # its a bot
|
||||||
self.name = "XMPP_Client_{}_{}".format(self.uid,self.devclass)
|
self.name = "XMPP_Client_{}_{}".format(self.uid, self.devclass)
|
||||||
self.bumper_jid = "{}@{}.ecorobot.net/atom".format(self.uid, self.devclass)
|
self.bumper_jid = "{}@{}.ecorobot.net/atom".format(
|
||||||
|
self.uid, self.devclass
|
||||||
|
)
|
||||||
xmppserverlog.debug("new bot {}".format(self.uid))
|
xmppserverlog.debug("new bot {}".format(self.uid))
|
||||||
res = '<iq type="result" id="{}"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>{}</jid></bind></iq>'.format(
|
res = '<iq type="result" id="{}"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>{}</jid></bind></iq>'.format(
|
||||||
xml.get("id"), self.bumper_jid
|
xml.get("id"), self.bumper_jid
|
||||||
|
|
@ -675,7 +703,9 @@ class Client(threading.Thread):
|
||||||
elif len(clientresourcexml) > 0:
|
elif len(clientresourcexml) > 0:
|
||||||
self.clientresource = clientresourcexml[0].text
|
self.clientresource = clientresourcexml[0].text
|
||||||
self.name = "XMPP_Client_{}".format(self.clientresource)
|
self.name = "XMPP_Client_{}".format(self.clientresource)
|
||||||
self.bumper_jid = "{}@{}/{}".format(self.uid, XMPPServer.server_id, self.clientresource)
|
self.bumper_jid = "{}@{}/{}".format(
|
||||||
|
self.uid, XMPPServer.server_id, self.clientresource
|
||||||
|
)
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
"new client {} using resource {}".format(
|
"new client {} using resource {}".format(
|
||||||
self.uid, self.clientresource
|
self.uid, self.clientresource
|
||||||
|
|
@ -684,8 +714,8 @@ class Client(threading.Thread):
|
||||||
res = '<iq type="result" id="{}"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>{}</jid></bind></iq>'.format(
|
res = '<iq type="result" id="{}"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>{}</jid></bind></iq>'.format(
|
||||||
xml.get("id"), self.bumper_jid
|
xml.get("id"), self.bumper_jid
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.name = "XMPP_Client_{}_{}".format(self.uid,self.address)
|
self.name = "XMPP_Client_{}_{}".format(self.uid, self.address)
|
||||||
self.bumper_jid = "{}@{}".format(self.uid, XMPPServer.server_id)
|
self.bumper_jid = "{}@{}".format(self.uid, XMPPServer.server_id)
|
||||||
xmppserverlog.debug("new client {}".format(self.uid))
|
xmppserverlog.debug("new client {}".format(self.uid))
|
||||||
res = '<iq type="result" id="{}"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>{}</jid></bind></iq>'.format(
|
res = '<iq type="result" id="{}"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>{}</jid></bind></iq>'.format(
|
||||||
|
|
@ -709,102 +739,119 @@ class Client(threading.Thread):
|
||||||
|
|
||||||
def _handle_presence(self, xml):
|
def _handle_presence(self, xml):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
if len(xml) and xml[0].tag == "status":
|
if len(xml) and xml[0].tag == "status":
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
"bot presence {} ".format(ET.tostring(xml, encoding="utf-8"))
|
"bot presence {} ".format(ET.tostring(xml, encoding="utf-8"))
|
||||||
)
|
)
|
||||||
#Most likely a bot, possibly hello world in text
|
# Most likely a bot, possibly hello world in text
|
||||||
|
|
||||||
#Send dummy return
|
# Send dummy return
|
||||||
self.send(
|
self.send(
|
||||||
'<presence to="{}"> dummy </presence>'.format(
|
'<presence to="{}"> dummy </presence>'.format(self.bumper_jid)
|
||||||
self.bumper_jid
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#If it is a BOT, send extras
|
# If it is a BOT, send extras
|
||||||
if self.type == self.BOT:
|
if self.type == self.BOT:
|
||||||
#get device info
|
# get device info
|
||||||
self.send(
|
self.send(
|
||||||
'<iq type="set" id="14" to="{}" from="{}"><query xmlns="com:ctl"><ctl td="GetDeviceInfo"/></query></iq>'.format(
|
'<iq type="set" id="14" to="{}" from="{}"><query xmlns="com:ctl"><ctl td="GetDeviceInfo"/></query></iq>'.format(
|
||||||
self.bumper_jid, XMPPServer.server_id
|
self.bumper_jid, XMPPServer.server_id
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
"client presence - {} ".format(ET.tostring(xml, encoding="utf-8"))
|
"client presence - {} ".format(ET.tostring(xml, encoding="utf-8"))
|
||||||
)
|
)
|
||||||
|
|
||||||
if xml.get("type") == "available":
|
if xml.get("type") == "available":
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
"client presence available - {} ".format(ET.tostring(xml, encoding="utf-8"))
|
"client presence available - {} ".format(
|
||||||
)
|
ET.tostring(xml, encoding="utf-8")
|
||||||
#Send dummy return
|
|
||||||
self.send(
|
|
||||||
'<presence to="{}"> dummy </presence>'.format(
|
|
||||||
self.bumper_jid
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
# Send dummy return
|
||||||
|
self.send(
|
||||||
|
'<presence to="{}"> dummy </presence>'.format(self.bumper_jid)
|
||||||
|
)
|
||||||
elif xml.get("type") == "unavailable":
|
elif xml.get("type") == "unavailable":
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
"client presence unavailable (DISCONNECT) - {} ".format(ET.tostring(xml, encoding="utf-8"))
|
"client presence unavailable (DISCONNECT) - {} ".format(
|
||||||
)
|
ET.tostring(xml, encoding="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(
|
|
||||||
'<presence to="{}"> dummy </presence>'.format(
|
|
||||||
self.bumper_jid
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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(
|
||||||
|
'<presence to="{}"> dummy </presence>'.format(self.bumper_jid)
|
||||||
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
xmppserverlog.exception("{}".format(e))
|
xmppserverlog.exception("{}".format(e))
|
||||||
|
|
||||||
def _parse_data(self, data):
|
def _parse_data(self, data):
|
||||||
|
|
||||||
|
if data.decode("utf-8").startswith(
|
||||||
|
"<?xml"
|
||||||
|
): # Strip <?xml and add artificial root
|
||||||
|
newdata = (
|
||||||
|
re.sub(r"(<\?xml[^>]+\?>)", r"<root>", data.decode("utf-8")) + "</root>"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if data.decode("utf-8").startswith("<?xml"): #Strip <?xml and add artificial root
|
|
||||||
newdata = re.sub(r"(<\?xml[^>]+\?>)", r"<root>",data.decode("utf-8")) + "</root>"
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
newdata = "<root>{}</root>".format(data.decode("utf-8")) #Add artificial root
|
newdata = "<root>{}</root>".format(
|
||||||
|
data.decode("utf-8")
|
||||||
try:
|
) # Add artificial root
|
||||||
|
|
||||||
|
try:
|
||||||
root = ET.fromstring(newdata)
|
root = ET.fromstring(newdata)
|
||||||
for item in root.iter():
|
for item in root.iter():
|
||||||
if item.tag != "root":
|
if item.tag != "root":
|
||||||
if item.tag == "iq":
|
if item.tag == "iq":
|
||||||
if self.log_incoming_data:
|
if self.log_incoming_data:
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
"from {} - {}".format(self.address, str(ET.tostring(item, encoding="utf-8").decode("utf-8")).replace("ns0:",""))
|
"from {} - {}".format(
|
||||||
)
|
self.address,
|
||||||
|
str(
|
||||||
|
ET.tostring(item, encoding="utf-8").decode(
|
||||||
|
"utf-8"
|
||||||
|
)
|
||||||
|
).replace("ns0:", ""),
|
||||||
|
)
|
||||||
|
)
|
||||||
self._handle_iq(item, newdata)
|
self._handle_iq(item, newdata)
|
||||||
item.clear()
|
item.clear()
|
||||||
|
|
||||||
elif "auth" in item.tag:
|
elif "auth" in item.tag:
|
||||||
if "urn:ietf:params:xml:ns:xmpp-sasl" in item.tag: #SASL Auth
|
if "urn:ietf:params:xml:ns:xmpp-sasl" in item.tag: # SASL Auth
|
||||||
self._handle_sasl_auth(item)
|
self._handle_sasl_auth(item)
|
||||||
item.clear()
|
item.clear()
|
||||||
|
|
||||||
elif "presence" in item.tag:
|
elif "presence" in item.tag:
|
||||||
self._handle_presence(item)
|
self._handle_presence(item)
|
||||||
item.clear()
|
item.clear()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if self.log_incoming_data:
|
if self.log_incoming_data:
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
"Unparsed Item - {}".format(str(ET.tostring(item, encoding="utf-8").decode("utf-8")).replace("ns0:",""))
|
"Unparsed Item - {}".format(
|
||||||
)
|
str(
|
||||||
|
ET.tostring(item, encoding="utf-8").decode(
|
||||||
|
"utf-8"
|
||||||
|
)
|
||||||
|
).replace("ns0:", "")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
except ET.ParseError as e:
|
except ET.ParseError as e:
|
||||||
if (
|
if (
|
||||||
"no element found" in e.msg
|
"no element found" in e.msg
|
||||||
|
|
@ -822,14 +869,12 @@ class Client(threading.Thread):
|
||||||
elif "not well-formed (invalid token)" in e.msg:
|
elif "not well-formed (invalid token)" in e.msg:
|
||||||
# If a lone </stream:stream> - client is signalling end of session/disconnect
|
# If a lone </stream:stream> - client is signalling end of session/disconnect
|
||||||
if not "</stream:stream>" in newdata:
|
if not "</stream:stream>" in newdata:
|
||||||
xmppserverlog.error(
|
xmppserverlog.error("xml parse error - {} - {}".format(newdata, e))
|
||||||
"xml parse error - {} - {}".format(newdata, e)
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
self.send("</stream:stream>") # Close stream
|
self.send("</stream:stream>") # Close stream
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if "<stream:stream" in newdata: #Handle start stream and connect
|
if "<stream:stream" in newdata: # Handle start stream and connect
|
||||||
if self.state == self.CONNECT or self.state == self.INIT:
|
if self.state == self.CONNECT or self.state == self.INIT:
|
||||||
xmppserverlog.debug(
|
xmppserverlog.debug(
|
||||||
"Handling connect data - {}".format(newdata)
|
"Handling connect data - {}".format(newdata)
|
||||||
|
|
@ -838,12 +883,11 @@ class Client(threading.Thread):
|
||||||
else:
|
else:
|
||||||
if not "</stream:stream>" in newdata:
|
if not "</stream:stream>" in newdata:
|
||||||
xmppserverlog.error(
|
xmppserverlog.error(
|
||||||
"xml parse error - {} - {}".format(newdata, e)
|
"xml parse error - {} - {}".format(newdata, e)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.send("</stream:stream>") # Close stream
|
self.send("</stream:stream>") # Close stream
|
||||||
self._set_state("DISCONNECT")
|
self._set_state("DISCONNECT")
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
xmppserverlog.exception("{}".format(e))
|
xmppserverlog.exception("{}".format(e))
|
||||||
|
|
@ -862,21 +906,21 @@ class Client(threading.Thread):
|
||||||
self._handle_session(xml)
|
self._handle_session(xml)
|
||||||
elif child == "ping":
|
elif child == "ping":
|
||||||
self._handle_ping(xml, data)
|
self._handle_ping(xml, data)
|
||||||
elif child == "query":
|
elif child == "query":
|
||||||
if self.type == self.BOT:
|
if self.type == self.BOT:
|
||||||
self._handle_result(xml, data)
|
self._handle_result(xml, data)
|
||||||
else:
|
else:
|
||||||
self._handle_ctl(xml, data)
|
self._handle_ctl(xml, data)
|
||||||
elif xml.get("type") == "result":
|
elif xml.get("type") == "result":
|
||||||
if self.type == self.BOT:
|
if self.type == self.BOT:
|
||||||
self._handle_result(xml, data)
|
self._handle_result(xml, data)
|
||||||
else:
|
else:
|
||||||
self._handle_result(xml, data)
|
self._handle_result(xml, data)
|
||||||
elif xml.get("type") == "set":
|
elif xml.get("type") == "set":
|
||||||
if self.type == self.BOT:
|
if self.type == self.BOT:
|
||||||
self._handle_result(xml, data)
|
self._handle_result(xml, data)
|
||||||
else:
|
else:
|
||||||
self._handle_result(xml, data)
|
self._handle_result(xml, data)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
xmppserverlog.exception("{}".format(e))
|
xmppserverlog.exception("{}".format(e))
|
||||||
|
|
@ -889,8 +933,8 @@ class Client(threading.Thread):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
if not self.connection._closed:
|
if not self.connection._closed:
|
||||||
try:
|
try:
|
||||||
data = self.connection.recv(4096)
|
data = self.connection.recv(4096)
|
||||||
if data != b"":
|
if data != b"":
|
||||||
self._parse_data(data)
|
self._parse_data(data)
|
||||||
except ConnectionResetError as e:
|
except ConnectionResetError as e:
|
||||||
xmppserverlog.error("{}".format(e))
|
xmppserverlog.error("{}".format(e))
|
||||||
|
|
@ -899,5 +943,3 @@ class Client(threading.Thread):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
xmppserverlog.exception("{}".format(e))
|
xmppserverlog.exception("{}".format(e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue