Skip to content

Commit 3abfc89

Browse files
committed
minor: support private ipaddress filtering
1 parent d273271 commit 3abfc89

File tree

3 files changed

+69
-50
lines changed

3 files changed

+69
-50
lines changed

README.md

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ func main() {
3434
// Maximum radius of the geofence in kilometers, only clients less than or equal to this distance will return true with isAddressNearby
3535
// 1 kilometer
3636
Radius: 1.0,
37+
// Allow 192.X, 172.X, 10.X and loopback addresses
38+
AllowPrivateIPAddresses: true
3739
// How long to cache if any ip address is nearby
3840
CacheTTL: 7 * (24 * time.Hour), // 1 week
3941
})
@@ -48,49 +50,3 @@ func main() {
4850
fmt.Println("Address nearby: ", isAddressNearby)
4951
}
5052
```
51-
52-
### Private IP Addresses
53-
54-
Private IP's will always result in `false` since their coordinates will come back as `0.0000`. You can work around these like so:
55-
56-
```go
57-
package main
58-
59-
import (
60-
"fmt"
61-
"log"
62-
"net"
63-
"time"
64-
65-
"github.com/circa10a/go-geofence"
66-
)
67-
68-
func main() {
69-
// Provide an IP Address to test with
70-
ipAddress := "192.168.1.100"
71-
geofence, err := geofence.New(&geofence.Config{
72-
// Empty string to geofence your current public IP address, or you can monitor a remote address by supplying it as the first parameter
73-
IPAddress: ipAddress,
74-
// freegeoip.app API token
75-
Token: "YOUR_FREEGEOIP_API_TOKEN",
76-
// Maximum radius of the geofence in kilometers, only clients less than or equal to this distance will return true with isAddressNearby
77-
// 1 kilometer
78-
Radius: 1.0,
79-
// How long to cache if any ip address is nearby
80-
CacheTTL: 7 * (24 * time.Hour), // 1 week
81-
})
82-
if err != nil {
83-
log.Fatal(err)
84-
}
85-
// Skip Private IP analysis as it will always be false
86-
ip := net.ParseIP(ipAddress)
87-
if !ip.IsPrivate() || !ip.IsLoopback() {
88-
isAddressNearby, err := geofence.IsIPAddressNear(ipAddress)
89-
if err != nil {
90-
log.Fatal(err)
91-
}
92-
// Address nearby: false
93-
fmt.Println("Address nearby: ", isAddressNearby)
94-
}
95-
}
96-
```

geofence.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ const (
1717

1818
// Config holds the user configuration to setup a new geofence
1919
type Config struct {
20-
IPAddress string
21-
Token string
22-
Radius float64
23-
CacheTTL time.Duration
20+
IPAddress string
21+
Token string
22+
Radius float64
23+
AllowPrivateIPAddresses bool
24+
CacheTTL time.Duration
2425
}
2526

2627
// Geofence holds a freegeoip.app client, cache and user supplied config
@@ -124,6 +125,13 @@ func (g *Geofence) IsIPAddressNear(ipAddress string) (bool, error) {
124125
return false, err
125126
}
126127

128+
if g.AllowPrivateIPAddresses {
129+
ip := net.ParseIP(ipAddress)
130+
if ip.IsPrivate() || ip.IsLoopback() {
131+
return true, nil
132+
}
133+
}
134+
127135
// Check if ipaddress has been looked up before and is in cache
128136
if isIPAddressNear, found := g.Cache.Get(ipAddress); found {
129137
return isIPAddressNear.(bool), nil

geofence_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,61 @@ func TestGeofenceNear(t *testing.T) {
9999
assert.Equal(t, info[fmt.Sprintf("GET %s", fakeEndpoint)], 1)
100100
}
101101

102+
func TestGeofencePrivateIP(t *testing.T) {
103+
fakeIPAddress := "192.168.1.1"
104+
fakeApiToken := "fakeApiToken"
105+
fakeLatitude := 37.751
106+
fakeLongitude := -97.822
107+
fakeRadius := 0.0
108+
fakeEndpoint := fmt.Sprintf("%s/%s?apikey=%s", freeGeoIPBaseURL, fakeIPAddress, fakeApiToken)
109+
110+
// new geofence
111+
geofence, _ := New(&Config{
112+
IPAddress: fakeIPAddress,
113+
Token: fakeApiToken,
114+
Radius: fakeRadius,
115+
AllowPrivateIPAddresses: true,
116+
CacheTTL: 7 * (24 * time.Hour), // 1 week
117+
})
118+
geofence.Latitude = fakeLatitude
119+
geofence.Longitude = fakeLongitude
120+
121+
httpmock.ActivateNonDefault(geofence.FreeGeoIPClient.GetClient())
122+
defer httpmock.DeactivateAndReset()
123+
124+
// mock json rsponse
125+
response := &FreeGeoIPResponse{
126+
IP: fakeIPAddress,
127+
CountryCode: "US",
128+
CountryName: "United States",
129+
TimeZone: "America/Chicago",
130+
Latitude: fakeLatitude,
131+
Longitude: fakeLongitude,
132+
}
133+
134+
// mock freegeoip.app response
135+
httpmock.RegisterResponder("GET", fakeEndpoint,
136+
func(req *http.Request) (*http.Response, error) {
137+
resp, err := httpmock.NewJsonResponse(200, response)
138+
if err != nil {
139+
return httpmock.NewStringResponse(500, ""), nil
140+
}
141+
return resp, nil
142+
})
143+
144+
// check that addresses is nearby
145+
isAddressNearby, err := geofence.IsIPAddressNear(fakeIPAddress)
146+
assert.NoError(t, err)
147+
assert.True(t, isAddressNearby)
148+
149+
// get count info
150+
httpmock.GetTotalCallCount()
151+
// get the amount of calls for the registered responder
152+
info := httpmock.GetCallCountInfo()
153+
// Check total calls
154+
assert.Equal(t, info[fmt.Sprintf("GET %s", fakeEndpoint)], 0)
155+
}
156+
102157
func TestGeofenceNotNear(t *testing.T) {
103158
fakeIPAddress := "8.8.8.8"
104159
fakeApiToken := "fakeApiToken"

0 commit comments

Comments
 (0)