Resolve Feishu names by verified open ID and scope VPN member access

This commit is contained in:
Codex committed 2026-10-23 02:02:52 +08:00
1 parent 578a58a129
commit d4eddf7365
19 files changed
+837 -35

No files matched your search

@@ -115,6 +115,18 @@ func (s *Service) Validate(cfg map[string]interface{}) (map[string]interface{},
return nil, fmt.Errorf("auth_mode 必须为 certificate、password、certificate+password 或 oidc")
}
if service.Str(out, "auth_mode") == "oidc" {
if raw, present := out["feishu_access_mode"]; present {
if _, ok := raw.(string); !ok {
return nil, fmt.Errorf("feishu_access_mode 必须为字符串")
}
}
mode := service.Str(out, "feishu_access_mode")
if mode != "" && mode != "all" && mode != "allowlist" {
return nil, fmt.Errorf("feishu_access_mode 必须为 all 或 allowlist")
}
if mode == "allowlist" && service.Str(out, "oidc_provider") != "builtin" {
return nil, fmt.Errorf("指定飞书成员仅适用于内置飞书身份服务")
}
switch service.Str(out, "oidc_provider") {
case "", "external", "builtin":
default:
@@ -138,6 +150,7 @@ func (s *Service) Validate(cfg map[string]interface{}) (map[string]interface{},
}
out["mfa_mode"] = "off" // 飞书 MFA 由身份提供方负责
} else {
delete(out, "feishu_access_mode")
for _, key := range []string{"oidc_provider", "oidc_issuer", "oidc_base_url", "oidc_client_id", "oidc_client_secret", "oidc_http_port", "oidc_http_secret", "oidc_management_password"} {
delete(out, key)
}
@@ -235,6 +235,19 @@ func TestOIDCTunnelsNeedDistinctCallbackAndPort(t *testing.T) {
}
func TestValidateOpenVPNModes(t *testing.T) {
feishu := map[string]interface{}{"auth_mode": "oidc", "oidc_provider": "builtin", "oidc_issuer": "https://vpn.example.com/id", "oidc_base_url": "https://vpn.example.com", "oidc_client_id": "opsx-vpn", "feishu_access_mode": "allowlist"}
if _, err := New().Validate(feishu); err != nil {
t.Fatalf("valid member policy: %v", err)
}
feishu["feishu_access_mode"] = true
if _, err := New().Validate(feishu); err == nil {
t.Fatal("non-string member policy accepted")
}
feishu["feishu_access_mode"] = "allowlist"
feishu["oidc_provider"] = "external"
if _, err := New().Validate(feishu); err == nil {
t.Fatal("external OIDC accepted Feishu member policy")
}
cfg, err := New().Validate(map[string]interface{}{"auth_mode": "password", "subnet": "10.8.0.0 255.255.255.0"})
if err != nil {
t.Fatal(err)
@@ -456,9 +469,10 @@ func TestWebAuthSessionIdentityAndTrafficTransition(t *testing.T) {
if rx, tx := svc.collectTraffic(tunnel); rx != 150 || tx != 230 {
t.Fatalf("initial traffic = %d/%d", rx, tx)
}
var unknown model.VPNSession
if err := store.DB.Where("tunnel_id = ? AND status = ?", tunnel.ID, "active").First(&unknown).Error; err != nil || unknown.Username != "" || unknown.VPNUserID != 0 {
t.Fatalf("unknown peer must not be attributed: %+v, %v", unknown, err)
var unknownCount int64
store.DB.Model(&model.VPNSession{}).Where("tunnel_id = ?", tunnel.ID).Count(&unknownCount)
if unknownCount != 0 {
t.Fatalf("pre-auth socket created %d audit sessions", unknownCount)
}
var placeholder model.VPNUser
store.DB.Where("tunnel_id = ? AND username = ?", tunnel.ID, "UNDEF").First(&placeholder)