Локальный FastAPI-сервис поверх GigaAM v3 и sherpa-onnx: приём аудио, очередь задач, разделение по говорящим, постобработка терминов. Доставка на Windows - ZIP со встроенным Python, без установки чего-либо. Обновление кода при запуске тянется из релизов Gitea: меняется только папка app, десятки килобайт вместо всего пакета. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
"""Проверка доступа: Bearer-токен и список разрешённых адресов."""
|
|
import ipaddress
|
|
import secrets
|
|
from ipaddress import IPv4Network, IPv6Network
|
|
|
|
__all__ = ["check_token", "parse_allowlist", "ip_allowed"]
|
|
|
|
Network = IPv4Network | IPv6Network
|
|
|
|
|
|
def check_token(header_value: str | None, expected: str) -> bool:
|
|
"""Сверяет заголовок Authorization с настроенным токеном.
|
|
|
|
Пустой токен в конфиге не открывает доступ, а закрывает его полностью -
|
|
иначе забытая настройка молча выставила бы сервис наружу.
|
|
Сравнение идёт в постоянное время, чтобы токен нельзя было подобрать по таймингам.
|
|
"""
|
|
if not expected or not header_value:
|
|
return False
|
|
scheme, _, value = header_value.partition(" ")
|
|
if scheme.lower() != "bearer":
|
|
return False
|
|
return secrets.compare_digest(value.strip(), expected)
|
|
|
|
|
|
def parse_allowlist(raw: str) -> list[Network]:
|
|
"""Разбирает список адресов и подсетей через запятую.
|
|
|
|
Некорректные записи пропускаются: опечатка в конфиге не должна ронять сервис.
|
|
"""
|
|
nets: list[Network] = []
|
|
for item in (raw or "").split(","):
|
|
item = item.strip()
|
|
if not item:
|
|
continue
|
|
try:
|
|
nets.append(ipaddress.ip_network(item, strict=False))
|
|
except ValueError:
|
|
continue
|
|
return nets
|
|
|
|
|
|
def ip_allowed(client_ip: str | None, allowlist: list[Network]) -> bool:
|
|
"""Проверяет адрес по списку. Пустой список означает «проверка выключена»."""
|
|
if not allowlist:
|
|
return True
|
|
if not client_ip:
|
|
return False
|
|
try:
|
|
addr = ipaddress.ip_address(client_ip)
|
|
except ValueError:
|
|
return False
|
|
return any(addr in net for net in allowlist)
|