Automated Action b078a91dd3 Implement simple ecommerce API with FastAPI and SQLite
- Setup project structure and FastAPI application
- Create SQLAlchemy models for users, products, carts, and orders
- Implement Alembic migrations
- Add CRUD operations and endpoints for all resources
- Setup authentication with JWT
- Add role-based access control
- Update documentation
2025-06-12 17:15:18 +00:00

107 lines
2.6 KiB
Python

from typing import Generator
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
from pydantic import ValidationError
from sqlalchemy.orm import Session
from app.core.config import settings
from app.crud.user import user as user_crud
from app.db.session import SessionLocal
from app.models.user import User
from app.schemas.token import TokenPayload
reusable_oauth2 = OAuth2PasswordBearer(tokenUrl=f"{settings.API_V1_STR}/auth/login")
def get_db() -> Generator:
"""
Dependency function that yields a SQLAlchemy database session.
The session is closed after the request is complete.
"""
try:
db = SessionLocal()
yield db
finally:
db.close()
def get_current_user(
db: Session = Depends(get_db), token: str = Depends(reusable_oauth2)
) -> User:
"""
Decode JWT token to get user identity and fetch user object from database.
Args:
db: Database session
token: JWT token
Returns:
User object
Raises:
HTTPException: If token is invalid or user not found
"""
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])
token_data = TokenPayload(**payload)
except (JWTError, ValidationError):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
user = user_crud.get(db, id=token_data.sub)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="User not found"
)
return user
def get_current_active_user(
current_user: User = Depends(get_current_user),
) -> User:
"""
Check if current user is active.
Args:
current_user: Current user
Returns:
User object
Raises:
HTTPException: If user is inactive
"""
if not user_crud.is_active(current_user):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="Inactive user"
)
return current_user
def get_current_active_superuser(
current_user: User = Depends(get_current_user),
) -> User:
"""
Check if current user is a superuser.
Args:
current_user: Current user
Returns:
User object
Raises:
HTTPException: If user is not a superuser
"""
if not user_crud.is_superuser(current_user):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="The user doesn't have enough privileges",
)
return current_user