package geoip import ( "log/slog" "net" "yobbly-gateway-go/internal/logger" "github.com/oschwald/geoip2-golang" ) // GeoIPService предоставляет методы для поиска GeoIP. type GeoIPService struct { reader *geoip2.Reader blockedCountries map[string]struct{} } // NewGeoIPService создает новый GeoIPService. func NewGeoIPService(dbPath string, blockedCountries []string) (*GeoIPService, error) { op := "geoip.NewGeoIPService" log := logger.NewLoggerWithOp(op) reader, err := geoip2.Open(dbPath) if err != nil { log.Error("failed to open GeoIP database", slog.String("db_path", dbPath), slog.Any("error", err)) return nil, err } blockedMap := make(map[string]struct{}) for _, country := range blockedCountries { blockedMap[country] = struct{}{} } log.Info("GeoIP service initialized", slog.String("db_path", dbPath), slog.Any("blocked_countries", blockedCountries)) return &GeoIPService{ reader: reader, blockedCountries: blockedMap, }, nil } // IsCountryBlocked проверяет, принадлежит ли данный IP-адрес заблокированной стране. func (s *GeoIPService) IsCountryBlocked(ipStr string) (bool, string) { op := "geoip.IsCountryBlocked" log := logger.NewLoggerWithOp(op) ip := net.ParseIP(ipStr) if ip == nil { log.Warn("invalid IP address for GeoIP lookup", slog.String("ip", ipStr)) return false, "" } record, err := s.reader.Country(ip) if err != nil { // Логируем ошибку, но не блокируем, аналогично поведению Python log.Error("GeoIP lookup failed", slog.String("ip", ipStr), slog.Any("error", err)) return false, "" } countryCode := record.Country.IsoCode log.Debug("GeoIP lookup result", slog.String("ip", ipStr), slog.String("country_code", countryCode)) if _, ok := s.blockedCountries[countryCode]; ok { log.Info("access denied for blocked country", slog.String("ip", ipStr), slog.String("country_code", countryCode)) return true, countryCode } return false, countryCode } // Close закрывает ридер базы данных GeoIP. func (s *GeoIPService) Close() error { op := "geoip.Close" log := logger.NewLoggerWithOp(op) log.Info("closing GeoIP service") return s.reader.Close() }