强化支付协议校验与证据保护
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user