verify-auth-permissions.py
4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env python3
"""WeChat Viewer 注册/权限分层 ad-hoc 验证(幂等,可重复运行)。
覆盖:注册 → user 登录 → 日报可见(/reports /digest /api/reports GET)→
敏感页 403(/resumes /boss-jobs /chat/* /api/articles 带 CF header)→
隧道流量 API 302/403 → 本地 cron 豁免 200 → admin 全权限。
验证脚本结尾自动清理测试账号 verifyuser。
用法:
python3 verify-auth-permissions.py
# 在 wechat-viewer 目录下直接跑;或任意目录跑(脚本自动 chdir)
"""
import os
import sqlite3
import sys
VIEWER = "/data/data/com.termux/files/home/wechat-viewer"
sys.path.insert(0, VIEWER)
os.chdir(VIEWER)
results = []
def check(name, cond, detail=""):
results.append((name, bool(cond), detail))
# 清理上次残留的 verifyuser(幂等)
_conn = sqlite3.connect(os.path.join(VIEWER, "circle.db"))
_conn.execute("DELETE FROM users WHERE username='verifyuser'")
_conn.commit()
_conn.close()
import app as viewer_app
client = viewer_app.app.test_client()
# 注册
check("register 页面 200", client.get("/register").status_code == 200)
r = client.post("/register", data={"username": "verifyuser", "password": "verify123", "password2": "verify123"})
check("register 提交 302", r.status_code == 302)
# 未登录:公开路由 /digest/ 免登录(2026-08-13 起公网分享),其余仍受保护
check("未登录 /digest 200", client.get("/digest/2026-08-07").status_code == 200)
check("未登录(带CF) /digest 200", client.get("/digest/2026-08-07", headers={"CF-Connecting-IP": "1.2.3.4"}).status_code == 200)
check("未登录 /reports 302", client.get("/reports").status_code == 302)
check("未登录(带CF) /api/reports 302", client.get("/api/reports", headers={"CF-Connecting-IP": "1.2.3.4"}).status_code == 302)
# user 登录
check("user login 302", client.post("/login", data={"username": "verifyuser", "password": "verify123"}).status_code == 302)
# user 日报可见
check("user /reports 200", client.get("/reports").status_code == 200)
check("user /digest 200", client.get("/digest/2026-08-07").status_code == 200)
check("user /api/reports 200", client.get("/api/reports").status_code == 200)
# user 敏感页 403(真实公网流量必带 CF header;不带 header 的 127.0.0.1 = 本地 cron 豁免场景)
for p in ["/resumes", "/boss-jobs", "/chat/x"]:
check(f"user {p} 403", client.get(p).status_code == 403)
check("user /api/articles(带CF) 403",
client.get("/api/articles", headers={"CF-Connecting-IP": "1.2.3.4"}).status_code == 403)
# 隧道流量(remote_addr=127.0.0.1 + CF header):未登录 302,user 403
client.get("/logout")
r = client.get("/api/articles", environ_base={"REMOTE_ADDR": "127.0.0.1"},
headers={"CF-Connecting-IP": "1.2.3.4"})
check("隧道未登录 /api/articles 302", r.status_code == 302)
client.post("/login", data={"username": "verifyuser", "password": "verify123"})
r = client.get("/api/articles", environ_base={"REMOTE_ADDR": "127.0.0.1"},
headers={"CF-Connecting-IP": "1.2.3.4"})
check("隧道 user /api/articles 403", r.status_code == 403)
# 本地 cron 豁免(127.0.0.1 无 header)→ 200
client.get("/logout")
r = client.get("/api/articles", environ_base={"REMOTE_ADDR": "127.0.0.1"})
check("本地 cron /api/articles 200", r.status_code == 200)
# admin 权限(默认账号 admin/wechat2026)
check("admin login 302", client.post("/login", data={"username": "admin", "password": "wechat2026"}).status_code == 302)
check("admin /resumes 200", client.get("/resumes").status_code == 200)
check("admin /api/articles 200", client.get("/api/articles").status_code == 200)
# 清理测试账号
_conn = sqlite3.connect(os.path.join(VIEWER, "circle.db"))
_conn.execute("DELETE FROM users WHERE username='verifyuser'")
_conn.commit()
_conn.close()
ok = True
for name, cond, detail in results:
print(("PASS " if cond else "FAIL ") + name + (f" | {detail}" if detail and not cond else ""))
ok = ok and cond
print()
print("RESULT:", "ALL PASS" if ok else f"{sum(1 for _, c, _ in results if not c)} FAILURES")
sys.exit(0 if ok else 1)