59 lines
1.9 KiB
Python
59 lines
1.9 KiB
Python
"""Shared dependencies: the database session and the two ways into the API."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Annotated
|
|
|
|
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_auth(
|
|
session: DbSession,
|
|
x_api_token: Annotated[str | None, Header()] = None,
|
|
kadence_session: Annotated[str | None, Cookie()] = None,
|
|
) -> None:
|
|
"""Guard every API call.
|
|
|
|
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 expected and x_api_token == expected:
|
|
return
|
|
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:
|
|
return load_settings(session)
|
|
|
|
|
|
Settings = Annotated[AppSettings, Depends(get_settings)]
|