diff --git a/base.py b/base.py index c205c0a..40c04fa 100644 --- a/base.py +++ b/base.py @@ -68,6 +68,8 @@ lyric_search_endpoint = importlib.import_module("endpoints.lyric_search").LyricS lastfm_endpoints = importlib.import_module("endpoints.lastfm").LastFM(app, util, constants, glob_state) # Below: YT endpoint(s) yt_endpoints = importlib.import_module("endpoints.yt").YT(app, util, constants, glob_state) +# Below: XC endpoint(s) +xc_endpoints = importlib.import_module("endpoints.xc").XC(app, util, constants, glob_state) diff --git a/endpoints/ai.py b/endpoints/ai.py index 4cb7879..c7c4287 100644 --- a/endpoints/ai.py +++ b/endpoints/ai.py @@ -28,7 +28,6 @@ class AI(FastAPI): async def ai_handler(self, request: Request): """ - /ai/ AI Request """ diff --git a/endpoints/xc.py b/endpoints/xc.py new file mode 100644 index 0000000..1a787a9 --- /dev/null +++ b/endpoints/xc.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3.12 + +from fastapi import FastAPI, Request, HTTPException +from pydantic import BaseModel +from aiohttp import ClientSession, ClientTimeout + +class ValidXCRequest(BaseModel): + """ + - **key**: valid XC API key + - **bid**: bot id + - **cmd**: bot command + - **data**: command data + """ + + key: str + bid: int + cmd: str + data: str | None = None + +class XC(FastAPI): + """XC (CrossComm) Endpoints""" + def __init__(self, app: FastAPI, util, constants, glob_state): # pylint: disable=super-init-not-called + self.app = app + self.util = util + self.constants = constants + self.glob_state = glob_state + + self.endpoints = { + "xc": self.xc_handler, + #tbd + } + + for endpoint, handler in self.endpoints.items(): + app.add_api_route(f"/{endpoint}/", handler, methods=["POST"]) + + async def xc_handler(self, data: ValidXCRequest, request: Request): + """ + /xc/ + Handle XC Commands + """ + key = data.key + bid = data.bid + cmd = data.cmd + cmd_data = data.data + + if not self.util.check_key(request.url.path, key): + raise HTTPException(status_code=403, detail="Unauthorized") + + BID_ADDR_MAP = { + 0: '10.10.10.101:5991' # Thomas/Aces + } + + if not bid in BID_ADDR_MAP.keys(): + return { + 'err': True, + 'errorText': 'Invalid bot id' + } + + bot_api_url = f'http://{BID_ADDR_MAP[bid]}/' + async with ClientSession() as session: + async with session.post(f"{bot_api_url}{cmd}", json=cmd_data, headers={ + 'Content-Type': 'application/json; charset=utf-8' + }, timeout=ClientTimeout(connect=5, sock_read=5)) as request: + response = await request.json() + return { + 'success': True, + 'response': response + } \ No newline at end of file diff --git a/util.py b/util.py index 95a79ae..e59c2b5 100644 --- a/util.py +++ b/util.py @@ -33,7 +33,11 @@ class Utilities: key = key.split("Bearer ", maxsplit=1)[1].strip() if not key in self.constants.API_KEYS: - print("Auth failed.") + print("Auth failed") + return False + + if path.lower().startswith("/xc/") and not(key.startswith("XC-")): + print("Auth failed - not an XC Key") return False print("Auth succeeded")