update gitignore and reformat files with black #13

Merged
bmartin5692 merged 2 commits from dev into master 2019-03-12 02:34:08 +01:00
8 changed files with 687 additions and 390 deletions

3
.gitignore vendored
View file

@ -1,6 +1,3 @@
__pycache__ __pycache__
.DS_Store .DS_Store
Pipfile.lock
/bumper.sublime-project
/bumper.sublime-workspace
.vscode/ .vscode/

View file

@ -9,3 +9,5 @@ aiohttp = "*"
tinydb = "*" tinydb = "*"
[dev-packages] [dev-packages]
black = "*"
nose = "*"

210
Pipfile.lock generated Normal file
View file

@ -0,0 +1,210 @@
{
"_meta": {
"hash": {
"sha256": "70717c50ea942dd109e3957a7b38923627300a7dec09c2e0754005318f210ed9"
},
"pipfile-spec": 6,
"requires": {},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
},
"default": {
"aiohttp": {
"hashes": [
"sha256:00d198585474299c9c3b4f1d5de1a576cc230d562abc5e4a0e81d71a20a6ca55",
"sha256:0155af66de8c21b8dba4992aaeeabf55503caefae00067a3b1139f86d0ec50ed",
"sha256:09654a9eca62d1bd6d64aa44db2498f60a5c1e0ac4750953fdd79d5c88955e10",
"sha256:199f1d106e2b44b6dacdf6f9245493c7d716b01d0b7fbe1959318ba4dc64d1f5",
"sha256:296f30dedc9f4b9e7a301e5cc963012264112d78a1d3094cd83ef148fdf33ca1",
"sha256:368ed312550bd663ce84dc4b032a962fcb3c7cae099dbbd48663afc305e3b939",
"sha256:40d7ea570b88db017c51392349cf99b7aefaaddd19d2c78368aeb0bddde9d390",
"sha256:629102a193162e37102c50713e2e31dc9a2fe7ac5e481da83e5bb3c0cee700aa",
"sha256:6d5ec9b8948c3d957e75ea14d41e9330e1ac3fed24ec53766c780f82805140dc",
"sha256:87331d1d6810214085a50749160196391a712a13336cd02ce1c3ea3d05bcf8d5",
"sha256:9a02a04bbe581c8605ac423ba3a74999ec9d8bce7ae37977a3d38680f5780b6d",
"sha256:9c4c83f4fa1938377da32bc2d59379025ceeee8e24b89f72fcbccd8ca22dc9bf",
"sha256:9cddaff94c0135ee627213ac6ca6d05724bfe6e7a356e5e09ec57bd3249510f6",
"sha256:a25237abf327530d9561ef751eef9511ab56fd9431023ca6f4803f1994104d72",
"sha256:a5cbd7157b0e383738b8e29d6e556fde8726823dae0e348952a61742b21aeb12",
"sha256:a97a516e02b726e089cffcde2eea0d3258450389bbac48cbe89e0f0b6e7b0366",
"sha256:acc89b29b5f4e2332d65cd1b7d10c609a75b88ef8925d487a611ca788432dfa4",
"sha256:b05bd85cc99b06740aad3629c2585bda7b83bd86e080b44ba47faf905fdf1300",
"sha256:c2bec436a2b5dafe5eaeb297c03711074d46b6eb236d002c13c42f25c4a8ce9d",
"sha256:cc619d974c8c11fe84527e4b5e1c07238799a8c29ea1c1285149170524ba9303",
"sha256:d4392defd4648badaa42b3e101080ae3313e8f4787cb517efd3f5b8157eaefd6",
"sha256:e1c3c582ee11af7f63a34a46f0448fca58e59889396ffdae1f482085061a2889"
],
"index": "pypi",
"version": "==3.5.4"
},
"async-timeout": {
"hashes": [
"sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f",
"sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"
],
"version": "==3.0.1"
},
"attrs": {
"hashes": [
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
],
"version": "==19.1.0"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"docopt": {
"hashes": [
"sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"
],
"version": "==0.6.2"
},
"hbmqtt": {
"hashes": [
"sha256:235fffa4645005536fefb9945084165d9e26cbf889b767f7d896aa929b99d49e",
"sha256:9886b1c8321d16e971376dc609b902e0c84118846642b5e09f08a4ca876a7f2a"
],
"index": "pypi",
"version": "==0.9.5"
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
],
"version": "==2.8"
},
"multidict": {
"hashes": [
"sha256:024b8129695a952ebd93373e45b5d341dbb87c17ce49637b34000093f243dd4f",
"sha256:041e9442b11409be5e4fc8b6a97e4bcead758ab1e11768d1e69160bdde18acc3",
"sha256:045b4dd0e5f6121e6f314d81759abd2c257db4634260abcfe0d3f7083c4908ef",
"sha256:047c0a04e382ef8bd74b0de01407e8d8632d7d1b4db6f2561106af812a68741b",
"sha256:068167c2d7bbeebd359665ac4fff756be5ffac9cda02375b5c5a7c4777038e73",
"sha256:148ff60e0fffa2f5fad2eb25aae7bef23d8f3b8bdaf947a65cdbe84a978092bc",
"sha256:1d1c77013a259971a72ddaa83b9f42c80a93ff12df6a4723be99d858fa30bee3",
"sha256:1d48bc124a6b7a55006d97917f695effa9725d05abe8ee78fd60d6588b8344cd",
"sha256:31dfa2fc323097f8ad7acd41aa38d7c614dd1960ac6681745b6da124093dc351",
"sha256:34f82db7f80c49f38b032c5abb605c458bac997a6c3142e0d6c130be6fb2b941",
"sha256:3d5dd8e5998fb4ace04789d1d008e2bb532de501218519d70bb672c4c5a2fc5d",
"sha256:4a6ae52bd3ee41ee0f3acf4c60ceb3f44e0e3bc52ab7da1c2b2aa6703363a3d1",
"sha256:4b02a3b2a2f01d0490dd39321c74273fed0568568ea0e7ea23e02bd1fb10a10b",
"sha256:4b843f8e1dd6a3195679d9838eb4670222e8b8d01bc36c9894d6c3538316fa0a",
"sha256:5de53a28f40ef3c4fd57aeab6b590c2c663de87a5af76136ced519923d3efbb3",
"sha256:61b2b33ede821b94fa99ce0b09c9ece049c7067a33b279f343adfe35108a4ea7",
"sha256:6a3a9b0f45fd75dc05d8e93dc21b18fc1670135ec9544d1ad4acbcf6b86781d0",
"sha256:76ad8e4c69dadbb31bad17c16baee61c0d1a4a73bed2590b741b2e1a46d3edd0",
"sha256:7ba19b777dc00194d1b473180d4ca89a054dd18de27d0ee2e42a103ec9b7d014",
"sha256:7c1b7eab7a49aa96f3db1f716f0113a8a2e93c7375dd3d5d21c4941f1405c9c5",
"sha256:7fc0eee3046041387cbace9314926aa48b681202f8897f8bff3809967a049036",
"sha256:8ccd1c5fff1aa1427100ce188557fc31f1e0a383ad8ec42c559aabd4ff08802d",
"sha256:8e08dd76de80539d613654915a2f5196dbccc67448df291e69a88712ea21e24a",
"sha256:c18498c50c59263841862ea0501da9f2b3659c00db54abfbf823a80787fde8ce",
"sha256:c49db89d602c24928e68c0d510f4fcf8989d77defd01c973d6cbe27e684833b1",
"sha256:ce20044d0317649ddbb4e54dab3c1bcc7483c78c27d3f58ab3d0c7e6bc60d26a",
"sha256:d1071414dd06ca2eafa90c85a079169bfeb0e5f57fd0b45d44c092546fcd6fd9",
"sha256:d3be11ac43ab1a3e979dac80843b42226d5d3cccd3986f2e03152720a4297cd7",
"sha256:db603a1c235d110c860d5f39988ebc8218ee028f07a7cbc056ba6424372ca31b"
],
"version": "==4.5.2"
},
"passlib": {
"hashes": [
"sha256:3d948f64138c25633613f303bcc471126eae67c04d5e3f6b7b8ce6242f8653e0",
"sha256:43526aea08fa32c6b6dbbbe9963c4c767285b78147b7437597f992812f69d280"
],
"version": "==1.7.1"
},
"pyyaml": {
"hashes": [
"sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b",
"sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf",
"sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a",
"sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3",
"sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1",
"sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1",
"sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613",
"sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04",
"sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f",
"sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537",
"sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531"
],
"version": "==3.13"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
],
"version": "==1.12.0"
},
"tinydb": {
"hashes": [
"sha256:24b3d4a9611e9953fd57caf063ede6d20abfa0886289fa251f5933082c605dca",
"sha256:54f6b52fc9bc8378ea29b60e8d93c58f0f4b580a0a3b345810fbc2375baa7655"
],
"index": "pypi",
"version": "==3.12.2"
},
"transitions": {
"hashes": [
"sha256:00bfa91b0cfe3f649731b2f28478c4314bb9e830c600b422973f1b3a704ac710",
"sha256:afe0f498cf1f3f3b0fc13562011b8895a172df8f891dbb5118923d46e78a96d7"
],
"version": "==0.6.9"
},
"websockets": {
"hashes": [
"sha256:04b42a1b57096ffa5627d6a78ea1ff7fad3bc2c0331ffc17bc32a4024da7fea0",
"sha256:08e3c3e0535befa4f0c4443824496c03ecc25062debbcf895874f8a0b4c97c9f",
"sha256:10d89d4326045bf5e15e83e9867c85d686b612822e4d8f149cf4840aab5f46e0",
"sha256:232fac8a1978fc1dead4b1c2fa27c7756750fb393eb4ac52f6bc87ba7242b2fa",
"sha256:4bf4c8097440eff22bc78ec76fe2a865a6e658b6977a504679aaf08f02c121da",
"sha256:51642ea3a00772d1e48fb0c492f0d3ae3b6474f34d20eca005a83f8c9c06c561",
"sha256:55d86102282a636e195dad68aaaf85b81d0bef449d7e2ef2ff79ac450bb25d53",
"sha256:564d2675682bd497b59907d2205031acbf7d3fadf8c763b689b9ede20300b215",
"sha256:5d13bf5197a92149dc0badcc2b699267ff65a867029f465accfca8abab95f412",
"sha256:5eda665f6789edb9b57b57a159b9c55482cbe5b046d7db458948370554b16439",
"sha256:5edb2524d4032be4564c65dc4f9d01e79fe8fad5f966e5b552f4e5164fef0885",
"sha256:79691794288bc51e2a3b8de2bc0272ca8355d0b8503077ea57c0716e840ebaef",
"sha256:7fcc8681e9981b9b511cdee7c580d5b005f3bb86b65bde2188e04a29f1d63317",
"sha256:8e447e05ec88b1b408a4c9cde85aa6f4b04f06aa874b9f0b8e8319faf51b1fee",
"sha256:90ea6b3e7787620bb295a4ae050d2811c807d65b1486749414f78cfd6fb61489",
"sha256:9e13239952694b8b831088431d15f771beace10edfcf9ef230cefea14f18508f",
"sha256:d40f081187f7b54d7a99d8a5c782eaa4edc335a057aa54c85059272ed826dc09",
"sha256:e1df1a58ed2468c7b7ce9a2f9752a32ad08eac2bcd56318625c3647c2cd2da6f",
"sha256:e98d0cec437097f09c7834a11c69d79fe6241729b23f656cfc227e93294fc242",
"sha256:f8d59627702d2ff27cb495ca1abdea8bd8d581de425c56e93bff6517134e0a9b",
"sha256:fc30cdf2e949a2225b012a7911d1d031df3d23e99b7eda7dfc982dc4a860dae9"
],
"version": "==7.0"
},
"yarl": {
"hashes": [
"sha256:024ecdc12bc02b321bc66b41327f930d1c2c543fa9a561b39861da9388ba7aa9",
"sha256:2f3010703295fbe1aec51023740871e64bb9664c789cba5a6bdf404e93f7568f",
"sha256:3890ab952d508523ef4881457c4099056546593fa05e93da84c7250516e632eb",
"sha256:3e2724eb9af5dc41648e5bb304fcf4891adc33258c6e14e2a7414ea32541e320",
"sha256:5badb97dd0abf26623a9982cd448ff12cb39b8e4c94032ccdedf22ce01a64842",
"sha256:73f447d11b530d860ca1e6b582f947688286ad16ca42256413083d13f260b7a0",
"sha256:7ab825726f2940c16d92aaec7d204cfc34ac26c0040da727cf8ba87255a33829",
"sha256:b25de84a8c20540531526dfbb0e2d2b648c13fd5dd126728c496d7c3fea33310",
"sha256:c6e341f5a6562af74ba55205dbd56d248daf1b5748ec48a0200ba227bb9e33f4",
"sha256:c9bb7c249c4432cd47e75af3864bc02d26c9594f49c82e2a28624417f0ae63b8",
"sha256:e060906c0c585565c718d1c3841747b61c5439af2211e185f6739a9412dfbde1"
],
"version": "==1.3.0"
}
},
"develop": {}
}

