from typing import Optional, Literal, List from datetime import datetime from pydantic import BaseModel, HttpUrl from enum import Enum from simple_openid_connect.data import IdToken class HttpProblemType(Enum): """ Statically known HTTP problem types using the [type URI scheme](https://datatracker.ietf.org/doc/rfc4151/) """ UNAUTHORIZED = "type:noc@hamburg.ccc.de,2026:UNAUTHORIZED" FORBIDDEN_TO_OPERATE = "type:noc@hamburg.ccc.de,2026,FORBIDDEN_TO_OPERATE" LOCK_NOT_FOUND = "type:noc@hamburg.ccc.de,2026:LOCK_NOT_FOUND" class HttpProblemDetail(BaseModel): """ API Error modeled after [RFC9475](https://www.rfc-editor.org/rfc/rfc9457.html). """ status: int type: HttpProblemType title: str detail: str instance: Optional[HttpUrl] class CurrentUser(BaseModel): id_token: IdToken raw_id_token: str @property def ccchh_roles(self) -> List[str]: return getattr(self.id_token, "ccchh-roles", []) @property def may_operate_locks(self) -> bool: return "intern@" in self.ccchh_roles class UserStatus(BaseModel): is_authorized: bool guaranteed_session_until: datetime username: str ccchh_roles: List[str] class LockStatus(BaseModel): is_unreachable: bool is_low_battery: bool is_error_jammed: bool 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 id: str status: LockStatus class LockOperation(BaseModel): desired_state: Literal["open", "closed"]