fix: sites 标量 domains 防御/_to_bool/403 锁定/注释

- _norm_domains 入口类型守卫:domains 传数字曾 500、字符串曾逐字符
  迭代成单字符域名静默落库,统一走 invalid_domains 400
- bool() 强转换 _to_bool:"false" 字符串曾是 True,对 allow_no_origin
  这类放宽开关方向不利,改按字面解析(其余未知值仍 False)
- 补 member DELETE 不存在 pk → 403(先于 404)锁定测试
- SiteDetailView 注释删去 GET 字样(无 detail GET,前端走列表+Dialog)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-15 14:43:26 +08:00
parent 16207ae309
commit eb27bc830b
2 changed files with 51 additions and 5 deletions
+34
View File
@@ -107,3 +107,37 @@ def test_delete_soft_keeps_collect_rejects(client, admin_user):
"session_id": "s1", "events": []}),
content_type="text/plain", HTTP_ORIGIN="https://a.com")
assert r.status_code == 403 and r.json()["message"] == "not_allowed"
# ---- 审查修复锁定测试 ----
def test_scalar_domains_400_not_500(client, member_user):
"""domains 传标量:数字曾直接 500(for d in 123)、字符串曾逐字符迭代成单字符域名静默落库——统一 400。"""
_auth(client, member_user)
assert client.post("/api/admin/sites",
{"name": "x", "domains": "example.com"}, format="json").status_code == 400
assert client.post("/api/admin/sites",
{"name": "x", "domains": 5}, format="json").status_code == 400
def test_bool_string_parsed_by_literal(client, member_user):
"""bool("false") 是 True,对 allow_no_origin 这类放宽开关方向不利——"false" 字符串须按字面落库 False。"""
_auth(client, member_user)
r = client.post("/api/admin/sites",
{"name": "x", "domains": ["a.com"], "allow_no_origin": "false"}, format="json")
assert r.status_code == 200
site = Site.objects.get(pk=r.json()["data"]["id"])
assert site.allow_no_origin is False
client.patch(f"/api/admin/sites/{site.pk}", {"is_active": "false"}, format="json")
site.refresh_from_db()
assert site.is_active is False
client.patch(f"/api/admin/sites/{site.pk}", {"allow_no_origin": "true"}, format="json")
site.refresh_from_db()
assert site.allow_no_origin is True
def test_delete_member_403_before_404(client, member_user):
"""权限先于存在性:member DELETE 不存在的 pk 也是 403——不泄露站点是否存在。"""
_auth(client, member_user)
r = client.delete("/api/admin/sites/99999")
assert r.status_code == 403 and r.json()["code"] == 403