From bd16331fc0de0f558c0c7c76009b88b3d7052219 Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Mon, 27 Jul 2015 22:31:33 -0400 Subject: [PATCH 1/2] Add ip, ipv4 and ipv6 validators --- baked_in.go | 24 ++++++++++ doc.go | 12 +++++ validator_test.go | 114 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) diff --git a/baked_in.go b/baked_in.go index 9bbf399..95a7431 100644 --- a/baked_in.go +++ b/baked_in.go @@ -2,6 +2,7 @@ package validator import ( "fmt" + "net" "net/url" "reflect" "strconv" @@ -64,6 +65,29 @@ var BakedInValidators = map[string]Func{ "latitude": isLatitude, "longitude": isLongitude, "ssn": isSSN, + "ipv4": isIPv4, + "ipv6": isIPv6, + "ip": isIP, +} + +func isIPv4(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + ip := net.ParseIP(field.String()) + + return ip != nil && ip.To4() != nil +} + +func isIPv6(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + ip := net.ParseIP(field.String()) + + return ip != nil && ip.To4() == nil +} + +func isIP(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + ip := net.ParseIP(field.String()) + + return ip != nil } func isSSN(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { diff --git a/doc.go b/doc.go index 82804b8..e81d6c2 100644 --- a/doc.go +++ b/doc.go @@ -372,6 +372,18 @@ Here is a list of the current built in validators: This validates that a string value contains a valid U.S. Social Security Number. (Usage: ssn) + ip + This validates that a string value contains a valid IP Adress. + (Usage: ip) + + ipv4 + This validates that a string value contains a valid v4 IP Adress. + (Usage: ipv4) + + ipv6 + This validates that a string value contains a valid v6 IP Adress. + (Usage: ipv6) + Validator notes: regex diff --git a/validator_test.go b/validator_test.go index 6048606..87e0716 100644 --- a/validator_test.go +++ b/validator_test.go @@ -119,6 +119,120 @@ func AssertError(t *testing.T, errs ValidationErrors, key, field, expectedTag st EqualSkip(t, 2, val.Tag, expectedTag) } +func TestIPValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"10.0.0.1", true}, + {"172.16.0.1", true}, + {"192.168.0.1", true}, + {"192.168.255.254", true}, + {"192.168.255.256", false}, + {"172.16.255.254", true}, + {"172.16.256.255", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652", true}, + {"2001:cdba:0:0:0:0:3257:9652", true}, + {"2001:cdba::3257:9652", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ip") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ip failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ip failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "ip" { + t.Fatalf("Index: %d ip failed Error: %s", i, errs) + } + } + } + } +} + +func TestIPv6Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"10.0.0.1", false}, + {"172.16.0.1", false}, + {"192.168.0.1", false}, + {"192.168.255.254", false}, + {"192.168.255.256", false}, + {"172.16.255.254", false}, + {"172.16.256.255", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652", true}, + {"2001:cdba:0:0:0:0:3257:9652", true}, + {"2001:cdba::3257:9652", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ipv6") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "ipv6" { + t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs) + } + } + } + } +} + +func TestIPv4Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"10.0.0.1", true}, + {"172.16.0.1", true}, + {"192.168.0.1", true}, + {"192.168.255.254", true}, + {"192.168.255.256", false}, + {"172.16.255.254", true}, + {"172.16.256.255", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652", false}, + {"2001:cdba:0:0:0:0:3257:9652", false}, + {"2001:cdba::3257:9652", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ipv4") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "ipv4" { + t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs) + } + } + } + } +} + func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) { var m map[string]string From 143b21eba1ed00e1e204970f6d6a11bcd18a2380 Mon Sep 17 00:00:00 2001 From: joeybloggs Date: Mon, 27 Jul 2015 22:45:59 -0400 Subject: [PATCH 2/2] Add mac validator --- baked_in.go | 6 ++++++ doc.go | 6 ++++++ validator_test.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/baked_in.go b/baked_in.go index 95a7431..b323863 100644 --- a/baked_in.go +++ b/baked_in.go @@ -68,6 +68,12 @@ var BakedInValidators = map[string]Func{ "ipv4": isIPv4, "ipv6": isIPv6, "ip": isIP, + "mac": isMac, +} + +func isMac(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + _, err := net.ParseMAC(field.String()) + return err == nil } func isIPv4(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { diff --git a/doc.go b/doc.go index e81d6c2..ba60177 100644 --- a/doc.go +++ b/doc.go @@ -384,6 +384,12 @@ Here is a list of the current built in validators: This validates that a string value contains a valid v6 IP Adress. (Usage: ipv6) + mac + This validates that a string value contains a valid MAC Adress defined + by go's ParseMAC accepted formats and types see: + http://golang.org/src/net/mac.go?s=866:918#L29 + (Usage: mac) + Validator notes: regex diff --git a/validator_test.go b/validator_test.go index 87e0716..d69c1a2 100644 --- a/validator_test.go +++ b/validator_test.go @@ -119,6 +119,41 @@ func AssertError(t *testing.T, errs ValidationErrors, key, field, expectedTag st EqualSkip(t, 2, val.Tag, expectedTag) } +func TestMACValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"3D:F2:C9:A6:B3:4F", true}, + {"3D-F2-C9-A6-B3:4F", false}, + {"123", false}, + {"", false}, + {"abacaba", false}, + {"00:25:96:FF:FE:12:34:56", true}, + {"0025:96FF:FE12:3456", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "mac") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d mac failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d mac failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "mac" { + t.Fatalf("Index: %d mac failed Error: %s", i, errs) + } + } + } + } +} + func TestIPValidation(t *testing.T) { tests := []struct { param string