"""DEV-ТОЛЬКО роутер: вход по нику (stub) + тестовые пользователи. Этот файл и app/auth/dev_stub.py ФИЗИЧЕСКИ исключены из прод-образа (.dockerignore), а подключается роутер лишь при APP_ENV=development (см. app/main.py). Так вход без пароля остаётся только на деве (по логину и паролю входят везде). """ from __future__ import annotations from fastapi import APIRouter, Depends, Request, Response from sqlmodel import Session, select from app.auth.dev_stub import DevStubProvider from app.auth.login import establish_session, login_with_identity from app.auth.provider import ExternalIdentity from app.db.session import get_session from app.models import User from app.routers.users import build_me from app.schemas import api as s from app.services import user_service router = APIRouter(prefix="/auth/dev", tags=["auth-dev"]) @router.post("/login", response_model=s.MeRead) def dev_login( body: s.DevLogin, request: Request, response: Response, session: Session = Depends(get_session), ) -> s.MeRead: # Dev-вход «стать игроком с этим ником». Если такой игрок уже есть (любого провайдера — # Telegram, или stub с изменённым позже ником), входим именно в него, а не плодим дубли. # Только если игрока с таким ником нет — создаём нового stub-пользователя. nickname = (body.nickname or "").strip() existing = ( session.exec(select(User).where(User.nickname == nickname)).first() if nickname else None ) if existing is not None: user = establish_session(session, response, request, existing, existing.auth_provider) return build_me(session, user) identity = DevStubProvider().authenticate({"nickname": nickname}) user = login_with_identity(session, response, request, identity) return build_me(session, user) @router.get("/users", response_model=list[s.DevUserRead]) def dev_list_users(session: Session = Depends(get_session)) -> list[s.DevUserRead]: users = session.exec( select(User).where(User.role == "player").order_by(User.nickname) ).all() return [ s.DevUserRead(id=u.id, nickname=u.nickname, is_active=u.is_active) # type: ignore[arg-type] for u in users ] @router.post("/users", response_model=s.DevUserRead) def dev_create_user( body: s.DevUserCreate, session: Session = Depends(get_session) ) -> s.DevUserRead: nickname = body.nickname.strip() identity = ExternalIdentity(provider="stub", external_id=nickname, suggested_nickname=nickname) user = user_service.get_or_create_from_identity(session, identity) return s.DevUserRead(id=user.id, nickname=user.nickname) # type: ignore[arg-type]