Files
JiriUhlir 0e05fef335 first
2026-07-16 11:56:15 +02:00

81 lines
2.7 KiB
Python

"""Extrakce per-request přihlašovacích údajů z X- hlaviček.
Secrets (ClientId/ClientSecret vydané PPL) chodí VÝHRADNĚ v hlavičkách,
nikdy v těle requestu ani v URL. Nic se neukládá — služba je stateless;
jedinou výjimkou je in-memory cache OAuth tokenů (viz token_cache.py),
klíčovaná hashem údajů, protože PPL limituje vydávání tokenů na 12/min.
"""
import hashlib
from dataclasses import dataclass
from fastapi import Header
from .config import CPL_DEFAULT_ENVIRONMENT, CPL_PRODUCTION_BASE_URL, CPL_TEST_BASE_URL
from .errors import BadRequestError, CredentialsError
_ENVIRONMENTS = ("production", "test")
@dataclass
class Credentials:
client_id: str | None
client_secret: str | None
environment: str
accept_language: str | None = None
def require(self) -> None:
if not self.client_id or not self.client_id.strip():
raise CredentialsError("Chybí hlavička X-Client-Id.")
if not self.client_secret or not self.client_secret.strip():
raise CredentialsError("Chybí hlavička X-Client-Secret.")
@property
def base_url(self) -> str:
if self.environment == "test":
return CPL_TEST_BASE_URL
return CPL_PRODUCTION_BASE_URL
@property
def cache_key(self) -> str:
"""Klíč do token cache — hash, aby se secrets nikde neobjevily v paměti navíc."""
raw = f"{self.client_id}|{self.client_secret}|{self.environment}"
return hashlib.sha256(raw.encode("utf-8")).hexdigest()
def get_credentials(
x_client_id: str | None = Header(
default=None,
alias="X-Client-Id",
description="PPL CPL ClientId (secret, přiděluje PPL).",
),
x_client_secret: str | None = Header(
default=None,
alias="X-Client-Secret",
description="PPL CPL ClientSecret (secret, přiděluje PPL).",
),
x_environment: str | None = Header(
default=None,
alias="X-Environment",
description=(
"Cílové prostředí PPL: `production` nebo `test`. "
f"Bez hlavičky se použije `{CPL_DEFAULT_ENVIRONMENT}`."
),
),
accept_language: str | None = Header(
default=None,
alias="Accept-Language",
description="Volitelný jazyk odpovědí PPL (např. `cs-CZ`). Předává se dál.",
),
) -> Credentials:
environment = (x_environment or CPL_DEFAULT_ENVIRONMENT).strip().lower()
if environment not in _ENVIRONMENTS:
raise BadRequestError(
f"Neplatná hodnota X-Environment '{environment}'. Povolené: production, test."
)
return Credentials(
client_id=x_client_id,
client_secret=x_client_secret,
environment=environment,
accept_language=accept_language,
)