diff --git a/config.ci.py b/config.ci.py index 83290d3..ead65ee 100644 --- a/config.ci.py +++ b/config.ci.py @@ -48,6 +48,9 @@ class Config: # Postgres credentials POSTGRES = {} + ADMIN_ID = None + ADMIN_TOKEN = None + class Development(Config): DEBUG = True diff --git a/config.example.py b/config.example.py index 56d701b..6a53554 100644 --- a/config.example.py +++ b/config.example.py @@ -17,6 +17,9 @@ along with this program. If not, see . """ +import os + + MODE = "Development" @@ -65,10 +68,13 @@ class Config: #: Postgres credentials POSTGRES = {} - + #: Shared secret for LVSP LVSP_SECRET = "" + ADMIN_ID = None + ADMIN_TOKEN = None + class Development(Config): DEBUG = True @@ -80,6 +86,12 @@ class Development(Config): "database": "litecord", } + ADMIN_ID = os.getenv("ADMIN_ID") + ADMIN_TOKEN = os.getenv("ADMIN_TOKEN") + + if ADMIN_ID is not None: + ADMIN_ID = int(ADMIN_ID) + class Production(Config): DEBUG = False @@ -91,3 +103,6 @@ class Production(Config): "password": "some_production_password", "database": "litecord_or_anything_else_really", } + + ADMIN_TOKEN = None + ADMIN_ID = None diff --git a/litecord/auth.py b/litecord/auth.py index 841c49d..7f4a76b 100644 --- a/litecord/auth.py +++ b/litecord/auth.py @@ -19,6 +19,7 @@ along with this program. If not, see . import base64 import binascii +from hmac import compare_digest import bcrypt from itsdangerous import TimestampSigner, BadSignature @@ -47,6 +48,11 @@ async def raw_token_check(token: str, db=None) -> int: Forbidden If token validation fails. """ + if app.config["ADMIN_TOKEN"] is not None and compare_digest( + token, app.config["ADMIN_TOKEN"] + ): + return app.config["ADMIN_ID"] + db = db or app.db # just try by fragments instead of @@ -121,6 +127,8 @@ async def token_check() -> int: async def admin_check() -> int: """Check if the user is an admin.""" user_id = await token_check() + if user_id == app.config["ADMIN_ID"]: + return user_id flags = await app.db.fetchval( """ diff --git a/run.py b/run.py index 0c80c06..7168755 100644 --- a/run.py +++ b/run.py @@ -122,7 +122,22 @@ redirect_logging() def make_app(): app = Quart(__name__) + app.config.from_object(f"config.{config.MODE}") + + admin_id, admin_token = app.config["ADMIN_ID"], app.config["ADMIN_TOKEN"] + if None in {admin_id, admin_token} and not admin_id == admin_token: + log.warning( + "Not both admin ID ({}) and token ({}) configured; ignoring", + admin_id, + admin_token, + ) + admin_id = admin_token = None + + # update config if the variables were updated + app.config["ADMIN_ID"] = admin_id + app.config["ADMIN_TOKEN"] = admin_token + is_debug = app.config.get("DEBUG", False) app.debug = is_debug