From acb5ba7eba1780fad88aeda698da7718f3660512 Mon Sep 17 00:00:00 2001 From: oauth2 Date: Wed, 19 Oct 2022 13:28:14 +0200 Subject: [PATCH 1/4] Implement admin ID for automated tests --- config.ci.py | 3 +++ config.example.py | 29 ++++++++++++++++++++++++++++- litecord/auth.py | 6 ++++++ 3 files changed, 37 insertions(+), 1 deletion(-) 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..07bce03 100644 --- a/config.example.py +++ b/config.example.py @@ -17,6 +17,13 @@ along with this program. If not, see . """ +import os +from logbook import Logger + + +log = Logger(__name__) + + MODE = "Development" @@ -65,10 +72,27 @@ class Config: #: Postgres credentials POSTGRES = {} - + #: Shared secret for LVSP LVSP_SECRET = "" + #: Admin credentials for automated testing + # The token is the value to pass in the Authorization header, and the ID + # is the user ID to use when it is passed. + ADMIN_ID = os.getenv("ADMIN_ID") + ADMIN_TOKEN = os.getenv("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 + + if ADMIN_ID is not None: + ADMIN_ID = int(ADMIN_ID) + class Development(Config): DEBUG = True @@ -91,3 +115,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..e462c58 100644 --- a/litecord/auth.py +++ b/litecord/auth.py @@ -19,6 +19,7 @@ along with this program. If not, see . import base64 import binascii +import os import bcrypt from itsdangerous import TimestampSigner, BadSignature @@ -47,6 +48,9 @@ async def raw_token_check(token: str, db=None) -> int: Forbidden If token validation fails. """ + if app.config["ADMIN_TOKEN"] is not None: + return app.config["ADMIN_ID"] + db = db or app.db # just try by fragments instead of @@ -121,6 +125,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( """ From 610b7e9811cf5fcab10eec8fe89184cef7789d7b Mon Sep 17 00:00:00 2001 From: oauth2 Date: Wed, 19 Oct 2022 13:36:00 +0200 Subject: [PATCH 2/4] Remove unused import in auth-file --- litecord/auth.py | 1 - 1 file changed, 1 deletion(-) diff --git a/litecord/auth.py b/litecord/auth.py index e462c58..3c3c0ae 100644 --- a/litecord/auth.py +++ b/litecord/auth.py @@ -19,7 +19,6 @@ along with this program. If not, see . import base64 import binascii -import os import bcrypt from itsdangerous import TimestampSigner, BadSignature From 210f1ab1d5b82a951aa698ecf87ce5b105cce7b2 Mon Sep 17 00:00:00 2001 From: Bluenix Date: Wed, 19 Oct 2022 23:10:28 +0200 Subject: [PATCH 3/4] Move admin token warning into app start --- config.example.py | 28 ++++++++-------------------- run.py | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/config.example.py b/config.example.py index 07bce03..6a53554 100644 --- a/config.example.py +++ b/config.example.py @@ -18,10 +18,6 @@ along with this program. If not, see . """ import os -from logbook import Logger - - -log = Logger(__name__) MODE = "Development" @@ -76,22 +72,8 @@ class Config: #: Shared secret for LVSP LVSP_SECRET = "" - #: Admin credentials for automated testing - # The token is the value to pass in the Authorization header, and the ID - # is the user ID to use when it is passed. - ADMIN_ID = os.getenv("ADMIN_ID") - ADMIN_TOKEN = os.getenv("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 - - if ADMIN_ID is not None: - ADMIN_ID = int(ADMIN_ID) + ADMIN_ID = None + ADMIN_TOKEN = None class Development(Config): @@ -104,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 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 From 83179f21ab4cb620348c506ec6d2cab9d35690fd Mon Sep 17 00:00:00 2001 From: Bluenix Date: Wed, 19 Oct 2022 23:13:44 +0200 Subject: [PATCH 4/4] Fix not comparing admin token to passed token --- litecord/auth.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/litecord/auth.py b/litecord/auth.py index 3c3c0ae..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,7 +48,9 @@ async def raw_token_check(token: str, db=None) -> int: Forbidden If token validation fails. """ - if app.config["ADMIN_TOKEN"] is not None: + 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