Automated Action 8fefbb7c13 Add user authentication to the Todo app
- Created User model and schemas
- Implemented secure password hashing with bcrypt
- Added JWT token-based authentication
- Created user registration and login endpoints
- Added authentication to todo routes
- Updated todos to be associated with users
- Created migration script for the user table
- Updated documentation with auth information
2025-05-19 13:45:22 +00:00

92 lines
2.8 KiB
Python

from typing import List
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from app import crud, models
from app.api import deps
from app.db.session import get_db
from app.schemas.todo import Todo, TodoCreate, TodoUpdate
router = APIRouter(prefix="/todos", tags=["todos"])
@router.get("/", response_model=List[Todo])
def get_todos(
skip: int = Query(0, description="Skip the first N items"),
limit: int = Query(100, description="Limit the number of items returned"),
db: Session = Depends(get_db),
current_user: models.User = Depends(deps.get_current_active_user),
):
"""
Get all todos for the current user with pagination
"""
return crud.todo.get_todos(db=db, user_id=current_user.id, skip=skip, limit=limit)
@router.post("/", response_model=Todo, status_code=status.HTTP_201_CREATED)
def create_todo(
todo: TodoCreate,
db: Session = Depends(get_db),
current_user: models.User = Depends(deps.get_current_active_user),
):
"""
Create a new todo for the current user
"""
return crud.todo.create_todo(db=db, todo=todo, user_id=current_user.id)
@router.get("/{todo_id}", response_model=Todo)
def get_todo(
todo_id: int,
db: Session = Depends(get_db),
current_user: models.User = Depends(deps.get_current_active_user),
):
"""
Get a specific todo by ID, ensuring it belongs to the current user
"""
db_todo = crud.todo.get_todo(db=db, todo_id=todo_id, user_id=current_user.id)
if db_todo is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Todo with ID {todo_id} not found",
)
return db_todo
@router.put("/{todo_id}", response_model=Todo)
def update_todo(
todo_id: int,
todo: TodoUpdate,
db: Session = Depends(get_db),
current_user: models.User = Depends(deps.get_current_active_user),
):
"""
Update a todo, ensuring it belongs to the current user
"""
db_todo = crud.todo.update_todo(db=db, todo_id=todo_id, todo=todo, user_id=current_user.id)
if db_todo is None:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Todo with ID {todo_id} not found",
)
return db_todo
@router.delete("/{todo_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_todo(
todo_id: int,
db: Session = Depends(get_db),
current_user: models.User = Depends(deps.get_current_active_user),
):
"""
Delete a todo, ensuring it belongs to the current user
"""
success = crud.todo.delete_todo(db=db, todo_id=todo_id, user_id=current_user.id)
if not success:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Todo with ID {todo_id} not found",
)
return None