Skip to content

Commit 55e8c8d

Browse files
Dean KarnDean Karn
authored andcommitted
Merge pull request #129 from bluesuncorp/v6-development
Add ip, ipv4, ipv6 and mac validators
2 parents c000117 + a7e8a12 commit 55e8c8d

File tree

3 files changed

+197
-0
lines changed

3 files changed

+197
-0
lines changed

baked_in.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package validator
22

33
import (
44
"fmt"
5+
"net"
56
"net/url"
67
"reflect"
78
"strconv"
@@ -64,6 +65,35 @@ var BakedInValidators = map[string]Func{
6465
"latitude": isLatitude,
6566
"longitude": isLongitude,
6667
"ssn": isSSN,
68+
"ipv4": isIPv4,
69+
"ipv6": isIPv6,
70+
"ip": isIP,
71+
"mac": isMac,
72+
}
73+
74+
func isMac(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
75+
_, err := net.ParseMAC(field.String())
76+
return err == nil
77+
}
78+
79+
func isIPv4(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
80+
81+
ip := net.ParseIP(field.String())
82+
83+
return ip != nil && ip.To4() != nil
84+
}
85+
86+
func isIPv6(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
87+
ip := net.ParseIP(field.String())
88+
89+
return ip != nil && ip.To4() == nil
90+
}
91+
92+
func isIP(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
93+
94+
ip := net.ParseIP(field.String())
95+
96+
return ip != nil
6797
}
6898

6999
func isSSN(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {

doc.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,24 @@ Here is a list of the current built in validators:
372372
This validates that a string value contains a valid U.S. Social Security Number.
373373
(Usage: ssn)
374374
375+
ip
376+
This validates that a string value contains a valid IP Adress.
377+
(Usage: ip)
378+
379+
ipv4
380+
This validates that a string value contains a valid v4 IP Adress.
381+
(Usage: ipv4)
382+
383+
ipv6
384+
This validates that a string value contains a valid v6 IP Adress.
385+
(Usage: ipv6)
386+
387+
mac
388+
This validates that a string value contains a valid MAC Adress defined
389+
by go's ParseMAC accepted formats and types see:
390+
http://golang.org/src/net/mac.go?s=866:918#L29
391+
(Usage: mac)
392+
375393
Validator notes:
376394
377395
regex

validator_test.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,155 @@ func AssertError(t *testing.T, errs ValidationErrors, key, field, expectedTag st
119119
EqualSkip(t, 2, val.Tag, expectedTag)
120120
}
121121

122+
func TestMACValidation(t *testing.T) {
123+
tests := []struct {
124+
param string
125+
expected bool
126+
}{
127+
{"3D:F2:C9:A6:B3:4F", true},
128+
{"3D-F2-C9-A6-B3:4F", false},
129+
{"123", false},
130+
{"", false},
131+
{"abacaba", false},
132+
{"00:25:96:FF:FE:12:34:56", true},
133+
{"0025:96FF:FE12:3456", false},
134+
}
135+
136+
for i, test := range tests {
137+
138+
errs := validate.Field(test.param, "mac")
139+
140+
if test.expected == true {
141+
if !IsEqual(errs, nil) {
142+
t.Fatalf("Index: %d mac failed Error: %s", i, errs)
143+
}
144+
} else {
145+
if IsEqual(errs, nil) {
146+
t.Fatalf("Index: %d mac failed Error: %s", i, errs)
147+
} else {
148+
val := errs[""]
149+
if val.Tag != "mac" {
150+
t.Fatalf("Index: %d mac failed Error: %s", i, errs)
151+
}
152+
}
153+
}
154+
}
155+
}
156+
157+
func TestIPValidation(t *testing.T) {
158+
tests := []struct {
159+
param string
160+
expected bool
161+
}{
162+
{"10.0.0.1", true},
163+
{"172.16.0.1", true},
164+
{"192.168.0.1", true},
165+
{"192.168.255.254", true},
166+
{"192.168.255.256", false},
167+
{"172.16.255.254", true},
168+
{"172.16.256.255", false},
169+
{"2001:cdba:0000:0000:0000:0000:3257:9652", true},
170+
{"2001:cdba:0:0:0:0:3257:9652", true},
171+
{"2001:cdba::3257:9652", true},
172+
}
173+
174+
for i, test := range tests {
175+
176+
errs := validate.Field(test.param, "ip")
177+
178+
if test.expected == true {
179+
if !IsEqual(errs, nil) {
180+
t.Fatalf("Index: %d ip failed Error: %s", i, errs)
181+
}
182+
} else {
183+
if IsEqual(errs, nil) {
184+
t.Fatalf("Index: %d ip failed Error: %s", i, errs)
185+
} else {
186+
val := errs[""]
187+
if val.Tag != "ip" {
188+
t.Fatalf("Index: %d ip failed Error: %s", i, errs)
189+
}
190+
}
191+
}
192+
}
193+
}
194+
195+
func TestIPv6Validation(t *testing.T) {
196+
tests := []struct {
197+
param string
198+
expected bool
199+
}{
200+
{"10.0.0.1", false},
201+
{"172.16.0.1", false},
202+
{"192.168.0.1", false},
203+
{"192.168.255.254", false},
204+
{"192.168.255.256", false},
205+
{"172.16.255.254", false},
206+
{"172.16.256.255", false},
207+
{"2001:cdba:0000:0000:0000:0000:3257:9652", true},
208+
{"2001:cdba:0:0:0:0:3257:9652", true},
209+
{"2001:cdba::3257:9652", true},
210+
}
211+
212+
for i, test := range tests {
213+
214+
errs := validate.Field(test.param, "ipv6")
215+
216+
if test.expected == true {
217+
if !IsEqual(errs, nil) {
218+
t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
219+
}
220+
} else {
221+
if IsEqual(errs, nil) {
222+
t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
223+
} else {
224+
val := errs[""]
225+
if val.Tag != "ipv6" {
226+
t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
227+
}
228+
}
229+
}
230+
}
231+
}
232+
233+
func TestIPv4Validation(t *testing.T) {
234+
tests := []struct {
235+
param string
236+
expected bool
237+
}{
238+
{"10.0.0.1", true},
239+
{"172.16.0.1", true},
240+
{"192.168.0.1", true},
241+
{"192.168.255.254", true},
242+
{"192.168.255.256", false},
243+
{"172.16.255.254", true},
244+
{"172.16.256.255", false},
245+
{"2001:cdba:0000:0000:0000:0000:3257:9652", false},
246+
{"2001:cdba:0:0:0:0:3257:9652", false},
247+
{"2001:cdba::3257:9652", false},
248+
}
249+
250+
for i, test := range tests {
251+
252+
errs := validate.Field(test.param, "ipv4")
253+
254+
if test.expected == true {
255+
if !IsEqual(errs, nil) {
256+
t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
257+
}
258+
} else {
259+
if IsEqual(errs, nil) {
260+
t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
261+
} else {
262+
val := errs[""]
263+
if val.Tag != "ipv4" {
264+
t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
265+
}
266+
}
267+
}
268+
}
269+
}
270+
122271
func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
123272

124273
var m map[string]string

0 commit comments

Comments
 (0)