From 028399c496cc095315fac044bf6ab482a919626c Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Mon, 11 Mar 2019 21:25:05 -0400 Subject: [PATCH 1/2] Update gitignore, pipfile Update gitignore, pipfile --- .gitignore | 3 - Pipfile | 2 + Pipfile.lock | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 Pipfile.lock diff --git a/.gitignore b/.gitignore index fca03ff..d1ca852 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ __pycache__ .DS_Store -Pipfile.lock -/bumper.sublime-project -/bumper.sublime-workspace .vscode/ \ No newline at end of file diff --git a/Pipfile b/Pipfile index 89d3377..f854238 100644 --- a/Pipfile +++ b/Pipfile @@ -9,3 +9,5 @@ aiohttp = "*" tinydb = "*" [dev-packages] +black = "*" +nose = "*" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..eb6caf1 --- /dev/null +++ b/Pipfile.lock @@ -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": {} +} From af3e4ab1cee9d0d3e511e7783360dd094f9bd3bb Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Mon, 11 Mar 2019 21:32:55 -0400 Subject: [PATCH 2/2] reformat files with black reformat files with black --- bumper.py | 10 +- bumper/__init__.py | 288 ++++++++++++++++++++-------------- bumper/confserver.py | 184 +++++++++++----------- bumper/mqttserver.py | 14 +- bumper/xmppserver.py | 366 ++++++++++++++++++++++++------------------- 5 files changed, 475 insertions(+), 387 deletions(-) diff --git a/bumper.py b/bumper.py index bf0fbae..8ec74dc 100644 --- a/bumper.py +++ b/bumper.py @@ -52,14 +52,10 @@ def main(): bumper_clients=bumper.bumper_clients_var, ) conf_server = bumper.ConfServer( - conf_address_443, - usessl=True, - helperbot=mqtt_helperbot, + conf_address_443, usessl=True, helperbot=mqtt_helperbot ) conf_server_2 = bumper.ConfServer( - conf_address_8007, - usessl=False, - helperbot=mqtt_helperbot, + conf_address_8007, usessl=False, helperbot=mqtt_helperbot ) # add user @@ -93,7 +89,7 @@ def main(): bumper.revoke_expired_tokens() disconnected_clients = bumper.get_disconnected_xmpp_clients() for client in disconnected_clients: - xmpp_server.remove_client_byuid(client['userid']) + xmpp_server.remove_client_byuid(client["userid"]) except KeyboardInterrupt: bumper.bumperlog.info("Bumper Exiting - Keyboard Interrupt") diff --git a/bumper/__init__.py b/bumper/__init__.py index a803240..6438226 100644 --- a/bumper/__init__.py +++ b/bumper/__init__.py @@ -23,7 +23,7 @@ server_cert = "./certs/cert.pem" server_key = "./certs/key.pem" use_auth = False -token_validity_seconds = 3600 #1 hour +token_validity_seconds = 3600 # 1 hour # Logs bumperlog = logging.getLogger("bumper") @@ -44,23 +44,26 @@ xmppserverlog = logging.getLogger("xmppserver") def get_milli_time(timetoconvert): return int(round(timetoconvert * 1000)) + def db_file(): - if platform.system() == 'Windows': - return os.path.join(os.getenv('APPDATA'), 'bumper.db') + if platform.system() == "Windows": + return os.path.join(os.getenv("APPDATA"), "bumper.db") else: - return os.path.expanduser('~/.config/bumper.db') + return os.path.expanduser("~/.config/bumper.db") + 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()) - #Will create the tables if they don't exist - users_table = db.table('users') - clients_table = db.table('clients') - bots_table = db.table('bots') + # Will create the tables if they don't exist + users_table = db.table("users") + clients_table = db.table("clients") + bots_table = db.table("bots") return db + class BumperUser(object): def __init__(self, userid=""): self.userid = userid @@ -68,131 +71,151 @@ class BumperUser(object): self.bots = [] def asdict(self): - return { - "userid": self.userid, - "devices": self.devices, - "bots": self.bots, - } + return {"userid": self.userid, "devices": self.devices, "bots": self.bots} + def user_add(userid): newuser = BumperUser() - newuser.userid = userid - + newuser.userid = userid + user = user_get(userid) if not user: bumperlog.info("Adding new user with userid: {}".format(newuser.userid)) user_full_upsert(newuser.asdict()) + def user_get(userid): - users = db_get().table('users') + users = db_get().table("users") User = Query() return users.get(User.userid == userid) - + + def user_by_deviceid(deviceid): - users = db_get().table('users') + users = db_get().table("users") User = Query() return users.get(User.devices.any([deviceid])) + def user_full_upsert(user): - users = db_get().table('users') - User = Query() - users.upsert(user, User.did == user['userid']) + users = db_get().table("users") + User = Query() + users.upsert(user, User.did == user["userid"]) + def user_add_device(userid, devid): - users = db_get().table('users') - User = Query() + users = db_get().table("users") + User = Query() user = users.get(User.userid == userid) - userdevices = list(user['devices']) + userdevices = list(user["devices"]) if not devid in userdevices: userdevices.append(devid) - - users.upsert({'devices': userdevices}, User.userid == userid) + + users.upsert({"devices": userdevices}, User.userid == userid) + def user_remove_device(userid, devid): - users = db_get().table('users') - User = Query() + users = db_get().table("users") + User = Query() user = users.get(User.userid == userid) - userdevices = list(user['devices']) + userdevices = list(user["devices"]) if devid in userdevices: userdevices.remove(devid) - - users.upsert({'devices': userdevices}, User.userid == userid) + + users.upsert({"devices": userdevices}, User.userid == userid) + def user_add_bot(userid, did): - users = db_get().table('users') - User = Query() + users = db_get().table("users") + User = Query() user = users.get(User.userid == userid) - userbots = list(user['bots']) + userbots = list(user["bots"]) if not did in userbots: userbots.append(did) - - users.upsert({'bots': userbots}, User.userid == userid) + + users.upsert({"bots": userbots}, User.userid == userid) + def user_remove_bot(userid, did): - users = db_get().table('users') - User = Query() + users = db_get().table("users") + User = Query() user = users.get(User.userid == userid) - userbots = list(user['bots']) + userbots = list(user["bots"]) if did in userbots: userbots.remove(did) - - users.upsert({'bots': userbots}, User.userid == userid) - + + users.upsert({"bots": userbots}, User.userid == userid) + + def user_get_tokens(userid): - tokens = db_get().table('tokens') - return tokens.search((Query().userid == userid)) + tokens = db_get().table("tokens") + return tokens.search((Query().userid == userid)) + def user_get_token(userid, token): - tokens = db_get().table('tokens') - return tokens.get((Query().userid == userid) & (Query().token == token)) + tokens = db_get().table("tokens") + return tokens.get((Query().userid == userid) & (Query().token == token)) + def user_add_token(userid, token): - tokens = db_get().table('tokens') + tokens = db_get().table("tokens") tmptoken = tokens.get((Query().userid == userid) & (Query().token == token)) if not tmptoken: - tokens.insert({'userid':userid, 'token':token, 'expiration':"{}".format(datetime.now() + timedelta(seconds=token_validity_seconds))}) + tokens.insert( + { + "userid": userid, + "token": token, + "expiration": "{}".format( + datetime.now() + timedelta(seconds=token_validity_seconds) + ), + } + ) + def user_revoke_all_tokens(userid): - tokens = db_get().table('tokens') + tokens = db_get().table("tokens") tsearch = tokens.search(Query().userid == userid) for i in tsearch: tokens.remove(doc_ids=[i.doc_id]) + def user_revoke_expired_tokens(userid): - tokens = db_get().table('tokens') + tokens = db_get().table("tokens") tsearch = tokens.search(Query().userid == userid) for i in tsearch: - if datetime.now() >= datetime.fromisoformat(i['expiration']): - bumperlog.debug("Removing token {} due to expiration".format(i['token'])) - tokens.remove(doc_ids=[i.doc_id]) + if datetime.now() >= datetime.fromisoformat(i["expiration"]): + bumperlog.debug("Removing token {} due to expiration".format(i["token"])) + tokens.remove(doc_ids=[i.doc_id]) + def user_revoke_token(userid, token): - tokens = db_get().table('tokens') + tokens = db_get().table("tokens") tmptoken = tokens.get((Query().userid == userid) & (Query().token == token)) if tmptoken: - tokens.remove(doc_ids=[tmptoken.doc_id]) + tokens.remove(doc_ids=[tmptoken.doc_id]) + def user_add_authcode(userid, token, authcode): - tokens = db_get().table('tokens') - tmptoken = tokens.get((Query().userid == userid) & (Query().token == token)) - if tmptoken: - tokens.upsert({'authcode': authcode}, ((Query().userid == userid) & (Query().token == token))) - -def user_revoke_authcode(userid, token, authcode): - tokens = db_get().table('tokens') + 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))) + tokens.upsert( + {"authcode": authcode}, + ((Query().userid == userid) & (Query().token == token)), + ) + + +def user_revoke_authcode(userid, token, authcode): + tokens = db_get().table("tokens") + tmptoken = tokens.get((Query().userid == userid) & (Query().token == token)) + if tmptoken: + tokens.upsert( + {"authcode": ""}, ((Query().userid == userid) & (Query().token == token)) + ) + class VacBotDevice(object): def __init__( - self, - did="", - vac_bot_device_class="", - resource="", - name="", - nick="", - company="", + self, did="", vac_bot_device_class="", resource="", name="", nick="", company="" ): self.vac_bot_device_class = vac_bot_device_class self.company = company @@ -212,7 +235,7 @@ class VacBotDevice(object): "nick": self.nick, "resource": self.resource, "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, "resource": self.resource, "mqtt_connection": self.mqtt_connection, - "xmpp_connection": self.xmpp_connection - } + "xmpp_connection": self.xmpp_connection, + } + def get_disconnected_xmpp_clients(): - clients = db_get().table('clients') + clients = db_get().table("clients") Client = Query() - return clients.search(Client.xmpp_connection == False) - + return clients.search(Client.xmpp_connection == False) + def check_authcode(uid, authcode): bumperlog.debug("Checking for authcode: {}".format(authcode)) - tokens = db_get().table('tokens') + tokens = db_get().table("tokens") tmpauth = tokens.get( - (Query().authcode == authcode) & #Match authcode - ((Query().userid == uid.replace("fuid_","")) | (Query().userid == "fuid_{}".format(uid))) #Userid with or without fuid_ - ) + (Query().authcode == authcode) + & ( # Match authcode + (Query().userid == uid.replace("fuid_", "")) + | (Query().userid == "fuid_{}".format(uid)) + ) # Userid with or without fuid_ + ) if tmpauth: return True - - return False + + return False + def check_token(uid, token): bumperlog.debug("Checking for token: {}".format(token)) - tokens = db_get().table('tokens') + tokens = db_get().table("tokens") tmpauth = tokens.get( - (Query().token == token) & #Match token - ((Query().userid == uid.replace("fuid_","")) | (Query().userid == "fuid_{}".format(uid))) #Userid with or without fuid_ - ) + (Query().token == token) + & ( # Match token + (Query().userid == uid.replace("fuid_", "")) + | (Query().userid == "fuid_{}".format(uid)) + ) # Userid with or without fuid_ + ) if tmpauth: return True - - return False + + return False + def revoke_expired_tokens(): - tokens = db_get().table('tokens').all() - for i in tokens: - if datetime.now() >= datetime.fromisoformat(i['expiration']): - bumperlog.debug("Removing token {} due to expiration".format(i['token'])) - db_get().table('tokens').remove(doc_ids=[i.doc_id]) + tokens = db_get().table("tokens").all() + for i in tokens: + if datetime.now() >= datetime.fromisoformat(i["expiration"]): + bumperlog.debug("Removing token {} due to expiration".format(i["token"])) + db_get().table("tokens").remove(doc_ids=[i.doc_id]) def 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.resource = resource newbot.company = company - + bot = bot_get(did) if not bot: - bumperlog.info("Adding new bot with SN: {} DID: {}".format(newbot.name, newbot.did)) + bumperlog.info( + "Adding new bot with SN: {} DID: {}".format(newbot.name, newbot.did) + ) bot_full_upsert(newbot.asdict()) + def bot_remove(did): - bots = db_get().table('bots') + bots = db_get().table("bots") bot = bot_get(did) bots.remove(doc_ids=[bot.doc_id]) - + + def bot_get(did): - bots = db_get().table('bots') + bots = db_get().table("bots") Bot = Query() return bots.get(Bot.did == did) + def bot_full_upsert(vacbot): - bots = db_get().table('bots') - Bot = Query() - bots.upsert(vacbot, Bot.did == vacbot['did']) + bots = db_get().table("bots") + Bot = Query() + bots.upsert(vacbot, Bot.did == vacbot["did"]) + def bot_set_nick(did, nick): - bots = db_get().table('bots') - Bot = Query() - bots.upsert({'nick': nick}, Bot.did == did) + bots = db_get().table("bots") + Bot = Query() + bots.upsert({"nick": nick}, Bot.did == did) + def bot_set_mqtt(did, mqtt): - bots = db_get().table('bots') - Bot = Query() - bots.upsert({'mqtt_connection': mqtt}, Bot.did == did) + bots = db_get().table("bots") + Bot = Query() + bots.upsert({"mqtt_connection": mqtt}, Bot.did == did) + def bot_set_xmpp(did, xmpp): - bots = db_get().table('bots') - Bot = Query() - bots.upsert({'xmpp_connection': xmpp}, Bot.did == did) + bots = db_get().table("bots") + Bot = Query() + bots.upsert({"xmpp_connection": xmpp}, Bot.did == did) + def client_add(userid, realm, resource): newclient = VacBotClient() @@ -325,25 +366,30 @@ def client_add(userid, realm, resource): bumperlog.info("Adding new client with resource {}".format(newclient.resource)) client_full_upsert(newclient.asdict()) + def client_get(resource): - clients = db_get().table('clients') + clients = db_get().table("clients") Client = Query() return clients.get(Client.resource == resource) + def client_full_upsert(client): - clients = db_get().table('clients') - Client = Query() - clients.upsert(client, Client.resource == client['resource']) + clients = db_get().table("clients") + Client = Query() + clients.upsert(client, Client.resource == client["resource"]) + def client_set_mqtt(resource, mqtt): - clients = db_get().table('clients') - Client = Query() - clients.upsert({'mqtt_connection': mqtt}, Client.resource == resource) + clients = db_get().table("clients") + Client = Query() + clients.upsert({"mqtt_connection": mqtt}, Client.resource == resource) + def client_set_xmpp(resource, xmpp): - clients = db_get().table('clients') - Client = Query() - clients.upsert({'xmpp_connection': xmpp}, Client.resource == resource) + clients = db_get().table("clients") + Client = Query() + clients.upsert({"xmpp_connection": xmpp}, Client.resource == resource) + RETURN_API_SUCCESS = "0000" ERR_ACTIVATE_TOKEN_TIMEOUT = "1006" diff --git a/bumper/confserver.py b/bumper/confserver.py index bc327fa..0125a2a 100644 --- a/bumper/confserver.py +++ b/bumper/confserver.py @@ -37,13 +37,7 @@ logging.getLogger("aiohttp.access").addFilter(aiohttp_filter()) class ConfServer: - - def __init__( - self, - address, - usessl=False, - helperbot=None, - ): + def __init__(self, address, usessl=False, helperbot=None): self.helperbot = helperbot self.usessl = usessl self.address = address @@ -166,7 +160,7 @@ class ConfServer: async def handle_base(self, request): 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!" return web.json_response(text) @@ -186,25 +180,29 @@ class ConfServer: not user_devid == "" ): # Performing basic "auth" using devid, super insecure user = bumper.user_by_deviceid(user_devid) - if "checkLogin" in request.path: - self.check_token(countrycode, user, request.query["accessToken"]) - else: - #Deactivate old tokens and authcodes - bumper.user_revoke_expired_tokens(user['userid']) - + if "checkLogin" in request.path: + self.check_token( + countrycode, user, request.query["accessToken"] + ) + else: + # Deactivate old tokens and authcodes + bumper.user_revoke_expired_tokens(user["userid"]) + body = { "code": bumper.RETURN_API_SUCCESS, "data": { - "accessToken": self.generate_token(user), # generate a new token + "accessToken": self.generate_token( + user + ), # generate a new token "country": countrycode, "email": "null@null.com", - "uid": "fuid_{}".format(user['userid']), - "username": "fusername_{}".format(user['userid']), + "uid": "fuid_{}".format(user["userid"]), + "username": "fusername_{}".format(user["userid"]), }, "msg": "操作成功", "time": bumper.get_milli_time(time.time()), } - return web.json_response(body) + return web.json_response(body) body = { "code": bumper.ERR_USER_NOT_ACTIVATED, @@ -214,7 +212,7 @@ class ConfServer: } return web.json_response(body) - + else: return web.json_response( self._auth_any(user_devid, countrycode, request) @@ -223,27 +221,22 @@ class ConfServer: except Exception as e: confserverlog.exception("{}".format(e)) - def check_token(self, countrycode, user, token): - if ( - bumper.check_token(user['userid'], token) - ): + if bumper.check_token(user["userid"], token): body = { "code": bumper.RETURN_API_SUCCESS, "data": { "accessToken": token, "country": countrycode, "email": "null@null.com", - "uid": "fuid_{}".format(user['userid']), - "username": "fusername_{}".format( - user['userid'] - ), + "uid": "fuid_{}".format(user["userid"]), + "username": "fusername_{}".format(user["userid"]), }, "msg": "操作成功", "time": bumper.get_milli_time(time.time()), } return web.json_response(body) - + else: body = { "code": bumper.ERR_TOKEN_INVALID, @@ -251,45 +244,46 @@ class ConfServer: "msg": "当前密码错误", "time": bumper.get_milli_time(time.time()), } - return web.json_response(body) + return web.json_response(body) def generate_token(self, user): tmpaccesstoken = uuid.uuid4().hex - bumper.user_add_token(user['userid'],tmpaccesstoken) + bumper.user_add_token(user["userid"], tmpaccesstoken) return tmpaccesstoken def generate_authcode(self, user, countrycode, token): tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex) - bumper.user_add_authcode(user['userid'], token, tmpauthcode) + bumper.user_add_authcode(user["userid"], token, tmpauthcode) return tmpauthcode - def _auth_any(self, devid, country, request): try: user_devid = devid countrycode = country user = bumper.user_by_deviceid(user_devid) - bots = bumper.db_get().table('bots').all() - - if user: #Default to user 0 - tmpuser = user - bumper.user_add_device(tmpuser['userid'], user_devid) - else: - bumper.user_add("tmpuser") #Add a new user - tmpuser = bumper.user_get("tmpuser") - bumper.user_add_device(tmpuser['userid'], user_devid) + bots = bumper.db_get().table("bots").all() - 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"]) + 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 + bumper.user_add_bot(tmpuser["userid"], bot["did"]) + + if "checkLogin" in request.path: # If request was to check a token do so + checkToken = self.check_token( + countrycode, user, request.query["accessToken"] + ) isGood = json.loads(checkToken.text) - if isGood['code'] == "0000": + if isGood["code"] == "0000": return isGood - - #Deactivate old tokens and authcodes - bumper.user_revoke_expired_tokens(tmpuser['userid']) + + # Deactivate old tokens and authcodes + bumper.user_revoke_expired_tokens(tmpuser["userid"]) body = { "code": bumper.RETURN_API_SUCCESS, @@ -297,8 +291,8 @@ class ConfServer: "accessToken": self.generate_token(tmpuser), # Generate a token "country": countrycode, "email": "null@null.com", - "uid": "fuid_{}".format(tmpuser['userid']), - "username": "fusername_{}".format(tmpuser['userid']), + "uid": "fuid_{}".format(tmpuser["userid"]), + "username": "fusername_{}".format(tmpuser["userid"]), }, "msg": "操作成功", "time": bumper.get_milli_time(time.time()), @@ -314,12 +308,12 @@ class ConfServer: user_devid = request.match_info.get("devid", "") if not user_devid == "": user = bumper.user_by_deviceid(user_devid) - if user: - if ( - bumper.check_token(user['userid'], request.query["accessToken"]) - ): - #Deactivate old tokens and authcodes - bumper.user_revoke_token(user['userid'], request.query["accessToken"]) + if user: + if bumper.check_token(user["userid"], request.query["accessToken"]): + # Deactivate old tokens and authcodes + bumper.user_revoke_token( + user["userid"], request.query["accessToken"] + ) body = { "code": bumper.RETURN_API_SUCCESS, @@ -338,16 +332,22 @@ class ConfServer: user_devid = request.match_info.get("devid", "") if not user_devid == "": - user = bumper.user_by_deviceid(user_devid) + user = bumper.user_by_deviceid(user_devid) if user: - token = bumper.user_get_token(user['userid'], request.query["accessToken"]) + token = bumper.user_get_token( + user["userid"], request.query["accessToken"] + ) if token: authcode = "" - if not 'authcode' in token: - authcode = self.generate_authcode(user, request.match_info.get("country", "us"), request.query["accessToken"]) + if not "authcode" in token: + authcode = self.generate_authcode( + user, + request.match_info.get("country", "us"), + request.query["accessToken"], + ) else: - authcode = token['authcode'] - + authcode = token["authcode"] + body = { "code": bumper.RETURN_API_SUCCESS, "data": { @@ -532,11 +532,9 @@ class ConfServer: } elif service == "EcoUpdate": body = {"result": "ok", "ip": "47.88.66.164", "port": 8005} - + elif todo == "loginByItToken": - if ( - bumper.check_authcode(postbody["userId"], postbody["token"]) - ): + if bumper.check_authcode(postbody["userId"], postbody["token"]): body = { "resource": postbody["resource"], "result": "ok", @@ -546,30 +544,32 @@ class ConfServer: } 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": bumper.bot_set_nick(postbody["did"], postbody["nick"]) body = {"result": "ok", "todo": "result"} - elif todo == "AddOneDevice": bumper.bot_set_nick(postbody["did"], postbody["nick"]) body = {"result": "ok", "todo": "result"} elif todo == "DeleteOneDevice": - bumper.bot_remove(postbody["did"]) - body = {"result": "ok", "todo": "result"} + bumper.bot_remove(postbody["did"]) + body = {"result": "ok", "todo": "result"} confserverlog.debug( "\r\n POST: {} \r\n Response: {}".format(postbody, body) ) - + return web.json_response(body) except Exception as e: confserverlog.exception("{}".format(e)) - async def handle_lookup(self, request): try: @@ -588,24 +588,26 @@ class ConfServer: if todo == "FindBest": service = postbody["service"] if service == "EcoMsgNew": - - srvip = socket.gethostbyname(socket.gethostname()) - msgserver = {"ip":srvip,"port":5223,"result":"ok"} + + srvip = socket.gethostbyname(socket.gethostname()) + msgserver = {"ip": srvip, "port": 5223, "result": "ok"} 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( "\r\n POST: {} \r\n Response: {}".format(postbody, msgserver) - ) + ) return web.json_response(text=msgserver) - + elif service == "EcoUpdate": body = {"result": "ok", "ip": "47.88.66.164", "port": 8005} confserverlog.debug( "\r\n POST: {} \r\n Response: {}".format(postbody, body) ) - return web.json_response(body) + return web.json_response(body) except Exception as e: confserverlog.exception("{}".format(e)) @@ -614,18 +616,18 @@ class ConfServer: try: json_body = json.loads(await request.text()) 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"]) - 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) body = retcmd confserverlog.debug( "\r\n POST: {} \r\n Response: {}".format(json_body, body) ) - return web.json_response(body) - else: - #No response, send error back + return web.json_response(body) + else: + # No response, send error back confserverlog.error( "No bots with DID: {} connected to MQTT".format( json_body["toId"] @@ -634,11 +636,9 @@ class ConfServer: body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} return web.json_response(body) else: - if "td" in json_body: #Seen when doing initial wifi config + if "td" in json_body: # Seen when doing initial wifi config if json_body["td"] == "PollSCResult": - body = { - "ret": "ok" - } + body = {"ret": "ok"} return web.json_response(body) except Exception as e: diff --git a/bumper/mqttserver.py b/bumper/mqttserver.py index 7ee850c..8f61a66 100644 --- a/bumper/mqttserver.py +++ b/bumper/mqttserver.py @@ -333,7 +333,11 @@ class BumperMQTTServer_Plugin: ): tmpbotdetail = str(didsplit[1]).split("/") bumper.bot_add( - username, didsplit[0], tmpbotdetail[0], tmpbotdetail[1], "eco-ng" + username, + didsplit[0], + tmpbotdetail[0], + tmpbotdetail[1], + "eco-ng", ) mqttserverlog.debug( "new bot authenticated SN: {} DID: {}".format( @@ -379,14 +383,14 @@ class BumperMQTTServer_Plugin: bot = bumper.bot_get(didsplit[0]) if bot: - bumper.bot_set_mqtt(bot['did'], True) + bumper.bot_set_mqtt(bot["did"], True) return clientuserid = didsplit[0] clientresource = didsplit[1].split("/")[1] client = bumper.client_get(clientresource) if client: - bumper.client_set_mqtt(client['resource'], True) + bumper.client_set_mqtt(client["resource"], True) return except Exception as e: @@ -398,13 +402,13 @@ class BumperMQTTServer_Plugin: bot = bumper.bot_get(didsplit[0]) if bot: - bumper.bot_set_mqtt(bot['did'], False) + bumper.bot_set_mqtt(bot["did"], False) clientuserid = didsplit[0] clientresource = didsplit[1].split("/")[1] client = bumper.client_get(clientresource) if client: - bumper.client_set_mqtt(client['resource'], False) + bumper.client_set_mqtt(client["resource"], False) except Exception as e: mqttserverlog.exception("{}".format(e)) diff --git a/bumper/xmppserver.py b/bumper/xmppserver.py index a9021ef..add4781 100644 --- a/bumper/xmppserver.py +++ b/bumper/xmppserver.py @@ -217,7 +217,7 @@ class Client(threading.Thread): except BrokenPipeError as e: xmppserverlog.error("{}".format(e)) - self._set_state('DISCONNECT') + self._set_state("DISCONNECT") except ConnectionResetError as e: xmppserverlog.error("{}".format(e)) @@ -228,15 +228,15 @@ class Client(threading.Thread): def _disconnect(self): try: - + bot = bumper.bot_get(self.uid) if bot: - bumper.bot_set_xmpp(bot['did'], False) + bumper.bot_set_xmpp(bot["did"], False) client = bumper.client_get(self.clientresource) if client: - bumper.client_set_xmpp(client['resource'], False) - + bumper.client_set_xmpp(client["resource"], False) + self.connection.close() except Exception as e: @@ -285,8 +285,7 @@ class Client(threading.Thread): if xml.get("type") == "set": if ( - "com:sf" in data - and xml.get("to") == "rl.ecorobot.net" + "com:sf" in data and xml.get("to") == "rl.ecorobot.net" ): # Android bind? Not sure what this does yet. self.send( ''.format( @@ -308,55 +307,64 @@ class Client(threading.Thread): # forward for client in XMPPServer.clients: - if client.bumper_jid != self.bumper_jid and client.state == client.READY: - ctl_to = xml.get("to") + if ( + client.bumper_jid != self.bumper_jid + and client.state == client.READY + ): + ctl_to = xml.get("to") xml.attrib["from"] = "{}".format(self.bumper_jid) 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("ns0:", "") rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq") - rxmlstring = rxmlstring.replace(''.format( - uuid.uuid4(), adminuser, self.bumper_jid, newuser) + uuid.uuid4(), adminuser, self.bumper_jid, newuser + ) xmppserverlog.debug("Add User: {}".format(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 = ''.format( - uuid.uuid4(), adminuser, self.bumper_jid, newuser) + uuid.uuid4(), adminuser, self.bumper_jid, newuser + ) xmppserverlog.debug("Add User ACs: {}".format(adduseracs)) self.send(adduseracs) - #GetUserInfo - Just to confirm it set correctly - self.send( + # GetUserInfo - Just to confirm it set correctly + self.send( ''.format( - uuid.uuid4(), adminuser, self.bumper_jid) + uuid.uuid4(), adminuser, self.bumper_jid + ) ) - - else: + + else: 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("ns0:", "") rxmlstring = rxmlstring.replace('iq xmlns="com:ctl"', "iq") - rxmlstring = rxmlstring.replace(' -1: sc = data.decode("utf-8").find("to=") ec = data.decode("utf-8").find(".ecorobot.net") - if ec > -1: - self.devclass = data.decode("utf-8")[sc+4:ec] + if ec > -1: + self.devclass = data.decode("utf-8")[sc + 4 : ec] # ack jabbr:client # no STARTTLS self.send( @@ -454,12 +482,14 @@ class Client(threading.Thread): else: self.send("") - + 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) - elif "urn:ietf:params:xml:ns:xmpp-sasl" in xml.tag: #Handle SASL Auth - self._handle_sasl_auth(xml) + elif ( + "urn:ietf:params:xml:ns:xmpp-sasl" in xml.tag + ): # Handle SASL Auth + self._handle_sasl_auth(xml) else: xmppserverlog.error("Couldn't handle: {}".format(xml)) @@ -479,19 +509,17 @@ class Client(threading.Thread): '' ) - else: # Handle init bind + else: # Handle init bind if len(xml): - child = self._tag_strip_uri(xml[0].tag) + child = self._tag_strip_uri(xml[0].tag) else: child = None if xml.tag == "iq": if child == "bind": - self._handle_bind(xml) + self._handle_bind(xml) else: xmppserverlog.error("Couldn't handle: {}".format(xml)) - - except Exception as e: xmppserverlog.exception("{}".format(e)) @@ -575,9 +603,7 @@ class Client(threading.Thread): except ET.ParseError as e: if "no element found" in e.msg: xmppserverlog.debug( - "xml parse error - {} - {}".format( - data.decode("utf-8"), e - ) + "xml parse error - {} - {}".format(data.decode("utf-8"), e) ) elif "not well-formed (invalid token)" in e.msg: xmppserverlog.debug( @@ -592,9 +618,9 @@ class Client(threading.Thread): xmppserverlog.exception("{}".format(e)) def _handle_sasl_auth(self, xml): - try: - - saslauth = base64.b64decode(xml.text).decode("utf-8").split("/") + try: + + saslauth = base64.b64decode(xml.text).decode("utf-8").split("/") username = saslauth[0] username = saslauth[0].split("\x00")[1] self.uid = username @@ -604,13 +630,13 @@ class Client(threading.Thread): elif len(saslauth[0].split("\x00")) > 2: resource = saslauth[0].split("\x00")[2] self.clientresource = resource - + if len(saslauth) > 2: authcode = saslauth[2] if not self.uid.startswith("fuid"): # 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 xmppserverlog.info("bot authenticated {}".format(self.uid)) # Send response @@ -654,20 +680,22 @@ class Client(threading.Thread): try: bumper_bots = self.bumper_bots.get() bumper_clients = self.bumper_clients.get() - + bot = bumper.bot_get(self.uid) if bot: - bumper.bot_set_xmpp(bot['did'], True) + bumper.bot_set_xmpp(bot["did"], True) client = bumper.client_get(self.clientresource) if client: - bumper.client_set_xmpp(client['resource'], True) + bumper.client_set_xmpp(client["resource"], True) clientbindxml = xml.getchildren() clientresourcexml = clientbindxml[0].getchildren() - if self.devclass: #its a bot - self.name = "XMPP_Client_{}_{}".format(self.uid,self.devclass) - self.bumper_jid = "{}@{}.ecorobot.net/atom".format(self.uid, self.devclass) + if self.devclass: # its a bot + self.name = "XMPP_Client_{}_{}".format(self.uid, self.devclass) + self.bumper_jid = "{}@{}.ecorobot.net/atom".format( + self.uid, self.devclass + ) xmppserverlog.debug("new bot {}".format(self.uid)) res = '{}'.format( xml.get("id"), self.bumper_jid @@ -675,7 +703,9 @@ class Client(threading.Thread): elif len(clientresourcexml) > 0: self.clientresource = clientresourcexml[0].text self.name = "XMPP_Client_{}".format(self.clientresource) - self.bumper_jid = "{}@{}/{}".format(self.uid, XMPPServer.server_id, self.clientresource) + self.bumper_jid = "{}@{}/{}".format( + self.uid, XMPPServer.server_id, self.clientresource + ) xmppserverlog.debug( "new client {} using resource {}".format( self.uid, self.clientresource @@ -684,8 +714,8 @@ class Client(threading.Thread): res = '{}'.format( xml.get("id"), self.bumper_jid ) - else: - self.name = "XMPP_Client_{}_{}".format(self.uid,self.address) + else: + self.name = "XMPP_Client_{}_{}".format(self.uid, self.address) self.bumper_jid = "{}@{}".format(self.uid, XMPPServer.server_id) xmppserverlog.debug("new client {}".format(self.uid)) res = '{}'.format( @@ -709,102 +739,119 @@ class Client(threading.Thread): def _handle_presence(self, xml): try: - + if len(xml) and xml[0].tag == "status": 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 - - #Send dummy return + # Most likely a bot, possibly hello world in text + + # Send dummy return self.send( - ' dummy '.format( - self.bumper_jid - ) + ' dummy '.format(self.bumper_jid) ) - #If it is a BOT, send extras + # If it is a BOT, send extras if self.type == self.BOT: - #get device info + # get device info self.send( ''.format( self.bumper_jid, XMPPServer.server_id ) - ) + ) - else: + else: 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": xmppserverlog.debug( - "client presence available - {} ".format(ET.tostring(xml, encoding="utf-8")) - ) - #Send dummy return - self.send( - ' dummy '.format( - self.bumper_jid + "client presence available - {} ".format( + ET.tostring(xml, encoding="utf-8") ) ) + # Send dummy return + self.send( + ' dummy '.format(self.bumper_jid) + ) elif xml.get("type") == "unavailable": xmppserverlog.debug( - "client presence unavailable (DISCONNECT) - {} ".format(ET.tostring(xml, encoding="utf-8")) - ) - - self._set_state("DISCONNECT") - else: - #Sometimes the android app sends these - xmppserverlog.debug( - "client presence (UNKNOWN) - {} ".format(ET.tostring(xml, encoding="utf-8")) - ) - #Send dummy return - self.send( - ' dummy '.format( - self.bumper_jid + "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( + ' dummy '.format(self.bumper_jid) + ) except Exception as e: xmppserverlog.exception("{}".format(e)) - def _parse_data(self, data): + def _parse_data(self, data): + + if data.decode("utf-8").startswith( + "]+\?>)", r"", data.decode("utf-8")) + "" + ) - - if data.decode("utf-8").startswith("]+\?>)", r"",data.decode("utf-8")) + "" - else: - newdata = "{}".format(data.decode("utf-8")) #Add artificial root - - try: + newdata = "{}".format( + data.decode("utf-8") + ) # Add artificial root + + try: root = ET.fromstring(newdata) for item in root.iter(): if item.tag != "root": if item.tag == "iq": if self.log_incoming_data: xmppserverlog.debug( - "from {} - {}".format(self.address, 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) item.clear() 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) item.clear() elif "presence" in item.tag: - self._handle_presence(item) + self._handle_presence(item) item.clear() - else: + else: if self.log_incoming_data: - xmppserverlog.debug( - "Unparsed Item - {}".format(str(ET.tostring(item, encoding="utf-8").decode("utf-8")).replace("ns0:","")) - ) - + xmppserverlog.debug( + "Unparsed Item - {}".format( + str( + ET.tostring(item, encoding="utf-8").decode( + "utf-8" + ) + ).replace("ns0:", "") + ) + ) + except ET.ParseError as e: if ( "no element found" in e.msg @@ -822,14 +869,12 @@ class Client(threading.Thread): elif "not well-formed (invalid token)" in e.msg: # If a lone - client is signalling end of session/disconnect if not "" in newdata: - xmppserverlog.error( - "xml parse error - {} - {}".format(newdata, e) - ) + xmppserverlog.error("xml parse error - {} - {}".format(newdata, e)) else: self.send("") # Close stream - + else: - if "" in newdata: xmppserverlog.error( - "xml parse error - {} - {}".format(newdata, e) - ) - else: + "xml parse error - {} - {}".format(newdata, e) + ) + else: self.send("") # Close stream self._set_state("DISCONNECT") - except Exception as e: xmppserverlog.exception("{}".format(e)) @@ -862,21 +906,21 @@ class Client(threading.Thread): self._handle_session(xml) elif child == "ping": self._handle_ping(xml, data) - elif child == "query": - if self.type == self.BOT: + elif child == "query": + if self.type == self.BOT: self._handle_result(xml, data) else: self._handle_ctl(xml, data) elif xml.get("type") == "result": - if self.type == self.BOT: - self._handle_result(xml, data) + if self.type == self.BOT: + self._handle_result(xml, data) else: - self._handle_result(xml, data) - elif xml.get("type") == "set": - if self.type == self.BOT: - self._handle_result(xml, data) + self._handle_result(xml, data) + elif xml.get("type") == "set": + if self.type == self.BOT: + self._handle_result(xml, data) else: - self._handle_result(xml, data) + self._handle_result(xml, data) except Exception as e: xmppserverlog.exception("{}".format(e)) @@ -889,8 +933,8 @@ class Client(threading.Thread): time.sleep(0.1) if not self.connection._closed: try: - data = self.connection.recv(4096) - if data != b"": + data = self.connection.recv(4096) + if data != b"": self._parse_data(data) except ConnectionResetError as e: xmppserverlog.error("{}".format(e)) @@ -899,5 +943,3 @@ class Client(threading.Thread): except Exception as e: xmppserverlog.exception("{}".format(e)) - -