From 186ab662fb0913a3bf1be33b953da3954431896a Mon Sep 17 00:00:00 2001
From: lilly
Date: Thu, 28 May 2026 17:31:06 +0200
Subject: [PATCH 1/2] 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,
From 99668e2a33f9188dd2284424ad1c8ee7b261e98f Mon Sep 17 00:00:00 2001
From: lilly
Date: Thu, 28 May 2026 17:53:15 +0200
Subject: [PATCH 2/2] document current api parameters in README
---
README.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/README.md b/README.md
index f83e55d..7cf569f 100644
--- a/README.md
+++ b/README.md
@@ -26,8 +26,10 @@ THe following table lists all available configuration parameters:
| `--base-url` | `DOORIS_BASE_URL` | Yes | *None* |
| `--serve-static` | `DOORIS_SERVE_STATIC` | No | *None* |
| `--ccujack-url` | `DOORIS_CCUJACK_URL` | No | `https://hmdooris-ccu.ccchh.net:2122` |
+| `--ccujack-mqtt` | `DOORIS_CCUJACK_MQTT` | No | `hmdooris-ccu.ccchh.net:1883` |
| `--ccujack-user` | `DOORIS_CCUJACK_USER` | Yes | *None* |
| `--ccujack-password` | `DOORIS_CCUJACK_PASSWORD` | Yes | *None* |
+| `--static-api-tokens` | `DOORIS_STATIC_API_TOKENS` | No | *None* |
## API Development