from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from typing import List, Any, Dict from datetime import datetime, timedelta from app.api import deps from app.models.identity import User, UserRole from app.models.system_config import SystemParameter from app.models.security import PendingAction, ActionStatus from app.models.history import AuditLog, LogSeverity from app.schemas.admin_security import PendingActionResponse, SecurityStatusResponse from app.services.security_service import security_service # Feltételezve, hogy a JSON-alapú TranslationService-ed már készen van from app.services.translation_service import TranslationService router = APIRouter() # --- 🛡️ ADMIN JOGOSULTSÁG ELLENŐRZŐ --- async def check_admin_access(current_user: User = Depends(deps.get_current_active_user)): if current_user.role not in [UserRole.admin, UserRole.superadmin]: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin jogosultság szükséges!" ) return current_user # --- 1. SENTINEL: NÉGY SZEM ELV (Approval System) --- @router.get("/pending-actions", response_model=List[PendingActionResponse]) async def list_pending_actions( db: AsyncSession = Depends(deps.get_db), admin: User = Depends(check_admin_access) ): """Jóváhagyásra váró kritikus kérések listázása.""" stmt = select(PendingAction).where(PendingAction.status == ActionStatus.pending) result = await db.execute(stmt) return result.scalars().all() @router.post("/approve/{action_id}") async def approve_action( action_id: int, db: AsyncSession = Depends(deps.get_db), admin: User = Depends(check_admin_access) ): """Művelet véglegesítése (második admin által).""" try: await security_service.approve_action(db, admin.id, action_id) return {"status": "success", "message": "Művelet végrehajtva."} except Exception as e: raise HTTPException(status_code=400, detail=str(e)) # --- 2. SENTINEL: BIZTONSÁGI ÖSSZEGZÉS --- @router.get("/security-status", response_model=SecurityStatusResponse) async def get_security_status( db: AsyncSession = Depends(deps.get_db), admin: User = Depends(check_admin_access) ): """Rendszerállapot: Zárolt júzerek és kritikus események.""" day_ago = datetime.now() - timedelta(days=1) crit_count = (await db.execute(select(func.count(AuditLog.id)).where( AuditLog.severity.in_([LogSeverity.critical, LogSeverity.emergency]), AuditLog.timestamp >= day_ago ))).scalar() or 0 locked_count = (await db.execute(select(func.count(User.id)).where( User.is_active == False, User.is_deleted == False ))).scalar() or 0 return { "total_pending": (await db.execute(select(func.count(PendingAction.id)).where(PendingAction.status == ActionStatus.pending))).scalar() or 0, "critical_logs_last_24h": crit_count, "emergency_locks_active": locked_count } # --- 3. RENDSZERBEÁLLÍTÁSOK (Dynamic Config) --- @router.get("/settings") async def get_settings(db: AsyncSession = Depends(deps.get_db), admin: User = Depends(check_admin_access)): """Minden globális paraméter (Gamification, Limitek stb.) lekérése.""" result = await db.execute(select(SystemParameter)) return result.scalars().all() @router.put("/settings/{key}") async def update_setting(key: str, value: Any, db: AsyncSession = Depends(deps.get_db), admin: User = Depends(check_admin_access)): """Paraméter módosítása és Audit Log generálása.""" stmt = select(SystemParameter).where(SystemParameter.key == key) param = (await db.execute(stmt)).scalar_one_or_none() if not param: raise HTTPException(status_code=404, detail="Nincs ilyen beállítás.") old_val = param.value param.value = value await security_service.log_event( db, admin.id, action="SETTING_CHANGE", severity=LogSeverity.warning, old_data={key: old_val}, new_data={key: value} ) await db.commit() return {"status": "success", "key": key, "new_value": value} # --- 🌍 JSON FORDÍTÁSOK KEZELÉSE --- @router.post("/translations/sync") async def sync_translations_to_json( db: AsyncSession = Depends(deps.get_db), admin: User = Depends(check_admin_access) ): """Szinkronizálja az adatbázisban tárolt fordításokat a JSON fájlokba.""" # A TranslationService-ben kell megírni a fájlbaíró logikát await TranslationService.export_to_json(db) return {"message": "JSON nyelvi fájlok frissítve."}