First Commit
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
web / web (push) Waiting to run
docs / links (push) Canceled after 0s
detections / detections (push) Canceled after 0s
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
web / web (push) Waiting to run
docs / links (push) Canceled after 0s
detections / detections (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
package db
|
||||
|
||||
import "testing"
|
||||
|
||||
func rule(kind, pattern string, enabled bool) AssetInterceptRule {
|
||||
return AssetInterceptRule{Kind: kind, Pattern: pattern, Enabled: enabled}
|
||||
}
|
||||
|
||||
func TestMatchAssetInterceptRules(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
rules []AssetInterceptRule
|
||||
domains []string
|
||||
ips []string
|
||||
urls []string
|
||||
want bool
|
||||
wantVal string
|
||||
}{
|
||||
{"内置模糊政府域名命中", []AssetInterceptRule{rule("fuzzy_domain", ".gov.cn", true)},
|
||||
[]string{"www.beijing.gov.cn"}, nil, nil, true, "www.beijing.gov.cn"},
|
||||
{"模糊教育域名命中", []AssetInterceptRule{rule("fuzzy_domain", ".edu", true)},
|
||||
[]string{"mit.edu"}, nil, nil, true, "mit.edu"},
|
||||
{"全等域名命中大小写不敏感", []AssetInterceptRule{rule("exact_domain", "Example.com", true)},
|
||||
[]string{"example.com"}, nil, nil, true, "example.com"},
|
||||
{"全等域名不命中子域", []AssetInterceptRule{rule("exact_domain", "example.com", true)},
|
||||
[]string{"a.example.com"}, nil, nil, false, ""},
|
||||
{"全等IP命中", []AssetInterceptRule{rule("exact_ip", "203.0.113.5", true)},
|
||||
nil, []string{"203.0.113.5"}, nil, true, "203.0.113.5"},
|
||||
{"模糊IP前缀命中", []AssetInterceptRule{rule("fuzzy_ip", "203.0.113.", true)},
|
||||
nil, []string{"203.0.113.99"}, nil, true, "203.0.113.99"},
|
||||
{"CIDR 命中", []AssetInterceptRule{rule("cidr", "192.168.0.0/16", true)},
|
||||
nil, []string{"192.168.5.20"}, nil, true, "192.168.5.20"},
|
||||
{"CIDR 不命中", []AssetInterceptRule{rule("cidr", "192.168.0.0/16", true)},
|
||||
nil, []string{"10.0.0.1"}, nil, false, ""},
|
||||
{"全等URL命中", []AssetInterceptRule{rule("exact_url", "https://a.gov.cn/login", true)},
|
||||
nil, nil, []string{"https://a.gov.cn/login"}, true, "https://a.gov.cn/login"},
|
||||
{"模糊URL命中路径", []AssetInterceptRule{rule("fuzzy_url", "/admin", true)},
|
||||
nil, nil, []string{"https://x.com/admin/panel"}, true, "https://x.com/admin/panel"},
|
||||
{"禁用规则不命中", []AssetInterceptRule{rule("fuzzy_domain", ".gov.cn", false)},
|
||||
[]string{"www.gov.cn"}, nil, nil, false, ""},
|
||||
{"无规则不命中", nil, []string{"www.gov.cn"}, nil, nil, false, ""},
|
||||
{"空pattern不命中", []AssetInterceptRule{rule("fuzzy_domain", " ", true)},
|
||||
[]string{"www.gov.cn"}, nil, nil, false, ""},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
r, val, ok := MatchAssetInterceptRules(c.rules, c.domains, c.ips, c.urls)
|
||||
if ok != c.want {
|
||||
t.Fatalf("命中 = %v, 期望 %v (rule=%+v)", ok, c.want, r)
|
||||
}
|
||||
if ok && val != c.wantVal {
|
||||
t.Fatalf("命中值 = %q, 期望 %q", val, c.wantVal)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvaluateAssetGate(t *testing.T) {
|
||||
block := []AssetInterceptRule{rule("fuzzy_domain", ".gov.cn", true)}
|
||||
allow := []AssetInterceptRule{rule("fuzzy_domain", "example.com", true)}
|
||||
|
||||
// 1. 命中拦截规则 → 拒绝(拦截原因优先)。
|
||||
if d := EvaluateAssetGate(block, allow, []string{"www.gov.cn"}, nil, nil); d.Allowed {
|
||||
t.Fatal("命中拦截规则应被拒绝")
|
||||
}
|
||||
|
||||
// 2. 未命中拦截、有允许规则但不命中 → 拒绝(不允许)。
|
||||
d := EvaluateAssetGate(block, allow, []string{"foo.other.com"}, nil, nil)
|
||||
if d.Allowed {
|
||||
t.Fatal("有白名单且不命中应被拒绝")
|
||||
}
|
||||
if d.Reason == "" {
|
||||
t.Fatal("拒绝应带原因")
|
||||
}
|
||||
|
||||
// 3. 未命中拦截、命中允许规则 → 放行。
|
||||
if d := EvaluateAssetGate(block, allow, []string{"api.example.com"}, nil, nil); !d.Allowed {
|
||||
t.Fatal("命中白名单应放行")
|
||||
}
|
||||
|
||||
// 4. 无允许规则(白名单未启用)→ 未命中拦截即放行。
|
||||
if d := EvaluateAssetGate(block, nil, []string{"foo.other.com"}, nil, nil); !d.Allowed {
|
||||
t.Fatal("无白名单时未命中拦截应放行")
|
||||
}
|
||||
|
||||
// 5. 允许规则全部禁用 → 视为白名单未启用,放行。
|
||||
disabledAllow := []AssetInterceptRule{rule("fuzzy_domain", "example.com", false)}
|
||||
if d := EvaluateAssetGate(nil, disabledAllow, []string{"foo.other.com"}, nil, nil); !d.Allowed {
|
||||
t.Fatal("白名单全禁用时应放行")
|
||||
}
|
||||
|
||||
// 6. 拦截优先于允许:同一目标既命中拦截又命中允许 → 拒绝。
|
||||
if d := EvaluateAssetGate(
|
||||
[]AssetInterceptRule{rule("fuzzy_domain", ".gov.cn", true)},
|
||||
[]AssetInterceptRule{rule("fuzzy_domain", ".gov.cn", true)},
|
||||
[]string{"www.gov.cn"}, nil, nil,
|
||||
); d.Allowed {
|
||||
t.Fatal("拦截应优先于允许")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAssetInterceptCandidates(t *testing.T) {
|
||||
// 只带 URL 的服务资产:host 应被拆出并归入域名候选,从而被 fuzzy_domain 命中。
|
||||
a := &Asset{Type: "service", URL: "https://portal.beijing.gov.cn:8443/app"}
|
||||
domains, _, urls := a.interceptCandidates()
|
||||
if len(urls) != 1 || urls[0] != a.URL {
|
||||
t.Fatalf("urls = %v", urls)
|
||||
}
|
||||
found := false
|
||||
for _, d := range domains {
|
||||
if d == "portal.beijing.gov.cn" {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("URL host 未拆入域名候选: %v", domains)
|
||||
}
|
||||
r, _, ok := MatchAssetInterceptRules([]AssetInterceptRule{rule("fuzzy_domain", ".gov.cn", true)}, domains, nil, urls)
|
||||
if !ok {
|
||||
t.Fatalf("仅带 URL 的政府服务资产应被 fuzzy_domain 命中, rule=%+v", r)
|
||||
}
|
||||
|
||||
// URL host 是 IP 时应归入 IP 候选,可被 CIDR 命中。
|
||||
b := &Asset{Type: "service", URL: "http://10.1.2.3/x"}
|
||||
_, ips, _ := b.interceptCandidates()
|
||||
if r, _, ok := MatchAssetInterceptRules([]AssetInterceptRule{rule("cidr", "10.0.0.0/8", true)}, nil, ips, nil); !ok {
|
||||
t.Fatalf("URL 中的 IP 应被 CIDR 命中, ips=%v rule=%+v", ips, r)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user