""" FastAPI server for the VPN Access Server. """ import uvicorn import os from fastapi import FastAPI, HTTPException from fastapi.responses import FileResponse from pydantic import BaseModel from util.client.generate_client import generate_client_config from util.email import send_vpn_config app = FastAPI( title="VPN Access Server API", description="API for managing VPN clients and server operations.", version="1.0.0", ) class ClientRequest(BaseModel): username: str email: str @app.post("/api/client/generate", summary="Generate a new VPN client configuration") def generate_client(request: ClientRequest): """ Generates a new OpenVPN client configuration (.ovpn) file and sends it via email. This endpoint will: 1. Trigger `easyrsa` to generate a new client certificate and key. 2. Assemble the `.ovpn` file with the new certificate/key and the server's CA and TA keys. 3. Save the file to the server's client configuration directory. 4. Send the .ovpn file and user guide via email to the provided email address. """ success, message = generate_client_config(request.username, request.email) if not success: raise HTTPException(status_code=500, detail=message) # Send email with VPN config and user guide vpn_config_path = os.path.join("generated-clients", f"{request.username}.ovpn") user_guide_path = "material/sample-ppt.pptx" email_success = send_vpn_config( to_email=request.email, username=request.username, vpn_config_path=vpn_config_path, user_guide_path=user_guide_path ) if not email_success: # Configuration was generated successfully, but email failed # Return success with warning about email return { "message": f"{message} Warning: Failed to send email with configuration files.", "email_sent": False } return { "message": f"{message} Configuration files sent to {request.email}", "email_sent": True } @app.get("/api/client/get-config/{username}", summary="Download a client configuration file") def get_client_config(username: str, email: str): """ Downloads the .ovpn configuration file for a specific client. The file is sought in the `generated-clients` directory. """ file_path = os.path.join("generated-clients", f"{username}.ovpn") if not os.path.isfile(file_path): raise HTTPException(status_code=404, detail="Configuration file not found for this user. Please generate it first.") return FileResponse(path=file_path, filename=f"{username}.ovpn", media_type='application/octet-stream') if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8443)