feat(user): support login with any case of username & email
This commit is contained in:
12
app/auth.py
12
app/auth.py
@@ -111,13 +111,15 @@ async def authenticate_user_legacy(db: AsyncSession, name: str, password: str) -
|
|||||||
pw_md5 = hashlib.md5(password.encode()).hexdigest()
|
pw_md5 = hashlib.md5(password.encode()).hexdigest()
|
||||||
|
|
||||||
# 2. 根据用户名查找用户
|
# 2. 根据用户名查找用户
|
||||||
statement = select(User).where(User.username == name).options()
|
user = None
|
||||||
user = (await db.exec(statement)).first()
|
user = (await db.exec(select(User).where(User.username == name))).first()
|
||||||
if not user:
|
if user is None:
|
||||||
|
user = (await db.exec(select(User).where(User.email == name))).first()
|
||||||
|
if user is None and name.isdigit():
|
||||||
|
user = (await db.exec(select(User).where(User.id == int(name)))).first()
|
||||||
|
if user is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
await db.refresh(user)
|
|
||||||
|
|
||||||
# 3. 验证密码
|
# 3. 验证密码
|
||||||
if user.pw_bcrypt is None or user.pw_bcrypt == "":
|
if user.pw_bcrypt is None or user.pw_bcrypt == "":
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ from fastapi import APIRouter, Depends, Form, Request
|
|||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
from redis.asyncio import Redis
|
from redis.asyncio import Redis
|
||||||
from sqlalchemy import text
|
from sqlalchemy import text
|
||||||
from sqlmodel import select
|
from sqlmodel import exists, select
|
||||||
|
|
||||||
|
|
||||||
def create_oauth_error_response(error: str, description: str, hint: str, status_code: int = 400):
|
def create_oauth_error_response(error: str, description: str, hint: str, status_code: int = 400):
|
||||||
@@ -101,12 +101,12 @@ async def register_user(
|
|||||||
email_errors = validate_email(user_email)
|
email_errors = validate_email(user_email)
|
||||||
password_errors = validate_password(user_password)
|
password_errors = validate_password(user_password)
|
||||||
|
|
||||||
result = await db.exec(select(User).where(User.username == user_username))
|
result = await db.exec(select(exists()).where(User.username == user_username))
|
||||||
existing_user = result.first()
|
existing_user = result.first()
|
||||||
if existing_user:
|
if existing_user:
|
||||||
username_errors.append("Username is already taken")
|
username_errors.append("Username is already taken")
|
||||||
|
|
||||||
result = await db.exec(select(User).where(User.email == user_email))
|
result = await db.exec(select(exists()).where(User.email == user_email))
|
||||||
existing_email = result.first()
|
existing_email = result.first()
|
||||||
if existing_email:
|
if existing_email:
|
||||||
email_errors.append("Email is already taken")
|
email_errors.append("Email is already taken")
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from app.utils import utcnow
|
|||||||
from .router import router
|
from .router import router
|
||||||
|
|
||||||
from fastapi import Body, HTTPException, Security
|
from fastapi import Body, HTTPException, Security
|
||||||
from sqlmodel import select
|
from sqlmodel import exists, select
|
||||||
|
|
||||||
|
|
||||||
@router.post(
|
@router.post(
|
||||||
@@ -34,7 +34,7 @@ async def user_rename(
|
|||||||
返回:
|
返回:
|
||||||
- 成功: None
|
- 成功: None
|
||||||
"""
|
"""
|
||||||
samename_user = (await session.exec(select(User).where(User.username == new_name))).first()
|
samename_user = (await session.exec(select(exists()).where(User.username == new_name))).first()
|
||||||
if samename_user:
|
if samename_user:
|
||||||
raise HTTPException(409, "Username Exisits")
|
raise HTTPException(409, "Username Exisits")
|
||||||
errors = validate_username(new_name)
|
errors = validate_username(new_name)
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
"""user: change collation for username and email
|
||||||
|
|
||||||
|
Revision ID: af88493881eb
|
||||||
|
Revises: 34a563187e47
|
||||||
|
Create Date: 2025-08-26 11:31:07.183273
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = "af88493881eb"
|
||||||
|
down_revision: str | Sequence[str] | None = "34a563187e47"
|
||||||
|
branch_labels: str | Sequence[str] | None = None
|
||||||
|
depends_on: str | Sequence[str] | None = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
"""Upgrade schema."""
|
||||||
|
# 1. 删除现有索引
|
||||||
|
op.drop_index("ix_lazer_users_email", table_name="lazer_users")
|
||||||
|
op.drop_index("ix_lazer_users_username", table_name="lazer_users")
|
||||||
|
|
||||||
|
# 2. 修改字段 collation 为 utf8mb4_general_ci
|
||||||
|
op.execute("""
|
||||||
|
ALTER TABLE lazer_users
|
||||||
|
MODIFY username VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
|
||||||
|
MODIFY email VARCHAR(254) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 3. 重新创建唯一索引(大小写不敏感)
|
||||||
|
op.create_index(op.f("ix_lazer_users_email"), "lazer_users", ["email"], unique=True)
|
||||||
|
op.create_index(op.f("ix_lazer_users_username"), "lazer_users", ["username"], unique=True)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
# 1. 删除索引
|
||||||
|
op.drop_index("ix_lazer_users_email", table_name="lazer_users")
|
||||||
|
op.drop_index("ix_lazer_users_username", table_name="lazer_users")
|
||||||
|
|
||||||
|
# 2. 恢复原 collation(假设原来是 utf8mb4_bin)
|
||||||
|
op.execute("""
|
||||||
|
ALTER TABLE lazer_users
|
||||||
|
MODIFY username VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||||
|
MODIFY email VARCHAR(254) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 3. 恢复原索引
|
||||||
|
op.create_index(op.f("ix_lazer_users_email"), "lazer_users", ["email"], unique=True)
|
||||||
|
op.create_index(op.f("ix_lazer_users_username"), "lazer_users", ["username"], unique=True)
|
||||||
Reference in New Issue
Block a user