v1.0.90: Steps 1-4 — auth.py, dedup, httponly cookie, _op_results TTL

This commit is contained in:
2026-07-27 22:56:51 +04:00
parent 9085c9088e
commit f6a7bf76c5
4 changed files with 123 additions and 87 deletions
+82
View File
@@ -0,0 +1,82 @@
"""
Единый модуль аутентификации и создания HTTP-клиента.
Раньше _client(), _client_id(), _stand(), _token_info() были продублированы
в main.py и api_test.py с идентичным или почти идентичным кодом.
Теперь всё здесь — один источник правды.
Функции:
get_token() — токен из cookie или env
get_client() — HttpClient с автоопределением стенда
get_client_id() — ClientID из JWT (base64, без проверки подписи)
get_stand() — "dev"/"test" по токену
get_token_info() — {email, company, client_id} из JWT
get_token_masked() — маскированный токен (abc...xyz)
"""
import base64
import json
from flask import request, current_app
from api.http_client import HttpClient, detect_endpoint, stand_name
def get_token():
"""Токен: сначала из cookie, потом из env-переменной."""
return request.cookies.get("token") or current_app.config["NUBES_API_TOKEN"]
def get_client():
"""HttpClient с автоопределением стенда по токену.
Использует detect_endpoint() — пробует dev→test стенды.
Если автоопределение не сработало — fallback на NUBES_API_ENDPOINT из конфига."""
token = get_token()
endpoint = detect_endpoint(token) or current_app.config["NUBES_API_ENDPOINT"]
return HttpClient(endpoint, token)
def get_client_id():
"""Извлечение ClientID из payload JWT-токена (base64url, без проверки подписи)."""
token = get_token()
try:
parts = token.split(".") # header.payload.signature
if len(parts) >= 2:
payload = base64.urlsafe_b64decode(parts[1] + "==") # padding
return json.loads(payload).get("ClientID", "")
except Exception:
pass
return ""
def get_stand():
"""dev/test — по токену (detect_endpoint → stand_name)."""
token = get_token()
endpoint = detect_endpoint(token) or current_app.config["NUBES_API_ENDPOINT"]
return stand_name(endpoint)
def get_token_info():
"""{email, company, client_id} из JWT — для отображения в топбаре UI."""
token = get_token()
try:
parts = token.split(".")
if len(parts) >= 2:
payload = base64.urlsafe_b64decode(parts[1] + "==")
d = json.loads(payload)
return {
"email": d.get("email", ""),
"company": d.get("company_name", ""),
"client_id": d.get("ClientID", ""),
}
except Exception:
pass
return {}
def get_token_masked():
"""Маскированный токен для placeholder: abc...xyz."""
token = current_app.config["NUBES_API_TOKEN"]
if not token or len(token) < 8:
return ""
return token[:4] + "*" * (len(token) - 8) + token[-4:]