from fastapi import APIRouter, Depends, Request, Form, HTTPException from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse import json from deps import current_user, admin_required from services.config_loader import ConfigService router = APIRouter() @router.get("/config", response_class=HTMLResponse) async def config_editor(req: Request, user = Depends(admin_required)): """ Show the JSON Config Editor. """ raw_config = ConfigService.get_raw_config() return req.app.state.render( req, "admin/config_editor.html", config_json=raw_config, page_title="Config Editor" ) @router.post("/config/save") async def save_config( req: Request, config_json: str = Form(...), user = Depends(admin_required) ): """ Save the JSON Configuration. """ try: # 1. Parse JSON to validate syntax new_config = json.loads(config_json) # 2. Logic Validation (basic) if "roles" not in new_config: raise ValueError("JSON must contain top-level 'roles' key.") # 3. Save via Service (handles atomic write & backup) success = ConfigService.save_config(new_config) if success: # Flash success via session if available, or return logic # Assuming flash() helper is available in main scope or we add it manually to session # We can reuse the flash helper logic if accessible, otherwise direct session append flashes = req.session.get("_flashes", []) flashes.append({"msg": "Configuration saved successfully. Backup created.", "cat": "success"}) req.session["_flashes"] = flashes return RedirectResponse("/admin/config", status_code=302) else: raise Exception("Write operation failed.") except json.JSONDecodeError as e: error_msg = f"Invalid JSON: {e}" return req.app.state.render( req, "admin/config_editor.html", config_json=config_json, error=error_msg ) except Exception as e: error_msg = f"Error saving config: {e}" return req.app.state.render( req, "admin/config_editor.html", config_json=config_json, error=error_msg )