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