package main import ( "errors" "testing" "github.com/tinode/chat/server/store/types" ) type staticTenantLoginIPWhitelistProvider struct { config *tenantLoginIPWhitelistConfig err error } func (p staticTenantLoginIPWhitelistProvider) TenantLoginIPWhitelist(types.TenantID) (*tenantLoginIPWhitelistConfig, error) { return p.config, p.err } func resetTenantLoginIPWhitelistTestState(t *testing.T) { t.Helper() previousProvider := loginIPWhitelistProvider tenantLoginIPWhitelistCache.Lock() previousCache := tenantLoginIPWhitelistCache.items tenantLoginIPWhitelistCache.items = make(map[types.TenantID]tenantLoginIPWhitelistCacheEntry) tenantLoginIPWhitelistCache.Unlock() t.Cleanup(func() { loginIPWhitelistProvider = previousProvider tenantLoginIPWhitelistCache.Lock() tenantLoginIPWhitelistCache.items = previousCache tenantLoginIPWhitelistCache.Unlock() }) } func TestTenantLoginIPChannel(t *testing.T) { for platform, expected := range map[string]string{ "web": "web", "WEB": "web", "ios": "app", "android": "app", "": "app", } { if actual := tenantLoginIPChannel(platform); actual != expected { t.Fatalf("platform %q: got %q, want %q", platform, actual, expected) } } } func TestCheckTenantLoginIPWhitelist(t *testing.T) { resetTenantLoginIPWhitelistTestState(t) tenantID := types.TenantID(1) loginIPWhitelistProvider = staticTenantLoginIPWhitelistProvider{config: &tenantLoginIPWhitelistConfig{ TenantID: tenantID, AppList: []string{"203.0.113.10", "2001:db8::/32"}, WebList: []string{"198.51.100.0/24"}, }} if err := checkTenantLoginIPWhitelist(tenantID, "ios", "203.0.113.10:443"); err != nil { t.Fatalf("APP白名单地址应允许登录: %v", err) } if err := checkTenantLoginIPWhitelist(tenantID, "web", "198.51.100.8:443"); err != nil { t.Fatalf("Web白名单网段应允许登录: %v", err) } if err := checkTenantLoginIPWhitelist(tenantID, "web", "203.0.113.10:443"); !errors.Is(err, types.ErrPermissionDenied) { t.Fatalf("APP地址不应绕过Web白名单: %v", err) } } func TestCheckTenantLoginIPWhitelistEmptyMeansUnrestricted(t *testing.T) { resetTenantLoginIPWhitelistTestState(t) tenantID := types.TenantID(1) loginIPWhitelistProvider = staticTenantLoginIPWhitelistProvider{config: &tenantLoginIPWhitelistConfig{TenantID: tenantID}} if err := checkTenantLoginIPWhitelist(tenantID, "web", "192.0.2.8:443"); err != nil { t.Fatalf("未配置渠道白名单时不应限制登录: %v", err) } } func TestCheckTenantLoginIPWhitelistProviderFailureAllowsLogin(t *testing.T) { resetTenantLoginIPWhitelistTestState(t) tenantID := types.TenantID(1) loginIPWhitelistProvider = staticTenantLoginIPWhitelistProvider{err: errors.New("admin timeout")} if err := checkTenantLoginIPWhitelist(tenantID, "ios", "203.0.113.10:443"); err != nil { t.Fatalf("白名单配置服务失败时不应阻断登录: %v", err) } if err := checkTenantLoginIPWhitelist(tenantID, "web", "198.51.100.8:443"); err != nil { t.Fatalf("白名单失败空配置应被短暂缓存并继续放行: %v", err) } }