Serve /api/ on piha.lc / beta.piha.li (#8)
## Summary - Serve `/api/` on `piha.lc` / `beta.piha.li` (Bearer still required). - Drop `shortener.aimloperations.com` / `shortener-beta.aimloperations.com` from env examples and caller docs. - `/admin/` stays 404 on the public host. Closes #7. ## Test plan - [ ] `POST https://beta.piha.li/api/links/` with valid Bearer → 201 - [ ] Same without Bearer → 401 - [ ] `GET https://beta.piha.li/<code>` still 302 - [ ] `/admin/` on beta.piha.li → 404 - [ ] Unit tests: `cd site && uv run python manage.py test` Reviewed-on: #8
This commit was merged in pull request #8.
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
"""Keep the short domain and Django admin off the public API hostname."""
|
||||
"""Host split: public short domain serves redirects + /api/; admin stays local."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import Http404, HttpRequest
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _normalize_host(host: str) -> str:
|
||||
return host.split(":")[0].lower().rstrip(".")
|
||||
@@ -33,11 +37,16 @@ def is_admin_host(host: str) -> bool:
|
||||
return _host_in(host, list(getattr(settings, "SHORT_ADMIN_HOSTS", []) or []))
|
||||
|
||||
|
||||
class HostSplitMiddleware:
|
||||
"""Short host = redirects only. API host = /api/ (Bearer). Admin = local only.
|
||||
def serves_api(host: str) -> bool:
|
||||
"""Short domain and extra API hosts both serve /api/ (Bearer)."""
|
||||
return is_api_host(host) or is_public_host(host)
|
||||
|
||||
A public DNS name may be listed in SHORT_API_HOSTS. Auth, not the network,
|
||||
keeps /api/ closed: missing/wrong Bearer is 401; empty token list is 503.
|
||||
|
||||
class HostSplitMiddleware:
|
||||
"""One public host: GET /<code> and /api/ (Bearer). Admin = local only.
|
||||
|
||||
Auth, not a second DNS name, keeps /api/ closed: missing/wrong Bearer is 401;
|
||||
empty token list is 503.
|
||||
"""
|
||||
|
||||
def __init__(self, get_response):
|
||||
@@ -61,8 +70,13 @@ class HostSplitMiddleware:
|
||||
return self.get_response(request)
|
||||
|
||||
if path.startswith("/api/"):
|
||||
# Short redirect hostname never serves the API, even if mis-listed.
|
||||
if is_public_host(host) or not is_api_host(host):
|
||||
if not serves_api(host):
|
||||
logger.warning(
|
||||
"blocked /api/ host=%s public=%s api=%s",
|
||||
host,
|
||||
is_public_host(host),
|
||||
is_api_host(host),
|
||||
)
|
||||
raise Http404()
|
||||
|
||||
return self.get_response(request)
|
||||
|
||||
Reference in New Issue
Block a user