Skip to content

Commit

Permalink
Merge pull request #105 from nyaruka/parse_networks
Browse files Browse the repository at this point in the history
Add `httpx.ParseNetworks` util function
  • Loading branch information
rowanseymour authored Oct 30, 2023
2 parents df62c23 + 82e4616 commit a9d3220
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
25 changes: 25 additions & 0 deletions httpx/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"
"time"

"github.com/pkg/errors"
"golang.org/x/net/context"
)

Expand Down Expand Up @@ -52,3 +53,27 @@ func (c *AccessConfig) Allow(request *http.Request) (bool, error) {
}
return true, nil
}

// ParseNetworks parses a list of IPs and IP networks (written in CIDR notation)
func ParseNetworks(addrs ...string) ([]net.IP, []*net.IPNet, error) {
ips := make([]net.IP, 0, len(addrs))
ipNets := make([]*net.IPNet, 0, len(addrs))

for _, addr := range addrs {
if strings.Contains(addr, "/") {
_, ipNet, err := net.ParseCIDR(addr)
if err != nil {
return nil, nil, errors.Errorf("couldn't parse '%s' as an IP network", addr)
}
ipNets = append(ipNets, ipNet)
} else {
ip := net.ParseIP(addr)
if ip == nil {
return nil, nil, errors.Errorf("couldn't parse '%s' as an IP address", addr)
}
ips = append(ips, ip)
}
}

return ips, ipNets, nil
}
30 changes: 29 additions & 1 deletion httpx/access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"time"

"github.com/nyaruka/gocommon/httpx"

"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -68,3 +67,32 @@ func TestAccessConfig(t *testing.T) {
}
}
}

func TestParseNetworkList(t *testing.T) {
privateNetwork1 := &net.IPNet{IP: net.IPv4(10, 0, 0, 0).To4(), Mask: net.CIDRMask(8, 32)}
privateNetwork2 := &net.IPNet{IP: net.IPv4(172, 16, 0, 0).To4(), Mask: net.CIDRMask(12, 32)}
privateNetwork3 := &net.IPNet{IP: net.IPv4(192, 168, 0, 0).To4(), Mask: net.CIDRMask(16, 32)}

linkLocalIPv4 := &net.IPNet{IP: net.IPv4(169, 254, 0, 0).To4(), Mask: net.CIDRMask(16, 32)}
_, linkLocalIPv6, _ := net.ParseCIDR("fe80::/10")

// test with mailroom defaults
ips, ipNets, err := httpx.ParseNetworks(`127.0.0.1`, `::1`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16`, `fe80::/10`)
assert.NoError(t, err)
assert.Equal(t, []net.IP{net.IPv4(127, 0, 0, 1), net.ParseIP(`::1`)}, ips)
assert.Equal(t, []*net.IPNet{privateNetwork1, privateNetwork2, privateNetwork3, linkLocalIPv4, linkLocalIPv6}, ipNets)

// test with empty
ips, ipNets, err = httpx.ParseNetworks()
assert.NoError(t, err)
assert.Equal(t, []net.IP{}, ips)
assert.Equal(t, []*net.IPNet{}, ipNets)

// test with invalid IP
_, _, err = httpx.ParseNetworks(`127.0.1`)
assert.EqualError(t, err, `couldn't parse '127.0.1' as an IP address`)

// test with invalid network
_, _, err = httpx.ParseNetworks(`127.0.0.1/x`)
assert.EqualError(t, err, `couldn't parse '127.0.0.1/x' as an IP network`)
}

0 comments on commit a9d3220

Please sign in to comment.