Harden auth and persist report schedules

This commit is contained in:
dwindown
2026-06-06 19:40:32 +07:00
parent aaf64264f7
commit fd7989f673
18 changed files with 748 additions and 105 deletions

View File

@@ -85,6 +85,15 @@ async def get_student_performance_report(
Returns individual student records and/or aggregate statistics.
"""
website_id = require_website_auth(auth, allowed_roles={"student", "admin", "system_admin"})
scoped_wp_user_id = None
if auth.role == "student":
if not auth.wp_user_id:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Student reports require an authenticated WordPress user",
)
scoped_wp_user_id = auth.wp_user_id
date_range = None
if date_start or date_end:
date_range = {}
@@ -99,6 +108,7 @@ async def get_student_performance_report(
db=db,
date_range=date_range,
format_type=format_type,
wp_user_id=scoped_wp_user_id,
)
return _convert_student_performance_report(report)
@@ -361,7 +371,8 @@ async def create_report_schedule(
"""
website_id = require_website_auth(auth, allowed_roles={"admin", "system_admin"})
ensure_website_scope_matches(website_id, request.website_id)
schedule_id = schedule_report(
schedule_id = await schedule_report(
db,
report_type=request.report_type,
schedule=request.schedule,
tryout_ids=request.tryout_ids,
@@ -370,7 +381,7 @@ async def create_report_schedule(
export_format=request.export_format,
)
scheduled = get_scheduled_report(schedule_id)
scheduled = await get_scheduled_report(db, schedule_id)
return ReportScheduleResponse(
schedule_id=schedule_id,
@@ -387,6 +398,7 @@ async def create_report_schedule(
)
async def get_scheduled_report_details(
schedule_id: str,
db: AsyncSession = Depends(get_db),
auth: AuthContext = Depends(get_auth_context),
) -> ReportScheduleOutput:
"""
@@ -395,7 +407,7 @@ async def get_scheduled_report_details(
Returns the configuration and status of a scheduled report.
"""
website_id = require_website_auth(auth, allowed_roles={"admin", "system_admin"})
scheduled = get_scheduled_report(schedule_id)
scheduled = await get_scheduled_report(db, schedule_id)
if not scheduled:
raise HTTPException(
@@ -431,6 +443,7 @@ async def get_scheduled_report_details(
description="List all scheduled reports for a website.",
)
async def list_scheduled_reports_endpoint(
db: AsyncSession = Depends(get_db),
auth: AuthContext = Depends(get_auth_context),
) -> List[ReportScheduleOutput]:
"""
@@ -439,7 +452,7 @@ async def list_scheduled_reports_endpoint(
Returns all scheduled reports for the current website.
"""
website_id = require_website_auth(auth, allowed_roles={"admin", "system_admin"})
reports = list_scheduled_reports(website_id=website_id)
reports = await list_scheduled_reports(db, website_id=website_id)
return [
ReportScheduleOutput(
@@ -466,6 +479,7 @@ async def list_scheduled_reports_endpoint(
)
async def cancel_scheduled_report_endpoint(
schedule_id: str,
db: AsyncSession = Depends(get_db),
auth: AuthContext = Depends(get_auth_context),
) -> dict:
"""
@@ -474,7 +488,7 @@ async def cancel_scheduled_report_endpoint(
Removes the scheduled report from the system.
"""
website_id = require_website_auth(auth, allowed_roles={"admin", "system_admin"})
scheduled = get_scheduled_report(schedule_id)
scheduled = await get_scheduled_report(db, schedule_id)
if not scheduled:
raise HTTPException(
@@ -488,7 +502,7 @@ async def cancel_scheduled_report_endpoint(
detail="Access denied to this scheduled report",
)
success = cancel_scheduled_report(schedule_id)
success = await cancel_scheduled_report(db, schedule_id)
if not success:
raise HTTPException(
@@ -523,7 +537,7 @@ async def export_scheduled_report(
Generates the report and returns it as a file download.
"""
website_id = require_website_auth(auth, allowed_roles={"admin", "system_admin"})
scheduled = get_scheduled_report(schedule_id)
scheduled = await get_scheduled_report(db, schedule_id)
if not scheduled:
raise HTTPException(
@@ -536,6 +550,11 @@ async def export_scheduled_report(
status_code=status.HTTP_403_FORBIDDEN,
detail="Access denied to this scheduled report",
)
if not scheduled.is_active:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Scheduled report is inactive",
)
# Generate report based on type
report = None