From 186ab662fb0913a3bf1be33b953da3954431896a Mon Sep 17 00:00:00 2001
From: lilly
Date: Thu, 28 May 2026 17:31:06 +0200
Subject: [PATCH] api: implement static dooris tokens
---
api/src/dooris_api/__init__.py | 3 ++-
api/src/dooris_api/deps.py | 40 +++++++++++++++++++++++++++++-----
2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/api/src/dooris_api/__init__.py b/api/src/dooris_api/__init__.py
index 618ce97..cdf4d67 100644
--- a/api/src/dooris_api/__init__.py
+++ b/api/src/dooris_api/__init__.py
@@ -78,9 +78,10 @@ def main():
required=False,
nargs=1,
action="append",
- default=[],
+ default=[i for i in os.environ.get("DOORIS_STATIC_API_TOKENS", "").split(",") if bool(i)],
)
args = argp.parse_args()
+ print(args.static_api_tokens)
# setup logging
logging.basicConfig(
diff --git a/api/src/dooris_api/deps.py b/api/src/dooris_api/deps.py
index c611b5d..b82ae05 100644
--- a/api/src/dooris_api/deps.py
+++ b/api/src/dooris_api/deps.py
@@ -1,11 +1,12 @@
-from typing import Annotated, Optional, Tuple
+from typing import Annotated, Optional
import logging
from datetime import datetime, UTC, timedelta
-from fastapi import Request, Depends, Response
+from fastapi import Request, Depends, Response, Header
+from fastapi.security import APIKeyHeader
from simple_openid_connect.data import TokenSuccessResponse
from simple_openid_connect.client import OpenidClient
-from simple_openid_connect.exceptions import ValidationError
+from dooris_api import app_config
from dooris_api import models, exceptions
from dooris_api.ccujack import CCUJackClient
@@ -13,6 +14,9 @@ from dooris_api.ccujack import CCUJackClient
logger = logging.getLogger(__name__)
+api_key_security_scheme = APIKeyHeader(name="Authorization", scheme_name="Static-Token", auto_error=False)
+
+
async def get_oidc_client(req: Request) -> OpenidClient:
return req.app.extra["oidc_client"]
@@ -129,13 +133,39 @@ def clear_oidc_auth_state(resp: Response):
resp.set_cookie("auth_start_time", "", max_age=0)
+def get_logged_in_token_user(req: Request, token: Optional[str]):
+ if not token or not token.startswith("Static-Token "):
+ logger.debug("No valid API-Token was provided")
+ return None
+
+ token = token.removeprefix("Static-Token ")
+ valid_tokens = app_config.get().static_api_tokens
+
+ if any((i == token for i in valid_tokens)):
+ logger.debug("Successfully authenticated a static API-Token")
+ return models.ApiUser(
+ is_anonymous=False,
+ is_ccchh_user=False,
+ is_token_user=True,
+ may_operate_locks=True,
+ username="static-token",
+ guaranteed_session_until=None,
+ raw_id_token=None,
+ )
+
+ return None
+
+
async def get_api_user(
- req: Request, resp: Response, oidc_client: OpenidClient
+ req: Request, resp: Response, oidc_client: OpenidClient, token: Annotated[Optional[str], Depends(api_key_security_scheme)] = None
) -> models.ApiUser:
oidc_user = await get_logged_in_oidc_user(req, resp, oidc_client)
- # TODO: Implement API user based on static tokens
+ token_user = get_logged_in_token_user(req, token)
+
if oidc_user is not None:
return oidc_user
+ elif token_user is not None:
+ return token_user
else:
return models.ApiUser(
is_anonymous=True,