This commit is contained in:
timka123 committed 2026-10-19 09:41:32 +03:00
1 parent 4bdbc8bfa8
commit 2be074f191
22 files changed
+1034 -25

No files matched your search

+32 -11
View File
@@ -1,33 +1,54 @@
"""Shared dependencies: the database session and the optional shared secret."""
"""Shared dependencies: the database session and the two ways into the API."""
from __future__ import annotations
from typing import Annotated
from fastapi import Depends, Header, HTTPException, status
from fastapi import Cookie, Depends, Header, HTTPException, status
from sqlalchemy.orm import Session
from app.config import env_settings
from app.db import get_session
from app.services import auth_service
from app.services.settings_service import load_settings
from app.settings_schema import AppSettings
DbSession = Annotated[Session, Depends(get_session)]
def require_token(x_api_token: Annotated[str | None, Header()] = None) -> None:
"""Guard every API call when `API_TOKEN` is set.
def require_auth(
session: DbSession,
x_api_token: Annotated[str | None, Header()] = None,
kadence_session: Annotated[str | None, Cookie()] = None,
) -> None:
"""Guard every API call.
Off by default: on a laptop the backend is bound to localhost and a token is
friction. Set it the moment the container is reachable from anywhere else.
Two independent gates, either of which lets a request through:
* `X-API-Token` against `API_TOKEN` — the desktop app and scripts, off by
default (friction-free on a laptop; set the moment the backend leaves it).
* a `kadence_session` cookie from `/api/auth/login*` — the browser, closed
the moment a password or Telegram login is configured in Settings → Access.
With neither `API_TOKEN` nor a login configured, the API stays open, exactly
as before this existed.
"""
expected = env_settings().api_token
if not expected:
if expected and x_api_token == expected:
return
if x_api_token != expected:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Bad or missing X-API-Token."
)
if auth_service.valid_session(session, kadence_session):
return
settings = load_settings(session)
login_required = bool(settings.auth.password_hash) or (
settings.auth.telegram_login_enabled and bool(settings.auth.telegram_owner_id)
)
if not expected and not login_required:
return
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Sign in, or send a valid X-API-Token.",
)
def get_settings(session: DbSession) -> AppSettings: