CodeReview/backend/app/api/v1/endpoints/auth.py

85 lines
2.7 KiB
Python

from datetime import timedelta
from typing import Any
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from pydantic import BaseModel, EmailStr
from app.api import deps
from app.core import security
from app.core.config import settings
from app.db.session import get_db
from app.models.user import User
from app.schemas.token import Token
from app.schemas.user import User as UserSchema, UserCreate
router = APIRouter()
class RegisterRequest(BaseModel):
email: EmailStr
password: str
full_name: str
@router.post("/login", response_model=Token)
async def login(
db: AsyncSession = Depends(get_db),
form_data: OAuth2PasswordRequestForm = Depends()
) -> Any:
"""
OAuth2 compatible token login, get an access token for future requests.
Username field should contain the email address.
"""
result = await db.execute(select(User).where(User.email == form_data.username))
user = result.scalars().first()
if not user or not security.verify_password(form_data.password, user.hashed_password):
raise HTTPException(status_code=400, detail="邮箱或密码错误")
elif not user.is_active:
raise HTTPException(status_code=400, detail="用户已被禁用")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
),
"token_type": "bearer",
}
@router.post("/register", response_model=UserSchema)
async def register(
*,
db: AsyncSession = Depends(get_db),
user_in: RegisterRequest,
) -> Any:
"""
Register a new user.
"""
# Check if user already exists
result = await db.execute(select(User).where(User.email == user_in.email))
existing_user = result.scalars().first()
if existing_user:
raise HTTPException(
status_code=400,
detail="该邮箱已被注册",
)
# Check if this is the first user (make them admin)
count_result = await db.execute(select(User))
all_users = count_result.scalars().all()
is_first_user = len(all_users) == 0
# Create new user
db_user = User(
email=user_in.email,
hashed_password=security.get_password_hash(user_in.password),
full_name=user_in.full_name,
is_active=True,
is_superuser=is_first_user,
role="admin" if is_first_user else "member",
)
db.add(db_user)
await db.commit()
await db.refresh(db_user)
return db_user