Files
tamabox/dev/devcheck-restrict.sh
T
2026-10-18 21:14:59 +08:00

130 lines
4.1 KiB
Bash
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.
#!/usr/bin/env bash
# 处置链路部署后自检(L1 停止分发 / L4 整页停用 / CLI 可用性)
#
# 为什么需要它:本机沙箱起不了 web(无 redis),L1/L4 的 HTTP 行为只能在服务器上验证。
# 这个脚本把「施加处置 → 观察 HTTP → 自动撤销」串起来,避免手工操作忘了解除。
#
# 用法:
# BASE_URL=https://box-dev.example.com DOMAIN=<测试箱主域名> TAMABOX=/path/to/NekoBox \
# bash dev/devcheck-restrict.sh # 只打印将要执行的命令(dry-run)
#
# BASE_URL=... DOMAIN=... TAMABOX=... RUN=1 \
# bash dev/devcheck-restrict.sh # 真正执行,结束时自动撤销
#
# 注意:
# - DOMAIN 必须是**测试箱主**,不要用真实用户;脚本会临时施加 L4/L1 再撤销。
# - 站点默认语言可能是 ja,页面文案断言按日文/英文各查一次,避免误判「没生效」。
# - 只依赖 CLI 与 curl,不需要 psql 凭据。
set -uo pipefail
BASE_URL=${BASE_URL:?need BASE_URL, e.g. https://box-dev.example.com}
DOMAIN=${DOMAIN:?need DOMAIN, a TEST box domain only}
TAMABOX=${TAMABOX:-./NekoBox}
RUN=${RUN:-0}
DAYS=${DAYS:-1}
pass=0
fail=0
restricted=0
say() { printf '%s\n' "$*"; }
check() {
local name=$1 want=$2 got=$3
if [ "$want" = "$got" ]; then
say " PASS $name (=$got)"
pass=$((pass + 1))
else
say " FAIL $name (want $want, got $got)"
fail=$((fail + 1))
fi
}
code() { curl -s -o /dev/null -w '%{http_code}' --max-time 10 "$1"; }
do_restrict() {
restricted=1
if [ "$RUN" = 1 ]; then
"$TAMABOX" restrict --domain "$DOMAIN" --level "$1" --days "$DAYS" --reason "deploy self-check" --yes
else
say " [dry-run] $TAMABOX restrict --domain $DOMAIN --level $1 --days $DAYS --reason 'deploy self-check' --yes"
fi
}
cleanup() {
if [ "$RUN" = 1 ] && [ "$restricted" = 1 ]; then
say ""
say "== 兜底撤销(无论中途是否失败)=="
"$TAMABOX" unrestrict --domain "$DOMAIN" || true
fi
}
trap cleanup EXIT
say "== 0. 二进制是否包含新命令 =="
if "$TAMABOX" --help 2>&1 | grep -q 'restrict'; then
say " PASS restrict 命令存在"
pass=$((pass + 1))
else
say " FAIL 二进制里没有 restrict —— 构建的是旧代码(注意入口是根目录 tamabox.go,或用 ./cmd/)"
fail=$((fail + 1))
say ""
say "结果: 无法继续,先修构建入口。"
exit 1
fi
say ""
say "== 1. 基线:处置前箱主页应可访问 =="
base=$(code "$BASE_URL/_/$DOMAIN")
check "box page before restrict" 200 "$base"
say ""
say "== 2. L4 整页停用 =="
do_restrict L4
sleep 1
check "box page under L4" 302 "$(code "$BASE_URL/_/$DOMAIN")"
check "restricted page" 200 "$(code "$BASE_URL/restricted")"
if [ "$RUN" = 1 ]; then
body=$(curl -sL --max-time 10 "$BASE_URL/_/$DOMAIN")
if printf '%s' "$body" | grep -qE '一時的に利用できません|temporarily unavailable|暫時無法存取|暂时不可访问'; then
say " PASS restricted page copy rendered"
pass=$((pass + 1))
else
say " FAIL restricted page copy not found (检查 i18n 与模板是否部署)"
fail=$((fail + 1))
fi
else
say " [dry-run] 跳过文案断言"
fi
say ""
say "== 3. L1 停止分发:页面恢复、分享卡被拦 =="
do_restrict L1
sleep 1
check "box page under L1" 200 "$(code "$BASE_URL/_/$DOMAIN")"
qid=$(curl -s --max-time 10 "$BASE_URL/_/$DOMAIN" | grep -o "/_/$DOMAIN/[0-9]\+" | head -1 | grep -o '[0-9]\+$')
if [ -n "${qid:-}" ]; then
check "share card under L1 (qid=$qid)" 302 "$(code "$BASE_URL/_/$DOMAIN/$qid/share-card")"
else
say " SKIP 该箱主没有已公开回答,无法验证分享卡(换一个有已答问题的测试箱主)"
fi
say ""
say "== 4. 撤销 =="
if [ "$RUN" = 1 ]; then
"$TAMABOX" unrestrict --domain "$DOMAIN"
restricted=0
check "box page after unrestrict" 200 "$(code "$BASE_URL/_/$DOMAIN")"
else
say " [dry-run] $TAMABOX unrestrict --domain $DOMAIN"
fi
say ""
say "== 结果: PASS=$pass FAIL=$fail =="
if [ "$fail" -gt 0 ]; then
say "有失败项,把上面输出 + 服务日志(journalctl / docker logs 里搜 'Failed to query user restriction')一起发我。"
exit 1
fi
say "全部通过。仍需人工手测两项:L2(回答应保存为私密)、L3(回答应被拒绝)。"