Files
live-hub-py/web/backend/routers/proxy.py
T

147 lines
4.7 KiB
Python

"""代理 & 白名单配置路由"""
import re
import time
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from ..database import get_db
from ..models import User, ProxyConfig as ProxyConfigModel, AuditLog
from ..schemas import ProxyConfigOut, ProxyConfigUpdate, MessageResponse
from ..deps import require_permission
router = APIRouter(prefix="/api/proxy", tags=["代理与白名单"])
def _get_or_create(db: Session) -> ProxyConfigModel:
cfg = db.query(ProxyConfigModel).first()
if not cfg:
cfg = ProxyConfigModel()
db.add(cfg)
db.commit()
db.refresh(cfg)
return cfg
@router.get("", response_model=ProxyConfigOut)
def get_proxy_config(
db: Session = Depends(get_db),
_: User = Depends(require_permission("proxy:manage")),
):
return _get_or_create(db)
@router.put("", response_model=ProxyConfigOut)
def update_proxy_config(
req: ProxyConfigUpdate,
db: Session = Depends(get_db),
current: User = Depends(require_permission("proxy:manage")),
):
cfg = _get_or_create(db)
cfg.enabled = req.enabled
cfg.api_url = req.api_url
cfg.http = req.http
cfg.https = req.https
cfg.whitelist_enabled = req.whitelist_enabled
cfg.whitelist_uid = req.whitelist_uid
cfg.whitelist_ukey = req.whitelist_ukey
db.commit()
db.refresh(cfg)
db.add(AuditLog(user_id=current.id, username=current.username,
action="proxy:update", target="proxy_config"))
db.commit()
return cfg
@router.post("/test")
def test_proxy(
db: Session = Depends(get_db),
current: User = Depends(require_permission("proxy:manage")),
):
"""测试代理连通性。"""
import requests as req_lib
cfg = _get_or_create(db)
if not cfg.enabled:
return {"success": False, "message": "代理未启用"}
proxy_url = cfg.http or cfg.https
if cfg.api_url and not proxy_url:
try:
resp = req_lib.get(cfg.api_url, timeout=10)
match = re.search(r'(\d+\.\d+\.\d+\.\d+):(\d+)', resp.text)
if match:
proxy_url = f"http://{match.group(1)}:{match.group(2)}"
except Exception as e:
return {"success": False, "message": f"代理API请求失败: {e}"}
if not proxy_url:
return {"success": False, "message": "无可用代理地址"}
try:
resp = req_lib.get(
"https://qifu-api.baidubce.com/ip/local/geo/v1/district",
proxies={"http": proxy_url, "https": proxy_url},
timeout=(4, 6),
headers={"User-Agent": "Mozilla/5.0"},
)
resp.raise_for_status()
return {"success": True, "message": f"代理可用,响应: {resp.text[:100]}"}
except Exception as e:
return {"success": False, "message": f"代理验证失败: {e}"}
@router.post("/whitelist/test")
def test_whitelist(
db: Session = Depends(get_db),
current: User = Depends(require_permission("whitelist:test")),
):
"""测试白名单连接并自动同步出口IP。"""
from core.douyu.whitelist import WhitelistManager, get_exit_ip_via_proxy
import requests as req_lib
cfg = _get_or_create(db)
if not cfg.whitelist_enabled:
return {"success": False, "message": "白名单未启用"}
if not cfg.whitelist_uid or not cfg.whitelist_ukey:
return {"success": False, "message": "未配置白名单UID/UKEY"}
manager = WhitelistManager(cfg.whitelist_uid, cfg.whitelist_ukey)
# 测试API连接
ok, msg = manager.test_connection()
if not ok:
return {"success": False, "message": msg}
# 获取出口IP
proxy_url = cfg.http or cfg.https
if cfg.api_url and not proxy_url:
try:
resp = req_lib.get(cfg.api_url, timeout=10)
match = re.search(r'(\d+\.\d+\.\d+\.\d+):(\d+)', resp.text)
if match:
proxy_url = f"http://{match.group(1)}:{match.group(2)}"
except Exception:
pass
exit_ip = None
if proxy_url:
exit_ip = get_exit_ip_via_proxy(proxy_url)
if not exit_ip:
try:
resp = req_lib.get("https://4.ipw.cn", timeout=6, headers={"User-Agent": "Mozilla/5.0"})
match = re.search(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', resp.text)
if match:
exit_ip = match.group(1)
except Exception:
pass
if not exit_ip:
return {"success": False, "message": "API连接正常但无法获取出口IP"}
# 同步白名单
sync_ok, sync_msg = manager.sync_ip(exit_ip)
if sync_ok:
return {"success": True, "message": f"出口IP {exit_ip} 已同步: {sync_msg}"}
return {"success": False, "message": f"同步失败: {sync_msg}"}