Added and fixed Create auction API endpoint. Added middleware, session-based authentication and logout endpoint
This commit is contained in:
@ -1,11 +1,14 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi import APIRouter, Depends, HTTPException, Response, Request
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from ..middleware import token_refresh_middleware, logout
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.future import select
|
||||
from ..database import get_db
|
||||
from ..models import User, UserCreate, UserLogin
|
||||
from ..security import create_access_token, verify_access_token
|
||||
from ..models import User, UserCreate, UserLogin, Session as SessionModel
|
||||
from ..security import create_access_token, verify_password
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
import bcrypt
|
||||
import secrets
|
||||
|
||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
|
||||
|
||||
@ -53,30 +56,40 @@ async def register(user_data: UserCreate, db: AsyncSession = Depends(get_db)):
|
||||
|
||||
# User login
|
||||
@router.post("/api/v1/login")
|
||||
async def login(login_data: UserLogin, db: AsyncSession = Depends(get_db)):
|
||||
async def login(login_data: UserLogin, db: AsyncSession = Depends(get_db), response: Response = None):
|
||||
async with db.begin():
|
||||
# Check if email is an email
|
||||
query = select(User).filter(User.email == login_data.email)
|
||||
|
||||
result = await db.execute(query)
|
||||
user = result.scalars().first()
|
||||
|
||||
if not user or not bcrypt.checkpw(login_data.password.encode('utf-8'), user.password.encode('utf-8')):
|
||||
if not user or not verify_password(login_data.password, user.password):
|
||||
raise HTTPException(status_code=400, detail="Invalid credentials")
|
||||
|
||||
# Create session token
|
||||
session_token = secrets.token_hex(32)
|
||||
session_expiry = datetime.now(timezone.utc) + timedelta(hours=12)
|
||||
|
||||
new_session = SessionModel(sessionToken=session_token, userId=user.id, expires=session_expiry)
|
||||
db.add(new_session)
|
||||
|
||||
# Create JWT access token
|
||||
access_token = create_access_token(data={"user_id": user.id})
|
||||
return {"access_token": access_token, "token_type": "bearer"}
|
||||
|
||||
await db.commit()
|
||||
|
||||
# Set session and access tokens after transaction is committed
|
||||
response.set_cookie(key="session_token", value=session_token, httponly=True, max_age=12*60*60)
|
||||
response.set_cookie(key="access_token", value=access_token, httponly=True, max_age=60*60)
|
||||
|
||||
return {"message": "Login successful"}
|
||||
|
||||
# Logout user
|
||||
@router.post("/api/v1/logout")
|
||||
async def logout_user(request: Request, response: Response, db: AsyncSession = Depends(get_db)):
|
||||
return await logout(request, db, response)
|
||||
|
||||
|
||||
# Protected route example
|
||||
# Protected route example using middleware
|
||||
@router.get("/api/v1/protected")
|
||||
async def protected_route(token: str = Depends(oauth2_scheme), db: AsyncSession = Depends(get_db)):
|
||||
user_id = verify_access_token(token)
|
||||
async with db.begin():
|
||||
query = select(User).filter(User.id == user_id)
|
||||
result = await db.execute(query)
|
||||
user = result.scalars().first()
|
||||
|
||||
if not user:
|
||||
raise HTTPException(status_code=401, detail="User not found")
|
||||
|
||||
return {"message": f"Hello, {user.name}"}
|
||||
async def protected_route(user: User = Depends(token_refresh_middleware)):
|
||||
return {"message": f"Hello, {user.name}"}
|
||||
Reference in New Issue
Block a user