Merge pull request #234 from go-playground/krhubert

Add validation functions for tcp/udp/ip/unix addresses
pull/235/head v8.16
Dean Karn 9 years ago
commit 4c79e69823
  1. 157
      baked_in.go
  2. 62
      doc.go
  3. 321
      validator_test.go

@ -84,6 +84,16 @@ var bakedInValidators = map[string]Func{
"cidrv4": IsCIDRv4,
"cidrv6": IsCIDRv6,
"cidr": IsCIDR,
"tcp4_addr": IsTCP4AddrResolvable,
"tcp6_addr": IsTCP6AddrResolvable,
"tcp_addr": IsTCPAddrResolvable,
"udp4_addr": IsUDP4AddrResolvable,
"udp6_addr": IsUDP6AddrResolvable,
"udp_addr": IsUDPAddrResolvable,
"ip4_addr": IsIP4AddrResolvable,
"ip6_addr": IsIP6AddrResolvable,
"ip_addr": IsIPAddrResolvable,
"unix_addr": IsUnixAddrResolvable,
"mac": IsMAC,
}
@ -1236,3 +1246,150 @@ func IsLt(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Val
func HasMaxOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
return IsLte(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param)
}
// IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsTCP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
return false
}
_, err := net.ResolveTCPAddr("tcp4", field.String())
return err == nil
}
// IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsTCP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
return false
}
_, err := net.ResolveTCPAddr("tcp6", field.String())
return err == nil
}
// IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsTCPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) &&
!isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
return false
}
_, err := net.ResolveTCPAddr("tcp", field.String())
return err == nil
}
// IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsUDP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
return false
}
_, err := net.ResolveUDPAddr("udp4", field.String())
return err == nil
}
// IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsUDP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
return false
}
_, err := net.ResolveUDPAddr("udp6", field.String())
return err == nil
}
// IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsUDPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) &&
!isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
return false
}
_, err := net.ResolveUDPAddr("udp", field.String())
return err == nil
}
// IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsIP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if !IsIPv4(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
return false
}
_, err := net.ResolveIPAddr("ip4", field.String())
return err == nil
}
// IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsIP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if !IsIPv6(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
return false
}
_, err := net.ResolveIPAddr("ip6", field.String())
return err == nil
}
// IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsIPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
if !IsIP(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) {
return false
}
_, err := net.ResolveIPAddr("ip", field.String())
return err == nil
}
// IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
func IsUnixAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
_, err := net.ResolveUnixAddr("unix", field.String())
return err == nil
}
func isIP4Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
val := field.String()
if idx := strings.LastIndex(val, ":"); idx != -1 {
val = val[0:idx]
}
if !IsIPv4(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) {
return false
}
return true
}
func isIP6Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
val := field.String()
if idx := strings.LastIndex(val, ":"); idx != -1 {
if idx != 0 && val[idx-1:idx] == "]" {
val = val[1 : idx-1]
}
}
if !IsIPv6(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) {
return false
}
return true
}

@ -735,6 +735,66 @@ This validates that a string value contains a valid v6 CIDR Adress.
Usage: cidrv6
Transmission Control Protocol Address TCP
This validates that a string value contains a valid resolvable TCP Adress.
Usage: tcp_addr
Transmission Control Protocol Address TCPv4
This validates that a string value contains a valid resolvable v4 TCP Adress.
Usage: tcp4_addr
Transmission Control Protocol Address TCPv6
This validates that a string value contains a valid resolvable v6 TCP Adress.
Usage: tcp6_addr
User Datagram Protocol Address UDP
This validates that a string value contains a valid resolvable UDP Adress.
Usage: udp_addr
User Datagram Protocol Address UDPv4
This validates that a string value contains a valid resolvable v4 UDP Adress.
Usage: udp4_addr
User Datagram Protocol Address UDPv6
This validates that a string value contains a valid resolvable v6 UDP Adress.
Usage: udp6_addr
Internet Protocol Address IP
This validates that a string value contains a valid resolvable IP Adress.
Usage: ip_addr
Internet Protocol Address IPv4
This validates that a string value contains a valid resolvable v4 IP Adress.
Usage: ip4_addr
Internet Protocol Address IPv6
This validates that a string value contains a valid resolvable v6 IP Adress.
Usage: ip6_addr
Unix domain socket end point Address
This validates that a string value contains a valid Unix Adress.
Usage: unix_addr
Media Access Control Address MAC
This validates that a string value contains a valid MAC Adress.
@ -745,8 +805,6 @@ Note: See Go's ParseMAC for accepted formats and types:
http://golang.org/src/net/mac.go?s=866:918#L29
Usage: mac
Alias Validators and Tags
NOTE: When returning an error, the tag returned in "FieldError" will be

