"""Threat actor endpoints. Provides listing, detail, coverage analysis, and gap analysis for threat actor profiles imported from MITRE CTI. """ # Import logging import logging # Import Optional from typing from typing import Optional # Import APIRouter, Depends, Query from fastapi from fastapi import APIRouter, Depends, Query # 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 from app.dependencies.auth from app.dependencies.auth import get_current_user # Import User from app.models.user from app.models.user import User # Import from app.services.threat_actor_service from app.services.threat_actor_service import ( get_actor_coverage, get_actor_detail, get_actor_gaps, list_actors, ) # Assign logger = logging.getLogger(__name__) logger = logging.getLogger(__name__) # Assign router = APIRouter(prefix="/threat-actors", tags=["threat-actors"]) router = APIRouter(prefix="/threat-actors", tags=["threat-actors"]) # Apply the @router.get decorator @router.get("") # Define function list_threat_actors def list_threat_actors( # Entry: search search: Optional[str] = Query(None), # Entry: country country: Optional[str] = Query(None), # Entry: motivation motivation: Optional[str] = Query(None), # Entry: sophistication sophistication: Optional[str] = Query(None), # Entry: target_sectors target_sectors: Optional[str] = Query(None), # Entry: offset offset: int = Query(0, ge=0), # Entry: limit limit: int = Query(50, ge=1, le=200), # Entry: db db: Session = Depends(get_db), # Entry: current_user current_user: User = Depends(get_current_user), ) -> dict: """List threat actors with optional filters and pagination. **Requires** authentication (any role). """ # Return list_actors( return list_actors( db, # Keyword argument: search search=search, # Keyword argument: country country=country, # Keyword argument: motivation motivation=motivation, # Keyword argument: sophistication sophistication=sophistication, # Keyword argument: target_sectors target_sectors=target_sectors, # Keyword argument: offset offset=offset, # Keyword argument: limit limit=limit, ) # Apply the @router.get decorator @router.get("/{actor_id}") # Define function get_threat_actor def get_threat_actor( # Entry: actor_id actor_id: str, # Entry: db db: Session = Depends(get_db), # Entry: current_user current_user: User = Depends(get_current_user), ) -> dict: """Get detailed info about a threat actor including techniques. **Requires** authentication (any role). """ # Return get_actor_detail(db, actor_id) return get_actor_detail(db, actor_id) # Apply the @router.get decorator @router.get("/{actor_id}/coverage") # Define function get_threat_actor_coverage def get_threat_actor_coverage( # Entry: actor_id actor_id: str, # Entry: db db: Session = Depends(get_db), # Entry: current_user current_user: User = Depends(get_current_user), ) -> dict: """Calculate coverage percentage against a specific threat actor. **Requires** authentication (any role). Returns the percentage of the actor's techniques that have been validated or partially validated, along with a breakdown. """ # Return get_actor_coverage(db, actor_id) return get_actor_coverage(db, actor_id) # Apply the @router.get decorator @router.get("/{actor_id}/gaps") # Define function get_threat_actor_gaps def get_threat_actor_gaps( # Entry: actor_id actor_id: str, # Entry: db db: Session = Depends(get_db), # Entry: current_user current_user: User = Depends(get_current_user), ) -> dict: """Identify techniques of this actor that are NOT fully validated. **Requires** authentication (any role). Returns list of gap techniques with available templates. """ # Return get_actor_gaps(db, actor_id) return get_actor_gaps(db, actor_id)