This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import json
|
||||
import logging
|
||||
from urllib.parse import parse_qsl
|
||||
|
||||
from fastapi import Depends, Header, HTTPException
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.config import settings
|
||||
from app.core.database import get_db
|
||||
from app.core.security import validate_init_data
|
||||
from app.models.user import User
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _log_auth_failure(reason: str, init_data: str | None) -> None:
|
||||
parsed = dict(parse_qsl(init_data or "", keep_blank_values=True))
|
||||
logger.warning(
|
||||
"telegram auth failed: reason=%s init_len=%s has_hash=%s has_user=%s auth_date=%s bot_token_set=%s",
|
||||
reason,
|
||||
len(init_data or ""),
|
||||
bool(parsed.get("hash")),
|
||||
bool(parsed.get("user")),
|
||||
parsed.get("auth_date", ""),
|
||||
bool(settings.bot_token),
|
||||
)
|
||||
|
||||
|
||||
async def get_current_user(
|
||||
x_telegram_init_data: str | None = Header(None, alias="X-Telegram-Init-Data"),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> User:
|
||||
if not x_telegram_init_data:
|
||||
_log_auth_failure("missing_header", x_telegram_init_data)
|
||||
raise HTTPException(status_code=401, detail="Open this page from the Telegram bot Mini App")
|
||||
|
||||
data = validate_init_data(x_telegram_init_data)
|
||||
if data is None:
|
||||
_log_auth_failure("invalid_init_data", x_telegram_init_data)
|
||||
raise HTTPException(status_code=401, detail="Invalid Telegram auth data")
|
||||
|
||||
user_json = data.get("user", "{}")
|
||||
try:
|
||||
user_data = json.loads(user_json)
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
_log_auth_failure("invalid_user_json", x_telegram_init_data)
|
||||
raise HTTPException(status_code=401, detail="Invalid user data")
|
||||
|
||||
user_id = user_data.get("id")
|
||||
if not user_id:
|
||||
_log_auth_failure("missing_user_id", x_telegram_init_data)
|
||||
raise HTTPException(status_code=401, detail="Missing user id")
|
||||
|
||||
result = await db.execute(select(User).where(User.id == user_id))
|
||||
user = result.scalar_one_or_none()
|
||||
|
||||
if user is None:
|
||||
user = User(
|
||||
id=user_id,
|
||||
username=user_data.get("username"),
|
||||
first_name=user_data.get("first_name", ""),
|
||||
last_name=user_data.get("last_name"),
|
||||
)
|
||||
db.add(user)
|
||||
await db.commit()
|
||||
await db.refresh(user)
|
||||
else:
|
||||
user.username = user_data.get("username")
|
||||
user.first_name = user_data.get("first_name") or user.first_name
|
||||
user.last_name = user_data.get("last_name")
|
||||
await db.commit()
|
||||
|
||||
return user
|
||||
Reference in New Issue
Block a user