@ -1755,6 +1755,7 @@ func TestIPValidation(t *testing.T) {
param string
expected bool
}{
{"", false},
{"10.0.0.1", true},
{"172.16.0.1", true},
{"192.168.0.1", true},
@ -1987,6 +1988,326 @@ func TestCIDRv4Validation(t *testing.T) {
}
}
func TestTCPAddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", false},
{":80", false},
{"127.0.0.1:80", true},
{"[::1]:80", true},
{"256.0.0.0:1", false},
{"[::1]", false},
}
for i, test := range tests {
errs := validate.Field(test.param, "tcp_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "tcp_addr" {
t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestTCP6AddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", false},
{":80", false},
{"127.0.0.1:80", false},
{"[::1]:80", true},
{"256.0.0.0:1", false},
{"[::1]", false},
}
for i, test := range tests {
errs := validate.Field(test.param, "tcp6_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "tcp6_addr" {
t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestTCP4AddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", false},
{":80", false},
{"127.0.0.1:80", true},
{"[::1]:80", false}, // https://github.com/golang/go/issues/14037
{"256.0.0.0:1", false},
{"[::1]", false},
}
for i, test := range tests {
errs := validate.Field(test.param, "tcp4_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Log(test.param, IsEqual(errs, nil))
t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "tcp4_addr" {
t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestUDPAddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", false},
{":80", false},
{"127.0.0.1:80", true},
{"[::1]:80", true},
{"256.0.0.0:1", false},
{"[::1]", false},
}
for i, test := range tests {
errs := validate.Field(test.param, "udp_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "udp_addr" {
t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestUDP6AddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", false},
{":80", false},
{"127.0.0.1:80", false},
{"[::1]:80", true},
{"256.0.0.0:1", false},
{"[::1]", false},
}
for i, test := range tests {
errs := validate.Field(test.param, "udp6_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "udp6_addr" {
t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestUDP4AddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", false},
{":80", false},
{"127.0.0.1:80", true},
{"[::1]:80", false}, // https://github.com/golang/go/issues/14037
{"256.0.0.0:1", false},
{"[::1]", false},
}
for i, test := range tests {
errs := validate.Field(test.param, "udp4_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Log(test.param, IsEqual(errs, nil))
t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "udp4_addr" {
t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestIPAddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", false},
{"127.0.0.1", true},
{"127.0.0.1:80", false},
{"::1", true},
{"256.0.0.0", false},
{"localhost", false},
}
for i, test := range tests {
errs := validate.Field(test.param, "ip_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "ip_addr" {
t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestIP6AddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", false},
{"127.0.0.1", false}, // https://github.com/golang/go/issues/14037
{"127.0.0.1:80", false},
{"::1", true},
{"0:0:0:0:0:0:0:1", true},
{"256.0.0.0", false},
}
for i, test := range tests {
errs := validate.Field(test.param, "ip6_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "ip6_addr" {
t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestIP4AddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", false},
{"127.0.0.1", true},
{"127.0.0.1:80", false},
{"::1", false}, // https://github.com/golang/go/issues/14037
{"256.0.0.0", false},
{"localhost", false},
}
for i, test := range tests {
errs := validate.Field(test.param, "ip4_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Log(test.param, IsEqual(errs, nil))
t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "ip4_addr" {
t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestUnixAddrValidation(t *testing.T) {
tests := []struct {
param string
expected bool
}{
{"", true},
{"v.sock", true},
}
for i, test := range tests {
errs := validate.Field(test.param, "unix_addr")
if test.expected == true {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Log(test.param, IsEqual(errs, nil))
t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
} else {
val := errs.(ValidationErrors)[""]
if val.Tag != "unix_addr" {
t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
}
}
}
}
}
func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
var m map[string]string

Loading…
Cancel
Save