forked from Hay1tsme/artemis
ChimeDB qr code lookup/userid complete
This commit is contained in:
@ -11,6 +11,7 @@ from typing import List
|
|||||||
|
|
||||||
from core import CoreConfig, TitleServlet, MuchaServlet
|
from core import CoreConfig, TitleServlet, MuchaServlet
|
||||||
from core.allnet import AllnetServlet, BillingServlet
|
from core.allnet import AllnetServlet, BillingServlet
|
||||||
|
from core.chimedb import ChimeServlet
|
||||||
from core.frontend import FrontendServlet
|
from core.frontend import FrontendServlet
|
||||||
|
|
||||||
async def dummy_rt(request: Request):
|
async def dummy_rt(request: Request):
|
||||||
@ -89,6 +90,14 @@ if not cfg.allnet.standalone:
|
|||||||
Route("/dl/ini/{file:str}", allnet.handle_dlorder_ini),
|
Route("/dl/ini/{file:str}", allnet.handle_dlorder_ini),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if cfg.chimedb.enable:
|
||||||
|
chimedb = ChimeServlet(cfg, cfg_dir)
|
||||||
|
route_lst += [
|
||||||
|
Route("/wc_aime/api/alive_check", chimedb.handle_qr_alive, methods=["POST"]),
|
||||||
|
Route("/qrcode/api/alive_check", chimedb.handle_qr_alive, methods=["POST"]),
|
||||||
|
Route("/wc_aime/api/get_data", chimedb.handle_qr_lookup, methods=["POST"])
|
||||||
|
]
|
||||||
|
|
||||||
for code, game in title.title_registry.items():
|
for code, game in title.title_registry.items():
|
||||||
route_lst += game.get_routes()
|
route_lst += game.get_routes()
|
||||||
|
|
||||||
|
139
core/chimedb.py
Normal file
139
core/chimedb.py
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
from enum import Enum
|
||||||
|
from logging.handlers import TimedRotatingFileHandler
|
||||||
|
|
||||||
|
import coloredlogs
|
||||||
|
from starlette.responses import PlainTextResponse
|
||||||
|
from starlette.requests import Request
|
||||||
|
|
||||||
|
from core.config import CoreConfig
|
||||||
|
from core.data import Data
|
||||||
|
|
||||||
|
class ChimeDBStatus(Enum):
|
||||||
|
NONE = 0
|
||||||
|
READER_SETUP_FAIL = 1
|
||||||
|
READER_ACCESS_FAIL = 2
|
||||||
|
READER_INCOMPATIBLE = 3
|
||||||
|
DB_RESOLVE_FAIL = 4
|
||||||
|
DB_ACCESS_TIMEOUT = 5
|
||||||
|
DB_ACCESS_FAIL = 6
|
||||||
|
AIME_ID_INVALID = 7
|
||||||
|
NO_BOARD_INFO = 8
|
||||||
|
LOCK_BAN_SYSTEM_USER = 9
|
||||||
|
LOCK_BAN_SYSTEM = 10
|
||||||
|
LOCK_BAN_USER = 11
|
||||||
|
LOCK_BAN = 12
|
||||||
|
LOCK_SYSTEM_USER = 13
|
||||||
|
LOCK_SYSTEM = 14
|
||||||
|
LOCK_USER = 15
|
||||||
|
|
||||||
|
class ChimeServlet:
|
||||||
|
def __init__(self, core_cfg: CoreConfig, cfg_folder: str) -> None:
|
||||||
|
self.config = core_cfg
|
||||||
|
self.config_folder = cfg_folder
|
||||||
|
|
||||||
|
self.data = Data(core_cfg)
|
||||||
|
|
||||||
|
self.logger = logging.getLogger("chimedb")
|
||||||
|
if not hasattr(self.logger, "initted"):
|
||||||
|
log_fmt_str = "[%(asctime)s] Chimedb | %(levelname)s | %(message)s"
|
||||||
|
log_fmt = logging.Formatter(log_fmt_str)
|
||||||
|
|
||||||
|
fileHandler = TimedRotatingFileHandler(
|
||||||
|
"{0}/{1}.log".format(self.config.server.log_dir, "chimedb"),
|
||||||
|
when="d",
|
||||||
|
backupCount=10,
|
||||||
|
)
|
||||||
|
fileHandler.setFormatter(log_fmt)
|
||||||
|
|
||||||
|
consoleHandler = logging.StreamHandler()
|
||||||
|
consoleHandler.setFormatter(log_fmt)
|
||||||
|
|
||||||
|
self.logger.addHandler(fileHandler)
|
||||||
|
self.logger.addHandler(consoleHandler)
|
||||||
|
|
||||||
|
self.logger.setLevel(self.config.aimedb.loglevel)
|
||||||
|
coloredlogs.install(
|
||||||
|
level=core_cfg.aimedb.loglevel, logger=self.logger, fmt=log_fmt_str
|
||||||
|
)
|
||||||
|
self.logger.initted = True
|
||||||
|
|
||||||
|
if not core_cfg.chimedb.key:
|
||||||
|
self.logger.error("!!!KEY NOT SET!!!")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
self.logger.info("Serving")
|
||||||
|
|
||||||
|
async def handle_qr_alive(self, request: Request):
|
||||||
|
return PlainTextResponse("alive")
|
||||||
|
|
||||||
|
async def handle_qr_lookup(self, request: Request) -> bytes:
|
||||||
|
req = json.loads(await request.body())
|
||||||
|
access_code = req["qrCode"][-20:]
|
||||||
|
timestamp = req["timestamp"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
userId = await self._lookup(access_code)
|
||||||
|
data = json.dumps({
|
||||||
|
"userID": userId,
|
||||||
|
"errorID": 0,
|
||||||
|
"timestamp": timestamp,
|
||||||
|
"key": self._hash_key(userId, timestamp)
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
|
||||||
|
self.logger.error(e.with_traceback(None))
|
||||||
|
|
||||||
|
data = json.dumps({
|
||||||
|
"userID": -1,
|
||||||
|
"errorID": ChimeDBStatus.DB_ACCESS_FAIL,
|
||||||
|
"timestamp": timestamp,
|
||||||
|
"key": self._hash_key(-1, timestamp)
|
||||||
|
})
|
||||||
|
|
||||||
|
return PlainTextResponse(data)
|
||||||
|
|
||||||
|
def _hash_key(self, chip_id, timestamp):
|
||||||
|
input_string = f"{chip_id}{timestamp}{self.config.chimedb.key}"
|
||||||
|
hash_object = hashlib.sha256(input_string.encode('utf-8'))
|
||||||
|
hex_dig = hash_object.hexdigest()
|
||||||
|
|
||||||
|
formatted_hex = format(int(hex_dig, 16), '064x').upper()
|
||||||
|
|
||||||
|
return formatted_hex
|
||||||
|
|
||||||
|
async def _lookup(self, access_code):
|
||||||
|
user_id = await self.data.card.get_user_id_from_card(access_code)
|
||||||
|
|
||||||
|
self.logger.info(f"access_code {access_code} -> user_id {user_id}")
|
||||||
|
|
||||||
|
if not user_id or user_id <= 0:
|
||||||
|
user_id = await self._register(access_code)
|
||||||
|
|
||||||
|
return user_id
|
||||||
|
|
||||||
|
async def _register(self, access_code):
|
||||||
|
user_id = -1
|
||||||
|
|
||||||
|
if self.config.server.allow_user_registration:
|
||||||
|
user_id = await self.data.user.create_user()
|
||||||
|
|
||||||
|
if user_id is None:
|
||||||
|
self.logger.error("Failed to register user!")
|
||||||
|
user_id = -1
|
||||||
|
else:
|
||||||
|
card_id = await self.data.card.create_card(user_id, access_code)
|
||||||
|
|
||||||
|
if card_id is None:
|
||||||
|
self.logger.error("Failed to register card!")
|
||||||
|
user_id = -1
|
||||||
|
|
||||||
|
self.logger.info(
|
||||||
|
f"Register access code {access_code} -> user_id {user_id}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.logger.info(f"Registration blocked!: access code {access_code}")
|
||||||
|
|
||||||
|
return user_id
|
@ -474,6 +474,28 @@ class AimedbConfig:
|
|||||||
self.__config, "core", "aimedb", "id_lifetime_seconds", default=86400
|
self.__config, "core", "aimedb", "id_lifetime_seconds", default=86400
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class ChimedbConfig:
|
||||||
|
def __init__(self, parent_config: "CoreConfig") -> None:
|
||||||
|
self.__config = parent_config
|
||||||
|
|
||||||
|
@property
|
||||||
|
def enable(self) -> bool:
|
||||||
|
return CoreConfig.get_config_field(
|
||||||
|
self.__config, "core", "chimedb", "enable", default=True
|
||||||
|
)
|
||||||
|
@property
|
||||||
|
def loglevel(self) -> int:
|
||||||
|
return CoreConfig.str_to_loglevel(
|
||||||
|
CoreConfig.get_config_field(
|
||||||
|
self.__config, "core", "chimedb", "loglevel", default="info"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@property
|
||||||
|
def key(self) -> str:
|
||||||
|
return CoreConfig.get_config_field(
|
||||||
|
self.__config, "core", "chimedb", "key", default=""
|
||||||
|
)
|
||||||
|
|
||||||
class MuchaConfig:
|
class MuchaConfig:
|
||||||
def __init__(self, parent_config: "CoreConfig") -> None:
|
def __init__(self, parent_config: "CoreConfig") -> None:
|
||||||
self.__config = parent_config
|
self.__config = parent_config
|
||||||
@ -495,6 +517,7 @@ class CoreConfig(dict):
|
|||||||
self.allnet = AllnetConfig(self)
|
self.allnet = AllnetConfig(self)
|
||||||
self.billing = BillingConfig(self)
|
self.billing = BillingConfig(self)
|
||||||
self.aimedb = AimedbConfig(self)
|
self.aimedb = AimedbConfig(self)
|
||||||
|
self.chimedb = ChimedbConfig(self)
|
||||||
self.mucha = MuchaConfig(self)
|
self.mucha = MuchaConfig(self)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -65,5 +65,10 @@ aimedb:
|
|||||||
id_secret: ""
|
id_secret: ""
|
||||||
id_lifetime_seconds: 86400
|
id_lifetime_seconds: 86400
|
||||||
|
|
||||||
|
chimedb:
|
||||||
|
enable: False
|
||||||
|
loglevel: "info"
|
||||||
|
key: ""
|
||||||
|
|
||||||
mucha:
|
mucha:
|
||||||
loglevel: "info"
|
loglevel: "info"
|
||||||
|
Reference in New Issue
Block a user