"""D3FEND endpoints — defensive technique listings, mappings, and import trigger.""" # 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, require_role from app.dependencies.auth from app.dependencies.auth import get_current_user, require_role # Import User from app.models.user from app.models.user import User # Import from app.services.d3fend_import_service from app.services.d3fend_import_service import ( import_d3fend_mappings, import_d3fend_techniques, ) # Import from app.services.d3fend_query_service from app.services.d3fend_query_service import ( get_defenses_for_attack_technique, list_d3fend_tactics, ) # Import from app.services.d3fend_query_service from app.services.d3fend_query_service import ( list_defensive_techniques as list_defensive_techniques_svc, ) # Assign logger = logging.getLogger(__name__) logger = logging.getLogger(__name__) # Assign router = APIRouter(prefix="/d3fend", tags=["d3fend"]) router = APIRouter(prefix="/d3fend", tags=["d3fend"]) # --------------------------------------------------------------------------- # GET /d3fend — List all defensive techniques # --------------------------------------------------------------------------- @router.get("") # Define function list_defensive_techniques def list_defensive_techniques( # Entry: tactic tactic: Optional[str] = Query(None), # Entry: search search: 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 all D3FEND defensive techniques with optional filters.""" # Return list_defensive_techniques_svc( return list_defensive_techniques_svc( db, tactic=tactic, search=search, offset=offset, limit=limit ) # --------------------------------------------------------------------------- # GET /d3fend/tactics — List all D3FEND tactics # --------------------------------------------------------------------------- @router.get("/tactics") # Define function list_d3fend_tactics_endpoint def list_d3fend_tactics_endpoint( # Entry: db db: Session = Depends(get_db), # Entry: current_user current_user: User = Depends(get_current_user), ) -> list: """Return a list of all D3FEND tactics with counts.""" # Return list_d3fend_tactics(db) return list_d3fend_tactics(db) # --------------------------------------------------------------------------- # GET /d3fend/for-technique/{mitre_id} — Defenses for a technique # --------------------------------------------------------------------------- @router.get("/for-technique/{mitre_id}") # Define function get_defenses_for_attack_technique_endpoint def get_defenses_for_attack_technique_endpoint( # Entry: mitre_id mitre_id: str, # Entry: db db: Session = Depends(get_db), # Entry: current_user current_user: User = Depends(get_current_user), ) -> dict: """Get all D3FEND defensive techniques mapped to a given ATT&CK technique.""" # Return get_defenses_for_attack_technique(db, mitre_id) return get_defenses_for_attack_technique(db, mitre_id) # --------------------------------------------------------------------------- # POST /d3fend/import — Trigger D3FEND import (admin only) # --------------------------------------------------------------------------- @router.post("/import") # Define function trigger_d3fend_import def trigger_d3fend_import( # Entry: db db: Session = Depends(get_db), # Entry: current_user current_user: User = Depends(require_role("admin")), ) -> dict: """Import D3FEND techniques and ATT&CK mappings. Admin only.""" # Assign tech_result = import_d3fend_techniques(db) tech_result = import_d3fend_techniques(db) # Assign mapping_result = import_d3fend_mappings(db) mapping_result = import_d3fend_mappings(db) # Return { return { # Literal argument value "techniques": tech_result, # Literal argument value "mappings": mapping_result, }