Files
volleyball_miniapp/auth.py
2026-07-01 17:58:05 +03:00

76 lines
2.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
import base64
import hmac
import hashlib
import os
import time
from dataclasses import dataclass
from typing import Optional
COOKIE_NAME = "voley_admin"
def _get_secret() -> bytes:
secret = os.getenv("SECRET_KEY", "").strip()
if not secret:
# Разрешаем запуск без секрета, но с сильно сниженной безопасностью.
# Для реального деплоя SECRET_KEY обязателен.
secret = "dev-unsafe-secret"
return secret.encode("utf-8")
def _b64url(b: bytes) -> str:
return base64.urlsafe_b64encode(b).decode("ascii").rstrip("=")
def _b64url_decode(s: str) -> bytes:
pad = "=" * (-len(s) % 4)
return base64.urlsafe_b64decode((s + pad).encode("ascii"))
def _sign(payload: bytes) -> str:
mac = hmac.new(_get_secret(), payload, hashlib.sha256).digest()
return _b64url(mac)
def make_session(ttl_seconds: int = 60 * 60 * 12) -> str:
exp = int(time.time()) + int(ttl_seconds)
payload = f"exp={exp}".encode("utf-8")
sig = _sign(payload)
return f"{_b64url(payload)}.{sig}"
def verify_session(token: str) -> bool:
try:
payload_b64, sig = token.split(".", 1)
payload = _b64url_decode(payload_b64)
except Exception:
return False
if not hmac.compare_digest(_sign(payload), sig):
return False
try:
parts = payload.decode("utf-8").split("=", 1)
if len(parts) != 2 or parts[0] != "exp":
return False
exp = int(parts[1])
except Exception:
return False
return time.time() < exp
def check_admin_password(password: str) -> bool:
expected = os.getenv("ADMIN_PASSWORD", "")
if not expected:
# Чтобы админка не осталась открытой по умолчанию.
return False
return hmac.compare_digest(password or "", expected)
@dataclass(frozen=True)
class AdminAuth:
is_admin: bool
token: Optional[str] = None