Files
ForbiddenStarsApp/backend/app/routers/dev_auth.py
T
NotBigGhostandClaude Opus 5 ec1e94119c Чистка: устаревшие комментарии и подсказки, export-скрипт, мусорный файл
Комментарии про методы входа приведены к факту (логин/пароль и Telegram везде,
stub только в development): config.py, .env.example, telegram.py, dev_stub.py,
dev_auth.py, login.py. admin_login.py больше не обещает «строже игроцкого» —
описаны реальные лимиты; client_ip — адрес за прокси уже даёт uvicorn.

Подсказки деплоя: run.ps1/run.sh (build-push на ПК, `up -d` на Pi), compose,
.env.example (build-push.ps1), Caddyfile (туннель-контейнер вместо autossh);
ratelimit.py ссылается на core/events.py вместо CLAUDE.md.

Удалены неиспользуемые scripts/export-prod.sh (с блоком export-ignore в
.gitattributes и упоминаниями в README), db/init_db.py и случайно закоммиченный
файл «h -u origin dev…». #70

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqSoRj99iwVEH5U5fnZgsd
2026-09-19 03:12:16 +03:00

67 lines
2.9 KiB
Python

"""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]