feat: 下线土耳其游戏列表财富等级门禁
土耳其区域/IP 用户不再按财富等级隐藏游戏列表;保留 Evaluate 的 区域查询给 provider SQL 做 regions 过滤,删除 IP 国家解析器。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
a1114fbbf5
commit
ca72ed3f97
@ -119,10 +119,7 @@ func main() {
|
||||
lingxian.NewAppProvider(lingxianService),
|
||||
hotgame.NewAppProvider(hotgameService),
|
||||
)
|
||||
gameVisibility := gameprovider.NewVisibilityPolicy(
|
||||
&app.Gateways,
|
||||
gameprovider.NewCachedIPCountryResolver(app.Repository.Redis, app.Config.HTTP.Timeout),
|
||||
)
|
||||
gameVisibility := gameprovider.NewVisibilityPolicy(&app.Gateways)
|
||||
engine := router.NewRouter(app.Config, app.Repository, &app.Gateways, router.Services{
|
||||
AppPopup: appPopupService,
|
||||
ErrorLog: errorLogService,
|
||||
|
||||
@ -200,7 +200,7 @@ func gameListAccess(c *gin.Context, visibility *gameprovider.VisibilityPolicy) (
|
||||
return user, true, true
|
||||
}
|
||||
// 游戏列表只在列表入口做展示门禁,结果里的区域继续向下传给 provider SQL 做 regions 过滤。
|
||||
result, err := visibility.Evaluate(c.Request.Context(), user, resolveClientIP(c))
|
||||
result, err := visibility.Evaluate(c.Request.Context(), user)
|
||||
if err != nil {
|
||||
writeError(c, err)
|
||||
return user, false, false
|
||||
|
||||
@ -186,7 +186,7 @@ func TestPublicLaunchMapsLingxianToLeaderForOldClients(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGameProviderRoutesReturnEmptyWhenVisibilityPolicyDenies(t *testing.T) {
|
||||
func TestGameProviderRoutesReturnRoomListForTurkeyRegionUser(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
provider := &routeStubProvider{}
|
||||
engine := gin.New()
|
||||
@ -196,11 +196,8 @@ func TestGameProviderRoutesReturnEmptyWhenVisibilityPolicyDenies(t *testing.T) {
|
||||
gameprovider.NewRegistry(provider),
|
||||
gameprovider.NewVisibilityPolicy(
|
||||
routeStubVisibilityGateway{
|
||||
region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "土耳其"},
|
||||
level: integration.UserLevel{WealthLevel: 2},
|
||||
targetRegionCode: "土耳其",
|
||||
region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "土耳其"},
|
||||
},
|
||||
routeStubIPCountryResolver{countryCode: "TR"},
|
||||
),
|
||||
)
|
||||
|
||||
@ -220,11 +217,11 @@ func TestGameProviderRoutesReturnEmptyWhenVisibilityPolicyDenies(t *testing.T) {
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
|
||||
t.Fatalf("response json error = %v: %s", err, rec.Body.String())
|
||||
}
|
||||
if len(payload.Body.Items) != 0 {
|
||||
t.Fatalf("items = %d, want 0", len(payload.Body.Items))
|
||||
if len(payload.Body.Items) != 1 {
|
||||
t.Fatalf("items = %d, want 1", len(payload.Body.Items))
|
||||
}
|
||||
if provider.listRoomCalls != 0 {
|
||||
t.Fatalf("provider list calls = %d, want 0", provider.listRoomCalls)
|
||||
if provider.listRoomCalls != 1 {
|
||||
t.Fatalf("provider list calls = %d, want 1", provider.listRoomCalls)
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,11 +336,8 @@ func TestGameProviderRoutesReturnProvidersWhenVisibilityPolicyAllows(t *testing.
|
||||
gameprovider.NewRegistry(&routeStubProvider{}),
|
||||
gameprovider.NewVisibilityPolicy(
|
||||
routeStubVisibilityGateway{
|
||||
region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "土耳其"},
|
||||
level: integration.UserLevel{WealthLevel: 3},
|
||||
targetRegionCode: "土耳其",
|
||||
region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "土耳其"},
|
||||
},
|
||||
routeStubIPCountryResolver{countryCode: "ZA"},
|
||||
),
|
||||
)
|
||||
|
||||
@ -422,31 +416,13 @@ func (routeStubAuthGateway) AuthenticateConsoleToken(context.Context, string) (i
|
||||
}
|
||||
|
||||
type routeStubVisibilityGateway struct {
|
||||
region integration.UserRegion
|
||||
level integration.UserLevel
|
||||
targetRegionCode string
|
||||
region integration.UserRegion
|
||||
}
|
||||
|
||||
func (s routeStubVisibilityGateway) GetUserRegion(context.Context, int64, string) (integration.UserRegion, error) {
|
||||
return s.region, nil
|
||||
}
|
||||
|
||||
func (s routeStubVisibilityGateway) GetUserLevel(context.Context, string, int64) (integration.UserLevel, error) {
|
||||
return s.level, nil
|
||||
}
|
||||
|
||||
func (s routeStubVisibilityGateway) ResolveRegionCodeByCountryCode(context.Context, string, string) (string, error) {
|
||||
return s.targetRegionCode, nil
|
||||
}
|
||||
|
||||
type routeStubIPCountryResolver struct {
|
||||
countryCode string
|
||||
}
|
||||
|
||||
func (s routeStubIPCountryResolver) CountryCode(context.Context, string) (string, error) {
|
||||
return s.countryCode, nil
|
||||
}
|
||||
|
||||
type routeStubProvider struct {
|
||||
listRoomCalls int
|
||||
shortcutCalls int
|
||||
|
||||
@ -2,38 +2,16 @@ package gameprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"chatapp3-golang/internal/integration"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
const (
|
||||
gameListTargetSysOrigin = "LIKEI"
|
||||
gameListTurkeyCountryCode = "TR"
|
||||
gameListTurkeyBlockLevel = 2
|
||||
ipCountryCachePrefix = "GAME_LIST:IP_COUNTRY:"
|
||||
ipCountryCacheTTL = 7 * 24 * time.Hour
|
||||
)
|
||||
const gameListTargetSysOrigin = "LIKEI"
|
||||
|
||||
// VisibilityGateway 聚合游戏列表门禁需要的 Java 用户区域和等级能力。
|
||||
// VisibilityGateway 聚合游戏列表门禁需要的 Java 用户区域能力。
|
||||
type VisibilityGateway interface {
|
||||
GetUserRegion(ctx context.Context, userID int64, authorization string) (integration.UserRegion, error)
|
||||
GetUserLevel(ctx context.Context, sysOrigin string, userID int64) (integration.UserLevel, error)
|
||||
ResolveRegionCodeByCountryCode(ctx context.Context, sysOrigin string, countryCode string) (string, error)
|
||||
}
|
||||
|
||||
// IPCountryResolver 把请求 IP 解析成国家二字码。
|
||||
type IPCountryResolver interface {
|
||||
CountryCode(ctx context.Context, ip string) (string, error)
|
||||
}
|
||||
|
||||
// VisibilityResult 返回门禁结果,并把已经查到的区域带回路由继续参与 SQL 过滤。
|
||||
@ -45,26 +23,21 @@ type VisibilityResult struct {
|
||||
|
||||
// VisibilityPolicy 判断当前用户是否可以看到游戏列表。
|
||||
type VisibilityPolicy struct {
|
||||
java VisibilityGateway
|
||||
ipResolver IPCountryResolver
|
||||
targetCountry string
|
||||
targetSys string
|
||||
blockLevel int
|
||||
java VisibilityGateway
|
||||
targetSys string
|
||||
}
|
||||
|
||||
// NewVisibilityPolicy 创建 LIKEI 游戏列表门禁:土耳其区域或土耳其 IP 的用户财富等级必须大于 2,其他用户直接展示。
|
||||
func NewVisibilityPolicy(java VisibilityGateway, ipResolver IPCountryResolver) *VisibilityPolicy {
|
||||
// NewVisibilityPolicy 创建 LIKEI 游戏列表门禁:土耳其财富等级限制已下线,现在对所有区域直接展示,
|
||||
// 保留 Evaluate 是因为路由仍依赖它查询用户区域给 provider SQL 做 regions 过滤。
|
||||
func NewVisibilityPolicy(java VisibilityGateway) *VisibilityPolicy {
|
||||
return &VisibilityPolicy{
|
||||
java: java,
|
||||
ipResolver: ipResolver,
|
||||
targetCountry: gameListTurkeyCountryCode,
|
||||
targetSys: gameListTargetSysOrigin,
|
||||
blockLevel: gameListTurkeyBlockLevel,
|
||||
java: java,
|
||||
targetSys: gameListTargetSysOrigin,
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate 只拦截土耳其区域或土耳其 IP 的低财富等级用户;非土耳其区域且非土耳其 IP 的用户直接展示游戏列表。
|
||||
func (p *VisibilityPolicy) Evaluate(ctx context.Context, user AuthUser, clientIP string) (VisibilityResult, error) {
|
||||
// Evaluate 给 LIKEI 用户补齐区域信息并放行;非 LIKEI 用户沿用自带区域直接展示。
|
||||
func (p *VisibilityPolicy) Evaluate(ctx context.Context, user AuthUser) (VisibilityResult, error) {
|
||||
if p == nil || !strings.EqualFold(strings.TrimSpace(user.SysOrigin), p.targetSys) {
|
||||
return VisibilityResult{Allow: true, RegionID: user.RegionID, RegionCode: user.RegionCode}, nil
|
||||
}
|
||||
@ -76,176 +49,9 @@ func (p *VisibilityPolicy) Evaluate(ctx context.Context, user AuthUser, clientIP
|
||||
if err != nil {
|
||||
return VisibilityResult{}, err
|
||||
}
|
||||
result := VisibilityResult{
|
||||
return VisibilityResult{
|
||||
Allow: true,
|
||||
RegionID: strings.TrimSpace(region.RegionID),
|
||||
RegionCode: strings.TrimSpace(region.RegionCode),
|
||||
}
|
||||
|
||||
// 区域配置是运营可变数据,所以先从 Java 区域配置解析 TR 对应的 regionCode,再判断用户是否属于土耳其区域。
|
||||
targetRegionCode, err := p.java.ResolveRegionCodeByCountryCode(ctx, user.SysOrigin, p.targetCountry)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
level, err := p.java.GetUserLevel(ctx, user.SysOrigin, user.UserID)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
result.Allow = level.WealthLevel > p.blockLevel
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func matchesTargetRegion(userRegionCode, targetRegionCode, targetCountry string) bool {
|
||||
userRegionCode = strings.TrimSpace(userRegionCode)
|
||||
targetRegionCode = strings.TrimSpace(targetRegionCode)
|
||||
if targetRegionCode != "" {
|
||||
return strings.EqualFold(userRegionCode, targetRegionCode)
|
||||
}
|
||||
return strings.EqualFold(userRegionCode, strings.TrimSpace(targetCountry))
|
||||
}
|
||||
|
||||
// CachedIPCountryResolver 使用 Redis 缓存 IP 国家码,未命中时按顺序调用几个公开 geoip provider。
|
||||
type CachedIPCountryResolver struct {
|
||||
cache redis.Cmdable
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
// NewCachedIPCountryResolver 创建可复用的 IP 国家解析器。
|
||||
func NewCachedIPCountryResolver(cache redis.Cmdable, timeout time.Duration) *CachedIPCountryResolver {
|
||||
if timeout <= 0 {
|
||||
timeout = 5 * time.Second
|
||||
}
|
||||
return &CachedIPCountryResolver{
|
||||
cache: cache,
|
||||
httpClient: &http.Client{
|
||||
Timeout: timeout,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CountryCode 返回 IP 对应国家二字码;解析不到时返回空字符串,调用方负责按不可见处理。
|
||||
func (r *CachedIPCountryResolver) CountryCode(ctx context.Context, ip string) (string, error) {
|
||||
ip = strings.TrimSpace(ip)
|
||||
if ip == "" || ip == "-" {
|
||||
return "", nil
|
||||
}
|
||||
if cached := r.cachedCountryCode(ctx, ip); cached != "" {
|
||||
return cached, nil
|
||||
}
|
||||
for _, provider := range ipGeoProviders {
|
||||
countryCode := r.requestCountryCode(ctx, provider, ip)
|
||||
if countryCode == "" {
|
||||
continue
|
||||
}
|
||||
r.cacheCountryCode(ctx, ip, countryCode)
|
||||
return countryCode, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (r *CachedIPCountryResolver) cachedCountryCode(ctx context.Context, ip string) string {
|
||||
if r == nil || r.cache == nil {
|
||||
return ""
|
||||
}
|
||||
value, err := r.cache.Get(ctx, ipCountryCachePrefix+ip).Result()
|
||||
if err != nil && !errors.Is(err, redis.Nil) {
|
||||
return ""
|
||||
}
|
||||
return strings.ToUpper(strings.TrimSpace(value))
|
||||
}
|
||||
|
||||
func (r *CachedIPCountryResolver) cacheCountryCode(ctx context.Context, ip string, countryCode string) {
|
||||
if r == nil || r.cache == nil || strings.TrimSpace(countryCode) == "" {
|
||||
return
|
||||
}
|
||||
_ = r.cache.Set(ctx, ipCountryCachePrefix+ip, strings.ToUpper(strings.TrimSpace(countryCode)), ipCountryCacheTTL).Err()
|
||||
}
|
||||
|
||||
type ipGeoProvider struct {
|
||||
name string
|
||||
urlFormat string
|
||||
}
|
||||
|
||||
var ipGeoProviders = []ipGeoProvider{
|
||||
{name: "ip.sb", urlFormat: "https://api.ip.sb/geoip/%s"},
|
||||
{name: "freeipapi", urlFormat: "https://freeipapi.com/api/json/%s"},
|
||||
{name: "ipwhois", urlFormat: "https://ipwhois.app/json/%s?format=json"},
|
||||
{name: "ip.nc.gy", urlFormat: "https://ip.nc.gy/json?ip=%s"},
|
||||
}
|
||||
|
||||
func (r *CachedIPCountryResolver) requestCountryCode(ctx context.Context, provider ipGeoProvider, ip string) string {
|
||||
if r == nil || r.httpClient == nil {
|
||||
return ""
|
||||
}
|
||||
endpoint := fmt.Sprintf(provider.urlFormat, url.QueryEscape(ip))
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
resp, err := r.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
|
||||
return ""
|
||||
}
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil || len(body) == 0 {
|
||||
return ""
|
||||
}
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(body, &payload); err != nil {
|
||||
return ""
|
||||
}
|
||||
return countryCodeFromProvider(provider.name, payload)
|
||||
}
|
||||
|
||||
func countryCodeFromProvider(provider string, payload map[string]any) string {
|
||||
switch provider {
|
||||
case "ip.sb":
|
||||
return upperString(payload["country_code"])
|
||||
case "freeipapi":
|
||||
return upperString(payload["countryCode"])
|
||||
case "ipwhois":
|
||||
if success, ok := payload["success"].(bool); ok && !success {
|
||||
return ""
|
||||
}
|
||||
return upperString(payload["country_code"])
|
||||
case "ip.nc.gy":
|
||||
if code := countryObjectCode(payload["country"]); code != "" {
|
||||
return code
|
||||
}
|
||||
return countryObjectCode(payload["registered_country"])
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func countryObjectCode(value any) string {
|
||||
object, ok := value.(map[string]any)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return upperString(object["iso_code"])
|
||||
}
|
||||
|
||||
func upperString(value any) string {
|
||||
text, _ := value.(string)
|
||||
return strings.ToUpper(strings.TrimSpace(text))
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -8,132 +8,73 @@ import (
|
||||
)
|
||||
|
||||
type stubVisibilityGateway struct {
|
||||
region integration.UserRegion
|
||||
level integration.UserLevel
|
||||
targetRegionCode string
|
||||
region integration.UserRegion
|
||||
}
|
||||
|
||||
func (s stubVisibilityGateway) GetUserRegion(context.Context, int64, string) (integration.UserRegion, error) {
|
||||
return s.region, nil
|
||||
}
|
||||
|
||||
func (s stubVisibilityGateway) GetUserLevel(context.Context, string, int64) (integration.UserLevel, error) {
|
||||
return s.level, nil
|
||||
}
|
||||
|
||||
func (s stubVisibilityGateway) ResolveRegionCodeByCountryCode(context.Context, string, string) (string, error) {
|
||||
return s.targetRegionCode, nil
|
||||
}
|
||||
|
||||
type stubIPCountryResolver struct {
|
||||
countryCode string
|
||||
}
|
||||
|
||||
func (s stubIPCountryResolver) CountryCode(context.Context, string) (string, error) {
|
||||
return s.countryCode, nil
|
||||
}
|
||||
|
||||
const account1007500UserID int64 = 2054163533368717314
|
||||
|
||||
func TestVisibilityPolicyAppliesTurkeyRegionOrIPWealthGate(t *testing.T) {
|
||||
func TestVisibilityPolicyAllowsAllRegions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
region integration.UserRegion
|
||||
ipCountry string
|
||||
wealth int
|
||||
wantAllow bool
|
||||
wantRegion integration.UserRegion
|
||||
name string
|
||||
region 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: "土耳其"},
|
||||
name: "turkey region is visible without wealth gate",
|
||||
region: integration.UserRegion{RegionID: "2046066409959649281", RegionCode: "土耳其"},
|
||||
},
|
||||
{
|
||||
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: "土耳其"},
|
||||
},
|
||||
{
|
||||
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: "南亚"},
|
||||
},
|
||||
{
|
||||
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: "南亚"},
|
||||
name: "south asia region is visible",
|
||||
region: integration.UserRegion{RegionID: "2045389832842178561", RegionCode: "南亚"},
|
||||
},
|
||||
}
|
||||
|
||||
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},
|
||||
)
|
||||
policy := NewVisibilityPolicy(stubVisibilityGateway{region: tt.region})
|
||||
|
||||
result, err := policy.Evaluate(context.Background(), AuthUser{UserID: account1007500UserID, SysOrigin: "LIKEI"}, "1.1.1.1")
|
||||
result, err := policy.Evaluate(context.Background(), AuthUser{UserID: account1007500UserID, SysOrigin: "LIKEI"})
|
||||
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.Allow {
|
||||
t.Fatalf("Evaluate() allow = false, want true")
|
||||
}
|
||||
if result.RegionID != tt.wantRegion.RegionID || result.RegionCode != tt.wantRegion.RegionCode {
|
||||
t.Fatalf("Evaluate() region = %#v, want %#v", result, tt.wantRegion)
|
||||
if result.RegionID != tt.region.RegionID || result.RegionCode != tt.region.RegionCode {
|
||||
t.Fatalf("Evaluate() region = %#v, want %#v", result, tt.region)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVisibilityPolicySkipsOtherSysOrigin(t *testing.T) {
|
||||
policy := NewVisibilityPolicy(
|
||||
stubVisibilityGateway{
|
||||
region: integration.UserRegion{RegionID: "2046067036517363714", RegionCode: "AR"},
|
||||
level: integration.UserLevel{WealthLevel: 0},
|
||||
targetRegionCode: "TR",
|
||||
},
|
||||
stubIPCountryResolver{countryCode: "SA"},
|
||||
)
|
||||
policy := NewVisibilityPolicy(stubVisibilityGateway{
|
||||
region: integration.UserRegion{RegionID: "2046067036517363714", RegionCode: "AR"},
|
||||
})
|
||||
|
||||
result, err := policy.Evaluate(context.Background(), AuthUser{UserID: 1001, SysOrigin: "ASWAT"}, "1.1.1.1")
|
||||
result, err := policy.Evaluate(context.Background(), AuthUser{UserID: 1001, SysOrigin: "ASWAT", RegionID: "r-1", RegionCode: "SA"})
|
||||
if err != nil {
|
||||
t.Fatalf("Evaluate() error = %v", err)
|
||||
}
|
||||
if !result.Allow {
|
||||
t.Fatalf("Evaluate() allow = false, want true")
|
||||
}
|
||||
if result.RegionID != "r-1" || result.RegionCode != "SA" {
|
||||
t.Fatalf("Evaluate() region = %#v, want user-provided region", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVisibilityPolicyDeniesInvalidUser(t *testing.T) {
|
||||
policy := NewVisibilityPolicy(stubVisibilityGateway{})
|
||||
|
||||
result, err := policy.Evaluate(context.Background(), AuthUser{UserID: 0, SysOrigin: "LIKEI"})
|
||||
if err != nil {
|
||||
t.Fatalf("Evaluate() error = %v", err)
|
||||
}
|
||||
if result.Allow {
|
||||
t.Fatalf("Evaluate() allow = true, want false for invalid user")
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user