Tobias Begalke há 8 anos atrás
commit
adb3716c5d
1 ficheiros alterados com 195 adições e 0 exclusões
  1. 195 0
      geoip.go

+ 195 - 0
geoip.go

@@ -0,0 +1,195 @@
+package geoip
+
+import (
+	"errors"
+	"fmt"
+	"net"
+
+	gg "github.com/oschwald/geoip2-golang"
+)
+
+type Anonymous struct {
+	// from geoip2-golang.AnonymousIP
+	IsAnonymous       bool `json:"is_anonymous"`
+	IsAnonymousVPN    bool `json:"is_anonymous_vpn"`
+	IsHostingProvider bool `json:"is_hosting_provider"`
+	IsPublicProxy     bool `json:"is_public_proxy"`
+	IsTorExitNode     bool `json:"is_tor_exit_node"`
+}
+
+type City struct {
+	Name                   string   `json:"name"`
+	Continent              string   `json:"continent"`
+	ContinentCode          string   `json:"continent_code"`
+	Country                string   `json:"country"`
+	CountryCode            string   `json:"country_code"`
+	AccuracyRadius         uint16   `json:"accuracy_radius"`
+	Latitude               float64  `json:"latitude"`
+	Longitude              float64  `json:"longitude"`
+	MetroCode              uint     `json:"metro_code"`
+	Timezone               string   `json:"timezone"`
+	Postcode               string   `json:"postcode"`
+	RegisteredCountry      string   `json:"registered_country"`
+	RegisteredCountryCode  string   `json:"registered_country_code"`
+	RepresentedCountry     string   `json:"represented_country"`
+	RepresentedCountryCode string   `json:"represented_country_code"`
+	RepresentedCountryType string   `json:"represented_country_type"`
+	Subdivisions           []string `json:"subdivisions"`
+	IsAnonymousProxy       bool     `json:"is_anonymous_proxy"`
+	IsSatelliteProvider    bool     `json:"is_satellite_provider"`
+}
+
+type ConnectionType struct {
+	Type string `json:"connection_type"`
+}
+
+type Country struct {
+	ContinentCode          string `json:"continent_code"`
+	Continent              string `json:"continent"`
+	CountryCode            string `json:"country_code"`
+	Country                string `json:"country"`
+	RegisteredCountryCode  string `json:"registered_country_code"`
+	RegisteredCountry      string `json:"registered_country"`
+	RepresentedCountryCode string `json:"represented_country_code"`
+	RepresentedCountryType string `json:"represented_country_type"`
+	RepresentedCountry     string `json:"represented_country"`
+	IsAnonymousProxy       bool   `json:"is_anonymous_proxy"`
+	IsSatelliteProvider    bool   `json:"is_satellite_provider"`
+}
+
+type Domain struct {
+	Domain string `json:"domain"`
+}
+
+type ISP struct {
+	AutonomousSystemNumber       uint   `json:"autonomous_system_number"`
+	AutonomousSystemOrganization string `json:"autonomous_system_organization"`
+	ISP                          string `json:"isp"`
+	Organization                 string `json:"organization"`
+}
+
+type GeoIP struct {
+	db        *gg.Reader `json:"-"`
+	IP        net.IP     `json:"ip"`
+	Anonymous *Anonymous `json:"anonymous"`
+	City      *City      `json:"city"`
+	Country   *Country   `json:"country"`
+	Domain    *Domain    `json:"domain"`
+	ISP       *ISP       `json:"isp"`
+}
+
+func NewGeoIP(dbpath string) (*GeoIP, error) {
+	ggReader, err := gg.Open(dbpath)
+	if err != nil {
+		return nil, err
+	}
+
+	g := GeoIP{
+		db: ggReader,
+	}
+
+	return &g, nil
+}
+
+func (g *GeoIP) Close() {
+	g.db.Close()
+}
+
+func (g *GeoIP) Lookup(ipAddr string) error {
+	g.IP = net.ParseIP(ipAddr)
+	if g.IP == nil {
+		return errors.New(fmt.Sprintf("%s is not a valid IP address!", ipAddr))
+	}
+
+	// ANONYMOUS IP
+	//
+	anon, err := g.db.AnonymousIP(g.IP)
+	if err == nil {
+		g.Anonymous = &Anonymous{}
+		g.Anonymous.IsAnonymous = anon.IsAnonymous
+		g.Anonymous.IsAnonymousVPN = anon.IsAnonymousVPN
+		g.Anonymous.IsHostingProvider = anon.IsHostingProvider
+		g.Anonymous.IsPublicProxy = anon.IsPublicProxy
+		g.Anonymous.IsTorExitNode = anon.IsTorExitNode
+	} else {
+		g.Anonymous = nil
+	}
+
+	// CITY
+	//
+	city, err := g.db.City(g.IP)
+	if err == nil {
+		g.City = &City{}
+		g.City.AccuracyRadius = city.Location.AccuracyRadius
+		g.City.Continent = city.Continent.Names["en"]
+		g.City.ContinentCode = city.Continent.Code
+		g.City.Country = city.Country.Names["en"]
+		g.City.CountryCode = city.Country.IsoCode
+		g.City.IsAnonymousProxy = city.Traits.IsAnonymousProxy
+		g.City.IsSatelliteProvider = city.Traits.IsSatelliteProvider
+		g.City.Latitude = city.Location.Latitude
+		g.City.Longitude = city.Location.Longitude
+		g.City.MetroCode = city.Location.MetroCode
+		g.City.Name = city.City.Names["en"]
+		g.City.Postcode = city.Postal.Code
+		g.City.RegisteredCountry = city.RegisteredCountry.Names["en"]
+		g.City.RegisteredCountryCode = city.RegisteredCountry.IsoCode
+		g.City.RepresentedCountry = city.RepresentedCountry.Names["en"]
+		g.City.RepresentedCountryCode = city.RepresentedCountry.IsoCode
+		g.City.RepresentedCountryType = city.RepresentedCountry.Type
+
+		subdivisions := make([]string, len(city.Subdivisions), len(city.Subdivisions))
+		for i, sd := range city.Subdivisions {
+			subdivisions[i] = sd.Names["en"]
+		}
+		g.City.Subdivisions = subdivisions
+		g.City.Timezone = city.Location.TimeZone
+	} else {
+		g.City = nil
+	}
+
+	// COUNTRY
+	//
+	country, err := g.db.Country(g.IP)
+	if err == nil {
+		g.Country = &Country{}
+		g.Country.Continent = country.Continent.Names["en"]
+		g.Country.ContinentCode = country.Continent.Code
+		g.Country.Country = country.Country.Names["en"]
+		g.Country.CountryCode = country.Country.IsoCode
+		g.Country.IsAnonymousProxy = country.Traits.IsAnonymousProxy
+		g.Country.IsSatelliteProvider = country.Traits.IsSatelliteProvider
+		g.Country.RegisteredCountry = country.RegisteredCountry.Names["en"]
+		g.Country.RegisteredCountryCode = country.RegisteredCountry.IsoCode
+		g.Country.RepresentedCountry = country.RepresentedCountry.Names["en"]
+		g.Country.RepresentedCountryCode = country.RepresentedCountry.IsoCode
+		g.Country.RepresentedCountryType = country.RepresentedCountry.Type
+	} else {
+		g.Country = nil
+	}
+
+	// DOMAIN
+	//
+	domain, err := g.db.Domain(g.IP)
+	if err == nil {
+		g.Domain = &Domain{}
+		g.Domain.Domain = domain.Domain
+	} else {
+		g.Domain = nil
+	}
+
+	// ISP
+	//
+	isp, err := g.db.ISP(g.IP)
+	if err == nil {
+		g.ISP = &ISP{}
+		g.ISP.AutonomousSystemNumber = isp.AutonomousSystemNumber
+		g.ISP.AutonomousSystemOrganization = isp.AutonomousSystemOrganization
+		g.ISP.ISP = isp.ISP
+		g.ISP.Organization = isp.Organization
+	} else {
+		g.ISP = nil
+	}
+
+	return nil
+}