Skip to content

Commit bd16331

Browse files
joeybloggsjoeybloggs
authored andcommitted
Add ip, ipv4 and ipv6 validators
1 parent e078205 commit bd16331

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed

baked_in.go

Lines changed: 24 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,29 @@ var BakedInValidators = map[string]Func{
6465
"latitude": isLatitude,
6566
"longitude": isLongitude,
6667
"ssn": isSSN,
68+
"ipv4": isIPv4,
69+
"ipv6": isIPv6,
70+
"ip": isIP,
71+
}
72+
73+
func isIPv4(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
74+
75+
ip := net.ParseIP(field.String())
76+
77+
return ip != nil && ip.To4() != nil
78+
}
79+
80+
func isIPv6(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
81+
ip := net.ParseIP(field.String())
82+
83+
return ip != nil && ip.To4() == nil
84+
}
85+
86+
func isIP(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool {
87+
88+
ip := net.ParseIP(field.String())
89+
90+
return ip != nil
6791
}
6892

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

doc.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,18 @@ 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+
375387
Validator notes:
376388
377389
regex

validator_test.go

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

122+
func TestIPValidation(t *testing.T) {
123+
tests := []struct {
124+
param string
125+
expected bool
126+
}{
127+
{"10.0.0.1", true},
128+
{"172.16.0.1", true},
129+
{"192.168.0.1", true},
130+
{"192.168.255.254", true},
131+
{"192.168.255.256", false},
132+
{"172.16.255.254", true},
133+
{"172.16.256.255", false},
134+
{"2001:cdba:0000:0000:0000:0000:3257:9652", true},
135+
{"2001:cdba:0:0:0:0:3257:9652", true},
136+
{"2001:cdba::3257:9652", true},
137+
}
138+
139+
for i, test := range tests {
140+
141+
errs := validate.Field(test.param, "ip")
142+
143+
if test.expected == true {
144+
if !IsEqual(errs, nil) {
145+
t.Fatalf("Index: %d ip failed Error: %s", i, errs)
146+
}
147+
} else {
148+
if IsEqual(errs, nil) {
149+
t.Fatalf("Index: %d ip failed Error: %s", i, errs)
150+
} else {
151+
val := errs[""]
152+
if val.Tag != "ip" {
153+
t.Fatalf("Index: %d ip failed Error: %s", i, errs)
154+
}
155+
}
156+
}
157+
}
158+
}
159+
160+
func TestIPv6Validation(t *testing.T) {
161+
tests := []struct {
162+
param string
163+
expected bool
164+
}{
165+
{"10.0.0.1", false},
166+
{"172.16.0.1", false},
167+
{"192.168.0.1", false},
168+
{"192.168.255.254", false},
169+
{"192.168.255.256", false},
170+
{"172.16.255.254", false},
171+
{"172.16.256.255", false},
172+
{"2001:cdba:0000:0000:0000:0000:3257:9652", true},
173+
{"2001:cdba:0:0:0:0:3257:9652", true},
174+
{"2001:cdba::3257:9652", true},
175+
}
176+
177+
for i, test := range tests {
178+
179+
errs := validate.Field(test.param, "ipv6")
180+
181+
if test.expected == true {
182+
if !IsEqual(errs, nil) {
183+
t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
184+
}
185+
} else {
186+
if IsEqual(errs, nil) {
187+
t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
188+
} else {
189+
val := errs[""]
190+
if val.Tag != "ipv6" {
191+
t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
192+
}
193+
}
194+
}
195+
}
196+
}
197+
198+
func TestIPv4Validation(t *testing.T) {
199+
tests := []struct {
200+
param string
201+
expected bool
202+
}{
203+
{"10.0.0.1", true},
204+
{"172.16.0.1", true},
205+
{"192.168.0.1", true},
206+
{"192.168.255.254", true},
207+
{"192.168.255.256", false},
208+
{"172.16.255.254", true},
209+
{"172.16.256.255", false},
210+
{"2001:cdba:0000:0000:0000:0000:3257:9652", false},
211+
{"2001:cdba:0:0:0:0:3257:9652", false},
212+
{"2001:cdba::3257:9652", false},
213+
}
214+
215+
for i, test := range tests {
216+
217+
errs := validate.Field(test.param, "ipv4")
218+
219+
if test.expected == true {
220+
if !IsEqual(errs, nil) {
221+
t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
222+
}
223+
} else {
224+
if IsEqual(errs, nil) {
225+
t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
226+
} else {
227+
val := errs[""]
228+
if val.Tag != "ipv4" {
229+
t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
230+
}
231+
}
232+
}
233+
}
234+
}
235+
122236
func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
123237

124238
var m map[string]string

0 commit comments

Comments
 (0)