89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
|
|
"code.nonshy.com/nonshy/website/pkg/config"
|
|
"code.nonshy.com/nonshy/website/pkg/controller/index"
|
|
"code.nonshy.com/nonshy/website/pkg/session"
|
|
"code.nonshy.com/nonshy/website/pkg/utility"
|
|
"github.com/oschwald/geoip2-golang"
|
|
)
|
|
|
|
// GeoGate: block access to the site based on the user's location (due to local laws or regulations).
|
|
func GeoGate(handler http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if !config.GeoGateEnabled {
|
|
handler.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
|
|
// Flash errors to admins.
|
|
onError := func(err error) {
|
|
session.FlashError(w, r, "GeoIP: %s", err)
|
|
handler.ServeHTTP(w, r)
|
|
}
|
|
|
|
// See where they're coming from.
|
|
db, err := geoip2.Open(config.GeoIPPath)
|
|
if err != nil {
|
|
onError(err)
|
|
return
|
|
}
|
|
defer db.Close()
|
|
|
|
// If you are using strings that may be invalid, check that ip is not nil
|
|
addr := utility.IPAddress(r)
|
|
ip := net.ParseIP(addr)
|
|
if ip != nil {
|
|
record, err := db.City(ip)
|
|
if err != nil {
|
|
onError(err)
|
|
return
|
|
}
|
|
|
|
// Blocked by US states
|
|
if record.Country.IsoCode == "US" {
|
|
for _, sub := range record.Subdivisions {
|
|
if _, ok := config.BlockUSStates[sub.IsoCode]; ok {
|
|
session.LogoutUser(w, r)
|
|
page := index.StaticTemplate("errors/geo_gate.html")()
|
|
page(w, r)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// Blocked by country code
|
|
if _, ok := config.BlockCountries[record.Country.IsoCode]; ok {
|
|
session.LogoutUser(w, r)
|
|
page := index.StaticTemplate("errors/geo_gate.html")()
|
|
page(w, r)
|
|
return
|
|
}
|
|
|
|
// Debug info
|
|
/*
|
|
fmt.Printf("Portuguese (BR) city name: %v\n", record.City.Names["pt-BR"])
|
|
if len(record.Subdivisions) > 0 {
|
|
fmt.Printf("English subdivision name: %v\n", record.Subdivisions[0].Names["en"])
|
|
}
|
|
fmt.Printf("Russian country name: %v\n", record.Country.Names["ru"])
|
|
fmt.Printf("ISO country code: %v\n", record.Country.IsoCode)
|
|
fmt.Printf("Time zone: %v\n", record.Location.TimeZone)
|
|
fmt.Printf("Coordinates: %v, %v\n", record.Location.Latitude, record.Location.Longitude)
|
|
// Output:
|
|
// Portuguese (BR) city name: Londres
|
|
// English subdivision name: England
|
|
// Russian country name: Великобритания
|
|
// ISO country code: GB
|
|
// Time zone: Europe/London
|
|
// Coordinates: 51.5142, -0.0931
|
|
*/
|
|
}
|
|
|
|
handler.ServeHTTP(w, r)
|
|
})
|
|
}
|