diff --git a/bumper/__init__.py b/bumper/__init__.py index 1ef871e..ff03f00 100644 --- a/bumper/__init__.py +++ b/bumper/__init__.py @@ -12,6 +12,9 @@ from logging.handlers import RotatingFileHandler import socket import sys +import importlib +import pkgutil +from pkgutil import extend_path def strtobool(strbool): if str(strbool).lower() in ["true", "1", "t", "y", "on", "yes"]: @@ -32,6 +35,8 @@ os.makedirs(data_dir, exist_ok=True) # Ensure data directory exists or create certs_dir = os.environ.get("BUMPER_CERTS") or os.path.join(bumper_dir, "certs") os.makedirs(certs_dir, exist_ok=True) # Ensure data directory exists or create + + # Certs ca_cert = os.environ.get("BUMPER_CA") or os.path.join(certs_dir, "ca.crt") server_cert = os.environ.get("BUMPER_CERT") or os.path.join(certs_dir, "bumper.crt") @@ -57,6 +62,16 @@ conf_server = None conf_server_2 = None xmpp_server = None +# Plugins +sys.path.append(os.path.join(bumper_dir, "bumper", "plugins")) +sys.path.append(os.path.join(data_dir, "plugins")) + +discovered_plugins = { + name: importlib.import_module(name) + for finder, name, ispkg in pkgutil.iter_modules() + if name.startswith('bumper_') +} + shutting_down = False # Set format for all logs @@ -206,10 +221,8 @@ async def start(): # Start web servers conf_server.confserver_app() - asyncio.create_task(conf_server.start_server()) - - conf_server_2.confserver_app() - asyncio.create_task(conf_server_2.start_server()) + asyncio.create_task(conf_server.start_site(conf_server.app, address=bumper_listen, port=conf1_listen_port, usessl=True)) + asyncio.create_task(conf_server.start_site(conf_server.app, address=bumper_listen, port=conf2_listen_port, usessl=False)) # Start maintenance while not shutting_down: diff --git a/bumper/confserver.py b/bumper/confserver.py index 618f42c..0e019f2 100644 --- a/bumper/confserver.py +++ b/bumper/confserver.py @@ -8,6 +8,7 @@ import random import bumper import os from bumper.models import * +from bumper import plugins from datetime import datetime, timedelta import asyncio from aiohttp import web @@ -47,14 +48,17 @@ class ConfServer: self.app = None self.site = None self.runner = None + self.runners = [] self.excludelogging = ["base", "remove-bot", "remove-client", "restart-service"] def get_milli_time(self, timetoconvert): return int(round(timetoconvert * 1000)) def confserver_app(self): - self.app = web.Application(loop=asyncio.get_event_loop(), middlewares=[self.log_all_requests]) - aiohttp_jinja2.setup(self.app, loader=jinja2.FileSystemLoader(os.path.join(bumper.data_dir, "web","templates"))) + self.app = web.Application(loop=asyncio.get_event_loop(), middlewares=[ + self.log_all_requests, + ]) + aiohttp_jinja2.setup(self.app, loader=jinja2.FileSystemLoader(os.path.join(bumper.data_dir, "web","templates"))) self.app.add_routes( [ @@ -62,99 +66,67 @@ class ConfServer: web.get("", self.handle_base, name="base"), web.get("/bot/remove/{did}", self.handle_RemoveBot, name='remove-bot'), web.get("/client/remove/{resource}", self.handle_RemoveClient, name='remove-client'), - web.get("/restart_{service}", self.handle_RestartService, name='restart-service'), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login", - self.handle_login, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", - self.handle_login, - ), - web.get( # EcoVacs Home GetUserAccountInfo - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo", - self.handle_getUserAccountInfo, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout", - self.handle_logout, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode", - self.handle_getAuthCode, - ), - web.get( # EcoVacs Home GetAuthCode - "/{apiversion}/{apptype}/auth/getAuthCode", self.handle_getAuthCode - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement", - self.handle_checkAgreement, - ), - web.get( # EcoVacs Home CheckAgreement - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreementBatch", - self.handle_checkAgreement, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion", - self.handle_checkVersion, - ), - web.get( # EcoVacs Home CheckAPPVersion - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkAPPVersion", - self.handle_checkAPPVersion, - ), - web.get( # EcoVacs Home Upload Device Info - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/uploadDeviceInfo", - self.handle_uploadDeviceInfo, - ), - web.get( # EcoVacs Home GetAdByPositionType - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getAdByPositionType", - self.handle_getAdByPositionType, - ), - web.get( # EcoVacs Home Get Boot Screen - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getBootScreen", - self.handle_getBootScreen, - ), - web.get( # EcoVacs Home message hasUnreadMsg - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/hasUnreadMsg", - self.handle_hasUnreadMessage, - ), - web.post( # EcoVacs Home neng message hasUnreadMsg - "/api/neng/message/hasUnreadMsg", self.handle_neng_hasUnreadMessage - ), - web.get( # EcoVacs Home message getMsgList - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/getMsgList", - self.handle_getMsgList, - ), - web.get( # EcoVacs Home common getSystemReminder - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getSystemReminder", - self.handle_getSystemReminder, - ), - web.get( # EcoVacs Home shop getCnWapShopConfig - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/shop/getCnWapShopConfig", - self.handle_getCnWapShopConfig, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert", - self.handle_homePageAlert, - ), - web.post("/api/users/user.do", self.handle_usersapi), - web.get("/api/users/user.do", self.handle_usersapi), - web.post("/api/appsvr/app.do", self.handle_appsvr_api), # EcoVacs Home - web.get("/api/appsvr/app.do", self.handle_appsvr_api), # EcoVacs Home - web.post( - "/api/pim/product/getProductIotMap", self.handle_getProductIotMap, name='getProductIotMap' - ), - web.post("/api/lg/log.do", self.handle_lg_log), # EcoVacs Home - web.post("/api/iot/devmanager.do", self.handle_devmanager_botcommand), - web.post( - "/api/dim/devmanager.do", self.handle_dim_devmanager - ), # EcoVacs Home + web.get("/restart_{service}", self.handle_RestartService, name='restart-service'), web.post("/lookup.do", self.handle_lookup), - web.get("/api/pim/file/get/{id}", self.handle_pimFile) + ] ) - # Direct register from app: - # /{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/directRegister + + # common api paths + api_v1 = {"prefix": "/v1/", "app": web.Application()} # for /v1/ + api_v2 = {"prefix": "/v2/", "app": web.Application()} # for /v2/ + portal_api = {"prefix": "/api/", "app": web.Application()} # for /api/ + + apis = { + "api_v1": api_v1, + "api_v2": api_v2, + "portal_api": portal_api, + + } + + # Load plugins + for plug in bumper.discovered_plugins: + if isinstance(bumper.discovered_plugins[plug].plugin, bumper.plugins.ConfServerApp): + plugin = bumper.discovered_plugins[plug].plugin + if plugin.plugin_type == "sub_api": # app or sub_api + if plugin.sub_api in apis: + if plugin.routes: + logging.debug(f"Adding confserver sub_api ({plugin.name})") + apis[plugin.sub_api]["app"].add_routes(plugin.routes) + + elif plugin.plugin_type == "app": + if plugin.path_prefix and plugin.app: + logging.debug(f"Adding confserver plugin ({plugin.name})") + self.app.add_subapp(plugin.path_prefix, plugin.app) + + for api in apis: + self.app.add_subapp(apis[api]["prefix"], apis[api]["app"]) + + for resource in self.app.router.resources(): + print(resource) + + + + async def start_site(self, app, address='localhost', port=8080, usessl=False): + runner = web.AppRunner(app) + self.runners.append(runner) + await runner.setup() + if usessl: + ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + ssl_ctx.load_cert_chain(bumper.server_cert, bumper.server_key) + site = web.TCPSite( + runner, + host=address, + port=port, + ssl_context=ssl_ctx, + ) + + else: + site = web.TCPSite( + runner, host=address, port=port + ) + + await site.start() async def start_server(self): try: @@ -486,655 +458,6 @@ class ConfServer: except Exception as e: confserverlog.exception("{}".format(e)) - def handle_getUserAccountInfo(self, request): - try: - user_devid = request.match_info.get("devid", "") - countrycode = request.match_info.get("country", "us") - apptype = request.match_info.get("apptype", "") - user = bumper.user_by_deviceid(user_devid) - - if "global_" in apptype: # EcoVacs Home - login_details = EcoVacsHome_Login() - login_details.ucUid = "fuid_{}".format(user["userid"]) - login_details.loginName = "fusername_{}".format(user["userid"]) - login_details.mobile = None - else: - login_details = EcoVacs_Login() - - login_details.uid = "fuid_{}".format(user["userid"]) - login_details.username = "fusername_{}".format(user["userid"]) - login_details.country = countrycode - login_details.email = "null@null.com" - - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "email": login_details.email, - "hasMobile": "N", - "hasPassword": "Y", - "uid": login_details.uid, - "userName": login_details.username, - "obfuscatedMobile": None, - "mobile": None, - "loginName": login_details.loginName, - }, - "msg": "操作成功", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - def check_token(self, apptype, countrycode, user, token): - try: - if bumper.check_token(user["userid"], token): - - if "global_" in apptype: # EcoVacs Home - login_details = EcoVacsHome_Login() - login_details.ucUid = "fuid_{}".format(user["userid"]) - login_details.loginName = "fusername_{}".format(user["userid"]) - login_details.mobile = None - else: - login_details = EcoVacs_Login() - - login_details.accessToken = token - login_details.uid = "fuid_{}".format(user["userid"]) - login_details.username = "fusername_{}".format(user["userid"]) - login_details.country = countrycode - login_details.email = "null@null.com" - - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": json.loads(login_details.toJSON()), - # { - # "accessToken": self.generate_token(tmpuser), # Generate a token - # "country": countrycode, - # "email": "null@null.com", - # "uid": "fuid_{}".format(tmpuser["userid"]), - # "username": "fusername_{}".format(tmpuser["userid"]), - # }, - "msg": "操作成功", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - return web.json_response(body) - - else: - body = { - "code": bumper.ERR_TOKEN_INVALID, - "data": None, - "msg": "当前密码错误", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - def generate_token(self, user): - try: - tmpaccesstoken = uuid.uuid4().hex - bumper.user_add_token(user["userid"], tmpaccesstoken) - return tmpaccesstoken - - except Exception as e: - confserverlog.exception("{}".format(e)) - - def generate_authcode(self, user, countrycode, token): - try: - tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex) - bumper.user_add_authcode(user["userid"], token, tmpauthcode) - return tmpauthcode - - except Exception as e: - confserverlog.exception("{}".format(e)) - - def _auth_any(self, devid, apptype, 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 - if "global_" in apptype: # EcoVacs Home - login_details = EcoVacsHome_Login() - login_details.ucUid = "fuid_{}".format(tmpuser["userid"]) - login_details.loginName = "fusername_{}".format(tmpuser["userid"]) - login_details.mobile = None - else: - login_details = EcoVacs_Login() - - login_details.accessToken = self.generate_token(tmpuser) - login_details.uid = "fuid_{}".format(tmpuser["userid"]) - login_details.username = "fusername_{}".format(tmpuser["userid"]) - login_details.country = countrycode - login_details.email = "null@null.com" - bumper.user_add_device(tmpuser["userid"], user_devid) - else: - bumper.user_add("tmpuser") # Add a new user - tmpuser = bumper.user_get("tmpuser") - if "global_" in apptype: # EcoVacs Home - login_details = EcoVacsHome_Login() - login_details.ucUid = "fuid_{}".format(tmpuser["userid"]) - login_details.loginName = "fusername_{}".format(tmpuser["userid"]) - login_details.mobile = None - else: - login_details = EcoVacs_Login() - - login_details.accessToken = self.generate_token(tmpuser) - login_details.uid = "fuid_{}".format(tmpuser["userid"]) - login_details.username = "fusername_{}".format(tmpuser["userid"]) - login_details.country = countrycode - login_details.email = "null@null.com" - bumper.user_add_device(tmpuser["userid"], user_devid) - - for bot in bots: # Add all bots to the user - if "did" in bot: - bumper.user_add_bot(tmpuser["userid"], bot["did"]) - else: - confserverlog.error("No DID for bot: {}".format(bot)) - - if "checkLogin" in request.path: # If request was to check a token do so - checkToken = self.check_token( - apptype, countrycode, tmpuser, request.query["accessToken"] - ) - isGood = json.loads(checkToken.text) - if isGood["code"] == "0000": - return isGood - - # Deactivate old tokens and authcodes - bumper.user_revoke_expired_tokens(tmpuser["userid"]) - - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": json.loads(login_details.toJSON()), - # { - # "accessToken": self.generate_token(tmpuser), # Generate a token - # "country": countrycode, - # "email": "null@null.com", - # "uid": "fuid_{}".format(tmpuser["userid"]), - # "username": "fusername_{}".format(tmpuser["userid"]), - # }, - "msg": "操作成功", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return body - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_logout(self, request): - try: - 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"] - ) - - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": None, - "msg": "操作成功", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_getAuthCode(self, request): - try: - apptype = request.match_info.get("apptype", "") - user_devid = request.match_info.get("devid", "") # Ecovacs - if user_devid == "": - user_devid = request.query["deviceId"] # Ecovacs Home - - if not user_devid == "": - user = bumper.user_by_deviceid(user_devid) - token = "" - if user: - if "accessToken" in request.query: - token = bumper.user_get_token( - user["userid"], request.query["accessToken"] - ) - if token: - authcode = "" - if not "authcode" in token: - authcode = self.generate_authcode( - user, - request.match_info.get("country", "us"), - request.query["accessToken"], - ) - else: - authcode = token["authcode"] - if "global" in apptype: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "authCode": authcode, - "ecovacsUid": request.query["uid"], - }, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time( - datetime.utcnow().timestamp() - ), - } - else: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "authCode": authcode, - "ecovacsUid": request.query["uid"], - }, - "msg": "操作成功", - "time": self.get_milli_time( - datetime.utcnow().timestamp() - ), - } - return web.json_response(body) - - body = { - "code": bumper.ERR_TOKEN_INVALID, - "data": None, - "msg": "当前密码错误", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_checkVersion(self, request): - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "c": None, - "img": None, - "r": 0, - "t": None, - "u": None, - "ut": 0, - "v": None, - }, - "msg": "操作成功", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_checkAPPVersion(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "c": None, - "downPageUrl": None, - "img": None, - "nextAlertTime": None, - "r": 0, - "t": None, - "u": None, - "ut": 0, - "v": None, - }, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_uploadDeviceInfo(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": None, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_getAdByPositionType(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": None, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_getBootScreen(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": None, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_hasUnreadMessage(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": "N", - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_neng_hasUnreadMessage(self, request): # EcoVacs Home - try: - body = {"code": 0, "data": {"hasUnRead": True}} - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_getMsgList(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": {"hasNextPage": 0, "items": []}, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_getCnWapShopConfig(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "myShopShowFlag": "N", - "myShopUrl": "", - "shopIndexShowFlag": "N", - "shopIndexUrl": "", - }, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_getSystemReminder(self, request): # EcoVacs Home - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "iosGradeTime": {"iodGradeFlag": "N"}, - "openNotification": { - "openNotificationContent": None, - "openNotificationFlag": "N", - "openNotificationTitle": None, - }, - }, - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_checkAgreement(self, request): - try: - apptype = request.match_info.get("apptype", "") - if "global_" in apptype: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": [ - { - "force": "N", - "id": "20180804040641_7d746faf18b8cb22a50d145598fe4c90", - "type": "USER", - "url": "https://bumper.ecovacs.com/content/agreement?id=20180804040641_7d746faf18b8cb22a50d145598fe4c90&language=EN", # "https://gl-us-wap.ecovacs.com/content/agreement?id=20180804040641_7d746faf18b8cb22a50d145598fe4c90&language=EN - "version": "1.01", - }, - { - "force": "N", - "id": "20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac", - "type": "PRIVACY", - "url": "https://bumper.ecovacs.com/content/agreement?id=20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac&language=EN", # "https://gl-us-wap.ecovacs.com/content/agreement?id=20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac&language=EN" - "version": "1.01", - }, - ], - "msg": "操作成功", - "success": True, - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - else: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": [], - "msg": "操作成功", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_homePageAlert(self, request): - try: - nextAlert = self.get_milli_time( - (datetime.now() + timedelta(hours=12)).timestamp() - ) - - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": { - "clickSchemeUrl": None, - "clickWebUrl": None, - "hasCampaign": "N", - "imageUrl": None, - "nextAlertTime": nextAlert, - "serverTime": self.get_milli_time(datetime.utcnow().timestamp()), - }, - "msg": "操作成功", - "time": self.get_milli_time(datetime.utcnow().timestamp()), - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_getProductIotMap(self, request): - try: - body = { - "code": bumper.RETURN_API_SUCCESS, - "data": EcoVacsHomeProducts, - } - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_usersapi(self, request): - if not request.method == "GET": # Skip GET for now - try: - - body = {} - postbody = {} - if request.content_type == "application/x-www-form-urlencoded": - postbody = await request.post() - - else: - postbody = json.loads(await request.text()) - - todo = postbody["todo"] - if todo == "FindBest": - service = postbody["service"] - if service == "EcoMsgNew": - srvip = bumper.bumper_announce_ip - srvport = 5223 - confserverlog.info( - "Announcing EcoMsgNew Server to bot as: {}:{}".format( - srvip, srvport - ) - ) - msgserver = {"ip": srvip, "port": srvport, "result": "ok"} - msgserver = json.dumps(msgserver) - msgserver = msgserver.replace( - " ", "" - ) # bot seems to be very picky about having no spaces, only way was with text - - return web.json_response(text=msgserver) - - elif service == "EcoUpdate": - srvip = "47.88.66.164" # EcoVacs Server - srvport = 8005 - confserverlog.info( - "Announcing EcoUpdate Server to bot as: {}:{}".format( - srvip, srvport - ) - ) - body = {"result": "ok", "ip": srvip, "port": srvport} - - elif todo == "loginByItToken": - if "userId" in postbody: - if bumper.check_authcode(postbody["userId"], postbody["token"]): - body = { - "resource": postbody["resource"], - "result": "ok", - "todo": "result", - "token": postbody["token"], - "userId": postbody["userId"], - } - else: # EcoVacs Home LoginByITToken - loginToken = bumper.loginByItToken(postbody["token"]) - if not loginToken == {}: - body = { - "resource": postbody["resource"], - "result": "ok", - "todo": "result", - "token": loginToken["token"], - "userId": loginToken["userid"], - } - else: - body = {"result": "fail", "todo": "result"} - - elif todo == "GetDeviceList": - 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"} - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - # Return fail for GET - body = {"result": "fail", "todo": "result"} - return web.json_response(body) - - async def handle_appsvr_api(self, request): - if not request.method == "GET": # Skip GET for now - try: - - body = {} - postbody = {} - if request.content_type == "application/x-www-form-urlencoded": - postbody = await request.post() - - else: - postbody = json.loads(await request.text()) - - todo = postbody["todo"] - - if todo == "GetGlobalDeviceList": # EcoVacs Home - bots = bumper.db_get().table("bots").all() - botlist = [] - for bot in bots: - if bot["class"] != "": - b = bumper.bot_toEcoVacsHome_JSON(bot) - if ( - not b is None - ): # Happens if the bot isn't on the EcoVacs Home list - botlist.append(json.loads(b)) - - body = { - "code": 0, - "devices": botlist, - "ret": "ok", - "todo": "result", - } - - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - # Return fail for GET - body = {"result": "fail", "todo": "result"} - return web.json_response(body) - async def handle_lookup(self, request): try: @@ -1182,181 +505,6 @@ class ConfServer: except Exception as e: confserverlog.exception("{}".format(e)) - async def handle_lg_log(self, request): # EcoVacs Home - try: - json_body = json.loads(await request.text()) - - randomid = "".join(random.sample(string.ascii_letters, 6)) - did = json_body["did"] - - botdetails = bumper.bot_get(did) - if botdetails: - if not "cmdName" in json_body: - if "td" in json_body: - json_body["cmdName"] = json_body["td"] - - if not "toId" in json_body: - json_body["toId"] = did - - if not "toType" in json_body: - json_body["toType"] = botdetails["class"] - - if not "toRes" in json_body: - json_body["toRes"] = botdetails["resource"] - - if not "payloadType" in json_body: - json_body["payloadType"] = "x" - - if not "payload" in json_body: - #json_body["payload"] = "" - if json_body["td"] == "GetCleanLogs": - json_body["td"] = "q" - json_body["payload"] = '' - - if did != "": - bot = bumper.bot_get(did) - if bot["company"] == "eco-ng": - retcmd = await bumper.mqtt_helperbot.send_command( - json_body, randomid - ) - body = retcmd - confserverlog.debug("Send Bot - {}".format(json_body)) - confserverlog.debug("Bot Response - {}".format(body)) - logs = [] - logsroot = ET.fromstring(retcmd["resp"]) - if logsroot.attrib["ret"] == "ok": - cleanlogs = logsroot.getchildren() - for l in cleanlogs: - cleanlog = { - "ts": l.attrib['s'], - "area": l.attrib['a'], - "last": l.attrib['l'], - "cleanType": l.attrib['t'], - #imageUrl allows for providing images of cleanings, something to look into later - #"imageUrl": "https://localhost:8007", - } - logs.append(cleanlog) - body = { - "ret": "ok", - "logs": logs, - } - - else: - body = {"ret": "ok", "logs": []} - - confserverlog.debug("lg logs return: {}".format(json.dumps(body))) - return web.json_response(body) - else: - # No response, send error back - confserverlog.error( - "No bots with DID: {} connected to MQTT".format( - json_body["toId"] - ) - ) - body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_devmanager_botcommand(self, request): - try: - json_body = json.loads(await request.text()) - - randomid = "".join(random.sample(string.ascii_letters, 6)) - did = "" - if "toId" in json_body: # Its a command - did = json_body["toId"] - - if did != "": - bot = bumper.bot_get(did) - if bot["company"] == "eco-ng": - retcmd = await bumper.mqtt_helperbot.send_command( - json_body, randomid - ) - body = retcmd - confserverlog.debug("Send Bot - {}".format(json_body)) - confserverlog.debug("Bot Response - {}".format(body)) - return web.json_response(body) - else: - # No response, send error back - confserverlog.error( - "No bots with DID: {} connected to MQTT".format( - json_body["toId"] - ) - ) - body = { - "id": randomid, - "errno": 500, - "ret": "fail", - "debug": "wait for response timed out", - } - return web.json_response(body) - - else: - if "td" in json_body: # Seen when doing initial wifi config - if json_body["td"] == "PollSCResult": - body = {"ret": "ok"} - return web.json_response(body) - - if json_body["td"] == "HasUnreadMsg": # EcoVacs Home - body = {"ret": "ok", "unRead": False} - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - async def handle_dim_devmanager(self, request): # Used in EcoVacs Home App - try: - json_body = json.loads(await request.text()) - - randomid = "".join(random.sample(string.ascii_letters, 6)) - did = "" - if "toId" in json_body: # Its a command - did = json_body["toId"] - - if did != "": - bot = bumper.bot_get(did) - if bot["company"] == "eco-ng" and bot["mqtt_connection"] == True: - retcmd = await bumper.mqtt_helperbot.send_command( - json_body, randomid - ) - body = retcmd - confserverlog.debug("Send Bot - {}".format(json_body)) - confserverlog.debug("Bot Response - {}".format(body)) - return web.json_response(body) - else: - # No response, send error back - confserverlog.error( - "No bots with DID: {} connected to MQTT".format( - json_body["toId"] - ) - ) - body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} - return web.json_response(body) - - else: - if "td" in json_body: # Seen when doing initial wifi config - if json_body["td"] == "PollSCResult": - body = {"ret": "ok"} - return web.json_response(body) - - if json_body["td"] == "HasUnreadMsg": # EcoVacs Home - body = {"ret": "ok", "unRead": False} - return web.json_response(body) - - except Exception as e: - confserverlog.exception("{}".format(e)) - - - async def handle_pimFile(self, request): - try: - fileID = request.match_info.get("id", "") - - return web.FileResponse(os.path.join(bumper.data_dir,"web","robotvac_image.jpg")) - - except Exception as e: - confserverlog.exception("{}".format(e)) async def disconnect(self): try: @@ -1366,3 +514,356 @@ class ConfServer: except Exception as e: confserverlog.exception("{}".format(e)) + class ConfServer_GeneralFunctions: + def __init__(self): + pass + + def get_milli_time(self, timetoconvert): + return int(round(timetoconvert * 1000)) + + class ConfServer_AuthHandler: + def __init__(self): + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + pass + + def generate_token(self, user): + try: + tmpaccesstoken = uuid.uuid4().hex + bumper.user_add_token(user["userid"], tmpaccesstoken) + return tmpaccesstoken + + except Exception as e: + confserverlog.exception("{}".format(e)) + + def generate_authcode(self, user, countrycode, token): + try: + tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex) + bumper.user_add_authcode(user["userid"], token, tmpauthcode) + return tmpauthcode + + except Exception as e: + confserverlog.exception("{}".format(e)) + + + async def login(self, request): + try: + user_devid = request.match_info.get("devid", "") + countrycode = request.match_info.get("country", "us") + apptype = request.match_info.get("apptype", "") + confserverlog.info( + "client with devid {} attempting login".format(user_devid) + ) + if bumper.use_auth: + if ( + 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( + apptype, countrycode, user, request.query["accessToken"] + ) + else: + if "global_" in apptype: # EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(user["userid"]) + login_details.loginName = "fusername_{}".format( + user["userid"] + ) + login_details.mobile = None + + else: + login_details = EcoVacs_Login() + + # Deactivate old tokens and authcodes + bumper.user_revoke_expired_tokens(user["userid"]) + + login_details.accessToken = self.generate_token(user) + login_details.uid = "fuid_{}".format(user["userid"]) + login_details.username = "fusername_{}".format(user["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" + + body = { + "code": API_ERRORS[RETURN_API_SUCCESS], + "data": json.loads(login_details.toJSON()), + # { + # "accessToken": self.generate_token(tmpuser), # Generate a token + # "country": countrycode, + # "email": "null@null.com", + # "uid": "fuid_{}".format(tmpuser["userid"]), + # "username": "fusername_{}".format(tmpuser["userid"]), + # }, + "msg": "操作成功", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + body = { + "code": bumper.ERR_USER_NOT_ACTIVATED, + "data": None, + "msg": "当前密码错误", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + else: + return web.json_response( + self._auth_any(user_devid, apptype, countrycode, request) + ) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + + async def get_AuthCode(self, request): + try: + apptype = request.match_info.get("apptype", "") + user_devid = request.match_info.get("devid", "") # Ecovacs + if user_devid == "": + user_devid = request.query["deviceId"] # Ecovacs Home + + if not user_devid == "": + user = bumper.user_by_deviceid(user_devid) + token = "" + if user: + if "accessToken" in request.query: + token = bumper.user_get_token( + user["userid"], request.query["accessToken"] + ) + if token: + authcode = "" + if not "authcode" in token: + authcode = self.generate_authcode( + user, + request.match_info.get("country", "us"), + request.query["accessToken"], + ) + else: + authcode = token["authcode"] + if "global" in apptype: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "authCode": authcode, + "ecovacsUid": request.query["uid"], + }, + "msg": "操作成功", + "success": True, + "time": self.get_milli_time( + datetime.utcnow().timestamp() + ), + } + else: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "authCode": authcode, + "ecovacsUid": request.query["uid"], + }, + "msg": "操作成功", + "time": self.get_milli_time( + datetime.utcnow().timestamp() + ), + } + return web.json_response(body) + + body = { + "code": bumper.ERR_TOKEN_INVALID, + "data": None, + "msg": "当前密码错误", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + def check_token(self, apptype, countrycode, user, token): + try: + if bumper.check_token(user["userid"], token): + + if "global_" in apptype: # EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(user["userid"]) + login_details.loginName = "fusername_{}".format(user["userid"]) + login_details.mobile = None + else: + login_details = EcoVacs_Login() + + login_details.accessToken = token + login_details.uid = "fuid_{}".format(user["userid"]) + login_details.username = "fusername_{}".format(user["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" + + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": json.loads(login_details.toJSON()), + # { + # "accessToken": self.generate_token(tmpuser), # Generate a token + # "country": countrycode, + # "email": "null@null.com", + # "uid": "fuid_{}".format(tmpuser["userid"]), + # "username": "fusername_{}".format(tmpuser["userid"]), + # }, + "msg": "操作成功", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + return web.json_response(body) + + else: + body = { + "code": bumper.ERR_TOKEN_INVALID, + "data": None, + "msg": "当前密码错误", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + def _auth_any(self, devid, apptype, 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 + if "global_" in apptype: # EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(tmpuser["userid"]) + login_details.loginName = "fusername_{}".format(tmpuser["userid"]) + login_details.mobile = None + else: + login_details = EcoVacs_Login() + + login_details.accessToken = self.generate_token(tmpuser) + login_details.uid = "fuid_{}".format(tmpuser["userid"]) + login_details.username = "fusername_{}".format(tmpuser["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" + bumper.user_add_device(tmpuser["userid"], user_devid) + else: + bumper.user_add("tmpuser") # Add a new user + tmpuser = bumper.user_get("tmpuser") + if "global_" in apptype: # EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(tmpuser["userid"]) + login_details.loginName = "fusername_{}".format(tmpuser["userid"]) + login_details.mobile = None + else: + login_details = EcoVacs_Login() + + login_details.accessToken = self.generate_token(tmpuser) + login_details.uid = "fuid_{}".format(tmpuser["userid"]) + login_details.username = "fusername_{}".format(tmpuser["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" + bumper.user_add_device(tmpuser["userid"], user_devid) + + for bot in bots: # Add all bots to the user + if "did" in bot: + bumper.user_add_bot(tmpuser["userid"], bot["did"]) + else: + confserverlog.error("No DID for bot: {}".format(bot)) + + if "checkLogin" in request.path: # If request was to check a token do so + checkToken = self.check_token( + apptype, countrycode, tmpuser, request.query["accessToken"] + ) + isGood = json.loads(checkToken.text) + if isGood["code"] == "0000": + return isGood + + # Deactivate old tokens and authcodes + bumper.user_revoke_expired_tokens(tmpuser["userid"]) + + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": json.loads(login_details.toJSON()), + # { + # "accessToken": self.generate_token(tmpuser), # Generate a token + # "country": countrycode, + # "email": "null@null.com", + # "uid": "fuid_{}".format(tmpuser["userid"]), + # "username": "fusername_{}".format(tmpuser["userid"]), + # }, + "msg": "操作成功", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return body + + except Exception as e: + confserverlog.exception("{}".format(e)) + + + def getUserAccountInfo(self, request): + try: + user_devid = request.match_info.get("devid", "") + countrycode = request.match_info.get("country", "us") + apptype = request.match_info.get("apptype", "") + user = bumper.user_by_deviceid(user_devid) + + if "global_" in apptype: # EcoVacs Home + login_details = EcoVacsHome_Login() + login_details.ucUid = "fuid_{}".format(user["userid"]) + login_details.loginName = "fusername_{}".format(user["userid"]) + login_details.mobile = None + else: + login_details = EcoVacs_Login() + + login_details.uid = "fuid_{}".format(user["userid"]) + login_details.username = "fusername_{}".format(user["userid"]) + login_details.country = countrycode + login_details.email = "null@null.com" + + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "email": login_details.email, + "hasMobile": "N", + "hasPassword": "Y", + "uid": login_details.uid, + "userName": login_details.username, + "obfuscatedMobile": None, + "mobile": None, + "loginName": login_details.loginName, + }, + "msg": "操作成功", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) + + async def logout(self, request): + try: + 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"] + ) + + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": None, + "msg": "操作成功", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + confserverlog.exception("{}".format(e)) \ No newline at end of file diff --git a/bumper/plugins.py b/bumper/plugins.py new file mode 100644 index 0000000..d1cbc9b --- /dev/null +++ b/bumper/plugins.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web + +class ConfServerApp(): + name = None + plugin_type = None + path_prefix = None + app = None + sub_api = None + routes = None + + diff --git a/bumper/plugins/bumper_confserver_portal_appsvr.py b/bumper/plugins/bumper_confserver_portal_appsvr.py new file mode 100644 index 0000000..523ec71 --- /dev/null +++ b/bumper/plugins/bumper_confserver_portal_appsvr.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class portal_api_appsvr(plugins.ConfServerApp): + + def __init__(self): + self.name = "portal_api_appsvr" + self.plugin_type = "sub_api" + self.sub_api = "portal_api" + + self.routes = [ + + web.route("*", "/appsvr/app.do", self.handle_appsvr_api, name="portal_api_appsvr_app"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_appsvr_api(self, request): + if not request.method == "GET": # Skip GET for now + try: + + body = {} + postbody = {} + if request.content_type == "application/x-www-form-urlencoded": + postbody = await request.post() + + else: + postbody = json.loads(await request.text()) + + todo = postbody["todo"] + + if todo == "GetGlobalDeviceList": # EcoVacs Home + bots = bumper.db_get().table("bots").all() + botlist = [] + for bot in bots: + if bot["class"] != "": + b = bumper.bot_toEcoVacsHome_JSON(bot) + if ( + not b is None + ): # Happens if the bot isn't on the EcoVacs Home list + botlist.append(json.loads(b)) + + body = { + "code": 0, + "devices": botlist, + "ret": "ok", + "todo": "result", + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + # Return fail for GET + body = {"result": "fail", "todo": "result"} + return web.json_response(body) + +plugin = portal_api_appsvr() + diff --git a/bumper/plugins/bumper_confserver_portal_dim.py b/bumper/plugins/bumper_confserver_portal_dim.py new file mode 100644 index 0000000..78e4583 --- /dev/null +++ b/bumper/plugins/bumper_confserver_portal_dim.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta +import string +import random + + +class portal_api_dim(plugins.ConfServerApp): + + def __init__(self): + self.name = "portal_api_dimr" + self.plugin_type = "sub_api" + self.sub_api = "portal_api" + + self.routes = [ + + web.route("*", "/dim/devmanager.do", self.handle_dim_devmanager, name="portal_api_dim_devmanager"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_dim_devmanager(self, request): # Used in EcoVacs Home App + try: + json_body = json.loads(await request.text()) + + randomid = "".join(random.sample(string.ascii_letters, 6)) + did = "" + if "toId" in json_body: # Its a command + did = json_body["toId"] + + if did != "": + bot = bumper.bot_get(did) + if bot["company"] == "eco-ng" and bot["mqtt_connection"] == True: + retcmd = await bumper.mqtt_helperbot.send_command( + json_body, randomid + ) + body = retcmd + logging.debug("Send Bot - {}".format(json_body)) + logging.debug("Bot Response - {}".format(body)) + return web.json_response(body) + else: + # No response, send error back + logging.error( + "No bots with DID: {} connected to MQTT".format( + json_body["toId"] + ) + ) + body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} + return web.json_response(body) + + else: + if "td" in json_body: # Seen when doing initial wifi config + if json_body["td"] == "PollSCResult": + body = {"ret": "ok"} + return web.json_response(body) + + if json_body["td"] == "HasUnreadMsg": # EcoVacs Home + body = {"ret": "ok", "unRead": False} + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + +plugin = portal_api_dim() + diff --git a/bumper/plugins/bumper_confserver_portal_iot.py b/bumper/plugins/bumper_confserver_portal_iot.py new file mode 100644 index 0000000..6023db6 --- /dev/null +++ b/bumper/plugins/bumper_confserver_portal_iot.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta +import string +import random + +class portal_api_iot(plugins.ConfServerApp): + + def __init__(self): + self.name = "portal_api_iot" + self.plugin_type = "sub_api" + self.sub_api = "portal_api" + + self.routes = [ + + web.route("*", "/iot/devmanager.do", self.handle_devmanager_botcommand, name="portal_api_iot_devmanager"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_devmanager_botcommand(self, request): + try: + json_body = json.loads(await request.text()) + + randomid = "".join(random.sample(string.ascii_letters, 6)) + did = "" + if "toId" in json_body: # Its a command + did = json_body["toId"] + + if did != "": + bot = bumper.bot_get(did) + if bot["company"] == "eco-ng": + retcmd = await bumper.mqtt_helperbot.send_command( + json_body, randomid + ) + body = retcmd + logging.debug("Send Bot - {}".format(json_body)) + logging.debug("Bot Response - {}".format(body)) + return web.json_response(body) + else: + # No response, send error back + logging.error( + "No bots with DID: {} connected to MQTT".format( + json_body["toId"] + ) + ) + body = { + "id": randomid, + "errno": 500, + "ret": "fail", + "debug": "wait for response timed out", + } + return web.json_response(body) + + else: + if "td" in json_body: # Seen when doing initial wifi config + if json_body["td"] == "PollSCResult": + body = {"ret": "ok"} + return web.json_response(body) + + if json_body["td"] == "HasUnreadMsg": # EcoVacs Home + body = {"ret": "ok", "unRead": False} + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + +plugin = portal_api_iot() + diff --git a/bumper/plugins/bumper_confserver_portal_lg.py b/bumper/plugins/bumper_confserver_portal_lg.py new file mode 100644 index 0000000..c43d59b --- /dev/null +++ b/bumper/plugins/bumper_confserver_portal_lg.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta +import os +import string +import random +import xml.etree.ElementTree as ET + +class portal_api_lg(plugins.ConfServerApp): + + def __init__(self): + self.name = "portal_api_lg" + self.plugin_type = "sub_api" + self.sub_api = "portal_api" + + self.routes = [ + + web.route("*", "/lg/log.do", self.handle_lg_log, name="portal_api_lg_log"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_lg_log(self, request): # EcoVacs Home + try: + json_body = json.loads(await request.text()) + + randomid = "".join(random.sample(string.ascii_letters, 6)) + did = json_body["did"] + + botdetails = bumper.bot_get(did) + if botdetails: + if not "cmdName" in json_body: + if "td" in json_body: + json_body["cmdName"] = json_body["td"] + + if not "toId" in json_body: + json_body["toId"] = did + + if not "toType" in json_body: + json_body["toType"] = botdetails["class"] + + if not "toRes" in json_body: + json_body["toRes"] = botdetails["resource"] + + if not "payloadType" in json_body: + json_body["payloadType"] = "x" + + if not "payload" in json_body: + #json_body["payload"] = "" + if json_body["td"] == "GetCleanLogs": + json_body["td"] = "q" + json_body["payload"] = '' + + if did != "": + bot = bumper.bot_get(did) + if bot["company"] == "eco-ng": + retcmd = await bumper.mqtt_helperbot.send_command( + json_body, randomid + ) + body = retcmd + logging.debug("Send Bot - {}".format(json_body)) + logging.debug("Bot Response - {}".format(body)) + logs = [] + logsroot = ET.fromstring(retcmd["resp"]) + if logsroot.attrib["ret"] == "ok": + cleanlogs = logsroot.getchildren() + for l in cleanlogs: + cleanlog = { + "ts": l.attrib['s'], + "area": l.attrib['a'], + "last": l.attrib['l'], + "cleanType": l.attrib['t'], + #imageUrl allows for providing images of cleanings, something to look into later + #"imageUrl": "https://localhost:8007", + } + logs.append(cleanlog) + body = { + "ret": "ok", + "logs": logs, + } + + else: + body = {"ret": "ok", "logs": []} + + logging.debug("lg logs return: {}".format(json.dumps(body))) + return web.json_response(body) + else: + # No response, send error back + logging.error( + "No bots with DID: {} connected to MQTT".format( + json_body["toId"] + ) + ) + body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"} + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + +plugin = portal_api_lg() + diff --git a/bumper/plugins/bumper_confserver_portal_neng.py b/bumper/plugins/bumper_confserver_portal_neng.py new file mode 100644 index 0000000..944c3aa --- /dev/null +++ b/bumper/plugins/bumper_confserver_portal_neng.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class portal_api_neng(plugins.ConfServerApp): + + def __init__(self): + self.name = "portal_api_neng" + self.plugin_type = "sub_api" + self.sub_api = "portal_api" + + self.routes = [ + + web.route("*", "/neng/message/hasUnreadMsg", self.handle_neng_hasUnreadMessage, name="portal_api_neng_hasUnreadMessage"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_neng_hasUnreadMessage(self, request): # EcoVacs Home + try: + body = {"code": 0, "data": {"hasUnRead": True}} + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + +plugin = portal_api_neng() + diff --git a/bumper/plugins/bumper_confserver_portal_pim.py b/bumper/plugins/bumper_confserver_portal_pim.py new file mode 100644 index 0000000..2473823 --- /dev/null +++ b/bumper/plugins/bumper_confserver_portal_pim.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta +import os + +class portal_api_pim(plugins.ConfServerApp): + + def __init__(self): + self.name = "portal_api_pim" + self.plugin_type = "sub_api" + self.sub_api = "portal_api" + + self.routes = [ + + web.route("*", "/pim/product/getProductIotMap", self.handle_getProductIotMap, name="portal_api_pim_getProductIotMap"), + web.route("*", "/pim/file/get/{id}", self.handle_pimFile, name="portal_api_pim_file"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_getProductIotMap(self, request): + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": EcoVacsHomeProducts, + } + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + async def handle_pimFile(self, request): + try: + fileID = request.match_info.get("id", "") + + return web.FileResponse(os.path.join(bumper.data_dir,"web","robotvac_image.jpg")) + + except Exception as e: + logging.exception("{}".format(e)) + +plugin = portal_api_pim() + diff --git a/bumper/plugins/bumper_confserver_portal_users.py b/bumper/plugins/bumper_confserver_portal_users.py new file mode 100644 index 0000000..fd4d5f8 --- /dev/null +++ b/bumper/plugins/bumper_confserver_portal_users.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class portal_api_users(plugins.ConfServerApp): + + def __init__(self): + self.name = "portal_api_users" + self.plugin_type = "sub_api" + self.sub_api = "portal_api" + + self.routes = [ + + web.route("*", "/users/user.do", self.handle_usersapi, name="portal_api_users_user"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_usersapi(self, request): + if not request.method == "GET": # Skip GET for now + try: + + body = {} + postbody = {} + if request.content_type == "application/x-www-form-urlencoded": + postbody = await request.post() + + else: + postbody = json.loads(await request.text()) + + todo = postbody["todo"] + if todo == "FindBest": + service = postbody["service"] + if service == "EcoMsgNew": + srvip = bumper.bumper_announce_ip + srvport = 5223 + logging.info( + "Announcing EcoMsgNew Server to bot as: {}:{}".format( + srvip, srvport + ) + ) + msgserver = {"ip": srvip, "port": srvport, "result": "ok"} + msgserver = json.dumps(msgserver) + msgserver = msgserver.replace( + " ", "" + ) # bot seems to be very picky about having no spaces, only way was with text + + return web.json_response(text=msgserver) + + elif service == "EcoUpdate": + srvip = "47.88.66.164" # EcoVacs Server + srvport = 8005 + logging.info( + "Announcing EcoUpdate Server to bot as: {}:{}".format( + srvip, srvport + ) + ) + body = {"result": "ok", "ip": srvip, "port": srvport} + + elif todo == "loginByItToken": + if "userId" in postbody: + if bumper.check_authcode(postbody["userId"], postbody["token"]): + body = { + "resource": postbody["resource"], + "result": "ok", + "todo": "result", + "token": postbody["token"], + "userId": postbody["userId"], + } + else: # EcoVacs Home LoginByITToken + loginToken = bumper.loginByItToken(postbody["token"]) + if not loginToken == {}: + body = { + "resource": postbody["resource"], + "result": "ok", + "todo": "result", + "token": loginToken["token"], + "userId": loginToken["userid"], + } + else: + body = {"result": "fail", "todo": "result"} + + elif todo == "GetDeviceList": + 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"} + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + # Return fail for GET + body = {"result": "fail", "todo": "result"} + return web.json_response(body) + +plugin = portal_api_users() + diff --git a/bumper/plugins/bumper_confserver_v1_global_auth.py b/bumper/plugins/bumper_confserver_v1_global_auth.py new file mode 100644 index 0000000..bbceb70 --- /dev/null +++ b/bumper/plugins/bumper_confserver_v1_global_auth.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class v1_global_auth(plugins.ConfServerApp): + + def __init__(self): + self.name = "v1_global_auth" + self.plugin_type = "sub_api" + self.sub_api = "api_v1" + + authhandler = bumper.ConfServer.ConfServer_AuthHandler() + self.routes = [ + web.route("*", "/global/auth/getAuthCode", authhandler.get_AuthCode, name="v1_global_auth_getAuthCode"), + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + +plugin = v1_global_auth() + diff --git a/bumper/plugins/bumper_confserver_v1_private_ad.py b/bumper/plugins/bumper_confserver_v1_private_ad.py new file mode 100644 index 0000000..2e7df5b --- /dev/null +++ b/bumper/plugins/bumper_confserver_v1_private_ad.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class v1_private_ad(plugins.ConfServerApp): + + def __init__(self): + self.name = "v1_private_ad" + self.plugin_type = "sub_api" + self.sub_api = "api_v1" + + self.routes = [ + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getAdByPositionType", self.handle_getAdByPositionType, name="v1_ad_getAdByPositionType"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/ad/getBootScreen", self.handle_getBootScreen, name="v1_ad_getBootScreen"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_getAdByPositionType(self, request): # EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": None, + "msg": "操作成功", + "success": True, + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + async def handle_getBootScreen(self, request): # EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": None, + "msg": "操作成功", + "success": True, + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + +plugin = v1_private_ad() + diff --git a/bumper/plugins/bumper_confserver_v1_private_campaign.py b/bumper/plugins/bumper_confserver_v1_private_campaign.py new file mode 100644 index 0000000..468ca8c --- /dev/null +++ b/bumper/plugins/bumper_confserver_v1_private_campaign.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class v1_private_campaign(plugins.ConfServerApp): + + def __init__(self): + self.name = "v1_private_campaign" + self.plugin_type = "sub_api" + self.sub_api = "api_v1" + + self.routes = [ + + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert", self.handle_homePageAlert, name="v1_campaign_homePageAlert"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_homePageAlert(self, request): + try: + nextAlert = self.get_milli_time( + (datetime.now() + timedelta(hours=12)).timestamp() + ) + + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "clickSchemeUrl": None, + "clickWebUrl": None, + "hasCampaign": "N", + "imageUrl": None, + "nextAlertTime": nextAlert, + "serverTime": self.get_milli_time(datetime.utcnow().timestamp()), + }, + "msg": "操作成功", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + +plugin = v1_private_campaign() + diff --git a/bumper/plugins/bumper_confserver_v1_private_common.py b/bumper/plugins/bumper_confserver_v1_private_common.py new file mode 100644 index 0000000..71a0034 --- /dev/null +++ b/bumper/plugins/bumper_confserver_v1_private_common.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class v1_private_common(plugins.ConfServerApp): + + def __init__(self): + self.name = "v1_private_common" + self.plugin_type = "sub_api" + self.sub_api = "api_v1" + + self.routes = [ + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkAPPVersion", self.handle_checkAPPVersion, name="v1_common_checkAppVersion"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion", self.handle_checkVersion, name="v1_common_checkVersion"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/uploadDeviceInfo", self.handle_uploadDeviceInfo, name="v1_common_uploadDeviceInfo"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/getSystemReminder", self.handle_getSystemReminder, name="v1_common_getSystemReminder"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_checkVersion(self, request): + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "c": None, + "img": None, + "r": 0, + "t": None, + "u": None, + "ut": 0, + "v": None, + }, + "msg": "操作成功", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + async def handle_checkAPPVersion(self, request): # EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "c": None, + "downPageUrl": None, + "img": None, + "nextAlertTime": None, + "r": 0, + "t": None, + "u": None, + "ut": 0, + "v": None, + }, + "msg": "操作成功", + "success": True, + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + async def handle_uploadDeviceInfo(self, request): # EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": None, + "msg": "操作成功", + "success": True, + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + async def handle_getSystemReminder(self, request): # EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "iosGradeTime": {"iodGradeFlag": "N"}, + "openNotification": { + "openNotificationContent": None, + "openNotificationFlag": "N", + "openNotificationTitle": None, + }, + }, + "msg": "操作成功", + "success": True, + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + +plugin = v1_private_common() + diff --git a/bumper/plugins/bumper_confserver_v1_private_message.py b/bumper/plugins/bumper_confserver_v1_private_message.py new file mode 100644 index 0000000..7e1d6d1 --- /dev/null +++ b/bumper/plugins/bumper_confserver_v1_private_message.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class v1_private_message(plugins.ConfServerApp): + + def __init__(self): + self.name = "v1_private_message" + self.plugin_type = "sub_api" + self.sub_api = "api_v1" + + self.routes = [ + + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/hasUnreadMsg", self.handle_hasUnreadMessage, name="v1_message_hasUnreadMsg"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/message/getMsgList", self.handle_getMsgList, name="v1_message_getMsgList"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_hasUnreadMessage(self, request): # EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": "N", + "msg": "操作成功", + "success": True, + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + + async def handle_getMsgList(self, request): # EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": {"hasNextPage": 0, "items": []}, + "msg": "操作成功", + "success": True, + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + +plugin = v1_private_message() + diff --git a/bumper/plugins/bumper_confserver_v1_private_shop.py b/bumper/plugins/bumper_confserver_v1_private_shop.py new file mode 100644 index 0000000..343f13a --- /dev/null +++ b/bumper/plugins/bumper_confserver_v1_private_shop.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class v1_private_shop(plugins.ConfServerApp): + + def __init__(self): + self.name = "v1_private_shop" + self.plugin_type = "sub_api" + self.sub_api = "api_v1" + + self.routes = [ + + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/shop/getCnWapShopConfig", self.handle_getCnWapShopConfig, name="v1_shop_getCnWapShopConfig"), + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_getCnWapShopConfig(self, request): # EcoVacs Home + try: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": { + "myShopShowFlag": "N", + "myShopUrl": "", + "shopIndexShowFlag": "N", + "shopIndexUrl": "", + }, + "msg": "操作成功", + "success": True, + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + +plugin = v1_private_shop() + diff --git a/bumper/plugins/bumper_confserver_v1_private_user.py b/bumper/plugins/bumper_confserver_v1_private_user.py new file mode 100644 index 0000000..397fcd1 --- /dev/null +++ b/bumper/plugins/bumper_confserver_v1_private_user.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class v1_private_user(plugins.ConfServerApp): + + def __init__(self): + + self.name = "v1_private_user" + self.plugin_type = "sub_api" + self.sub_api = "api_v1" + + authhandler = bumper.ConfServer.ConfServer_AuthHandler() + self.routes = [ + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login", authhandler.login, name="v1_user_login"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", authhandler.login, name="v1_user_checkLogin"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode", authhandler.get_AuthCode, name="v1_user_getAuthCode"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout", authhandler.logout, name="v1_user_logout"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement", self.handle_checkAgreement,name="v1_user_checkAgreement"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreementBatch", self.handle_checkAgreement,name="v1_user_checkAgreementBatch"), + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo", authhandler.getUserAccountInfo,name="v1_user_getUserAccountInfo"), + # Direct register from app: + # /{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/directRegister + + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + async def handle_checkAgreement(self, request): + try: + apptype = request.match_info.get("apptype", "") + if "global_" in apptype: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": [ + { + "force": "N", + "id": "20180804040641_7d746faf18b8cb22a50d145598fe4c90", + "type": "USER", + "url": "https://bumper.ecovacs.com/content/agreement?id=20180804040641_7d746faf18b8cb22a50d145598fe4c90&language=EN", # "https://gl-us-wap.ecovacs.com/content/agreement?id=20180804040641_7d746faf18b8cb22a50d145598fe4c90&language=EN + "version": "1.01", + }, + { + "force": "N", + "id": "20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac", + "type": "PRIVACY", + "url": "https://bumper.ecovacs.com/content/agreement?id=20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac&language=EN", # "https://gl-us-wap.ecovacs.com/content/agreement?id=20180804040245_4e7c56dfb7ebd3b81b1f2747d0859fac&language=EN" + "version": "1.01", + }, + ], + "msg": "操作成功", + "success": True, + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + else: + body = { + "code": bumper.RETURN_API_SUCCESS, + "data": [], + "msg": "操作成功", + "time": self.get_milli_time(datetime.utcnow().timestamp()), + } + + return web.json_response(body) + + except Exception as e: + logging.exception("{}".format(e)) + +plugin = v1_private_user() + diff --git a/bumper/plugins/bumper_confserver_v2_private_user.py b/bumper/plugins/bumper_confserver_v2_private_user.py new file mode 100644 index 0000000..5a3c7a3 --- /dev/null +++ b/bumper/plugins/bumper_confserver_v2_private_user.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +import asyncio +from aiohttp import web +from bumper import plugins +import logging +import bumper +from bumper.models import * +from bumper import plugins +from datetime import datetime, timedelta + + +class v2_private_user(plugins.ConfServerApp): + + def __init__(self): + + self.name = "v2_private_user" + self.plugin_type = "sub_api" + self.sub_api = "api_v2" + + authhandler = bumper.ConfServer.ConfServer_AuthHandler() + self.routes = [ + web.route("*", "/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", authhandler.login, name="v2_user_checkLogin"), + ] + + self.get_milli_time = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time + + +plugin = v2_private_user() +