|
|
from fastapi import APIRouter, HTTPException, Depends, status |
|
|
from sqlalchemy.ext.asyncio import AsyncSession |
|
|
from sqlalchemy import select |
|
|
from datetime import timedelta |
|
|
from app.schema import UserCreate, LoginRequest |
|
|
from app.schema.models import LoginResponse |
|
|
from app.models import User |
|
|
from app.core import verify_password, get_password_hash, create_access_token |
|
|
from app.api.deps import get_db |
|
|
from app.config import settings |
|
|
|
|
|
|
|
|
router = APIRouter() |
|
|
|
|
|
|
|
|
@router.post("/register", response_model=dict) |
|
|
async def register(user: UserCreate, db: AsyncSession = Depends(get_db)): |
|
|
try: |
|
|
result = await db.execute(select(User).filter(User.email == user.email)) |
|
|
existing_user = result.scalar_one_or_none() |
|
|
|
|
|
if existing_user: |
|
|
raise HTTPException( |
|
|
status_code=status.HTTP_400_BAD_REQUEST, |
|
|
detail='Username already registered' |
|
|
) |
|
|
new_user = User( |
|
|
username=user.username, |
|
|
email=user.email, |
|
|
hashed_password=get_password_hash(user.password) |
|
|
) |
|
|
db.add(new_user) |
|
|
await db.commit() |
|
|
|
|
|
return {"message": "User registered sucessfully", "username": user.username} |
|
|
except HTTPException: |
|
|
raise |
|
|
except Exception as e: |
|
|
raise HTTPException( |
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
|
|
detail=f'registered failed: {str(e)}' |
|
|
) |
|
|
|
|
|
@router.post("/login", response_model=LoginResponse) |
|
|
async def login(request: LoginRequest, db: AsyncSession = Depends(get_db)): |
|
|
try: |
|
|
result = await db.execute(select(User).filter(User.email == request.email)) |
|
|
user = result.scalar_one_or_none() |
|
|
|
|
|
if not user or not verify_password(request.password, user.hashed_password): |
|
|
raise HTTPException( |
|
|
status_code=status.HTTP_401_UNAUTHORIZED, |
|
|
detail="Incorrect email or password", |
|
|
headers={"WWW-Authenticate": "Bearer"}, |
|
|
) |
|
|
|
|
|
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES) |
|
|
access_token = create_access_token( |
|
|
data={"sub": user.username}, |
|
|
expires_deltas=access_token_expires |
|
|
) |
|
|
|
|
|
return LoginResponse( |
|
|
access_token=access_token, |
|
|
token_type="bearer", |
|
|
username=user.username |
|
|
) |
|
|
except HTTPException: |
|
|
raise |
|
|
except Exception as e: |
|
|
raise HTTPException( |
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
|
|
detail=f"Login failed: {str(e)}" |
|
|
) |