api: implement logout endpoint

This commit is contained in:
lilly 2026-05-14 15:27:36 +02:00
commit 07c72c752f
Signed by: lilly
SSH key fingerprint: SHA256:y9T5GFw2A20WVklhetIxG1+kcg/Ce0shnQmbu1LQ37g
3 changed files with 200 additions and 64 deletions

View file

@ -1,4 +1,4 @@
from typing import Optional, Self, Mapping, Any, Literal
from typing import Optional, Self, Literal
from datetime import datetime
from pydantic import BaseModel, HttpUrl
from enum import Enum
@ -9,8 +9,9 @@ from fastapi import status
class HttpProblemType(Enum):
"""
Statically known HTTP problem types using the [type URI scheme](https://datatracker.ietf.org/doc/rfc4151/)
Statically known HTTP problem types using the [type URI scheme](https://datatracker.ietf.org/doc/rfc4151/)
"""
UNAUTHORIZED = "type:noc@hamburg.ccc.de,2026:UNAUTHORIZED"
DOOR_NOT_FOUND = "type:noc@hamburg.ccc.de,2026:DOOR_NOT_FOUND"
@ -19,6 +20,7 @@ class HttpProblemDetail(BaseModel):
"""
API Error modeled after [RFC9475](https://www.rfc-editor.org/rfc/rfc9457.html).
"""
status: int
type: HttpProblemType
title: str
@ -27,15 +29,28 @@ class HttpProblemDetail(BaseModel):
@classmethod
def new_unauthorized(cls, request_uri: str | URL) -> Self:
return cls(type=HttpProblemType.UNAUTHORIZED, status=status.HTTP_401_UNAUTHORIZED, title="Unauthorized", detail="You tried to access a ressource which requires authentication but you are not authenticated", instance=HttpUrl(str(request_uri)))
return cls(
type=HttpProblemType.UNAUTHORIZED,
status=status.HTTP_401_UNAUTHORIZED,
title="Unauthorized",
detail="You tried to access a ressource which requires authentication but you are not authenticated",
instance=HttpUrl(str(request_uri)),
)
@classmethod
def new_door_not_found(cls, requested_door: str, request_uri: str | URL) -> Self:
return cls(type=HttpProblemType.DOOR_NOT_FOUND, status=status.HTTP_404_NOT_FOUND, title="Door not found", detail=f"You tried to interact with door {requested_door!r} that is not known to dooris", instance=str(request_uri))
return cls(
type=HttpProblemType.DOOR_NOT_FOUND,
status=status.HTTP_404_NOT_FOUND,
title="Door not found",
detail=f"You tried to interact with door {requested_door!r} that is not known to dooris",
instance=str(request_uri),
)
class CurrentUser(BaseModel):
id_token: IdToken
raw_id_token: str
class UserStatus(BaseModel):
@ -52,9 +67,8 @@ class LockStatus(BaseModel):
lock_target_level: Literal["locked", "unlocked", "open"]
lock_state: Literal["unknown", "locked", "unlocked"]
activity_state: Literal["unknown", "locking", "unlocking", "stable"]
class Lock(BaseModel):
name: str
status: LockStatus