feat: migrate to Pydantic V2 and implement rate limiting middleware
- Migrate settings.py to Pydantic V2 (SettingsConfigDict, validation_alias) - Update config models to use @field_validator with @classmethod - Replace deprecated datetime.utcnow() with datetime.now(timezone.utc) - Migrate FastAPI app from @app.on_event to lifespan context manager - Implement comprehensive rate limiting middleware with: * Endpoint-specific rate limits (login: 5/min, register: 3/min) * IP-based and user-based tracking * Authenticated user multiplier (2x limits) * Bypass paths for health, docs, static, websocket endpoints * Rate limit headers in responses - Add 13 comprehensive tests for rate limiting (all passing) - Update instructions.md to mark completed tasks - Fix asyncio.create_task usage in anime_service.py All 714 tests passing. No deprecation warnings.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
Tests CRUD operations for all database services using in-memory SQLite.
|
||||
"""
|
||||
import asyncio
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
import pytest
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
|
||||
@@ -538,7 +538,7 @@ async def test_retry_failed_downloads(db_session):
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_user_session(db_session):
|
||||
"""Test creating a user session."""
|
||||
expires_at = datetime.utcnow() + timedelta(hours=24)
|
||||
expires_at = datetime.now(timezone.utc) + timedelta(hours=24)
|
||||
session = await UserSessionService.create(
|
||||
db_session,
|
||||
session_id="test-session-1",
|
||||
@@ -556,7 +556,7 @@ async def test_create_user_session(db_session):
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_session_by_id(db_session):
|
||||
"""Test retrieving session by ID."""
|
||||
expires_at = datetime.utcnow() + timedelta(hours=24)
|
||||
expires_at = datetime.now(timezone.utc) + timedelta(hours=24)
|
||||
session = await UserSessionService.create(
|
||||
db_session,
|
||||
session_id="test-session-2",
|
||||
@@ -578,7 +578,7 @@ async def test_get_session_by_id(db_session):
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_active_sessions(db_session):
|
||||
"""Test retrieving active sessions."""
|
||||
expires_at = datetime.utcnow() + timedelta(hours=24)
|
||||
expires_at = datetime.now(timezone.utc) + timedelta(hours=24)
|
||||
|
||||
# Create active session
|
||||
await UserSessionService.create(
|
||||
@@ -593,7 +593,7 @@ async def test_get_active_sessions(db_session):
|
||||
db_session,
|
||||
session_id="expired-session",
|
||||
token_hash="hashed-token",
|
||||
expires_at=datetime.utcnow() - timedelta(hours=1),
|
||||
expires_at=datetime.now(timezone.utc) - timedelta(hours=1),
|
||||
)
|
||||
await db_session.commit()
|
||||
|
||||
@@ -606,7 +606,7 @@ async def test_get_active_sessions(db_session):
|
||||
@pytest.mark.asyncio
|
||||
async def test_revoke_session(db_session):
|
||||
"""Test revoking a session."""
|
||||
expires_at = datetime.utcnow() + timedelta(hours=24)
|
||||
expires_at = datetime.now(timezone.utc) + timedelta(hours=24)
|
||||
session = await UserSessionService.create(
|
||||
db_session,
|
||||
session_id="test-session-3",
|
||||
@@ -637,13 +637,13 @@ async def test_cleanup_expired_sessions(db_session):
|
||||
db_session,
|
||||
session_id="expired-1",
|
||||
token_hash="hashed-token",
|
||||
expires_at=datetime.utcnow() - timedelta(hours=1),
|
||||
expires_at=datetime.now(timezone.utc) - timedelta(hours=1),
|
||||
)
|
||||
await UserSessionService.create(
|
||||
db_session,
|
||||
session_id="expired-2",
|
||||
token_hash="hashed-token",
|
||||
expires_at=datetime.utcnow() - timedelta(hours=2),
|
||||
expires_at=datetime.now(timezone.utc) - timedelta(hours=2),
|
||||
)
|
||||
await db_session.commit()
|
||||
|
||||
@@ -657,7 +657,7 @@ async def test_cleanup_expired_sessions(db_session):
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_session_activity(db_session):
|
||||
"""Test updating session last activity."""
|
||||
expires_at = datetime.utcnow() + timedelta(hours=24)
|
||||
expires_at = datetime.now(timezone.utc) + timedelta(hours=24)
|
||||
session = await UserSessionService.create(
|
||||
db_session,
|
||||
session_id="test-session-4",
|
||||
|
||||
Reference in New Issue
Block a user