View file

@ -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")

View file

@ -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,11 +71,8 @@ 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()
@ -83,116 +83,139 @@ def user_add(userid):
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)) tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
if tmptoken: if tmptoken:
tokens.upsert({'authcode': authcode}, ((Query().userid == userid) & (Query().token == token))) tokens.upsert(
{"authcode": authcode},
((Query().userid == userid) & (Query().token == token)),
)
def user_revoke_authcode(userid, token, authcode): def user_revoke_authcode(userid, token, authcode):
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.upsert({'authcode': ''}, ((Query().userid == userid) & (Query().token == token))) 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):
@ -281,38 +313,47 @@ def bot_add(sn, did, devclass, resource, 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"

View file

@ -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
@ -187,19 +181,23 @@ class ConfServer:
): # 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(
countrycode, user, request.query["accessToken"]
)
else: else:
# Deactivate old tokens and authcodes # Deactivate old tokens and authcodes
bumper.user_revoke_expired_tokens(user['userid']) 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()),
@ -223,21 +221,16 @@ 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()),
@ -255,41 +248,42 @@ class ConfServer:
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 if user: # Default to user 0
tmpuser = user tmpuser = user
bumper.user_add_device(tmpuser['userid'], user_devid) bumper.user_add_device(tmpuser["userid"], user_devid)
else: else:
bumper.user_add("tmpuser") # Add a new user bumper.user_add("tmpuser") # Add a new user
tmpuser = bumper.user_get("tmpuser") tmpuser = bumper.user_get("tmpuser")
bumper.user_add_device(tmpuser['userid'], user_devid) bumper.user_add_device(tmpuser["userid"], user_devid)
for bot in bots: # Add all bots to the user for bot in bots: # Add all bots to the user
bumper.user_add_bot(tmpuser['userid'], bot['did']) bumper.user_add_bot(tmpuser["userid"], bot["did"])
if "checkLogin" in request.path: # If request was to check a token do so if "checkLogin" in request.path: # If request was to check a token do so
checkToken = self.check_token(countrycode, user, request.query["accessToken"]) 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()),
@ -315,11 +309,11 @@ class ConfServer:
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 # Deactivate old tokens and authcodes
bumper.user_revoke_token(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,
@ -340,13 +334,19 @@ class ConfServer:
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,
@ -534,9 +534,7 @@ class ConfServer:
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,13 +544,16 @@ 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"}
@ -570,7 +571,6 @@ class ConfServer:
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:
@ -592,7 +592,9 @@ class ConfServer:
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)
@ -617,7 +619,7 @@ class ConfServer:
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(
@ -636,9 +638,7 @@ class ConfServer:
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:

View file

@ -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))

