Skip to content

Commit

Permalink
fix api response types
Browse files Browse the repository at this point in the history
Signed-off-by: circa10a <[email protected]>
  • Loading branch information
circa10a committed Jul 13, 2024
1 parent f91114c commit 4173f00
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 93 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ By default, the library will use an in-memory cache that will be used to reduce

### Persistent

If you need a persistent cache to live outside of your application, [Redis](https://redis.io/) is supported by this library. To have the library cache address proximity using a Redis instance, simply provide a `geofence.RedisOptions` struct to `geofence.Config.RedisOptions`. If `RedisOptions` is configured, the in-memory cache will not be used.
If you need a persistent cache to live outside of your application, [Redis](https://redis.io/) is supported by this library. To have the library cache address proximity using a Redis instance, simply provide a `RedisOptions` struct using the `cache` package to `geofence.Config.RedisOptions`. If `RedisOptions` is configured, the in-memory cache will not be used.

> Note: Only Redis 7 is currently supported at the time of this writing.
Expand All @@ -76,7 +76,7 @@ import (
"time"

"github.com/circa10a/go-geofence"
"github.com/go-redis/redis/v9"
geofencecache "github.com/circa10a/go-geofence/cache"
)

func main() {
Expand All @@ -87,7 +87,7 @@ func main() {
AllowPrivateIPAddresses: true,
CacheTTL: 7 * (24 * time.Hour), // 1 week
// Use Redis for caching
RedisOptions: &geofence.RedisOptions{
RedisOptions: &geofencecache.RedisOptions{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
Expand All @@ -100,6 +100,7 @@ func main() {
if err != nil {
log.Fatal(err)
}

// Address nearby: false
fmt.Println("Address nearby: ", isAddressNearby)
}
Expand Down
9 changes: 6 additions & 3 deletions cache/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,34 @@ const (
deleteExpiredCacheItemsInternal = 10 * time.Minute
)

// MemoryCache is used to store/fetch ip proximity from an in-memory cache.
type MemoryCache struct {
memoryClient *gocache.Cache
memoryOptions *MemoryOptions
}

// MemoryOptions holds in memory cache configuration parameters.
// MemoryOptions holds in-memory cache configuration parameters.
type MemoryOptions struct {
TTL time.Duration
}

// NewRedisCache provides a new in-memory cache client.
func NewMemoryCache(memoryOptions *MemoryOptions) *MemoryCache {
return &MemoryCache{
memoryClient: gocache.New(memoryOptions.TTL, deleteExpiredCacheItemsInternal),
memoryOptions: memoryOptions,
}
}

// Get gets value from the in-memory cache.
func (m *MemoryCache) Get(ctx context.Context, key string) (bool, bool, error) {
if isIPAddressNear, found := m.memoryClient.Get(key); found {
return isIPAddressNear.(bool), found, nil
} else {
return false, false, nil
}
return false, false, nil
}

// Set sets k/v in the in-memory cache.
func (m *MemoryCache) Set(ctx context.Context, key string, value bool) error {
m.memoryClient.Set(key, value, m.memoryOptions.TTL)
return nil
Expand Down
6 changes: 5 additions & 1 deletion cache/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/redis/go-redis/v9"
)

// RedisCache is used to store/fetch data from redis.
type RedisCache struct {
redisClient *redis.Client
redisOptions *RedisOptions
Expand All @@ -21,6 +22,7 @@ type RedisOptions struct {
TTL time.Duration
}

// NewRedisCache provides a new redis cache client.
func NewRedisCache(redisOpts *RedisOptions) *RedisCache {
return &RedisCache{
redisClient: redis.NewClient(&redis.Options{
Expand All @@ -32,6 +34,7 @@ func NewRedisCache(redisOpts *RedisOptions) *RedisCache {
}
}

// Get gets value from redis.
func (r *RedisCache) Get(ctx context.Context, key string) (bool, bool, error) {
val, err := r.redisClient.Get(ctx, key).Result()
if err != nil {
Expand All @@ -49,7 +52,8 @@ func (r *RedisCache) Get(ctx context.Context, key string) (bool, bool, error) {
return isIPAddressNear, true, nil
}

// Set sets k/v in redis.
func (r *RedisCache) Set(ctx context.Context, key string, value bool) error {
// Redis stores false as 0 for whatever reason, so we'll store as a string and parse out in cacheGet
// Redis stores false as 0 for whatever reason, so we'll store as a string and parse it out
return r.redisClient.Set(ctx, key, strconv.FormatBool(value), r.redisOptions.TTL).Err()
}
82 changes: 1 addition & 81 deletions geofence.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,91 +35,11 @@ type Geofence struct {
Longitude float64
}

// ipBaseResponse is the json response from ipbase.com
// ipbaseResponse is the json response from ipbase.com
type ipbaseResponse struct {
Data data `json:"data"`
}

type timezone struct {
Id string `json:"id"`
CurrentTime string `json:"current_time"`
Code string `json:"code"`
IDaylightSaving bool `json:"is_daylight_saving"`
GmtOffset int `json:"gmt_offset"`
}

type connection struct {
Organization string `json:"organization"`
Isp string `json:"isp"`
Asn int `json:"asn"`
}

type continent struct {
Code string `json:"code"`
Name string `json:"name"`
NameTranslated string `json:"name_translated"`
}

type currencies struct {
Symbol string `json:"symbol"`
Name string `json:"name"`
SymbolNative string `json:"symbol_native"`
Code string `json:"code"`
NamePlural string `json:"name_plural"`
DecimalDigits int `json:"decimal_digits"`
Rounding int `json:"rounding"`
}

type languages struct {
Name string `json:"name"`
NameNative string `json:"name_native"`
}

type country struct {
Alpha2 string `json:"alpha2"`
Alpha3 string `json:"alpha3"`
CallingCodes []string `json:"calling_codes"`
Currencies []currencies `json:"currencies"`
Emoji string `json:"emoji"`
Ioc string `json:"ioc"`
Languages []languages `json:"languages"`
Name string `json:"name"`
NameTranslated string `json:"name_translated"`
Timezones []string `json:"timezones"`
IsInEuropeanUnion bool `json:"is_in_european_union"`
}

type city struct {
Name string `json:"name"`
NameTranslated string `json:"name_translated"`
}

type region struct {
Fips interface{} `json:"fips"`
Alpha2 interface{} `json:"alpha2"`
Name string `json:"name"`
NameTranslated string `json:"name_translated"`
}

type location struct {
GeonamesID interface{} `json:"geonames_id"`
Region region `json:"region"`
Continent continent `json:"continent"`
City city `json:"city"`
Zip string `json:"zip"`
Country country `json:"country"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}

type data struct {
Timezone timezone `json:"timezone"`
IP string `json:"ip"`
Type string `json:"type"`
Connection connection `json:"connection"`
Location location `json:"location"`
}

// IPBaseError is the json response when there is an error from ipbase.com
type IPBaseError struct {
Message string `json:"message"`
Expand Down
8 changes: 4 additions & 4 deletions geofence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestGeofenceNear(t *testing.T) {
httpmock.ActivateNonDefault(geofence.ipbaseClient.GetClient())
defer httpmock.DeactivateAndReset()

// mock json rsponse
// mock json response
response := &ipbaseResponse{
Data: data{
IP: fakeIPAddress,
Expand All @@ -83,7 +83,7 @@ func TestGeofenceNear(t *testing.T) {
},
},
Timezone: timezone{
Id: "America/Chicago",
ID: "America/Chicago",
},
},
}
Expand Down Expand Up @@ -146,7 +146,7 @@ func TestGeofencePrivateIP(t *testing.T) {
},
},
Timezone: timezone{
Id: "America/Chicago",
ID: "America/Chicago",
},
},
}
Expand Down Expand Up @@ -208,7 +208,7 @@ func TestGeofenceNotNear(t *testing.T) {
},
},
Timezone: timezone{
Id: "America/Chicago",
ID: "America/Chicago",
},
},
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/circa10a/go-geofence

go 1.17
go 1.18

require (
github.com/EpicStep/go-simple-geo/v2 v2.0.1
Expand Down
129 changes: 129 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Look.
// I know people hate types.go and want to keep the structs
// but damn these are some exaustive types and it flooded the primary package logic

package geofence

type rangeType struct {
Type string `json:"type"`
Description string `json:"description"`
}

type connection struct {
Organization string `json:"organization"`
Isp string `json:"isp"`
Range string `json:"range"`
Asn int `json:"asn"`
}

type continent struct {
Name string `json:"name"`
NameTranslated string `json:"name_translated"`
WikidataID string `json:"wikidata_id"`
Code int `json:"code"`
GeonamesID int `json:"geonames_id"`
}

type currencies struct {
Symbol string `json:"symbol"`
Name string `json:"name"`
SymbolNative string `json:"symbol_native"`
Code string `json:"code"`
NamePlural string `json:"name_plural"`
DecimalDigits int `json:"decimal_digits"`
Rounding int `json:"rounding"`
}

type languages struct {
Name string `json:"name"`
NameNative string `json:"name_native"`
}

type country struct {
Fips string `json:"fips"`
Alpha3 string `json:"alpha3"`
WikidataID string `json:"wikidata_id"`
HascID string `json:"hasc_id"`
Emoji string `json:"emoji"`
Ioc string `json:"ioc"`
Alpha2 string `json:"alpha2"`
Name string `json:"name"`
NameTranslated string `json:"name_translated"`
Languages []languages `json:"languages"`
Timezones []string `json:"timezones"`
Currencies []currencies `json:"currencies"`
CallingCodes []string `json:"calling_codes"`
GeonamesID int `json:"geonames_id"`
IsInEuropeanUnion bool `json:"is_in_european_union"`
}

type city struct {
Alpha2 any `json:"alpha2"`
HascID any `json:"hasc_id"`
Fips string `json:"fips"`
WikidataID string `json:"wikidata_id"`
Name string `json:"name"`
NameTranslated string `json:"name_translated"`
GeonamesID int `json:"geonames_id"`
}

type region struct {
Fips string `json:"fips"`
Alpha2 string `json:"alpha2"`
HascID string `json:"hasc_id"`
WikidataID string `json:"wikidata_id"`
Name string `json:"name"`
NameTranslated string `json:"name_translated"`
GeonamesID int `json:"geonames_id"`
}

type location struct {

Check failure on line 80 in types.go

View workflow job for this annotation

GitHub Actions / golangci-lint

fieldalignment: struct with 536 pointer bytes could be 512 (govet)

Check failure on line 80 in types.go

View workflow job for this annotation

GitHub Actions / golangci-lint

fieldalignment: struct with 536 pointer bytes could be 512 (govet)
Country country `json:"country"`
City city `json:"city"`
Region region `json:"region"`
Continent continent `json:"continent"`
Zip string `json:"zip"`
GeonamesID int `json:"geonames_id"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}

type timezone struct {
ID string `json:"id"`
CurrentTime string `json:"current_time"`
Code string `json:"code"`
IsDaylightSaving bool `json:"is_daylight_saving"`
GmtOffset int `json:"gmt_offset"`
}

type security struct {
IsAnonymous bool `json:"is_anonymous"`
IsDatacenter bool `json:"is_datacenter"`
IsVpn bool `json:"is_vpn"`
IsBot bool `json:"is_bot"`
IsAbuser bool `json:"is_abuser"`
IsKnownAttacker bool `json:"is_known_attacker"`
IsProxy bool `json:"is_proxy"`
IsSpam bool `json:"is_spam"`
IsTor bool `json:"is_tor"`
IsIcloudRelay bool `json:"is_icloud_relay"`
ThreatScore int `json:"threat_score"`
}

type domains struct {
Domains []string `json:"domains"`
Count int `json:"count"`
}

type data struct {

Check failure on line 118 in types.go

View workflow job for this annotation

GitHub Actions / golangci-lint

fieldalignment: struct with 800 pointer bytes could be 792 (govet)

Check failure on line 118 in types.go

View workflow job for this annotation

GitHub Actions / golangci-lint

fieldalignment: struct with 800 pointer bytes could be 792 (govet)
Location location `json:"location"`
Connection connection `json:"connection"`
RangeType rangeType `json:"range_type"`
IP string `json:"ip"`
Hostname string `json:"hostname"`
Type string `json:"type"`
Domains domains `json:"domains"`
Tlds []string `json:"tlds"`
Timezone timezone `json:"timezone"`
Security security `json:"security"`
}

0 comments on commit 4173f00

Please sign in to comment.