74 lines
2.1 KiB
Go
74 lines
2.1 KiB
Go
package auth
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"strings"
|
||
|
||
"hyapp/pkg/xerr"
|
||
authdomain "hyapp/services/user-service/internal/domain/auth"
|
||
)
|
||
|
||
type edgeCountryProvider struct{}
|
||
|
||
type staticCountryProvider struct {
|
||
name string
|
||
countryCode string
|
||
}
|
||
|
||
type unavailableIPGeoProvider struct {
|
||
name string
|
||
}
|
||
|
||
func BuildIPGeoProviders(names []string) []IPGeoProvider {
|
||
providers := make([]IPGeoProvider, 0, len(names))
|
||
for _, name := range names {
|
||
name = strings.TrimSpace(name)
|
||
if name == "" {
|
||
continue
|
||
}
|
||
switch {
|
||
case strings.EqualFold(name, "edge_country"):
|
||
providers = append(providers, edgeCountryProvider{})
|
||
case strings.HasPrefix(strings.ToLower(name), "static:"):
|
||
country := normalizeCountryCode(strings.TrimPrefix(name, "static:"))
|
||
providers = append(providers, staticCountryProvider{name: name, countryCode: country})
|
||
default:
|
||
// 未配置具体 provider 适配器时显式降级为 unavailable,worker 会按顺序继续尝试下一个。
|
||
providers = append(providers, unavailableIPGeoProvider{name: name})
|
||
}
|
||
}
|
||
return providers
|
||
}
|
||
|
||
func (p edgeCountryProvider) Name() string {
|
||
return "edge_country"
|
||
}
|
||
|
||
func (p edgeCountryProvider) ResolveCountry(_ context.Context, job authdomain.LoginIPRiskJob) (IPGeoResult, error) {
|
||
country := normalizeCountryCode(job.EdgeCountryCode)
|
||
if country == "" {
|
||
return IPGeoResult{}, xerr.New(xerr.Unavailable, "edge country is empty")
|
||
}
|
||
return IPGeoResult{CountryCode: country, Confidence: 60}, nil
|
||
}
|
||
|
||
func (p staticCountryProvider) Name() string {
|
||
return p.name
|
||
}
|
||
|
||
func (p staticCountryProvider) ResolveCountry(_ context.Context, _ authdomain.LoginIPRiskJob) (IPGeoResult, error) {
|
||
if p.countryCode == "" {
|
||
return IPGeoResult{}, xerr.New(xerr.Unavailable, "static country is empty")
|
||
}
|
||
return IPGeoResult{CountryCode: p.countryCode, Confidence: 100}, nil
|
||
}
|
||
|
||
func (p unavailableIPGeoProvider) Name() string {
|
||
return p.name
|
||
}
|
||
|
||
func (p unavailableIPGeoProvider) ResolveCountry(_ context.Context, _ authdomain.LoginIPRiskJob) (IPGeoResult, error) {
|
||
return IPGeoResult{}, fmt.Errorf("ip geo provider %s is not configured", p.name)
|
||
}
|