View file

@ -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))
@ -231,11 +231,11 @@ class Client(threading.Thread):
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()
@ -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,7 +307,10 @@ 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 (
client.bumper_jid != self.bumper_jid
and client.state == client.READY
):
ctl_to = xml.get("to") 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")
@ -316,14 +318,15 @@ class Client(threading.Thread):
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))
@ -347,15 +350,20 @@ class Client(threading.Thread):
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 (
client.bumper_jid != self.bumper_jid
and client.state == client.READY
):
if pingto.lower() in client.bumper_jid.lower(): 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(
"ping from {} to {}".format(pingfrom, pingto)
)
client.send(pingstring) client.send(pingstring)
except Exception as e: except Exception as e:
@ -365,33 +373,40 @@ 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 (
"errno='103' error='permission denied," in data
): # No permissions, usually if bot was last on Ecovac network
if self.type == self.BOT: 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 (
adminuser.startswith("fuid_") or bumper.use_auth
): # if not fuid_ then its ecovacs OR ignore bumper auth
# TODO: Implement auth later, should this user have access to bot? # TODO: Implement auth later, should this user have access to bot?
# Add user jid 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:
@ -400,10 +415,14 @@ class Client(threading.Thread):
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)
@ -413,13 +432,22 @@ class Client(threading.Thread):
ctl_to = "{}@ecouser.net".format(ctl_to.split("@")[0]) ctl_to = "{}@ecouser.net".format(ctl_to.split("@")[0])
for client in XMPPServer.clients: for client in XMPPServer.clients:
if client.bumper_jid != self.bumper_jid and client.state == client.READY: if (
client.bumper_jid != self.bumper_jid
and client.state == client.READY
):
if not "@" in ctl_to: # No user@, send to all clients? if not "@" in ctl_to: # No user@, send to all clients?
# TODO: Revisit later, this may be wrong # TODO: Revisit later, this may be wrong
client.send(rxmlstring) client.send(rxmlstring)
elif client.uid.lower() in ctl_to.lower(): #If client matches TO= elif (
xmppserverlog.debug("Sending from {} to client {}: {}".format(self.uid, client.uid, rxmlstring)) 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) client.send(rxmlstring)
except Exception as e: except Exception as e:
@ -458,7 +486,9 @@ class Client(threading.Thread):
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 (
"urn:ietf:params:xml:ns:xmpp-sasl" in xml.tag
): # Handle SASL Auth
self._handle_sasl_auth(xml) self._handle_sasl_auth(xml)
else: else:
xmppserverlog.error("Couldn't handle: {}".format(xml)) xmppserverlog.error("Couldn't handle: {}".format(xml))
@ -491,8 +521,6 @@ class Client(threading.Thread):
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(
@ -657,17 +683,19 @@ class Client(threading.Thread):
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
@ -718,9 +748,7 @@ class Client(threading.Thread):
# 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
@ -739,44 +767,50 @@ class Client(threading.Thread):
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 # Send dummy return
self.send( self.send(
'<presence to="{}"> dummy </presence>'.format( '<presence to="{}"> dummy </presence>'.format(self.bumper_jid)
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") self._set_state("DISCONNECT")
else: else:
# Sometimes the android app sends these # Sometimes the android app sends these
xmppserverlog.debug( xmppserverlog.debug(
"client presence (UNKNOWN) - {} ".format(ET.tostring(xml, encoding="utf-8")) "client presence (UNKNOWN) - {} ".format(
ET.tostring(xml, encoding="utf-8")
)
) )
# 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
) )
)
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(
if data.decode("utf-8").startswith("<?xml"): #Strip <?xml and add artificial root "<?xml"
newdata = re.sub(r"(<\?xml[^>]+\?>)", r"<root>",data.decode("utf-8")) + "</root>" ): # 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")
) # Add artificial root
try: try:
root = ET.fromstring(newdata) root = ET.fromstring(newdata)
@ -785,7 +819,14 @@ class Client(threading.Thread):
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()
@ -802,7 +843,13 @@ class Client(threading.Thread):
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:
@ -822,9 +869,7 @@ 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
@ -844,7 +889,6 @@ class Client(threading.Thread):
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))
@ -899,5 +943,3 @@ class Client(threading.Thread):
except Exception as e: except Exception as e:
xmppserverlog.exception("{}".format(e)) xmppserverlog.exception("{}".format(e))