Files
phishingclub/backend/vo/network.go
Ronni Skansing 691cff9659 ip filtering becomes filtering with ja4 and cidrs
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
2025-11-05 21:10:33 +01:00

107 lines
2.1 KiB
Go

package vo
import (
"encoding/json"
"net"
"strings"
"github.com/phishingclub/phishingclub/errs"
)
type IPNetSlice []IPNet
// UnmarshalJSON implements custom unmarshaling for IPNetSlice
func (s *IPNetSlice) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err != nil {
return err
}
// if empty string, return empty slice (allow empty cidrs for ja4-only filters)
if strings.TrimSpace(str) == "" {
*s = IPNetSlice{}
return nil
}
strs := strings.Split(str, "\n")
// Convert each string to IPNet
result := make(IPNetSlice, 0, len(strs))
for _, cidr := range strs {
// skip empty lines
if strings.TrimSpace(cidr) == "" {
continue
}
ipnet, err := NewIPNet(cidr)
if err != nil {
return unwrapError(err)
}
result = append(result, *ipnet)
}
*s = result
return nil
}
// MarshalJSON implements custom marshaling for IPNetSlice
func (s IPNetSlice) MarshalJSON() ([]byte, error) {
if len(s) == 0 {
return json.Marshal("")
}
strs := make([]string, len(s))
for i, ipnet := range s {
strs[i] = ipnet.String()
}
return json.Marshal(
strings.Join(strs, "\n"),
)
}
type IPNet struct {
net.IPNet
}
// NewIPNet creates a new IPNet
func NewIPNet(ipNet string) (*IPNet, error) {
_, in, err := net.ParseCIDR(ipNet)
if err != nil {
return nil, errs.Wrap(err)
}
return &IPNet{
*in,
}, nil
}
// NewIPNetMust creates a new IPNet and panics if it is invalid
func NewIPNetMust(ipNet string) *IPNet {
i, err := NewIPNet(ipNet)
if err != nil {
panic(err)
}
return i
}
// MarshalJSON implements the json.Marshaler interface
func (i IPNet) MarshalJSON() ([]byte, error) {
return json.Marshal(i.String())
}
// UnmarshalJSON unmarshals the json into a string
func (i *IPNet) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err != nil {
return err
}
ss, err := NewIPNet(str)
if err != nil {
return unwrapError(err)
}
i.IPNet = ss.IPNet
return nil
}
// String returns the string representation of the IPNet
func (i IPNet) String() string {
return i.IPNet.String()
}