Files
oaip-project-app/web_server.py

128 lines
4.0 KiB
Python
Raw Normal View History

2025-05-21 14:24:31 +03:00
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse
2025-05-22 01:54:24 +03:00
from fastapi.middleware.cors import CORSMiddleware
2025-05-21 14:24:31 +03:00
from typing import Optional, Dict, Any
import uvicorn
from callback import call_action
from fastapi.responses import JSONResponse
2025-05-22 01:54:24 +03:00
import hashlib
import json
import time
2025-05-22 21:57:13 +03:00
import yaml
from pathlib import Path
from utils.get_primary_ip import get_primary_ip
2025-05-22 01:54:24 +03:00
2025-05-22 21:57:13 +03:00
PASSWORD = "10010055"
2025-05-22 01:54:24 +03:00
2025-05-21 14:24:31 +03:00
app = FastAPI()
2025-05-22 01:54:24 +03:00
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allows all origins
allow_credentials=True,
allow_methods=["*"], # Allows all methods (GET, POST, etc.)
allow_headers=["*"], # Allows all headers
)
2025-05-21 14:24:31 +03:00
# Static files & UI server
app.mount("/static", StaticFiles(directory="static"), name="static")
# Show main page
@app.get("/")
async def read_index():
with open("static/index.html", "r", encoding="utf-8") as f:
html_content = f.read()
return HTMLResponse(content=html_content, status_code=200)
2025-05-22 21:57:13 +03:00
# Pydantic model for request payload
class CommandModel(BaseModel):
args: Dict[str, Any]
hash: str # Mandatory hash field
@app.get("/primary-ip", response_model=None)
def get_config():
return get_primary_ip()
@app.get("/frontend-config", response_model=None)
def get_config(hash: str):
computed_hash = hashlib.sha256( ("frontend_config"+PASSWORD).encode("utf-8")).hexdigest()
# Verify hash
if computed_hash != hash:
raise HTTPException(status_code=401, detail="Invalid hash")
CONFIG_FILE = Path("config/frontend.yaml")
# Checking the existence of the file
if not CONFIG_FILE.exists():
raise HTTPException(status_code=404, detail="Файл frontend.yaml не найден")
try:
# YAML reading and parsing
with open(CONFIG_FILE, "r", encoding="utf-8") as file:
data = yaml.safe_load(file)
# Adding an id
for idx, item in enumerate(data):
item["id"] = idx
return data
except yaml.YAMLError as e:
# YAML parsing error
raise HTTPException(status_code=500, detail=f"Ошибка в формате YAML: {e}")
except Exception as e:
# Any other error
raise HTTPException(status_code=500, detail=f"Внутренняя ошибка сервера: {e}")
2025-05-21 14:24:31 +03:00
# Process actions via POST
@app.post("/action/{name:path}")
2025-05-22 01:54:24 +03:00
async def handle_action(name: str, payload: CommandModel):
action_args = payload.args
hash_with_ts = payload.hash
if not hash_with_ts:
raise HTTPException(status_code=400, detail="Missing hash")
# Split hash and timestamp
try:
received_hash, received_ts = hash_with_ts.split(".")
received_ts = int(received_ts)
except ValueError:
raise HTTPException(status_code=400, detail="Invalid hash format")
# Check if token is within 5-second window
current_ts = int(time.time())
if abs(current_ts - received_ts) > 5:
raise HTTPException(status_code=401, detail="Token expired")
# Reconstruct hash
data_to_hash = PASSWORD + json.dumps(action_args, separators=(",", ":")) + str(received_ts)
computed_hash = hashlib.sha256(data_to_hash.encode("utf-8")).hexdigest()
# Verify hash
if computed_hash != received_hash:
raise HTTPException(status_code=401, detail="Invalid hash")
2025-05-21 14:24:31 +03:00
try:
# Вызываем функцию из callback.py, передавая имя действия и аргументы
2025-05-22 01:54:24 +03:00
result = await call_action(name, action_args or {})
2025-05-21 14:24:31 +03:00
return JSONResponse(content={"status": "success", "result": result, "command": name})
except ValueError as e:
# Если функция не найдена, возвращаем 404
raise HTTPException(status_code=404, detail=str(e))
except Exception as e:
# Обработка остальных ошибок
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
uvicorn.run(app, host="0.0.0.0", port=8000)