"""Audit log API endpoints.""" from datetime import datetime from typing import Optional from fastapi import APIRouter, Depends, Query, HTTPException, status from sqlalchemy.orm import Session from app.dependencies import get_db, get_current_superuser from app.models.user import User from app import crud from app.schemas.audit_log import ( AuditLog, AuditLogList, AuditLogFilter, AuditLogStats ) router = APIRouter() @router.get("", response_model=AuditLogList) def get_audit_logs( db: Session = Depends(get_db), current_user: User = Depends(get_current_superuser), page: int = Query(1, ge=1), page_size: int = Query(50, ge=1, le=100), user_id: Optional[str] = None, username: Optional[str] = None, action: Optional[str] = None, resource_type: Optional[str] = None, resource_id: Optional[str] = None, status_filter: Optional[str] = Query(None, alias="status"), start_date: Optional[datetime] = None, end_date: Optional[datetime] = None, ): """ Get paginated audit logs with optional filtering. Requires superuser authentication. """ filters = AuditLogFilter( user_id=user_id, username=username, action=action, resource_type=resource_type, resource_id=resource_id, status=status_filter, start_date=start_date, end_date=end_date ) skip = (page - 1) * page_size items, total = crud.audit_log.get_multi( db, skip=skip, limit=page_size, filters=filters ) total_pages = (total + page_size - 1) // page_size return AuditLogList( items=items, total=total, page=page, page_size=page_size, total_pages=total_pages ) @router.get("/stats", response_model=AuditLogStats) def get_audit_stats( db: Session = Depends(get_db), current_user: User = Depends(get_current_superuser), ): """ Get audit log statistics. Requires superuser authentication. """ return crud.audit_log.get_stats(db) @router.get("/actions") def get_distinct_actions( db: Session = Depends(get_db), current_user: User = Depends(get_current_superuser), ): """ Get list of distinct action types for filtering. """ return {"actions": crud.audit_log.get_distinct_actions(db)} @router.get("/resource-types") def get_distinct_resource_types( db: Session = Depends(get_db), current_user: User = Depends(get_current_superuser), ): """ Get list of distinct resource types for filtering. """ return {"resource_types": crud.audit_log.get_distinct_resource_types(db)} @router.get("/user/{user_id}", response_model=AuditLogList) def get_user_audit_logs( user_id: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_superuser), page: int = Query(1, ge=1), page_size: int = Query(50, ge=1, le=100), ): """ Get audit logs for a specific user. Requires superuser authentication. """ filters = AuditLogFilter(user_id=user_id) skip = (page - 1) * page_size items, total = crud.audit_log.get_multi( db, skip=skip, limit=page_size, filters=filters ) total_pages = (total + page_size - 1) // page_size return AuditLogList( items=items, total=total, page=page, page_size=page_size, total_pages=total_pages ) @router.get("/{log_id}", response_model=AuditLog) def get_audit_log( log_id: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_superuser), ): """ Get a specific audit log entry. Requires superuser authentication. """ log = crud.audit_log.get(db, id=log_id) if not log: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Audit log not found" ) return log @router.delete("/cleanup") def cleanup_old_logs( db: Session = Depends(get_db), current_user: User = Depends(get_current_superuser), days: int = Query(90, ge=1, le=365), ): """ Delete audit logs older than specified days. Requires superuser authentication. Default: 90 days. """ deleted = crud.audit_log.delete_old(db, days=days) return {"deleted": deleted, "days_threshold": days}