start refactoring confserver
This commit is contained in:
parent
ba3f28165f
commit
4dce3c262c
32 changed files with 627 additions and 840 deletions
|
|
@ -6,7 +6,7 @@ import socket
|
||||||
import sys
|
import sys
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from bumper.confserver import ConfServer
|
from bumper.confserver import ConfServer, WebServerBinding
|
||||||
from bumper.db import *
|
from bumper.db import *
|
||||||
from bumper.models import *
|
from bumper.models import *
|
||||||
from bumper.mqttserver import MQTTHelperBot, MQTTServer
|
from bumper.mqttserver import MQTTHelperBot, MQTTServer
|
||||||
|
|
@ -53,11 +53,10 @@ token_validity_seconds = 3600 # 1 hour
|
||||||
oauth_validity_days = 15
|
oauth_validity_days = 15
|
||||||
db = None
|
db = None
|
||||||
|
|
||||||
mqtt_server: Optional[MQTTServer] = None
|
mqtt_server: MQTTServer
|
||||||
mqtt_helperbot: Optional[MQTTHelperBot] = None
|
mqtt_helperbot: MQTTHelperBot
|
||||||
conf_server: Optional[ConfServer] = None
|
conf_server: ConfServer
|
||||||
conf_server_2: Optional[ConfServer] = None
|
xmpp_server: XMPPServer
|
||||||
xmpp_server: Optional[XMPPServer] = None
|
|
||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
sys.path.append(os.path.join(bumper_dir, "bumper", "plugins"))
|
sys.path.append(os.path.join(bumper_dir, "bumper", "plugins"))
|
||||||
|
|
@ -75,9 +74,11 @@ bumperlog = get_logger("bumper")
|
||||||
logging.getLogger("asyncio").setLevel(logging.CRITICAL + 1) # Ignore this logger
|
logging.getLogger("asyncio").setLevel(logging.CRITICAL + 1) # Ignore this logger
|
||||||
|
|
||||||
mqtt_listen_port = 8883
|
mqtt_listen_port = 8883
|
||||||
conf1_listen_port = 443
|
|
||||||
conf2_listen_port = 8007
|
|
||||||
xmpp_listen_port = 5223
|
xmpp_listen_port = 5223
|
||||||
|
conf_server_bindings = [
|
||||||
|
WebServerBinding(bumper_listen, 8443, True),
|
||||||
|
WebServerBinding(bumper_listen, 8007, False),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
async def start():
|
async def start():
|
||||||
|
|
@ -117,9 +118,7 @@ async def start():
|
||||||
global mqtt_helperbot
|
global mqtt_helperbot
|
||||||
mqtt_helperbot = MQTTHelperBot(bumper_listen, mqtt_listen_port)
|
mqtt_helperbot = MQTTHelperBot(bumper_listen, mqtt_listen_port)
|
||||||
global conf_server
|
global conf_server
|
||||||
conf_server = ConfServer((bumper_listen, conf1_listen_port), usessl=True)
|
conf_server = ConfServer(conf_server_bindings)
|
||||||
global conf_server_2
|
|
||||||
conf_server_2 = ConfServer((bumper_listen, conf2_listen_port), usessl=False)
|
|
||||||
global xmpp_server
|
global xmpp_server
|
||||||
xmpp_server = XMPPServer((bumper_listen, xmpp_listen_port))
|
xmpp_server = XMPPServer((bumper_listen, xmpp_listen_port))
|
||||||
|
|
||||||
|
|
@ -138,17 +137,7 @@ async def start():
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
|
|
||||||
# Start web servers
|
# Start web servers
|
||||||
conf_server.confserver_app()
|
await conf_server.start()
|
||||||
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
|
# Start maintenance
|
||||||
while not shutting_down:
|
while not shutting_down:
|
||||||
|
|
@ -165,8 +154,7 @@ async def shutdown():
|
||||||
try:
|
try:
|
||||||
bumperlog.info("Shutting down")
|
bumperlog.info("Shutting down")
|
||||||
|
|
||||||
await conf_server.stop_server()
|
await conf_server.shutdown()
|
||||||
await conf_server_2.stop_server()
|
|
||||||
if mqtt_server.state == "started":
|
if mqtt_server.state == "started":
|
||||||
await mqtt_server.shutdown()
|
await mqtt_server.shutdown()
|
||||||
elif mqtt_server.state == "starting":
|
elif mqtt_server.state == "starting":
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,36 @@
|
||||||
#!/usr/bin/env python3
|
"""Web server module."""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import dataclasses
|
||||||
|
import inspect
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import ssl
|
import ssl
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
import aiohttp_jinja2
|
import aiohttp_jinja2
|
||||||
import jinja2
|
import jinja2
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
|
from aiohttp.typedefs import Handler
|
||||||
|
from aiohttp.web_exceptions import (
|
||||||
|
HTTPInternalServerError,
|
||||||
|
HTTPNoContent,
|
||||||
|
HTTPBadRequest,
|
||||||
|
)
|
||||||
|
from aiohttp.web_request import Request
|
||||||
|
from aiohttp.web_response import Response, StreamResponse
|
||||||
|
|
||||||
from bumper import plugins
|
import bumper
|
||||||
from bumper.models import *
|
from .plugins import ConfServerApp
|
||||||
|
|
||||||
from .util import get_logger
|
from .util import get_logger
|
||||||
|
|
||||||
|
|
||||||
class aiohttp_filter(logging.Filter):
|
class _aiohttp_filter(logging.Filter):
|
||||||
def filter(self, record):
|
def filter(self, record: logging.LogRecord) -> bool:
|
||||||
if (
|
if record.name == "aiohttp.access" and record.levelno == 20:
|
||||||
record.name == "aiohttp.access" and record.levelno == 20
|
# Filters aiohttp.access log to switch it from INFO to DEBUG
|
||||||
): # Filters aiohttp.access log to switch it from INFO to DEBUG
|
|
||||||
record.levelno = 10
|
record.levelno = 10
|
||||||
record.levelname = "DEBUG"
|
record.levelname = "DEBUG"
|
||||||
|
|
||||||
|
|
@ -30,53 +41,64 @@ class aiohttp_filter(logging.Filter):
|
||||||
|
|
||||||
|
|
||||||
confserverlog = get_logger("confserver")
|
confserverlog = get_logger("confserver")
|
||||||
logging.getLogger("aiohttp.access").addFilter(
|
# Add logging filter above to aiohttp.access
|
||||||
aiohttp_filter()
|
logging.getLogger("aiohttp.access").addFilter(_aiohttp_filter())
|
||||||
) # Add logging filter above to aiohttp.access
|
|
||||||
|
|
||||||
|
@dataclasses.dataclass(frozen=True)
|
||||||
|
class WebServerBinding:
|
||||||
|
"""Web server binding."""
|
||||||
|
|
||||||
|
host: str
|
||||||
|
port: int
|
||||||
|
use_ssl: bool
|
||||||
|
|
||||||
|
|
||||||
class ConfServer:
|
class ConfServer:
|
||||||
def __init__(self, address, usessl=False):
|
"""Web server."""
|
||||||
self.usessl = usessl
|
|
||||||
self.address = address
|
|
||||||
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):
|
_EXCLUDE_FROM_LOGGING = ["base", "remove-bot", "remove-client", "restart-service"]
|
||||||
return int(round(timetoconvert * 1000))
|
|
||||||
|
|
||||||
def confserver_app(self):
|
def __init__(self, bindings: Union[list[WebServerBinding], WebServerBinding]):
|
||||||
self.app = web.Application(
|
self._runners: list[web.AppRunner] = []
|
||||||
|
|
||||||
|
if isinstance(bindings, WebServerBinding):
|
||||||
|
bindings = [bindings]
|
||||||
|
self._bindings = bindings
|
||||||
|
|
||||||
|
self._app = web.Application(
|
||||||
middlewares=[
|
middlewares=[
|
||||||
self.log_all_requests,
|
self._log_all_requests,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
aiohttp_jinja2.setup(
|
aiohttp_jinja2.setup(
|
||||||
self.app,
|
self._app,
|
||||||
loader=jinja2.FileSystemLoader(
|
loader=jinja2.FileSystemLoader(
|
||||||
os.path.join(bumper.bumper_dir, "bumper", "web", "templates")
|
os.path.join(bumper.bumper_dir, "bumper", "web", "templates")
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
self._add_routes()
|
||||||
|
self._app.freeze() # no modification allowed anymore
|
||||||
|
|
||||||
self.app.add_routes(
|
def _add_routes(self) -> None:
|
||||||
|
self._app.add_routes(
|
||||||
[
|
[
|
||||||
web.get("", self.handle_base, name="base"),
|
web.get("", self._handle_base, name="base"),
|
||||||
web.get("/bot/remove/{did}", self.handle_RemoveBot, name="remove-bot"),
|
web.get(
|
||||||
|
"/bot/remove/{did}", self._handle_remove_bot, name="remove-bot"
|
||||||
|
),
|
||||||
web.get(
|
web.get(
|
||||||
"/client/remove/{resource}",
|
"/client/remove/{resource}",
|
||||||
self.handle_RemoveClient,
|
self._handle_remove_client,
|
||||||
name="remove-client",
|
name="remove-client",
|
||||||
),
|
),
|
||||||
web.get(
|
web.get(
|
||||||
"/restart_{service}",
|
"/restart_{service}",
|
||||||
self.handle_RestartService,
|
self._handle_restart_service,
|
||||||
name="restart-service",
|
name="restart-service",
|
||||||
),
|
),
|
||||||
web.post("/lookup.do", self.handle_lookup),
|
web.post("/lookup.do", self._handle_lookup),
|
||||||
web.post("/newauth.do", self.handle_newauth),
|
web.post("/newauth.do", self._handle_newauth),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -94,11 +116,17 @@ class ConfServer:
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load plugins
|
# Load plugins
|
||||||
for plug in bumper.discovered_plugins:
|
for module in bumper.discovered_plugins.values():
|
||||||
if isinstance(
|
plugins = [
|
||||||
bumper.discovered_plugins[plug].plugin, bumper.plugins.ConfServerApp
|
m[1]
|
||||||
):
|
for m in inspect.getmembers(module, inspect.isclass)
|
||||||
plugin = bumper.discovered_plugins[plug].plugin
|
if m[1].__module__ == module.__name__
|
||||||
|
]
|
||||||
|
for plugin_type in plugins:
|
||||||
|
if not issubclass(plugin_type, ConfServerApp):
|
||||||
|
continue
|
||||||
|
|
||||||
|
plugin = plugin_type()
|
||||||
if plugin.plugin_type == "sub_api": # app or sub_api
|
if plugin.plugin_type == "sub_api": # app or sub_api
|
||||||
if plugin.sub_api in apis:
|
if plugin.sub_api in apis:
|
||||||
if plugin.routes:
|
if plugin.routes:
|
||||||
|
|
@ -108,73 +136,51 @@ class ConfServer:
|
||||||
elif plugin.plugin_type == "app":
|
elif plugin.plugin_type == "app":
|
||||||
if plugin.path_prefix and plugin.app:
|
if plugin.path_prefix and plugin.app:
|
||||||
logging.debug(f"Adding confserver plugin ({plugin.name})")
|
logging.debug(f"Adding confserver plugin ({plugin.name})")
|
||||||
self.app.add_subapp(plugin.path_prefix, plugin.app)
|
self._app.add_subapp(plugin.path_prefix, plugin.app)
|
||||||
|
|
||||||
for api in apis:
|
for api in apis:
|
||||||
self.app.add_subapp(apis[api]["prefix"], apis[api]["app"])
|
self._app.add_subapp(apis[api]["prefix"], apis[api]["app"])
|
||||||
|
|
||||||
# for resource in self.app.router.resources():
|
async def start(self) -> None:
|
||||||
# print(resource)
|
"""Start server."""
|
||||||
|
|
||||||
async def start_site(self, app, address="localhost", port=8080, usessl=False):
|
|
||||||
try:
|
try:
|
||||||
runner = web.AppRunner(app)
|
confserverlog.info("Starting ConfServer")
|
||||||
self.runners.append(runner)
|
for binding in self._bindings:
|
||||||
|
runner = web.AppRunner(self._app)
|
||||||
|
self._runners.append(runner)
|
||||||
await runner.setup()
|
await runner.setup()
|
||||||
if usessl:
|
|
||||||
|
ssl_ctx = None
|
||||||
|
if binding.use_ssl:
|
||||||
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||||
ssl_ctx.load_cert_chain(bumper.server_cert, bumper.server_key)
|
ssl_ctx.load_cert_chain(bumper.server_cert, bumper.server_key)
|
||||||
|
|
||||||
site = web.TCPSite(
|
site = web.TCPSite(
|
||||||
runner,
|
runner,
|
||||||
host=address,
|
host=binding.host,
|
||||||
port=port,
|
port=binding.port,
|
||||||
ssl_context=ssl_ctx,
|
ssl_context=ssl_ctx,
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
|
||||||
site = web.TCPSite(runner, host=address, port=port)
|
|
||||||
|
|
||||||
await site.start()
|
await site.start()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception(f"{e}")
|
confserverlog.exception(f"{e}")
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
async def start_server(self):
|
async def shutdown(self) -> None:
|
||||||
|
"""Shutdown server."""
|
||||||
try:
|
try:
|
||||||
confserverlog.info(
|
confserverlog.info("Shutting down")
|
||||||
f"Starting ConfServer at {self.address[0]}:{self.address[1]}"
|
for runner in self._runners:
|
||||||
)
|
await runner.shutdown()
|
||||||
self.runner = web.AppRunner(self.app)
|
|
||||||
await self.runner.setup()
|
|
||||||
|
|
||||||
if self.usessl:
|
self._runners.clear()
|
||||||
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
await self._app.shutdown()
|
||||||
ssl_ctx.load_cert_chain(bumper.server_cert, bumper.server_key)
|
|
||||||
self.site = web.TCPSite(
|
|
||||||
self.runner,
|
|
||||||
host=self.address[0],
|
|
||||||
port=self.address[1],
|
|
||||||
ssl_context=ssl_ctx,
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
self.site = web.TCPSite(
|
|
||||||
self.runner, host=self.address[0], port=self.address[1]
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.site.start()
|
|
||||||
except Exception as e:
|
|
||||||
confserverlog.exception(f"{e}")
|
|
||||||
raise e
|
|
||||||
|
|
||||||
async def stop_server(self):
|
|
||||||
try:
|
|
||||||
await self.runner.shutdown()
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception(f"{e}")
|
confserverlog.exception(f"{e}")
|
||||||
|
|
||||||
async def handle_base(self, request):
|
async def _handle_base(self, request: Request) -> Response:
|
||||||
try:
|
try:
|
||||||
bots = bumper.db_get().table("bots").all()
|
bots = bumper.db_get().table("bots").all()
|
||||||
clients = bumper.db_get().table("clients").all()
|
clients = bumper.db_get().table("clients").all()
|
||||||
|
|
@ -196,20 +202,21 @@ class ConfServer:
|
||||||
"sessions": {
|
"sessions": {
|
||||||
"count": len(mq_sessions),
|
"count": len(mq_sessions),
|
||||||
"clients": mq_sessions,
|
"clients": mq_sessions,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"xmpp_server": bumper.xmpp_server,
|
"xmpp_server": bumper.xmpp_server,
|
||||||
}
|
}
|
||||||
resp = aiohttp_jinja2.render_template("home.jinja2", request, context=all)
|
return aiohttp_jinja2.render_template("home.jinja2", request, context=all)
|
||||||
return resp
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception(f"{e}")
|
confserverlog.exception(f"{e}")
|
||||||
|
|
||||||
@web.middleware
|
raise HTTPInternalServerError
|
||||||
async def log_all_requests(self, request, handler):
|
|
||||||
|
|
||||||
if request._match_info.route.name not in self.excludelogging:
|
@web.middleware
|
||||||
|
async def _log_all_requests(
|
||||||
|
self, request: Request, handler: Handler
|
||||||
|
) -> StreamResponse:
|
||||||
|
if request._match_info.route.name not in self._EXCLUDE_FROM_LOGGING:
|
||||||
to_log = {
|
to_log = {
|
||||||
"request": {
|
"request": {
|
||||||
"route_name": f"{request.match_info.route.name}",
|
"route_name": f"{request.match_info.route.name}",
|
||||||
|
|
@ -230,8 +237,8 @@ class ConfServer:
|
||||||
try:
|
try:
|
||||||
postbody = json.loads(await request.text())
|
postbody = json.loads(await request.text())
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.error(f"Request body not json: {e} - {e.doc}")
|
confserverlog.error(f"Request body not json: {e}")
|
||||||
postbody = e.doc
|
raise HTTPBadRequest(reason="Body was not json")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
postbody = await request.post()
|
postbody = await request.post()
|
||||||
|
|
@ -242,12 +249,15 @@ class ConfServer:
|
||||||
if response is None:
|
if response is None:
|
||||||
confserverlog.warning("Response was null!")
|
confserverlog.warning("Response was null!")
|
||||||
confserverlog.warning(json.dumps(to_log))
|
confserverlog.warning(json.dumps(to_log))
|
||||||
return response
|
raise HTTPNoContent
|
||||||
|
|
||||||
to_log["response"] = {
|
to_log["response"] = {
|
||||||
"status": f"{response.status}",
|
"status": f"{response.status}",
|
||||||
}
|
}
|
||||||
if not "application/octet-stream" in response.content_type:
|
if (
|
||||||
|
"application/octet-stream" not in response.content_type
|
||||||
|
and isinstance(response, Response)
|
||||||
|
):
|
||||||
to_log["response"]["body"] = f"{json.loads(response.body)}"
|
to_log["response"]["body"] = f"{json.loads(response.body)}"
|
||||||
|
|
||||||
confserverlog.debug(json.dumps(to_log))
|
confserverlog.debug(json.dumps(to_log))
|
||||||
|
|
@ -262,16 +272,16 @@ class ConfServer:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception(f"{e}")
|
confserverlog.exception(f"{e}")
|
||||||
confserverlog.error(json.dumps(to_log))
|
confserverlog.error(json.dumps(to_log))
|
||||||
return e
|
raise e
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return await handler(request)
|
return await handler(request)
|
||||||
|
|
||||||
async def restart_Helper(self):
|
async def _restart_helper_bot(self) -> None:
|
||||||
await bumper.mqtt_helperbot.disconnect()
|
await bumper.mqtt_helperbot.disconnect()
|
||||||
asyncio.create_task(bumper.mqtt_helperbot.start())
|
asyncio.create_task(bumper.mqtt_helperbot.start())
|
||||||
|
|
||||||
async def restart_MQTT(self):
|
async def _restart_mqtt_server(self) -> None:
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
if bumper.mqtt_server.state not in ["stopped", "not_started"]:
|
if bumper.mqtt_server.state not in ["stopped", "not_started"]:
|
||||||
|
|
@ -287,35 +297,31 @@ class ConfServer:
|
||||||
|
|
||||||
loop.call_later(1.5, lambda: asyncio.create_task(bumper.mqtt_server.start()))
|
loop.call_later(1.5, lambda: asyncio.create_task(bumper.mqtt_server.start()))
|
||||||
|
|
||||||
async def restart_XMPP(self):
|
async def _handle_restart_service(self, request: Request) -> Response:
|
||||||
bumper.xmpp_server.disconnect()
|
|
||||||
await bumper.xmpp_server.start_async_server()
|
|
||||||
|
|
||||||
async def handle_RestartService(self, request):
|
|
||||||
try:
|
try:
|
||||||
service = request.match_info.get("service", "")
|
service = request.match_info.get("service", "")
|
||||||
if service == "Helperbot":
|
if service == "Helperbot":
|
||||||
await self.restart_Helper()
|
await self._restart_helper_bot()
|
||||||
return web.json_response({"status": "complete"})
|
return web.json_response({"status": "complete"})
|
||||||
elif service == "MQTTServer":
|
if service == "MQTTServer":
|
||||||
asyncio.create_task(self.restart_MQTT())
|
asyncio.create_task(self._restart_mqtt_server())
|
||||||
aloop = asyncio.get_event_loop()
|
aloop = asyncio.get_event_loop()
|
||||||
aloop.call_later(
|
aloop.call_later(
|
||||||
5, lambda: asyncio.create_task(self.restart_Helper())
|
5, lambda: asyncio.create_task(self._restart_helper_bot())
|
||||||
) # In 5 seconds restart Helperbot
|
) # In 5 seconds restart Helperbot
|
||||||
|
|
||||||
return web.json_response({"status": "complete"})
|
return web.json_response({"status": "complete"})
|
||||||
elif service == "XMPPServer":
|
if service == "XMPPServer":
|
||||||
await self.restart_XMPP()
|
bumper.xmpp_server.disconnect()
|
||||||
|
await bumper.xmpp_server.start_async_server()
|
||||||
return web.json_response({"status": "complete"})
|
return web.json_response({"status": "complete"})
|
||||||
else:
|
|
||||||
return web.json_response({"status": "invalid service"})
|
|
||||||
|
|
||||||
|
return web.json_response({"status": "invalid service"})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception(f"{e}")
|
confserverlog.exception(f"{e}")
|
||||||
pass
|
raise
|
||||||
|
|
||||||
async def handle_RemoveBot(self, request):
|
async def _handle_remove_bot(self, request: Request) -> Response:
|
||||||
try:
|
try:
|
||||||
did = request.match_info.get("did", "")
|
did = request.match_info.get("did", "")
|
||||||
bumper.bot_remove(did)
|
bumper.bot_remove(did)
|
||||||
|
|
@ -326,9 +332,10 @@ class ConfServer:
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception(f"{e}")
|
confserverlog.exception(f"{e}")
|
||||||
pass
|
|
||||||
|
|
||||||
async def handle_RemoveClient(self, request):
|
raise HTTPInternalServerError
|
||||||
|
|
||||||
|
async def _handle_remove_client(self, request: Request) -> Response:
|
||||||
try:
|
try:
|
||||||
resource = request.match_info.get("resource", "")
|
resource = request.match_info.get("resource", "")
|
||||||
bumper.client_remove(resource)
|
bumper.client_remove(resource)
|
||||||
|
|
@ -339,93 +346,20 @@ class ConfServer:
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception(f"{e}")
|
confserverlog.exception(f"{e}")
|
||||||
pass
|
|
||||||
|
|
||||||
async def handle_login(self, request):
|
raise HTTPInternalServerError
|
||||||
|
|
||||||
|
async def _handle_lookup(self, request: Request) -> Response:
|
||||||
try:
|
try:
|
||||||
user_devid = request.match_info.get("devid", "")
|
|
||||||
countrycode = request.match_info.get("country", "us")
|
|
||||||
apptype = request.match_info.get("apptype", "")
|
|
||||||
confserverlog.info(f"client with devid {user_devid} attempting login")
|
|
||||||
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(f"{e}")
|
|
||||||
|
|
||||||
async def handle_lookup(self, request):
|
|
||||||
try:
|
|
||||||
|
|
||||||
body = {}
|
|
||||||
postbody = {}
|
|
||||||
if request.content_type == "application/x-www-form-urlencoded":
|
if request.content_type == "application/x-www-form-urlencoded":
|
||||||
postbody = await request.post()
|
body = await request.post()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
postbody = json.loads(await request.text())
|
body = json.loads(await request.text())
|
||||||
|
|
||||||
confserverlog.debug(postbody)
|
confserverlog.debug(body)
|
||||||
|
|
||||||
todo = postbody["todo"]
|
if body["todo"] == "FindBest":
|
||||||
if todo == "FindBest":
|
service = body["service"]
|
||||||
service = postbody["service"]
|
|
||||||
if service == "EcoMsgNew":
|
if service == "EcoMsgNew":
|
||||||
srvip = bumper.bumper_announce_ip
|
srvip = bumper.bumper_announce_ip
|
||||||
srvport = 5223
|
srvport = 5223
|
||||||
|
|
@ -434,13 +368,10 @@ class ConfServer:
|
||||||
srvip, srvport
|
srvip, srvport
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
msgserver = {"ip": srvip, "port": srvport, "result": "ok"}
|
server = json.dumps({"ip": srvip, "port": srvport, "result": "ok"})
|
||||||
msgserver = json.dumps(msgserver)
|
# bot seems to be very picky about having no spaces, only way was with text
|
||||||
msgserver = msgserver.replace(
|
server = server.replace(" ", "")
|
||||||
" ", ""
|
return web.json_response(text=server)
|
||||||
) # bot seems to be very picky about having no spaces, only way was with text
|
|
||||||
|
|
||||||
return web.json_response(text=msgserver)
|
|
||||||
|
|
||||||
elif service == "EcoUpdate":
|
elif service == "EcoUpdate":
|
||||||
srvip = "47.88.66.164" # EcoVacs Server
|
srvip = "47.88.66.164" # EcoVacs Server
|
||||||
|
|
@ -450,14 +381,18 @@ class ConfServer:
|
||||||
srvip, srvport
|
srvip, srvport
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
body = {"result": "ok", "ip": srvip, "port": srvport}
|
return web.json_response(
|
||||||
|
{"result": "ok", "ip": srvip, "port": srvport}
|
||||||
|
)
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response({})
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception(f"{e}")
|
confserverlog.exception(f"{e}")
|
||||||
|
|
||||||
async def handle_newauth(self, request):
|
raise HTTPInternalServerError
|
||||||
|
|
||||||
|
async def _handle_newauth(self, request: Request) -> Response:
|
||||||
# Bumper is only returning the submitted token. No reason yet to create another new token
|
# Bumper is only returning the submitted token. No reason yet to create another new token
|
||||||
try:
|
try:
|
||||||
if request.content_type == "application/x-www-form-urlencoded":
|
if request.content_type == "application/x-www-form-urlencoded":
|
||||||
|
|
@ -474,401 +409,4 @@ class ConfServer:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
confserverlog.exception(f"{e}")
|
confserverlog.exception(f"{e}")
|
||||||
|
|
||||||
async def disconnect(self):
|
raise HTTPInternalServerError
|
||||||
try:
|
|
||||||
confserverlog.info("shutting down")
|
|
||||||
await self.app.shutdown()
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
confserverlog.exception(f"{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(f"{e}")
|
|
||||||
|
|
||||||
def generate_authcode(self, user, countrycode, token):
|
|
||||||
try:
|
|
||||||
tmpauthcode = f"{countrycode}_{uuid.uuid4().hex}"
|
|
||||||
bumper.user_add_authcode(user["userid"], token, tmpauthcode)
|
|
||||||
return tmpauthcode
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
confserverlog.exception(f"{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(f"client with devid {user_devid} attempting login")
|
|
||||||
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(f"{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(f"{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(f"{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(f"No DID for bot: {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(f"{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()),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Example body
|
|
||||||
# {
|
|
||||||
# "code": "0000",
|
|
||||||
# "data": {
|
|
||||||
# "email": "user@gmail.com",
|
|
||||||
# "hasMobile": "N",
|
|
||||||
# "hasPassword": "Y",
|
|
||||||
# "headIco": "",
|
|
||||||
# "loginName": "user@gmail.com",
|
|
||||||
# "mobile": null,
|
|
||||||
# "mobileAreaNo": null,
|
|
||||||
# "nickname": "",
|
|
||||||
# "obfuscatedMobile": null,
|
|
||||||
# "thirdLoginInfoList": [
|
|
||||||
# {
|
|
||||||
# "accountType": "WeChat",
|
|
||||||
# "hasBind": "N"
|
|
||||||
# }
|
|
||||||
# ],
|
|
||||||
# "uid": "20180719212155_*****",
|
|
||||||
# "userName": "EAY*****"
|
|
||||||
# },
|
|
||||||
# "msg": "操作成功",
|
|
||||||
# "success": true,
|
|
||||||
# "time": 1578203898343
|
|
||||||
# }
|
|
||||||
|
|
||||||
return web.json_response(body)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
confserverlog.exception(f"{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(f"{e}")
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ def os_db_path(): # createdir=True):
|
||||||
return os.path.join(bumper.data_dir, "bumper.db")
|
return os.path.join(bumper.data_dir, "bumper.db")
|
||||||
|
|
||||||
|
|
||||||
def db_get():
|
def db_get() -> TinyDB:
|
||||||
# Will create the database if it doesn't exist
|
# Will create the database if it doesn't exist
|
||||||
db = TinyDB(db_file())
|
db = TinyDB(db_file())
|
||||||
|
|
||||||
|
|
@ -340,7 +340,7 @@ def bot_add(sn: str, did: str, devclass: str, resource: str, company: str) -> No
|
||||||
bot_full_upsert(newbot.asdict())
|
bot_full_upsert(newbot.asdict())
|
||||||
|
|
||||||
|
|
||||||
def bot_remove(did):
|
def bot_remove(did: str):
|
||||||
bots = db_get().table("bots")
|
bots = db_get().table("bots")
|
||||||
bot = bot_get(did)
|
bot = bot_get(did)
|
||||||
if bot:
|
if bot:
|
||||||
|
|
@ -392,7 +392,7 @@ def client_add(userid: str, realm: str, resource: str) -> None:
|
||||||
client_full_upsert(newclient.asdict())
|
client_full_upsert(newclient.asdict())
|
||||||
|
|
||||||
|
|
||||||
def client_remove(resource):
|
def client_remove(resource: str):
|
||||||
clients = db_get().table("clients")
|
clients = db_get().table("clients")
|
||||||
client = client_get(resource)
|
client = client_get(resource)
|
||||||
if client:
|
if client:
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from typing import Any
|
||||||
from amqtt.session import Session
|
from amqtt.session import Session
|
||||||
|
|
||||||
import bumper
|
import bumper
|
||||||
|
from bumper.util import convert_to_millis
|
||||||
|
|
||||||
|
|
||||||
class VacBotDevice:
|
class VacBotDevice:
|
||||||
|
|
@ -116,9 +117,7 @@ class OAuth:
|
||||||
|
|
||||||
def toResponse(self):
|
def toResponse(self):
|
||||||
data = self.__dict__
|
data = self.__dict__
|
||||||
data[
|
data["expire_at"] = convert_to_millis(
|
||||||
"expire_at"
|
|
||||||
] = bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time(
|
|
||||||
datetime.fromisoformat(self.expire_at).timestamp()
|
datetime.fromisoformat(self.expire_at).timestamp()
|
||||||
)
|
)
|
||||||
return data
|
return data
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
|
|
||||||
from bumper import plugins
|
import bumper
|
||||||
from bumper.models import *
|
from bumper.plugins import ConfServerApp
|
||||||
|
|
||||||
|
|
||||||
class portal_api_appsvr(plugins.ConfServerApp):
|
class portal_api_appsvr(ConfServerApp):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = "portal_api_appsvr"
|
self.name = "portal_api_appsvr"
|
||||||
self.plugin_type = "sub_api"
|
self.plugin_type = "sub_api"
|
||||||
|
|
@ -34,10 +35,6 @@ class portal_api_appsvr(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_appsvr_app(self, request):
|
async def handle_appsvr_app(self, request):
|
||||||
if not request.method == "GET": # Skip GET for now
|
if not request.method == "GET": # Skip GET for now
|
||||||
try:
|
try:
|
||||||
|
|
@ -211,6 +208,3 @@ class portal_api_appsvr(plugins.ConfServerApp):
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = portal_api_appsvr()
|
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,6 @@ class portal_api_dim(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_dim_devmanager(self, request): # Used in EcoVacs Home App
|
async def handle_dim_devmanager(self, request): # Used in EcoVacs Home App
|
||||||
try:
|
try:
|
||||||
json_body = json.loads(await request.text())
|
json_body = json.loads(await request.text())
|
||||||
|
|
@ -76,6 +72,3 @@ class portal_api_dim(plugins.ConfServerApp):
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = portal_api_dim()
|
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,6 @@ class portal_api_ecms(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_ad_res(self, request):
|
async def handle_ad_res(self, request):
|
||||||
try:
|
try:
|
||||||
body = {"code": 0, "data": [], "message": "success", "success": True}
|
body = {"code": 0, "data": [], "message": "success", "success": True}
|
||||||
|
|
@ -34,6 +30,3 @@ class portal_api_ecms(plugins.ConfServerApp):
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = portal_api_ecms()
|
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,6 @@ class portal_api_iot(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_devmanager_botcommand(self, request):
|
async def handle_devmanager_botcommand(self, request):
|
||||||
try:
|
try:
|
||||||
json_body = json.loads(await request.text())
|
json_body = json.loads(await request.text())
|
||||||
|
|
@ -81,6 +77,3 @@ class portal_api_iot(plugins.ConfServerApp):
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = portal_api_iot()
|
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,6 @@ class portal_api_lg(plugins.ConfServerApp):
|
||||||
web.route("*", "/lg/log.do", self.handle_lg_log, name="portal_api_lg_log"),
|
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
|
async def handle_lg_log(self, request): # EcoVacs Home
|
||||||
randomid = "".join(random.sample(string.ascii_letters, 6))
|
randomid = "".join(random.sample(string.ascii_letters, 6))
|
||||||
|
|
||||||
|
|
@ -101,6 +97,3 @@ class portal_api_lg(plugins.ConfServerApp):
|
||||||
|
|
||||||
body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"}
|
body = {"id": randomid, "errno": bumper.ERR_COMMON, "ret": "fail"}
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
|
|
||||||
plugin = portal_api_lg()
|
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,6 @@ class portal_api_neng(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_neng_hasUnreadMessage(self, request): # EcoVacs Home
|
async def handle_neng_hasUnreadMessage(self, request): # EcoVacs Home
|
||||||
try:
|
try:
|
||||||
body = {"code": 0, "data": {"hasUnRead": True}}
|
body = {"code": 0, "data": {"hasUnRead": True}}
|
||||||
|
|
@ -107,6 +103,3 @@ class portal_api_neng(plugins.ConfServerApp):
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = portal_api_neng()
|
|
||||||
|
|
|
||||||
|
|
@ -53,10 +53,6 @@ class portal_api_pim(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_getProductIotMap(self, request):
|
async def handle_getProductIotMap(self, request):
|
||||||
try:
|
try:
|
||||||
body = {
|
body = {
|
||||||
|
|
@ -130,8 +126,6 @@ class portal_api_pim(plugins.ConfServerApp):
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = portal_api_pim()
|
|
||||||
|
|
||||||
confignetAllResponse = {
|
confignetAllResponse = {
|
||||||
"code": 0,
|
"code": 0,
|
||||||
"data": [
|
"data": [
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,6 @@ class api_rapp(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_map_get(self, request):
|
async def handle_map_get(self, request):
|
||||||
try:
|
try:
|
||||||
body = {
|
body = {
|
||||||
|
|
@ -35,6 +31,3 @@ class api_rapp(plugins.ConfServerApp):
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = api_rapp()
|
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,6 @@ class portal_api_users(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_usersapi(self, request):
|
async def handle_usersapi(self, request):
|
||||||
if not request.method == "GET": # Skip GET for now
|
if not request.method == "GET": # Skip GET for now
|
||||||
try:
|
try:
|
||||||
|
|
@ -120,6 +116,3 @@ class portal_api_users(plugins.ConfServerApp):
|
||||||
# Return fail for GET
|
# Return fail for GET
|
||||||
body = {"result": "fail", "todo": "result"}
|
body = {"result": "fail", "todo": "result"}
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
|
|
||||||
plugin = portal_api_users()
|
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,6 @@ class upload_global(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_upload_global_file(self, request):
|
async def handle_upload_global_file(self, request):
|
||||||
try:
|
try:
|
||||||
fileID = request.match_info.get("id", "")
|
fileID = request.match_info.get("id", "")
|
||||||
|
|
@ -42,6 +38,3 @@ class upload_global(plugins.ConfServerApp):
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = upload_global()
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from aiohttp import web
|
||||||
import bumper
|
import bumper
|
||||||
from bumper import plugins
|
from bumper import plugins
|
||||||
from bumper.models import *
|
from bumper.models import *
|
||||||
|
from bumper.rest import auth_util
|
||||||
|
|
||||||
|
|
||||||
class v1_global_auth(plugins.ConfServerApp):
|
class v1_global_auth(plugins.ConfServerApp):
|
||||||
|
|
@ -16,19 +17,11 @@ class v1_global_auth(plugins.ConfServerApp):
|
||||||
self.plugin_type = "sub_api"
|
self.plugin_type = "sub_api"
|
||||||
self.sub_api = "api_v1"
|
self.sub_api = "api_v1"
|
||||||
|
|
||||||
authhandler = bumper.ConfServer.ConfServer_AuthHandler()
|
|
||||||
self.routes = [
|
self.routes = [
|
||||||
web.route(
|
web.route(
|
||||||
"*",
|
"*",
|
||||||
"/global/auth/getAuthCode",
|
"/global/auth/getAuthCode",
|
||||||
authhandler.get_AuthCode,
|
auth_util.get_authcode,
|
||||||
name="v1_global_auth_getAuthCode",
|
name="v1_global_auth_getAuthCode",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
plugin = v1_global_auth()
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from aiohttp import web
|
||||||
import bumper
|
import bumper
|
||||||
from bumper import plugins
|
from bumper import plugins
|
||||||
from bumper.models import *
|
from bumper.models import *
|
||||||
|
from bumper.util import get_current_time_as_millis
|
||||||
|
|
||||||
|
|
||||||
class v1_private_ad(plugins.ConfServerApp):
|
class v1_private_ad(plugins.ConfServerApp):
|
||||||
|
|
@ -31,10 +32,6 @@ class v1_private_ad(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_getAdByPositionType(self, request): # EcoVacs Home
|
async def handle_getAdByPositionType(self, request): # EcoVacs Home
|
||||||
try:
|
try:
|
||||||
body = {
|
body = {
|
||||||
|
|
@ -42,7 +39,7 @@ class v1_private_ad(plugins.ConfServerApp):
|
||||||
"data": None,
|
"data": None,
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -57,13 +54,10 @@ class v1_private_ad(plugins.ConfServerApp):
|
||||||
"data": None,
|
"data": None,
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = v1_private_ad()
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from aiohttp import web
|
||||||
import bumper
|
import bumper
|
||||||
from bumper import plugins
|
from bumper import plugins
|
||||||
from bumper.models import *
|
from bumper.models import *
|
||||||
|
from bumper.util import get_current_time_as_millis
|
||||||
|
|
||||||
|
|
||||||
class v1_private_campaign(plugins.ConfServerApp):
|
class v1_private_campaign(plugins.ConfServerApp):
|
||||||
|
|
@ -25,13 +26,9 @@ class v1_private_campaign(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_homePageAlert(self, request):
|
async def handle_homePageAlert(self, request):
|
||||||
try:
|
try:
|
||||||
nextAlert = self.get_milli_time(
|
nextAlert = convert_to_millis(
|
||||||
(datetime.now() + timedelta(hours=12)).timestamp()
|
(datetime.now() + timedelta(hours=12)).timestamp()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -43,16 +40,13 @@ class v1_private_campaign(plugins.ConfServerApp):
|
||||||
"hasCampaign": "N",
|
"hasCampaign": "N",
|
||||||
"imageUrl": None,
|
"imageUrl": None,
|
||||||
"nextAlertTime": nextAlert,
|
"nextAlertTime": nextAlert,
|
||||||
"serverTime": self.get_milli_time(datetime.utcnow().timestamp()),
|
"serverTime": get_current_time_as_millis(),
|
||||||
},
|
},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = v1_private_campaign()
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from aiohttp import web
|
||||||
|
|
||||||
from bumper import plugins
|
from bumper import plugins
|
||||||
from bumper.models import *
|
from bumper.models import *
|
||||||
|
from bumper.util import get_current_time_as_millis
|
||||||
|
|
||||||
|
|
||||||
class v1_private_common(plugins.ConfServerApp):
|
class v1_private_common(plugins.ConfServerApp):
|
||||||
|
|
@ -64,10 +65,6 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_checkVersion(self, request):
|
async def handle_checkVersion(self, request):
|
||||||
try:
|
try:
|
||||||
body = {
|
body = {
|
||||||
|
|
@ -82,7 +79,7 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
"v": None,
|
"v": None,
|
||||||
},
|
},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -107,7 +104,7 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
},
|
},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -122,7 +119,7 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
"data": None,
|
"data": None,
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -144,7 +141,7 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
},
|
},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -163,7 +160,7 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
"data": data,
|
"data": data,
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -178,7 +175,7 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
"data": AREA_LIST,
|
"data": AREA_LIST,
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -210,7 +207,7 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
],
|
],
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -220,7 +217,7 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
|
|
||||||
async def handle_getTimestamp(self, request): # EcoVacs Home
|
async def handle_getTimestamp(self, request): # EcoVacs Home
|
||||||
try:
|
try:
|
||||||
time = self.get_milli_time(datetime.utcnow().timestamp())
|
time = get_current_time_as_millis()
|
||||||
body = {
|
body = {
|
||||||
"code": bumper.RETURN_API_SUCCESS,
|
"code": bumper.RETURN_API_SUCCESS,
|
||||||
"data": {"timestamp": time},
|
"data": {"timestamp": time},
|
||||||
|
|
@ -235,8 +232,6 @@ class v1_private_common(plugins.ConfServerApp):
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = v1_private_common()
|
|
||||||
|
|
||||||
AREA_LIST = {
|
AREA_LIST = {
|
||||||
"currentVersion": 231,
|
"currentVersion": 231,
|
||||||
"areaList": [
|
"areaList": [
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from aiohttp import web
|
||||||
import bumper
|
import bumper
|
||||||
from bumper import plugins
|
from bumper import plugins
|
||||||
from bumper.models import *
|
from bumper.models import *
|
||||||
|
from bumper.util import get_current_time_as_millis
|
||||||
|
|
||||||
|
|
||||||
class v1_private_message(plugins.ConfServerApp):
|
class v1_private_message(plugins.ConfServerApp):
|
||||||
|
|
@ -31,10 +32,6 @@ class v1_private_message(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_hasUnreadMessage(self, request): # EcoVacs Home
|
async def handle_hasUnreadMessage(self, request): # EcoVacs Home
|
||||||
try:
|
try:
|
||||||
body = {
|
body = {
|
||||||
|
|
@ -42,7 +39,7 @@ class v1_private_message(plugins.ConfServerApp):
|
||||||
"data": "N",
|
"data": "N",
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -57,13 +54,10 @@ class v1_private_message(plugins.ConfServerApp):
|
||||||
"data": {"hasNextPage": 0, "items": []},
|
"data": {"hasNextPage": 0, "items": []},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = v1_private_message()
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from aiohttp import web
|
||||||
import bumper
|
import bumper
|
||||||
from bumper import plugins
|
from bumper import plugins
|
||||||
from bumper.models import *
|
from bumper.models import *
|
||||||
|
from bumper.util import get_current_time_as_millis
|
||||||
|
|
||||||
|
|
||||||
class v1_private_shop(plugins.ConfServerApp):
|
class v1_private_shop(plugins.ConfServerApp):
|
||||||
|
|
@ -25,10 +26,6 @@ class v1_private_shop(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_getCnWapShopConfig(self, request): # EcoVacs Home
|
async def handle_getCnWapShopConfig(self, request): # EcoVacs Home
|
||||||
try:
|
try:
|
||||||
body = {
|
body = {
|
||||||
|
|
@ -41,13 +38,10 @@ class v1_private_shop(plugins.ConfServerApp):
|
||||||
},
|
},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = v1_private_shop()
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ from aiohttp import web
|
||||||
import bumper
|
import bumper
|
||||||
from bumper import plugins
|
from bumper import plugins
|
||||||
from bumper.models import *
|
from bumper.models import *
|
||||||
|
from bumper.rest import auth_util
|
||||||
|
from bumper.util import get_current_time_as_millis
|
||||||
|
|
||||||
|
|
||||||
class v1_private_user(plugins.ConfServerApp):
|
class v1_private_user(plugins.ConfServerApp):
|
||||||
|
|
@ -17,30 +19,29 @@ class v1_private_user(plugins.ConfServerApp):
|
||||||
self.plugin_type = "sub_api"
|
self.plugin_type = "sub_api"
|
||||||
self.sub_api = "api_v1"
|
self.sub_api = "api_v1"
|
||||||
|
|
||||||
authhandler = bumper.ConfServer.ConfServer_AuthHandler()
|
|
||||||
self.routes = [
|
self.routes = [
|
||||||
web.route(
|
web.route(
|
||||||
"*",
|
"*",
|
||||||
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login",
|
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login",
|
||||||
authhandler.login,
|
auth_util.login,
|
||||||
name="v1_user_login",
|
name="v1_user_login",
|
||||||
),
|
),
|
||||||
web.route(
|
web.route(
|
||||||
"*",
|
"*",
|
||||||
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin",
|
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin",
|
||||||
authhandler.login,
|
auth_util.login,
|
||||||
name="v1_user_checkLogin",
|
name="v1_user_checkLogin",
|
||||||
),
|
),
|
||||||
web.route(
|
web.route(
|
||||||
"*",
|
"*",
|
||||||
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode",
|
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode",
|
||||||
authhandler.get_AuthCode,
|
auth_util.get_authcode,
|
||||||
name="v1_user_getAuthCode",
|
name="v1_user_getAuthCode",
|
||||||
),
|
),
|
||||||
web.route(
|
web.route(
|
||||||
"*",
|
"*",
|
||||||
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout",
|
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout",
|
||||||
authhandler.logout,
|
auth_util.logout,
|
||||||
name="v1_user_logout",
|
name="v1_user_logout",
|
||||||
),
|
),
|
||||||
web.route(
|
web.route(
|
||||||
|
|
@ -58,7 +59,7 @@ class v1_private_user(plugins.ConfServerApp):
|
||||||
web.route(
|
web.route(
|
||||||
"*",
|
"*",
|
||||||
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo",
|
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getUserAccountInfo",
|
||||||
authhandler.getUserAccountInfo,
|
auth_util.get_user_account_info,
|
||||||
name="v1_user_getUserAccountInfo",
|
name="v1_user_getUserAccountInfo",
|
||||||
),
|
),
|
||||||
web.route(
|
web.route(
|
||||||
|
|
@ -91,10 +92,6 @@ class v1_private_user(plugins.ConfServerApp):
|
||||||
# /registerByEmail
|
# /registerByEmail
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_checkAgreement(self, request):
|
async def handle_checkAgreement(self, request):
|
||||||
try:
|
try:
|
||||||
apptype = request.match_info.get("apptype", "")
|
apptype = request.match_info.get("apptype", "")
|
||||||
|
|
@ -119,14 +116,14 @@ class v1_private_user(plugins.ConfServerApp):
|
||||||
],
|
],
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
body = {
|
body = {
|
||||||
"code": bumper.RETURN_API_SUCCESS,
|
"code": bumper.RETURN_API_SUCCESS,
|
||||||
"data": [],
|
"data": [],
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -195,7 +192,7 @@ class v1_private_user(plugins.ConfServerApp):
|
||||||
],
|
],
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -210,7 +207,7 @@ class v1_private_user(plugins.ConfServerApp):
|
||||||
"data": {"isNeedReLogin": "N"},
|
"data": {"isNeedReLogin": "N"},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
@ -225,13 +222,10 @@ class v1_private_user(plugins.ConfServerApp):
|
||||||
"data": None,
|
"data": None,
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"success": True,
|
"success": True,
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = v1_private_user()
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
|
|
||||||
import bumper
|
import bumper
|
||||||
from bumper import plugins
|
from bumper import plugins
|
||||||
|
from bumper.util import get_current_time_as_millis
|
||||||
|
|
||||||
|
|
||||||
class v1_private_userSetting(plugins.ConfServerApp):
|
class v1_private_userSetting(plugins.ConfServerApp):
|
||||||
|
|
@ -24,10 +24,6 @@ class v1_private_userSetting(plugins.ConfServerApp):
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
async def handle_getSuggestionSetting(self, request):
|
async def handle_getSuggestionSetting(self, request):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
|
@ -54,13 +50,10 @@ class v1_private_userSetting(plugins.ConfServerApp):
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"msg": "操作成功",
|
"msg": "操作成功",
|
||||||
"time": self.get_milli_time(datetime.utcnow().timestamp()),
|
"time": get_current_time_as_millis(),
|
||||||
}
|
}
|
||||||
|
|
||||||
return web.json_response(body)
|
return web.json_response(body)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception(f"{e}")
|
logging.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
plugin = v1_private_userSetting()
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,8 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import asyncio
|
|
||||||
import logging
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
|
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
|
|
||||||
import bumper
|
|
||||||
from bumper import plugins
|
from bumper import plugins
|
||||||
from bumper.models import *
|
from bumper.rest import auth_util
|
||||||
|
|
||||||
|
|
||||||
class v2_private_user(plugins.ConfServerApp):
|
class v2_private_user(plugins.ConfServerApp):
|
||||||
|
|
@ -17,19 +12,11 @@ class v2_private_user(plugins.ConfServerApp):
|
||||||
self.plugin_type = "sub_api"
|
self.plugin_type = "sub_api"
|
||||||
self.sub_api = "api_v2"
|
self.sub_api = "api_v2"
|
||||||
|
|
||||||
authhandler = bumper.ConfServer.ConfServer_AuthHandler()
|
|
||||||
self.routes = [
|
self.routes = [
|
||||||
web.route(
|
web.route(
|
||||||
"*",
|
"*",
|
||||||
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin",
|
"/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin",
|
||||||
authhandler.login,
|
auth_util.login,
|
||||||
name="v2_user_checkLogin",
|
name="v2_user_checkLogin",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.get_milli_time = (
|
|
||||||
bumper.ConfServer.ConfServer_GeneralFunctions().get_milli_time
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
plugin = v2_private_user()
|
|
||||||
|
|
|
||||||
0
bumper/rest/__init__.py
Normal file
0
bumper/rest/__init__.py
Normal file
384
bumper/rest/auth_util.py
Normal file
384
bumper/rest/auth_util.py
Normal file
|
|
@ -0,0 +1,384 @@
|
||||||
|
"""Auth util module."""
|
||||||
|
import json
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from aiohttp import web
|
||||||
|
|
||||||
|
import bumper
|
||||||
|
from bumper import (
|
||||||
|
get_logger,
|
||||||
|
EcoVacsHome_Login,
|
||||||
|
EcoVacs_Login,
|
||||||
|
API_ERRORS,
|
||||||
|
RETURN_API_SUCCESS,
|
||||||
|
)
|
||||||
|
from bumper.util import get_current_time_as_millis
|
||||||
|
|
||||||
|
_logger = get_logger("confserver")
|
||||||
|
|
||||||
|
|
||||||
|
def generate_token(user):
|
||||||
|
try:
|
||||||
|
tmpaccesstoken = uuid.uuid4().hex
|
||||||
|
bumper.user_add_token(user["userid"], tmpaccesstoken)
|
||||||
|
return tmpaccesstoken
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
|
def generate_authcode(user, countrycode, token):
|
||||||
|
try:
|
||||||
|
tmpauthcode = f"{countrycode}_{uuid.uuid4().hex}"
|
||||||
|
bumper.user_add_authcode(user["userid"], token, tmpauthcode)
|
||||||
|
return tmpauthcode
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
|
async def login(request):
|
||||||
|
try:
|
||||||
|
user_devid = request.match_info.get("devid", "")
|
||||||
|
countrycode = request.match_info.get("country", "us")
|
||||||
|
apptype = request.match_info.get("apptype", "")
|
||||||
|
_logger.info(f"client with devid {user_devid} attempting login")
|
||||||
|
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:
|
||||||
|
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 = 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": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return web.json_response(body)
|
||||||
|
|
||||||
|
body = {
|
||||||
|
"code": bumper.ERR_USER_NOT_ACTIVATED,
|
||||||
|
"data": None,
|
||||||
|
"msg": "当前密码错误",
|
||||||
|
"time": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return web.json_response(body)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return web.json_response(
|
||||||
|
_auth_any(user_devid, apptype, countrycode, request)
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
|
async def get_authcode(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 = 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": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
body = {
|
||||||
|
"code": bumper.RETURN_API_SUCCESS,
|
||||||
|
"data": {
|
||||||
|
"authCode": authcode,
|
||||||
|
"ecovacsUid": request.query["uid"],
|
||||||
|
},
|
||||||
|
"msg": "操作成功",
|
||||||
|
"time": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
return web.json_response(body)
|
||||||
|
|
||||||
|
body = {
|
||||||
|
"code": bumper.ERR_TOKEN_INVALID,
|
||||||
|
"data": None,
|
||||||
|
"msg": "当前密码错误",
|
||||||
|
"time": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return web.json_response(body)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
|
def check_token(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": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
return web.json_response(body)
|
||||||
|
|
||||||
|
else:
|
||||||
|
body = {
|
||||||
|
"code": bumper.ERR_TOKEN_INVALID,
|
||||||
|
"data": None,
|
||||||
|
"msg": "当前密码错误",
|
||||||
|
"time": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
return web.json_response(body)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
|
def _auth_any(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 = 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 = 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:
|
||||||
|
_logger.error(f"No DID for bot: {bot}")
|
||||||
|
|
||||||
|
if "checkLogin" in request.path: # If request was to check a token do so
|
||||||
|
checkToken = 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": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return body
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_account_info(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": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
|
||||||
|
# Example body
|
||||||
|
# {
|
||||||
|
# "code": "0000",
|
||||||
|
# "data": {
|
||||||
|
# "email": "user@gmail.com",
|
||||||
|
# "hasMobile": "N",
|
||||||
|
# "hasPassword": "Y",
|
||||||
|
# "headIco": "",
|
||||||
|
# "loginName": "user@gmail.com",
|
||||||
|
# "mobile": null,
|
||||||
|
# "mobileAreaNo": null,
|
||||||
|
# "nickname": "",
|
||||||
|
# "obfuscatedMobile": null,
|
||||||
|
# "thirdLoginInfoList": [
|
||||||
|
# {
|
||||||
|
# "accountType": "WeChat",
|
||||||
|
# "hasBind": "N"
|
||||||
|
# }
|
||||||
|
# ],
|
||||||
|
# "uid": "20180719212155_*****",
|
||||||
|
# "userName": "EAY*****"
|
||||||
|
# },
|
||||||
|
# "msg": "操作成功",
|
||||||
|
# "success": true,
|
||||||
|
# "time": 1578203898343
|
||||||
|
# }
|
||||||
|
|
||||||
|
return web.json_response(body)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.exception(f"{e}")
|
||||||
|
|
||||||
|
|
||||||
|
async def logout(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": get_current_time_as_millis(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return web.json_response(body)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
_logger.exception(f"{e}")
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from datetime import datetime
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
from typing import MutableMapping
|
from typing import MutableMapping, Union
|
||||||
|
|
||||||
logformat = logging.Formatter(
|
logformat = logging.Formatter(
|
||||||
"[%(asctime)s] :: %(levelname)s :: %(name)s :: %(module)s :: %(funcName)s :: %(lineno)d :: %(message)s"
|
"[%(asctime)s] :: %(levelname)s :: %(name)s :: %(module)s :: %(funcName)s :: %(lineno)d :: %(message)s"
|
||||||
|
|
@ -43,3 +44,12 @@ def get_logger(name: str, rotate: RotatingFileHandler = None) -> logging.Logger:
|
||||||
get_logger("amqtt.client", rotate)
|
get_logger("amqtt.client", rotate)
|
||||||
|
|
||||||
return logger
|
return logger
|
||||||
|
|
||||||
|
|
||||||
|
def convert_to_millis(seconds: Union[int, float]) -> int:
|
||||||
|
"""Convert seconds to milliseconds."""
|
||||||
|
return int(round(seconds * 1000))
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_time_as_millis() -> int:
|
||||||
|
return convert_to_millis(datetime.utcnow().timestamp())
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class XMPPServer:
|
||||||
self.address = address
|
self.address = address
|
||||||
self.xmpp_protocol = lambda: XMPPServer_Protocol()
|
self.xmpp_protocol = lambda: XMPPServer_Protocol()
|
||||||
|
|
||||||
async def start_async_server(self):
|
async def start_async_server(self) -> None:
|
||||||
try:
|
try:
|
||||||
xmppserverlog.info(
|
xmppserverlog.info(
|
||||||
f"Starting XMPP Server at {self.address[0]}:{self.address[1]}"
|
f"Starting XMPP Server at {self.address[0]}:{self.address[1]}"
|
||||||
|
|
@ -44,7 +44,7 @@ class XMPPServer:
|
||||||
xmppserverlog.exception(f"{e}")
|
xmppserverlog.exception(f"{e}")
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self) -> None:
|
||||||
|
|
||||||
xmppserverlog.debug("waiting for all clients to disconnect")
|
xmppserverlog.debug("waiting for all clients to disconnect")
|
||||||
for client in self.clients:
|
for client in self.clients:
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
HOST = "127.0.0.1"
|
HOST = "127.0.0.1"
|
||||||
MQTT_PORT = 8883
|
MQTT_PORT = 8883
|
||||||
|
CONF_SERVER_PORT = 11111
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import pytest
|
||||||
from amqtt.client import MQTTClient
|
from amqtt.client import MQTTClient
|
||||||
|
|
||||||
import bumper
|
import bumper
|
||||||
from tests import HOST, MQTT_PORT
|
from bumper import WebServerBinding
|
||||||
|
from tests import HOST, MQTT_PORT, CONF_SERVER_PORT
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
@ -37,10 +38,8 @@ async def mqtt_client():
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def conf_server_client(aiohttp_client):
|
async def conf_server_client(aiohttp_client):
|
||||||
confserver = bumper.ConfServer("127.0.0.1:11111", False)
|
confserver = bumper.ConfServer(WebServerBinding(HOST, CONF_SERVER_PORT, False))
|
||||||
confserver.confserver_app()
|
client = await aiohttp_client(confserver._app)
|
||||||
|
|
||||||
client = await aiohttp_client(confserver.app)
|
|
||||||
|
|
||||||
yield client
|
yield client
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,12 @@ from aiohttp import web
|
||||||
from testfixtures import LogCapture
|
from testfixtures import LogCapture
|
||||||
|
|
||||||
import bumper
|
import bumper
|
||||||
from tests import HOST, MQTT_PORT
|
from bumper import WebServerBinding
|
||||||
|
from tests import HOST, MQTT_PORT, CONF_SERVER_PORT
|
||||||
|
|
||||||
|
|
||||||
def create_confserver():
|
def create_confserver():
|
||||||
return bumper.ConfServer("127.0.0.1:11111", False)
|
return bumper.ConfServer(WebServerBinding(HOST, CONF_SERVER_PORT, False))
|
||||||
|
|
||||||
|
|
||||||
def async_return(result):
|
def async_return(result):
|
||||||
|
|
@ -28,27 +29,13 @@ def remove_existing_db():
|
||||||
|
|
||||||
|
|
||||||
async def test_confserver_ssl():
|
async def test_confserver_ssl():
|
||||||
conf_server = bumper.ConfServer((HOST, 11111), usessl=True)
|
conf_server = bumper.ConfServer(WebServerBinding(HOST, CONF_SERVER_PORT, True))
|
||||||
conf_server.confserver_app()
|
await conf_server.start()
|
||||||
await conf_server.start_server()
|
|
||||||
|
|
||||||
|
|
||||||
async def test_confserver_no_ssl():
|
async def test_confserver_no_ssl():
|
||||||
conf_server = bumper.ConfServer((HOST, 11112), usessl=False)
|
conf_server = bumper.ConfServer(WebServerBinding(HOST, 11112, False))
|
||||||
conf_server.confserver_app()
|
await conf_server.start()
|
||||||
await conf_server.start_server()
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_milli_time():
|
|
||||||
cserv = create_confserver()
|
|
||||||
assert (
|
|
||||||
cserv.get_milli_time(
|
|
||||||
datetime.datetime(
|
|
||||||
2018, 1, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc
|
|
||||||
).timestamp()
|
|
||||||
)
|
|
||||||
== 1514768400000
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("mqtt_server")
|
@pytest.mark.usefixtures("mqtt_server")
|
||||||
|
|
|
||||||
|
|
@ -26,15 +26,12 @@ async def test_start_stop():
|
||||||
|
|
||||||
b = bumper
|
b = bumper
|
||||||
b.db = "tests/tmp.db" # Set db location for testing
|
b.db = "tests/tmp.db" # Set db location for testing
|
||||||
b.conf1_listen_address = "127.0.0.1"
|
|
||||||
b.conf1_listen_port = 444
|
|
||||||
asyncio.create_task(b.start())
|
asyncio.create_task(b.start())
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
l.check_present(("bumper", "INFO", "Starting Bumper"))
|
l.check_present(("bumper", "INFO", "Starting Bumper"))
|
||||||
l.clear()
|
l.clear()
|
||||||
|
|
||||||
asyncio.create_task(b.shutdown())
|
await b.shutdown()
|
||||||
await asyncio.sleep(0.1)
|
|
||||||
l.check_present(
|
l.check_present(
|
||||||
("bumper", "INFO", "Shutting down"), ("bumper", "INFO", "Shutdown complete")
|
("bumper", "INFO", "Shutting down"), ("bumper", "INFO", "Shutdown complete")
|
||||||
)
|
)
|
||||||
|
|
|
||||||
14
tests/test_util.py
Normal file
14
tests/test_util.py
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from bumper.util import convert_to_millis
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_milli_time():
|
||||||
|
assert (
|
||||||
|
convert_to_millis(
|
||||||
|
datetime.datetime(
|
||||||
|
2018, 1, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc
|
||||||
|
).timestamp()
|
||||||
|
)
|
||||||
|
== 1514768400000
|
||||||
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue