"""Professional report generation endpoints — PDF, DOCX, HTML output.""" # Import UUID from uuid from uuid import UUID # Import APIRouter, Depends, Query, Request from fastapi from fastapi import APIRouter, Depends, Query, Request # Import FileResponse from fastapi.responses from fastapi.responses import FileResponse # Import Session from sqlalchemy.orm from sqlalchemy.orm import Session # Import get_db from app.database from app.database import get_db # Import get_current_user, require_any_role from app.dependencies.auth from app.dependencies.auth import get_current_user, require_any_role # Import limiter from app.limiter from app.limiter import limiter # Import User from app.models.user from app.models.user import User # Import report_generation_service from app.services from app.services import report_generation_service # Assign router = APIRouter(prefix="/reports/generate", tags=["professional-reports"]) router = APIRouter(prefix="/reports/generate", tags=["professional-reports"]) # Assign _MEDIA_TYPES = { _MEDIA_TYPES = { # Literal argument value "pdf": "application/pdf", # Literal argument value "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", # Literal argument value "html": "text/html", } # Apply the @router.get decorator @router.get("/purple-campaign/{campaign_id}") # Apply the @limiter.limit decorator @limiter.limit("5/minute") # Define function generate_purple_report def generate_purple_report( # Entry: request request: Request, # Entry: campaign_id campaign_id: UUID, # Entry: format format: str = Query("pdf", pattern="^(pdf|docx|html)$"), # Entry: db db: Session = Depends(get_db), # Entry: user user: User = Depends(require_any_role("red_lead", "blue_lead", "viewer")), ) -> FileResponse: """Generate a Purple Team campaign assessment report.""" # Assign filepath = report_generation_service.generate_purple_campaign_report( filepath = report_generation_service.generate_purple_campaign_report( db, str(campaign_id), output_format=format, ) # Return FileResponse( return FileResponse( filepath, # Keyword argument: media_type media_type=_MEDIA_TYPES[format], # Keyword argument: filename filename=f"purple_report.{format}", ) # Apply the @router.get decorator @router.get("/coverage-summary") # Apply the @limiter.limit decorator @limiter.limit("5/minute") # Define function generate_coverage_report def generate_coverage_report( # Entry: request request: Request, # Entry: format format: str = Query("pdf", pattern="^(pdf|docx|html)$"), # Entry: db db: Session = Depends(get_db), # Entry: user user: User = Depends(require_any_role("red_lead", "blue_lead", "viewer")), ) -> FileResponse: """Generate an organization-wide MITRE ATT&CK coverage report.""" # Assign filepath = report_generation_service.generate_coverage_report( filepath = report_generation_service.generate_coverage_report( db, output_format=format, ) # Return FileResponse( return FileResponse( filepath, # Keyword argument: media_type media_type=_MEDIA_TYPES[format], # Keyword argument: filename filename=f"coverage_report.{format}", ) # Apply the @router.get decorator @router.get("/executive-summary") # Apply the @limiter.limit decorator @limiter.limit("5/minute") # Define function generate_executive_report def generate_executive_report( # Entry: request request: Request, # Entry: format format: str = Query("pdf", pattern="^(pdf|docx|html)$"), # Entry: db db: Session = Depends(get_db), # Entry: user user: User = Depends(require_any_role("red_lead", "blue_lead", "viewer")), ) -> FileResponse: """Generate an executive security summary report.""" # Assign filepath = report_generation_service.generate_executive_summary( filepath = report_generation_service.generate_executive_summary( db, output_format=format, ) # Return FileResponse( return FileResponse( filepath, # Keyword argument: media_type media_type=_MEDIA_TYPES[format], # Keyword argument: filename filename=f"executive_summary.{format}", ) # Apply the @router.get decorator @router.get("/quarterly-summary") # Apply the @limiter.limit decorator @limiter.limit("5/minute") # Define function generate_quarterly_report def generate_quarterly_report( # Entry: request request: Request, # Entry: format format: str = Query("pdf", pattern="^(pdf|docx|html)$"), # Entry: db db: Session = Depends(get_db), # Entry: user user: User = Depends(require_any_role("red_lead", "blue_lead", "viewer")), ) -> FileResponse: """Generate a quarterly security summary report.""" # Assign filepath = report_generation_service.generate_quarterly_summary( filepath = report_generation_service.generate_quarterly_summary( db, output_format=format, ) # Return FileResponse( return FileResponse( filepath, # Keyword argument: media_type media_type=_MEDIA_TYPES[format], # Keyword argument: filename filename=f"quarterly_summary.{format}", ) # Apply the @router.get decorator @router.get("/technique/{technique_id}") # Apply the @limiter.limit decorator @limiter.limit("5/minute") # Define function generate_technique_report def generate_technique_report( # Entry: request request: Request, # Entry: technique_id technique_id: UUID, # Entry: format format: str = Query("pdf", pattern="^(pdf|docx|html)$"), # Entry: db db: Session = Depends(get_db), # Entry: user user: User = Depends(get_current_user), ) -> FileResponse: """Generate a detailed report for one MITRE technique.""" # Assign filepath = report_generation_service.generate_technique_detail_report( filepath = report_generation_service.generate_technique_detail_report( db, str(technique_id), output_format=format, ) # Return FileResponse( return FileResponse( filepath, # Keyword argument: media_type media_type=_MEDIA_TYPES[format], # Keyword argument: filename filename=f"technique_{technique_id}.{format}", )