All checks were successful
Build Container / Build Container (push) Successful in 1m26s
69 lines
1.9 KiB
Python
69 lines
1.9 KiB
Python
from typing import Optional, Literal, Self
|
|
from datetime import datetime, UTC
|
|
from pydantic import BaseModel, HttpUrl, Field
|
|
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 ApiUser(BaseModel):
|
|
is_anonymous: bool
|
|
is_ccchh_user: bool
|
|
is_token_user: bool
|
|
may_operate_locks: bool
|
|
username: str
|
|
guaranteed_session_until: Optional[datetime]
|
|
|
|
raw_id_token: Optional[str] = Field(exclude=True)
|
|
|
|
@classmethod
|
|
def from_id_token(cls, id_token: IdToken, raw_id_token: str) -> Self:
|
|
return cls(
|
|
is_anonymous=False,
|
|
is_ccchh_user=True,
|
|
is_token_user=False,
|
|
may_operate_locks="intern@" in getattr(id_token, "ccchh-roles", []),
|
|
username=id_token.preferred_username,
|
|
guaranteed_session_until=datetime.fromtimestamp(id_token.exp, UTC),
|
|
raw_id_token=raw_id_token,
|
|
)
|
|
|
|
|
|
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"]
|