Files
ForbiddenStarsApp/backend/app/auth/login.py
T
NotBigGhostandClaude Opus 4.8 3f8667b561 Отзыв JWT при выходе и смене пароля
logout отзывает предъявленный токен по jti (in-memory denylist до exp);
смена и сброс пароля инкрементят users.token_version (claim ver в JWT,
сверка в auth/deps) — все прежние сессии отзываются. Своё устройство при
смене пароля остаётся в сессии (перевыдача cookie). Миграция 0013. #57

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XfTsytzT6TojfmprRDKiV6
2026-09-13 17:09:57 +03:00

46 lines
1.8 KiB
Python
Raw 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.
"""Общий вход: внешняя личность → пользователь → сессия.
Прод-безопасный модуль (без импортов dev-провайдера). Используется и Telegram-входом,
и dev-входом.
"""
from __future__ import annotations
from fastapi import Request, Response
from sqlmodel import Session
from app.auth.provider import ExternalIdentity
from app.core import security
from app.core.security import client_ip
from app.core.errors import ForbiddenError
from app.models import User
from app.services import audit_service, user_service
def establish_session(
session: Session, response: Response, request: Request, user: User, provider: str
) -> User:
"""Открыть сессию уже найденному/созданному пользователю (cookie + аудит)."""
if not user.is_active:
raise ForbiddenError("Аккаунт отключён администратором.", code="ACCOUNT_DISABLED")
security.set_user_session(response, user.id, provider, user.token_version) # type: ignore[arg-type]
audit_service.record(
session,
actor_id=user.id,
action="login",
entity_type="user",
entity_id=user.id,
payload={"provider": provider},
ip=client_ip(request),
user_agent=request.headers.get("user-agent"),
)
session.commit()
return user
def login_with_identity(
session: Session, response: Response, request: Request, identity: ExternalIdentity
) -> User:
"""Вход с авто-созданием (dev-вход по нику): ник подбирается автоматически."""
user = user_service.get_or_create_from_identity(session, identity)
return establish_session(session, response, request, user, identity.provider)