фикс бага с дублем аккаунтов при логине по нику
This commit is contained in:
@@ -10,7 +10,7 @@ from fastapi import APIRouter, Depends, Request, Response
|
|||||||
from sqlmodel import Session, select
|
from sqlmodel import Session, select
|
||||||
|
|
||||||
from app.auth.dev_stub import DevStubProvider
|
from app.auth.dev_stub import DevStubProvider
|
||||||
from app.auth.login import login_with_identity
|
from app.auth.login import establish_session, login_with_identity
|
||||||
from app.auth.provider import ExternalIdentity
|
from app.auth.provider import ExternalIdentity
|
||||||
from app.db.session import get_session
|
from app.db.session import get_session
|
||||||
from app.models import User
|
from app.models import User
|
||||||
@@ -28,7 +28,19 @@ def dev_login(
|
|||||||
response: Response,
|
response: Response,
|
||||||
session: Session = Depends(get_session),
|
session: Session = Depends(get_session),
|
||||||
) -> s.MeRead:
|
) -> s.MeRead:
|
||||||
identity = DevStubProvider().authenticate({"nickname": body.nickname})
|
# 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)
|
user = login_with_identity(session, response, request, identity)
|
||||||
return build_me(session, user)
|
return build_me(session, user)
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,47 @@ def _telegram_payload(token: str, **fields) -> dict:
|
|||||||
return {**data, "hash": sig}
|
return {**data, "hash": sig}
|
||||||
|
|
||||||
|
|
||||||
|
def test_dev_login_into_telegram_user_no_duplicate(client: TestClient, engine, monkeypatch):
|
||||||
|
"""Dev-вход по нику Telegram-аккаунта входит в него, а не создаёт дубль «ник 2»."""
|
||||||
|
from sqlmodel import Session, select
|
||||||
|
|
||||||
|
from app.core.config import settings
|
||||||
|
from app.models import User
|
||||||
|
|
||||||
|
monkeypatch.setattr(settings, "telegram_bot_token", "TEST_BOT_TOKEN")
|
||||||
|
r = client.post("/api/auth/telegram", json=_telegram_payload("TEST_BOT_TOKEN"))
|
||||||
|
assert r.status_code == 200, r.text
|
||||||
|
tg_id, nick = r.json()["id"], r.json()["nickname"]
|
||||||
|
|
||||||
|
client.cookies.clear() # «другой вход» — без сессии
|
||||||
|
r2 = client.post("/api/auth/dev/login", json={"nickname": nick})
|
||||||
|
assert r2.status_code == 200, r2.text
|
||||||
|
assert r2.json()["id"] == tg_id # тот же аккаунт, не новый
|
||||||
|
|
||||||
|
with Session(engine) as s:
|
||||||
|
users = s.exec(select(User).where(User.nickname == nick)).all()
|
||||||
|
assert len(users) == 1 # дубликат не создан
|
||||||
|
|
||||||
|
|
||||||
|
def test_dev_login_after_rename_no_duplicate(client: TestClient, engine):
|
||||||
|
"""После смены ника dev-вход по новому нику входит в того же игрока (без дубля)."""
|
||||||
|
from sqlmodel import Session, select
|
||||||
|
|
||||||
|
from app.models import User
|
||||||
|
|
||||||
|
uid = client.post("/api/auth/dev/login", json={"nickname": "Старый"}).json()["id"]
|
||||||
|
pr = client.patch("/api/users/me", json={"nickname": "Новый"}, headers=csrf_headers(client))
|
||||||
|
assert pr.status_code == 200, pr.text
|
||||||
|
|
||||||
|
client.cookies.clear()
|
||||||
|
r2 = client.post("/api/auth/dev/login", json={"nickname": "Новый"})
|
||||||
|
assert r2.status_code == 200, r2.text
|
||||||
|
assert r2.json()["id"] == uid
|
||||||
|
|
||||||
|
with Session(engine) as s:
|
||||||
|
assert len(s.exec(select(User).where(User.nickname == "Новый")).all()) == 1
|
||||||
|
|
||||||
|
|
||||||
def test_telegram_login_valid_signature(client: TestClient, monkeypatch):
|
def test_telegram_login_valid_signature(client: TestClient, monkeypatch):
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user