111 lines
4.6 KiB
Python
111 lines
4.6 KiB
Python
import json
|
|
import os
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, Request
|
|
|
|
from app.core.config import ENV_FILE_PATH
|
|
from app.core.security import admin_auth, persist_env_value, set_admin_token
|
|
from app.repositories import app_channel_repository
|
|
from app.schemas.admin_config import ChangeAdminTokenRequest, ClientConfigGenerateRequest
|
|
from app.services.admin_config_service import (
|
|
PUBLISH_MAX_FIELDS,
|
|
PUBLISH_MAX_FILES,
|
|
PUBLISH_MAX_REQUEST_BYTES,
|
|
RELEASE_MAIN_EXECUTABLE,
|
|
TARGET_ARCH,
|
|
TARGET_PLATFORM,
|
|
default_client_config_values,
|
|
normalize_executable_name,
|
|
public_api_base_url,
|
|
)
|
|
from app.services.common_service import validate_channel_code
|
|
|
|
|
|
router = APIRouter(tags=["admin-config"])
|
|
|
|
|
|
@router.get("/admin/auth/check")
|
|
def admin_auth_check(auth=Depends(admin_auth)):
|
|
return {"code": 0, "msg": "管理员令牌有效"}
|
|
|
|
|
|
@router.post("/admin/token/change")
|
|
def admin_change_token(body: ChangeAdminTokenRequest, auth=Depends(admin_auth)):
|
|
new_token = body.new_token.strip()
|
|
if len(new_token) < 8:
|
|
raise HTTPException(status_code=400, detail="新令牌至少需要 8 个字符")
|
|
if len(new_token) > 128:
|
|
raise HTTPException(status_code=400, detail="新令牌不能超过 128 个字符")
|
|
try:
|
|
persist_env_value(ENV_FILE_PATH, "ADMIN_TOKEN", new_token)
|
|
except Exception as exc:
|
|
raise HTTPException(status_code=500, detail=f"令牌已通过校验,但写入 .env 失败: {exc}")
|
|
set_admin_token(new_token)
|
|
os.environ["ADMIN_TOKEN"] = new_token
|
|
return {"code": 0, "msg": f"管理员令牌已更新,并已写入 {ENV_FILE_PATH}"}
|
|
|
|
|
|
@router.get("/admin/runtime-config")
|
|
def admin_runtime_config(request: Request, auth=Depends(admin_auth)):
|
|
return {
|
|
"release_main_executable": RELEASE_MAIN_EXECUTABLE,
|
|
"target_platform": TARGET_PLATFORM,
|
|
"target_arch": TARGET_ARCH,
|
|
"publish_max_request_bytes": PUBLISH_MAX_REQUEST_BYTES,
|
|
"publish_max_files": PUBLISH_MAX_FILES,
|
|
"publish_max_fields": PUBLISH_MAX_FIELDS,
|
|
"api_base_url": public_api_base_url(request),
|
|
"default_client_config": default_client_config_values(request),
|
|
}
|
|
|
|
|
|
@router.post("/admin/client-config/generate")
|
|
def admin_generate_client_config(body: ClientConfigGenerateRequest, request: Request, auth=Depends(admin_auth)):
|
|
app_id = body.app_id.strip()
|
|
channel = body.channel.strip() or "stable"
|
|
current_version = body.current_version.strip() or "1.0.0"
|
|
client_protocol = max(1, int(body.client_protocol or 3))
|
|
api_base_url = (body.api_base_url.strip() or public_api_base_url(request)).rstrip("/")
|
|
if not app_id:
|
|
raise HTTPException(status_code=400, detail="请先选择或填写 App ID")
|
|
if not validate_channel_code(channel):
|
|
raise HTTPException(status_code=400, detail="渠道代码无效")
|
|
if not api_base_url.startswith(("http://", "https://")):
|
|
raise HTTPException(status_code=400, detail="api_base_url 必须以 http:// 或 https:// 开头")
|
|
|
|
app_row = app_channel_repository.get_app(app_id)
|
|
if not app_row:
|
|
raise HTTPException(status_code=404, detail="应用不存在,请先在应用管理中创建")
|
|
channel_row = app_channel_repository.get_channel(app_id, channel)
|
|
if not channel_row:
|
|
raise HTTPException(status_code=400, detail={"error": "channel_not_found", "msg": f"渠道 {channel} 不存在"})
|
|
|
|
defaults = default_client_config_values(request)
|
|
main_executable = normalize_executable_name(body.main_executable) or defaults["main_executable"]
|
|
config = {
|
|
"app_id": app_id,
|
|
"app_name": app_row["app_name"],
|
|
"channel": channel,
|
|
"current_version": current_version,
|
|
"client_protocol": str(client_protocol),
|
|
"launch_token": defaults["launch_token"],
|
|
"license_key": body.license_key.strip(),
|
|
"api_base_url": api_base_url,
|
|
"client_token": defaults["client_token"],
|
|
"request_timeout_ms": defaults["request_timeout_ms"],
|
|
"temp_folder": defaults["temp_folder"],
|
|
"device_id": "",
|
|
"install_root": defaults["install_root"],
|
|
"main_executable": main_executable,
|
|
"launcher_executable": defaults["launcher_executable"],
|
|
"updater_executable": defaults["updater_executable"],
|
|
"bootstrap_executable": defaults["bootstrap_executable"],
|
|
"health_check_timeout_ms": defaults["health_check_timeout_ms"],
|
|
"platform": defaults["platform"],
|
|
"arch": defaults["arch"],
|
|
}
|
|
return {
|
|
"config": config,
|
|
"json_text": json.dumps(config, ensure_ascii=False, indent=2),
|
|
}
|