guanghu-ice-heart/modules/guanghu-panel-kit/hooks/pre-receive-review.template
冰朔 a6ad978b04 feat(panel-kit): 写入窗口时长升级为配置驱动 window_hours
苍耳提请:一次授权3小时太短,胖头鱼升至12小时。
- server.js:WINDOW_HOURS 读 config.json(缺省3h保持向后兼容),
  TTL/全部文案/唤醒链/领取规则/git代理提示动态化;state() 新增 windowHours
- config.example.json:新增 window_hours 字段(示例12)
- INDEX.hdlp:窗口制说明与铁律同步
- 两套前端示例:授权按钮改读 s.windowHours 动态时长
- 钩子模板:拒绝文案去掉写死时长
2026-08-07 18:56:35 +08:00

95 lines
3.7 KiB
Shell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# mm-review · maomao-fifth-domain pre-receive 自动审核 · 铸渊 2026-08-06
# ⊢ 明文密钥必拦 ⊢ 破坏现有必拦 ⊢ 写入窗口必验 ⊢ 每次写入留痕
LOG_DIR=/srv/guanghu/mm-gz-001/access/logs
GRANTS=/srv/guanghu/mm-gz-001/access/grants.json
PUSHER="${GITEA_PUSHER_NAME:-unknown}"
VERDICT=PASS
REASONS=()
COMMITS=0
REFSLIST=""
PUSHER_ATTR=""
ZERO=0000000000000000000000000000000000000000
mkdir -p "$LOG_DIR"
active_grant() {
python3 - "$GRANTS" <<'PY'
import json,sys,datetime
try: g=json.load(open(sys.argv[1]))
except Exception: print("none"); sys.exit()
now=datetime.datetime.now(datetime.timezone.utc)
for x in g:
if x.get("status")=="active":
try: exp=datetime.datetime.fromisoformat(x["expiresAt"])
except Exception: continue
if exp>now: print(x.get("persona","persona")); sys.exit()
print("none")
PY
}
while read -r old new ref; do
REFSLIST="$REFSLIST $ref"
branch=${ref#refs/heads/}
if [ "$new" = "$ZERO" ]; then
case "$branch" in
guanghu/main|deploy) VERDICT=REJECT; REASONS+=("禁止删除受保护分支: $branch");;
esac
continue
fi
if [ "$PUSHER" = "mm-writer" ]; then
W=$(active_grant)
if [ "$W" = "none" ]; then
VERDICT=REJECT
REASONS+=("无有效写入窗口(授权已过期或未申请)。人格体请先 POST https://maomao.guanghulab.com/api/access-request 申请,等苍耳审批")
continue
fi
PUSHER_ATTR="$W"
fi
if [ "$old" != "$ZERO" ]; then
if ! git merge-base --is-ancestor "$old" "$new" 2>/dev/null; then
VERDICT=REJECT; REASONS+=("禁止历史重写(非快进推送): $branch")
continue
fi
fi
for c in $(git rev-list "$old".."$new" 2>/dev/null || git rev-list -n 20 "$new" 2>/dev/null); do
COMMITS=$((COMMITS+1))
for f in $(git diff-tree --root --no-commit-id --name-only --diff-filter=AM -r "$c" 2>/dev/null | head -60); do
if git show "$c:$f" 2>/dev/null | head -c 400000 | grep -qE "sk-[A-Za-z0-9]{16,}|AKIA[A-Z0-9]{16}|-----BEGIN [A-Z ]*PRIVATE KEY-----|gh[pousr]_[A-Za-z0-9]{20,}|xox[baprs]-[A-Za-z0-9-]{10,}|(api[_-]?key|apikey|secret[_-]?key|access[_-]?token|password|passwd)[\"']?[[:space:]]*[:=][[:space:]]*[\"'][A-Za-z0-9+/=_.-]{12,}"; then
VERDICT=REJECT; REASONS+=("文件疑似包含明文密钥: $f(提交 ${c:0:8})。密钥必须移出仓库")
fi
done
if [ "$PUSHER" != "maomao" ]; then
for f in $(git diff-tree --root --no-commit-id --name-only --diff-filter=D -r "$c" 2>/dev/null); do
case "$f" in
REPO-MAP.hdlp|GLW-ENTRY.hdlp|INDEX.hdlp|README.md|AGENTS.md|guanghu-nodes/MM-GZ-001/machine/NAVIGATION.json|guanghu-nodes/MM-GZ-001/recovery/WAKE-UP-ROUTE.json|guanghu-nodes/MM-GZ-001/personas/registry.json)
VERDICT=REJECT; REASONS+=("人格体不得删除入口文件: $f");;
esac
done
fi
done
done
python3 - "$LOG_DIR" "$PUSHER" "$PUSHER_ATTR" "$VERDICT" "$COMMITS" "$REFSLIST" "$(printf '%s|' "${REASONS[@]}")" <<'PY'
import json,sys,datetime,os
logdir,pusher,attr,verdict,commits,refs,reasons=sys.argv[1:8]
rec={"ts":datetime.datetime.now(datetime.timezone.utc).isoformat(),
"pusher":pusher,"persona":attr or None,"verdict":verdict,
"commits":int(commits),"refs":refs.split(),
"reasons":[r for r in reasons.split("|") if r]}
os.makedirs(logdir,exist_ok=True)
p=os.path.join(logdir,"PUSH-%s.json"%datetime.datetime.now().strftime("%Y%m%dT%H%M%S%f"))
open(p,"w").write(json.dumps(rec,ensure_ascii=False,indent=1))
PY
if [ "$VERDICT" = "REJECT" ]; then
echo "── 守望自动审核REJECT ──"
for r in "${REASONS[@]}"; do echo "$r"; done
exit 1
fi
echo "── 守望自动审核PASS$COMMITS 提交 · 推送者 $PUSHER${PUSHER_ATTR:+ · 人格 $PUSHER_ATTR})──"
exit 0