95 lines
3.7 KiB
Text
95 lines
3.7 KiB
Text
|
|
#!/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+=("无有效写入窗口(3小时授权已过期或未申请)。人格体请先 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
|