
- 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
92 lines
2.8 KiB
Python
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
|