diff --git a/internal/service/gameprovider/visibility.go b/internal/service/gameprovider/visibility.go index 8a2e3f0..016db80 100644 --- a/internal/service/gameprovider/visibility.go +++ b/internal/service/gameprovider/visibility.go @@ -18,8 +18,8 @@ import ( const ( gameListTargetSysOrigin = "LIKEI" - gameListTargetCountryCode = "TR" - gameListMinWealthLevel = 2 + gameListTurkeyCountryCode = "TR" + gameListTurkeyBlockLevel = 2 ipCountryCachePrefix = "GAME_LIST:IP_COUNTRY:" ipCountryCacheTTL = 7 * 24 * time.Hour ) @@ -49,21 +49,21 @@ type VisibilityPolicy struct { ipResolver IPCountryResolver targetCountry string targetSys string - minWealth int + blockLevel int } -// NewVisibilityPolicy 创建 LIKEI 游戏列表门禁:土耳其区域、土耳其 IP、财富等级 2 级及以上。 +// NewVisibilityPolicy 创建 LIKEI 游戏列表门禁:土耳其区域或土耳其 IP 的用户财富等级必须大于 2,其他用户直接展示。 func NewVisibilityPolicy(java VisibilityGateway, ipResolver IPCountryResolver) *VisibilityPolicy { return &VisibilityPolicy{ java: java, ipResolver: ipResolver, - targetCountry: gameListTargetCountryCode, + targetCountry: gameListTurkeyCountryCode, targetSys: gameListTargetSysOrigin, - minWealth: gameListMinWealthLevel, + blockLevel: gameListTurkeyBlockLevel, } } -// Evaluate 串行校验区域、财富等级和 IP 国家;任何条件不能确认时都按不可见处理。 +// Evaluate 只拦截土耳其区域或土耳其 IP 的低财富等级用户;非土耳其区域且非土耳其 IP 的用户直接展示游戏列表。 func (p *VisibilityPolicy) Evaluate(ctx context.Context, user AuthUser, clientIP string) (VisibilityResult, error) { if p == nil || !strings.EqualFold(strings.TrimSpace(user.SysOrigin), p.targetSys) { return VisibilityResult{Allow: true, RegionID: user.RegionID, RegionCode: user.RegionCode}, nil @@ -81,12 +81,24 @@ func (p *VisibilityPolicy) Evaluate(ctx context.Context, user AuthUser, clientIP RegionCode: strings.TrimSpace(region.RegionCode), } - // 区域配置是运营可变数据,所以先从 Java 区域配置解析 TR 对应的 regionCode,再与当前用户区域对比。 + // 区域配置是运营可变数据,所以先从 Java 区域配置解析 TR 对应的 regionCode,再判断用户是否属于土耳其区域。 targetRegionCode, err := p.java.ResolveRegionCodeByCountryCode(ctx, user.SysOrigin, p.targetCountry) if err != nil { return result, err } - if !matchesTargetRegion(result.RegionCode, targetRegionCode, p.targetCountry) { + turkeyRegion := matchesTargetRegion(result.RegionCode, targetRegionCode, p.targetCountry) + turkeyIP := false + if p.ipResolver != nil { + countryCode, err := p.ipResolver.CountryCode(ctx, clientIP) + if err != nil { + return result, err + } + turkeyIP = strings.EqualFold(strings.TrimSpace(countryCode), p.targetCountry) + } + + // 用户区域和当前 IP 都不是土耳其时,直接放行;只有命中土耳其门禁时才需要读取财富等级。 + if !turkeyRegion && !turkeyIP { + result.Allow = true return result, nil } @@ -94,18 +106,7 @@ func (p *VisibilityPolicy) Evaluate(ctx context.Context, user AuthUser, clientIP if err != nil { return result, err } - if level.WealthLevel < p.minWealth { - return result, nil - } - - if p.ipResolver == nil { - return result, nil - } - countryCode, err := p.ipResolver.CountryCode(ctx, clientIP) - if err != nil || !strings.EqualFold(strings.TrimSpace(countryCode), p.targetCountry) { - return result, nil - } - result.Allow = true + result.Allow = level.WealthLevel > p.blockLevel return result, nil } diff --git a/internal/service/gameprovider/visibility_test.go b/internal/service/gameprovider/visibility_test.go index 446c5b5..bf89e2b 100644 --- a/internal/service/gameprovider/visibility_test.go +++ b/internal/service/gameprovider/visibility_test.go @@ -33,82 +33,87 @@ func (s stubIPCountryResolver) CountryCode(context.Context, string) (string, err return s.countryCode, nil } -func TestVisibilityPolicyAllowsTurkeyRegionTurkeyIPAndWealthLevel2(t *testing.T) { - policy := NewVisibilityPolicy( - stubVisibilityGateway{ - region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "TR"}, - level: integration.UserLevel{WealthLevel: 2}, - targetRegionCode: "TR", +func TestVisibilityPolicyAppliesTurkeyRegionOrIPWealthGate(t *testing.T) { + tests := []struct { + name string + region integration.UserRegion + ipCountry string + wealth int + wantAllow bool + wantRegion integration.UserRegion + }{ + { + name: "turkey region level 2 is blocked", + region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "土耳其"}, + ipCountry: "ZA", + wealth: 2, + wantAllow: false, + wantRegion: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "土耳其"}, }, - stubIPCountryResolver{countryCode: "TR"}, - ) - - result, err := policy.Evaluate(context.Background(), AuthUser{UserID: 1001, SysOrigin: "LIKEI"}, "1.1.1.1") - if err != nil { - t.Fatalf("Evaluate() error = %v", err) - } - if !result.Allow { - t.Fatalf("Evaluate() allow = false, want true") - } - if result.RegionID != "2046066409959649281" || result.RegionCode != "TR" { - t.Fatalf("Evaluate() region = %#v", result) - } -} - -func TestVisibilityPolicyDeniesNonTurkeyIP(t *testing.T) { - policy := NewVisibilityPolicy( - stubVisibilityGateway{ - region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "TR"}, - level: integration.UserLevel{WealthLevel: 2}, - targetRegionCode: "TR", + { + name: "turkey region level 3 is visible even when ip is not turkey", + region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "土耳其"}, + ipCountry: "ZA", + wealth: 3, + wantAllow: true, + wantRegion: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "土耳其"}, }, - stubIPCountryResolver{countryCode: "SA"}, - ) - - result, err := policy.Evaluate(context.Background(), AuthUser{UserID: 1001, SysOrigin: "LIKEI"}, "1.1.1.1") - if err != nil { - t.Fatalf("Evaluate() error = %v", err) - } - if result.Allow { - t.Fatalf("Evaluate() allow = true, want false") - } -} - -func TestVisibilityPolicyDeniesLowWealthLevel(t *testing.T) { - policy := NewVisibilityPolicy( - stubVisibilityGateway{ - region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "TR"}, - level: integration.UserLevel{WealthLevel: 1}, - targetRegionCode: "TR", + { + name: "turkey ip level 2 is blocked", + region: integration.UserRegion{RegionID: "2045389832842178561", RegionCode: "南亚"}, + ipCountry: "TR", + wealth: 2, + wantAllow: false, + wantRegion: integration.UserRegion{RegionID: "2045389832842178561", RegionCode: "南亚"}, }, - stubIPCountryResolver{countryCode: "TR"}, - ) - - result, err := policy.Evaluate(context.Background(), AuthUser{UserID: 1001, SysOrigin: "LIKEI"}, "1.1.1.1") - if err != nil { - t.Fatalf("Evaluate() error = %v", err) - } - if result.Allow { - t.Fatalf("Evaluate() allow = true, want false") - } -} - -func TestVisibilityPolicyDeniesNonTurkeyRegion(t *testing.T) { - policy := NewVisibilityPolicy( - stubVisibilityGateway{ - region: integration.UserRegion{RegionID: "2046067036517363714", RegionCode: "AR"}, - level: integration.UserLevel{WealthLevel: 2}, - targetRegionCode: "TR", + { + name: "turkey ip level 3 is visible", + region: integration.UserRegion{RegionID: "2045389832842178561", RegionCode: "南亚"}, + ipCountry: "TR", + wealth: 3, + wantAllow: true, + wantRegion: integration.UserRegion{RegionID: "2045389832842178561", RegionCode: "南亚"}, + }, + { + name: "non turkey region and non turkey ip are visible even at level 1", + region: integration.UserRegion{RegionID: "2045389832842178561", RegionCode: "南亚"}, + ipCountry: "ZA", + wealth: 1, + wantAllow: true, + wantRegion: integration.UserRegion{RegionID: "2045389832842178561", RegionCode: "南亚"}, + }, + { + name: "account 1007500 current region and ip are visible", + region: integration.UserRegion{RegionID: "2045389832842178561", RegionCode: "南亚"}, + ipCountry: "ZA", + wealth: 35, + wantAllow: true, + wantRegion: integration.UserRegion{RegionID: "2045389832842178561", RegionCode: "南亚"}, }, - stubIPCountryResolver{countryCode: "TR"}, - ) - - result, err := policy.Evaluate(context.Background(), AuthUser{UserID: 1001, SysOrigin: "LIKEI"}, "1.1.1.1") - if err != nil { - t.Fatalf("Evaluate() error = %v", err) } - if result.Allow { - t.Fatalf("Evaluate() allow = true, want false") + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + policy := NewVisibilityPolicy( + stubVisibilityGateway{ + region: tt.region, + level: integration.UserLevel{WealthLevel: tt.wealth}, + targetRegionCode: "土耳其", + }, + stubIPCountryResolver{countryCode: tt.ipCountry}, + ) + + result, err := policy.Evaluate(context.Background(), AuthUser{UserID: 1007500, SysOrigin: "LIKEI"}, "1.1.1.1") + if err != nil { + t.Fatalf("Evaluate() error = %v", err) + } + if result.Allow != tt.wantAllow { + t.Fatalf("Evaluate() allow = %v, want %v", result.Allow, tt.wantAllow) + } + if result.RegionID != tt.wantRegion.RegionID || result.RegionCode != tt.wantRegion.RegionCode { + t.Fatalf("Evaluate() region = %#v, want %#v", result, tt.wantRegion) + } + }) } }