强化支付协议校验与证据保护

This commit is contained in:
yml2213
2026-08-12 23:54:14 +08:00
parent 74a85c8328
commit 99520d9b9b
6 changed files with 292 additions and 143 deletions
@@ -13,6 +13,7 @@ import importlib.util
import json
import os
import re
import shutil
import subprocess
import sys
import threading
@@ -25,6 +26,7 @@ from urllib.parse import urlparse
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
DEFAULT_DATA = ROOT / "config" / "worker-jobs"
DEFAULT_EVIDENCE_TTL_HOURS = 72
WORKER_KEY = os.environ.get("YYB_WORKER_KEY", "")
_jobs: dict[str, dict] = {}
_lock = threading.Lock()
@@ -53,6 +55,25 @@ def _job_dir(job_id: str) -> Path:
return Path(_jobs[job_id]["directory"])
def _cleanup_expired_jobs(data_dir: Path, ttl_hours: int) -> int:
"""清理超过保留期的任务证据;只处理 data_dir 的一级任务目录。"""
if ttl_hours <= 0 or not data_dir.exists():
return 0
deadline = time.time() - ttl_hours * 3600
removed = 0
for directory in data_dir.iterdir():
if not directory.is_dir() or directory.is_symlink():
continue
try:
if directory.stat().st_mtime >= deadline:
continue
shutil.rmtree(directory)
removed += 1
except OSError as exc:
print(f"无法清理过期任务证据 {directory.name}: {exc}", flush=True)
return removed
def _safe_log(job: dict, line: str) -> None:
# Do not persist cookies, payment URI, or long opaque tokens in the worker API.
clean = re.sub(r"weixin://\S+", "[付款链接已隐藏]", line)
@@ -389,6 +410,7 @@ class Handler(BaseHTTPRequestHandler):
job_id = uuid.uuid4().hex[:16]
directory = DEFAULT_DATA / job_id
directory.mkdir(parents=True, exist_ok=True)
os.chmod(directory, 0o700)
_jobs[job_id] = {"job_id": job_id, "status": "created", "phase": "login",
"logs": [], "directory": str(directory), "created_at": int(time.time())}
return self._json(201, _public_job(job_id))
@@ -565,6 +587,8 @@ def main() -> int:
parser.add_argument("--host", default="127.0.0.1")
parser.add_argument("--port", type=int, default=8810)
parser.add_argument("--data-dir", type=Path, default=DEFAULT_DATA)
parser.add_argument("--evidence-ttl-hours", type=int, default=DEFAULT_EVIDENCE_TTL_HOURS,
help="任务原始证据保留时长;0 表示不自动清理")
parser.add_argument("--key", default=None, help="HTTP Bearer 鉴权密钥;默认读取 YYB_WORKER_KEY")
args = parser.parse_args()
# 强制绝对路径:子进程以 ROOT 为 cwd,相对路径会让任务文件写到错误位置。
@@ -573,7 +597,13 @@ def main() -> int:
WORKER_KEY = args.key
if args.host not in {"127.0.0.1", "localhost", "::1"} and not WORKER_KEY:
parser.error("监听非本机地址时必须设置 --key 或 YYB_WORKER_KEY")
if args.evidence_ttl_hours < 0:
parser.error("--evidence-ttl-hours 不能小于 0")
DEFAULT_DATA.mkdir(parents=True, exist_ok=True)
os.chmod(DEFAULT_DATA, 0o700)
removed = _cleanup_expired_jobs(DEFAULT_DATA, args.evidence_ttl_hours)
if removed:
print(f"已清理 {removed} 个过期任务证据(保留期 {args.evidence_ttl_hours} 小时)", flush=True)
restored = _restore_jobs(DEFAULT_DATA)
if restored:
print(f"已从任务目录恢复 {restored} 个支付任务", flush=True)