Complete Section 1 security/auth hardening

This commit is contained in:
dwindown
2026-04-30 11:35:56 +07:00
parent 432ffbcdb9
commit 12d2d9458f
15 changed files with 863 additions and 232 deletions

View File

@@ -10,11 +10,12 @@ Endpoints:
import logging
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Header, status
from fastapi import APIRouter, Depends, HTTPException, Header, Request, status
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.database import get_db
from app.core.auth import issue_access_token
from app.models.user import User
from app.models.website import Website
from app.schemas.wordpress import (
@@ -36,6 +37,7 @@ from app.services.wordpress_auth import (
WordPressTokenInvalidError,
WebsiteNotFoundError,
)
from app.core.rate_limit import enforce_rate_limit
logger = logging.getLogger(__name__)
@@ -104,6 +106,7 @@ async def get_valid_website(
description="Fetch all users from WordPress API and sync to local database. Requires admin WordPress token.",
)
async def sync_users_endpoint(
request: Request,
db: AsyncSession = Depends(get_db),
website_id: int = Depends(get_website_id_from_header),
authorization: Optional[str] = Header(None, alias="Authorization"),
@@ -129,6 +132,13 @@ async def sync_users_endpoint(
Raises:
HTTPException: If website not found, token invalid, or API error
"""
enforce_rate_limit(
request,
scope="wordpress.sync_users",
max_requests=20,
window_seconds=300,
)
# Validate website exists
await get_valid_website(website_id, db)
@@ -196,6 +206,7 @@ async def sync_users_endpoint(
description="Verify WordPress JWT token and user identity.",
)
async def verify_session_endpoint(
http_request: Request,
request: VerifySessionRequest,
db: AsyncSession = Depends(get_db),
) -> VerifySessionResponse:
@@ -219,6 +230,13 @@ async def verify_session_endpoint(
Raises:
HTTPException: If website not found or API error
"""
enforce_rate_limit(
http_request,
scope="wordpress.verify_session",
max_requests=60,
window_seconds=300,
)
# Validate website exists
await get_valid_website(request.website_id, db)
@@ -253,6 +271,12 @@ async def verify_session_endpoint(
"display_name": wp_user_info.display_name,
"roles": wp_user_info.roles,
},
access_token=issue_access_token(
website_id=request.website_id,
role="student",
wp_user_id=request.wp_user_id,
expires_in_seconds=3600 * 24,
),
)
except WordPressTokenInvalidError as e: