docs: update environment configuration and API documentation
All checks were successful
CI / lint-and-test (push) Successful in 24s
All checks were successful
CI / lint-and-test (push) Successful in 24s
- Revised the `.env.example` file to clarify the purpose of the `MINI_APP_SKIP_AUTH` variable, emphasizing its insecure nature and restriction to development use only. - Updated the `README.md` to reflect changes in API authentication requirements, specifying that unauthenticated access to `/api/duties` and `/api/calendar-events` is only allowed with `MINI_APP_SKIP_AUTH=1`. - Enhanced `configuration.md` to detail the implications of using `MINI_APP_SKIP_AUTH` for API access without Telegram initData. - Removed the `_is_private_client` function and its associated tests, streamlining the codebase and focusing on the current authentication model. - Added logging in `run.py` to warn when `MINI_APP_SKIP_AUTH` is enabled, highlighting the security risks.
This commit is contained in:
@@ -118,34 +118,6 @@ def require_miniapp_username(
|
||||
return get_authenticated_username(request, x_telegram_init_data, session)
|
||||
|
||||
|
||||
def _is_private_client(client_host: str | None) -> bool:
|
||||
"""Return True if client_host is localhost or RFC 1918 private IPv4.
|
||||
|
||||
Used to allow /api/duties without initData when opened from local/private
|
||||
network (e.g. dev). IPv4 only; IPv6 only 127/::1 checked.
|
||||
|
||||
Args:
|
||||
client_host: Client IP or hostname from request.
|
||||
|
||||
Returns:
|
||||
True if loopback or 10.x, 172.16–31.x, 192.168.x.x.
|
||||
"""
|
||||
if not client_host:
|
||||
return False
|
||||
if client_host in ("127.0.0.1", "::1"):
|
||||
return True
|
||||
# RFC 1918 private ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
|
||||
parts = client_host.split(".")
|
||||
if len(parts) == 4:
|
||||
try:
|
||||
a, b, c, d = (int(x) for x in parts)
|
||||
if (a == 10) or (a == 172 and 16 <= b <= 31) or (a == 192 and b == 168):
|
||||
return True
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
def get_authenticated_username(
|
||||
request: Request,
|
||||
x_telegram_init_data: str | None,
|
||||
@@ -154,26 +126,25 @@ def get_authenticated_username(
|
||||
"""Return identifier for miniapp auth (username or full_name or id:...); empty if skip-auth.
|
||||
|
||||
Args:
|
||||
request: FastAPI request (client host for private-IP bypass).
|
||||
request: FastAPI request (for Accept-Language in error messages).
|
||||
x_telegram_init_data: Raw X-Telegram-Init-Data header value.
|
||||
session: DB session (for phone allowlist lookup).
|
||||
|
||||
Returns:
|
||||
Username, full_name, or "id:<telegram_id>"; empty string if MINI_APP_SKIP_AUTH
|
||||
or private IP and no initData.
|
||||
Username, full_name, or "id:<telegram_id>"; empty string only if MINI_APP_SKIP_AUTH.
|
||||
|
||||
Raises:
|
||||
HTTPException: 403 if initData missing/invalid or user not in allowlist.
|
||||
"""
|
||||
if config.MINI_APP_SKIP_AUTH:
|
||||
log.warning("allowing without any auth check (MINI_APP_SKIP_AUTH is set)")
|
||||
log.warning(
|
||||
"MINI_APP_SKIP_AUTH is set — no auth check (insecure, dev only); "
|
||||
"do not use in production"
|
||||
)
|
||||
return ""
|
||||
init_data = (x_telegram_init_data or "").strip()
|
||||
if not init_data:
|
||||
client_host = request.client.host if request.client else None
|
||||
if _is_private_client(client_host):
|
||||
return ""
|
||||
log.warning("no X-Telegram-Init-Data header (client=%s)", client_host)
|
||||
log.warning("no X-Telegram-Init-Data header")
|
||||
lang = _lang_from_accept_language(request.headers.get("Accept-Language"))
|
||||
raise HTTPException(status_code=403, detail=t(lang, "api.open_from_telegram"))
|
||||
max_age = config.INIT_DATA_MAX_AGE_SECONDS or None
|
||||
|
||||
Reference in New Issue
Block a user