from __future__ import annotations import secrets from fastapi import APIRouter, Depends, HTTPException, Query, Request from fastapi.responses import PlainTextResponse from ..dependencies import ServiceDep, SettingsDep, StoreDep, apply_update_response, authenticate_update router = APIRouter() @router.get("/u/{update_slug}", response_class=PlainTextResponse, response_model=None) def slug_update( update_slug: str, request: Request, store: StoreDep, service: ServiceDep, myip: str | None = Query(default=None), ipaddr: str | None = Query(default=None), myipv6: str | None = Query(default=None), ip6addr: str | None = Query(default=None), ) -> str | PlainTextResponse: account = store.get_account_by_slug(update_slug) if not account or account["disabled"]: raise HTTPException(status_code=404, detail="not found") return apply_update_response(service, request, str(account["hostname"]), myip, ipaddr, myipv6, ip6addr) @router.get("/nic/update", response_class=PlainTextResponse, response_model=None) def update( request: Request, settings: SettingsDep, store: StoreDep, service: ServiceDep, credentials: tuple[str | None, str | None] = Depends(authenticate_update), hostname: str | None = Query(default=None), domain: str | None = Query(default=None), myip: str | None = Query(default=None), ipaddr: str | None = Query(default=None), myipv6: str | None = Query(default=None), ip6addr: str | None = Query(default=None), ) -> str | PlainTextResponse: host = (hostname or domain or "").strip().lower().rstrip(".") if not host: return PlainTextResponse("nohost", status_code=400) if settings.allowed_hosts and host not in settings.allowed_hosts: return PlainTextResponse("nohost", status_code=403) supplied_user, supplied_token = credentials account_ok = store.verify_account(host, supplied_user, supplied_token) global_secret_ok = ( bool(settings.allowed_hosts) and host in settings.allowed_hosts and bool(settings.shared_secret) and bool(supplied_token) and secrets.compare_digest(supplied_token, settings.shared_secret) ) if not global_secret_ok and not account_ok: return PlainTextResponse("badauth", status_code=401) return apply_update_response(service, request, host, myip, ipaddr, myipv6, ip6addr)