api: implement static dooris tokens

This commit is contained in:
lilly 2026-05-28 17:31:06 +02:00
commit 186ab662fb
Signed by: lilly
SSH key fingerprint: SHA256:y9T5GFw2A20WVklhetIxG1+kcg/Ce0shnQmbu1LQ37g
2 changed files with 37 additions and 6 deletions

View file

@ -78,9 +78,10 @@ def main():
required=False, required=False,
nargs=1, nargs=1,
action="append", action="append",
default=[], default=[i for i in os.environ.get("DOORIS_STATIC_API_TOKENS", "").split(",") if bool(i)],
) )
args = argp.parse_args() args = argp.parse_args()
print(args.static_api_tokens)
# setup logging # setup logging
logging.basicConfig( logging.basicConfig(

View file

@ -1,11 +1,12 @@
from typing import Annotated, Optional, Tuple from typing import Annotated, Optional
import logging import logging
from datetime import datetime, UTC, timedelta 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.data import TokenSuccessResponse
from simple_openid_connect.client import OpenidClient 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 import models, exceptions
from dooris_api.ccujack import CCUJackClient from dooris_api.ccujack import CCUJackClient
@ -13,6 +14,9 @@ from dooris_api.ccujack import CCUJackClient
logger = logging.getLogger(__name__) 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: async def get_oidc_client(req: Request) -> OpenidClient:
return req.app.extra["oidc_client"] 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) 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( 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: ) -> models.ApiUser:
oidc_user = await get_logged_in_oidc_user(req, resp, oidc_client) 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: if oidc_user is not None:
return oidc_user return oidc_user
elif token_user is not None:
return token_user
else: else:
return models.ApiUser( return models.ApiUser(
is_anonymous=True, is_anonymous=True,