peace2024's picture
saving changes
e27e999
raw
history blame
2.24 kB
from fastapi import APIRouter, HTTPException, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from passlib.context import CryptContext
from jose import jwt
from pydantic.v1 import BaseModel, EmailStr
from app.database import get_db # Updated: use the correct async session dependency
from app.models import User
import os
import logging
from dotenv import load_dotenv
router = APIRouter()
logger = logging.getLogger(__name__)
load_dotenv()
# Load secret key and JWT algorithm
SECRET_KEY = os.getenv("SECRET_KEY", "secret")
ALGORITHM = "HS256"
# Password hashing config
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
# Request Schemas
class SignUp(BaseModel):
email: EmailStr
password: str
class Login(BaseModel):
email: EmailStr
password: str
@router.post("/auth/signup")
async def signup(data: SignUp, db: AsyncSession = Depends(get_db)):
# Check if user already exists
result = await db.execute(select(User).where(User.email == data.email))
existing_user = result.scalar_one_or_none()
if existing_user:
raise HTTPException(status_code=400, detail="Email already exists")
hashed_password = pwd_context.hash(data.password)
new_user = User(email=data.email, hashed_password=hashed_password)
try:
db.add(new_user)
await db.commit()
await db.refresh(new_user)
return {"message": "User created", "user_id": new_user.id}
except Exception as e:
await db.rollback()
logger.error(f"Signup error: {e}")
raise HTTPException(status_code=500, detail="Internal Server Error")
@router.post("/auth/login")
async def login(data: Login, db: AsyncSession = Depends(get_db)):
result = await db.execute(select(User).where(User.email == data.email))
user = result.scalar_one_or_none()
if not user or not pwd_context.verify(data.password, user.hashed_password):
raise HTTPException(status_code=401, detail="Invalid credentials")
token = jwt.encode({"user_id": user.id}, SECRET_KEY, algorithm=ALGORITHM)
return {
"access_token": token,
"token_type": "bearer",
"user": {"id": user.id, "email": user.email},
}