Добавлена форма изменения ника при регистрации аккаунта на случай, когда уже существует аакунт с ником, совпадающим с ТГ тегом регистрируемого аккаунта
This commit is contained in:
@@ -25,6 +25,11 @@ def nickname_available(session: Session, nickname: str, exclude_user_id: int | N
|
||||
return existing is None or existing.id == exclude_user_id
|
||||
|
||||
|
||||
def nickname_format_ok(nickname: str) -> bool:
|
||||
"""Ник подходит по формату (2–64, буквы/цифры/пробел/.-_)."""
|
||||
return bool(_NICK_RE.match((nickname or "").strip()))
|
||||
|
||||
|
||||
def _unique_nickname(session: Session, base: str) -> str:
|
||||
base = (base or "Игрок").strip()[:60] or "Игрок"
|
||||
candidate = base
|
||||
@@ -35,18 +40,24 @@ def _unique_nickname(session: Session, base: str) -> str:
|
||||
return candidate
|
||||
|
||||
|
||||
def get_or_create_from_identity(session: Session, identity: ExternalIdentity) -> User:
|
||||
def find_by_identity(session: Session, identity: ExternalIdentity) -> User | None:
|
||||
"""Существующий пользователь по внешней личности (provider+external_id).
|
||||
|
||||
Для Telegram external_id — это НЕИЗМЕНЯЕМЫЙ числовой id аккаунта (не @тег), поэтому
|
||||
вход с любого устройства/после смены тега ведёт к одному и тому же пользователю.
|
||||
"""
|
||||
link = session.exec(
|
||||
select(AuthIdentity).where(
|
||||
AuthIdentity.provider == identity.provider,
|
||||
AuthIdentity.external_id == identity.external_id,
|
||||
)
|
||||
).first()
|
||||
if link is not None:
|
||||
return get_user(session, link.user_id)
|
||||
return get_user(session, link.user_id) if link is not None else None
|
||||
|
||||
|
||||
def _create_from_identity(session: Session, identity: ExternalIdentity, nickname: str) -> User:
|
||||
user = User(
|
||||
nickname=_unique_nickname(session, identity.suggested_nickname or identity.external_id),
|
||||
nickname=nickname,
|
||||
role="player",
|
||||
auth_provider=identity.provider,
|
||||
telegram_id=identity.telegram_id,
|
||||
@@ -65,6 +76,31 @@ def get_or_create_from_identity(session: Session, identity: ExternalIdentity) ->
|
||||
return user
|
||||
|
||||
|
||||
def get_or_create_from_identity(session: Session, identity: ExternalIdentity) -> User:
|
||||
"""Найти по личности или создать, авто-подбирая уникальный ник (dev-вход по нику)."""
|
||||
user = find_by_identity(session, identity)
|
||||
if user is not None:
|
||||
return user
|
||||
nickname = _unique_nickname(session, identity.suggested_nickname or identity.external_id)
|
||||
return _create_from_identity(session, identity, nickname)
|
||||
|
||||
|
||||
def register_from_identity(
|
||||
session: Session, identity: ExternalIdentity, nickname: str
|
||||
) -> User:
|
||||
"""Создать пользователя с ЯВНО выбранным ником (регистрация через Telegram).
|
||||
|
||||
В отличие от get_or_create — ник не подбирается автоматически: занятый/неподходящий
|
||||
ник вызывает ошибку, чтобы пользователь выбрал другой.
|
||||
"""
|
||||
nickname = (nickname or "").strip()
|
||||
if not nickname_format_ok(nickname):
|
||||
raise ValidationError("Ник: 2–64 символа, буквы/цифры/пробел/.-_")
|
||||
if not nickname_available(session, nickname):
|
||||
raise NicknameTakenError()
|
||||
return _create_from_identity(session, identity, nickname)
|
||||
|
||||
|
||||
def update_nickname(session: Session, user: User, new_nickname: str) -> User:
|
||||
new_nickname = (new_nickname or "").strip()
|
||||
if not _NICK_RE.match(new_nickname):
|
||||
|
||||
Reference in New Issue
Block a user