Skip to content

Commit d529ee1

Browse files
author
Dean Karn
authored
Merge pull request #298 from senuphtyz/v9
Append new validations hostname and fqdn
2 parents 44d9acf + dbd50b3 commit d529ee1

File tree

4 files changed

+125
-0
lines changed

4 files changed

+125
-0
lines changed

baked_in.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ var (
125125
"ip_addr": isIPAddrResolvable,
126126
"unix_addr": isUnixAddrResolvable,
127127
"mac": isMAC,
128+
"hostname": isHostname,
129+
"fqdn": isFQDN,
128130
}
129131
)
130132

@@ -1477,3 +1479,18 @@ func isIP6Addr(fl FieldLevel) bool {
14771479

14781480
return ip != nil && ip.To4() == nil
14791481
}
1482+
1483+
func isHostname(fl FieldLevel) bool {
1484+
return hostnameRegex.MatchString(fl.Field().String())
1485+
}
1486+
1487+
func isFQDN(fl FieldLevel) bool {
1488+
val := fl.Field().String()
1489+
1490+
if val[len(val)-1] == '.' {
1491+
val = val[0 : len(val)-1]
1492+
}
1493+
1494+
return (strings.IndexAny(val, ".") > -1) &&
1495+
hostnameRegex.MatchString(val)
1496+
}

doc.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,18 @@ Note: See Go's ParseMAC for accepted formats and types:
794794
795795
http://golang.org/src/net/mac.go?s=866:918#L29
796796
797+
Hostname
798+
799+
This validates that a string value is a valid Hostname
800+
801+
Usage: hostname
802+
803+
Full Qualified Domain Name (FQDN)
804+
805+
This validates that a string value contains a valid FQDN.
806+
807+
Usage: fqdn
808+
797809
Alias Validators and Tags
798810
799811
NOTE: When returning an error, the tag returned in "FieldError" will be

regexes.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const (
3030
latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
3131
longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
3232
sSNRegexString = `^\d{3}[- ]?\d{2}[- ]?\d{4}$`
33+
hostnameRegexString = `^[a-zA-Z][a-zA-Z0-9\-\.]+[a-z-Az0-9]$`
3334
)
3435

3536
var (
@@ -60,4 +61,5 @@ var (
6061
latitudeRegex = regexp.MustCompile(latitudeRegexString)
6162
longitudeRegex = regexp.MustCompile(longitudeRegexString)
6263
sSNRegex = regexp.MustCompile(sSNRegexString)
64+
hostnameRegex = regexp.MustCompile(hostnameRegexString)
6365
)

validator_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7119,3 +7119,97 @@ func TestValidateStructRegisterCtx(t *testing.T) {
71197119
Equal(t, ctxVal, "testval")
71207120
Equal(t, ctxSlVal, "slVal")
71217121
}
7122+
7123+
func TestHostnameValidation(t *testing.T) {
7124+
tests := []struct {
7125+
param string
7126+
expected bool
7127+
}{
7128+
{"test.example.com", true},
7129+
{"example.com", true},
7130+
{"example24.com", true},
7131+
{"test.example24.com", true},
7132+
{"test24.example24.com", true},
7133+
{"example", true},
7134+
{"test.example.com.", false},
7135+
{"example.com.", false},
7136+
{"example24.com.", false},
7137+
{"test.example24.com.", false},
7138+
{"test24.example24.com.", false},
7139+
{"example.", false},
7140+
{"192.168.0.1", false},
7141+
{"[email protected]", false},
7142+
{"2001:cdba:0000:0000:0000:0000:3257:9652", false},
7143+
{"2001:cdba:0:0:0:0:3257:9652", false},
7144+
{"2001:cdba::3257:9652", false},
7145+
}
7146+
7147+
validate := New()
7148+
7149+
for i, test := range tests {
7150+
7151+
errs := validate.Var(test.param, "hostname")
7152+
7153+
if test.expected {
7154+
if !IsEqual(errs, nil) {
7155+
t.Fatalf("Index: %d hostname failed Error: %s", i, errs)
7156+
}
7157+
} else {
7158+
if IsEqual(errs, nil) {
7159+
t.Fatalf("Index: %d hostname failed Error: %s", i, errs)
7160+
} else {
7161+
val := getError(errs, "", "")
7162+
if val.Tag() != "hostname" {
7163+
t.Fatalf("Index: %d hostname failed Error: %s", i, errs)
7164+
}
7165+
}
7166+
}
7167+
}
7168+
}
7169+
7170+
func TestFQDNValidation(t *testing.T) {
7171+
tests := []struct {
7172+
param string
7173+
expected bool
7174+
}{
7175+
{"test.example.com", true},
7176+
{"example.com", true},
7177+
{"example24.com", true},
7178+
{"test.example24.com", true},
7179+
{"test24.example24.com", true},
7180+
{"test.example.com.", true},
7181+
{"example.com.", true},
7182+
{"example24.com.", true},
7183+
{"test.example24.com.", true},
7184+
{"test24.example24.com.", true},
7185+
{"test24.example24.com..", false},
7186+
{"example", false},
7187+
{"192.168.0.1", false},
7188+
{"[email protected]", false},
7189+
{"2001:cdba:0000:0000:0000:0000:3257:9652", false},
7190+
{"2001:cdba:0:0:0:0:3257:9652", false},
7191+
{"2001:cdba::3257:9652", false},
7192+
}
7193+
7194+
validate := New()
7195+
7196+
for i, test := range tests {
7197+
7198+
errs := validate.Var(test.param, "fqdn")
7199+
7200+
if test.expected {
7201+
if !IsEqual(errs, nil) {
7202+
t.Fatalf("Index: %d fqdn failed Error: %s", i, errs)
7203+
}
7204+
} else {
7205+
if IsEqual(errs, nil) {
7206+
t.Fatalf("Index: %d fqdn failed Error: %s", i, errs)
7207+
} else {
7208+
val := getError(errs, "", "")
7209+
if val.Tag() != "fqdn" {
7210+
t.Fatalf("Index: %d fqdn failed Error: %s", i, errs)
7211+
}
7212+
}
7213+
}
7214+
}
7215+
}

0 commit comments

Comments
 (0)