Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URN (RFC 2141) validation #429

Merged
merged 3 commits into from
Dec 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions baked_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"crypto/sha256"
"fmt"
urn "github.com/leodido/go-urn"
"net"
"net/url"
"os"
Expand Down Expand Up @@ -98,6 +99,7 @@ var (
"email": isEmail,
"url": isURL,
"uri": isURI,
"urn_rfc2141": isUrnRFC2141, // RFC 2141
"file": isFile,
"base64": isBase64,
"base64url": isBase64URL,
Expand Down Expand Up @@ -1077,6 +1079,24 @@ func isURL(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}

// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
func isUrnRFC2141(fl FieldLevel) bool {
field := fl.Field()

switch field.Kind() {

case reflect.String:

str := field.String()

_, match := urn.Parse([]byte(str))

return match
}

panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}

// IsFile is the validation function for validating if the current field's value is a valid file path.
func isFile(fl FieldLevel) bool {
field := fl.Field()
Expand Down
7 changes: 7 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,13 @@ This will accept any uri the golang request uri accepts

Usage: uri

Urn RFC 2141 String

This validataes that a string value contains a valid URN
according to the RFC 2141 spec.

Usage: urn_rfc2141

Base64 String

This validates that a string value contains a valid base64 value.
Expand Down
77 changes: 77 additions & 0 deletions validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5748,6 +5748,83 @@ func TestIsLte(t *testing.T) {
NotEqual(t, errs, nil)
}

func TestUrnRFC2141(t *testing.T) {

var tests = []struct {
param string
expected bool
}{
{"urn:a:b", true},
{"urn:a::", true},
{"urn:a:-", true},
{"URN:simple:simple", true},
{"urn:urna:simple", true},
{"urn:burnout:nss", true},
{"urn:burn:nss", true},
{"urn:urnurnurn:x", true},
{"urn:abcdefghilmnopqrstuvzabcdefghilm:x", true},
{"URN:123:x", true},
{"URN:abcd-:x", true},
{"URN:abcd-abcd:x", true},
{"urn:urnx:urn", true},
{"urn:ciao:a:b:c", true},
{"urn:aaa:x:y:", true},
{"urn:ciao:-", true},
{"urn:colon:::::nss", true},
{"urn:ciao:@!=%2C(xyz)+a,b.*@g=$_'", true},
{"URN:hexes:%25", true},
{"URN:x:abc%1Dz%2F%3az", true},
{"URN:foo:a123,456", true},
{"urn:foo:a123,456", true},
{"urn:FOO:a123,456", true},
{"urn:foo:A123,456", true},
{"urn:foo:a123%2C456", true},
{"URN:FOO:a123%2c456", true},
{"URN:FOO:ABC%FFabc123%2c456", true},
{"URN:FOO:ABC%FFabc123%2C456%9A", true},
{"urn:ietf:params:scim:schemas:core:2.0:User", true},
{"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:meta.lastModified", true},
{"URN:-xxx:x", false},
{"urn::colon:nss", false},
{"urn:abcdefghilmnopqrstuvzabcdefghilmn:specificstring", false},
{"URN:a!?:x", false},
{"URN:#,:x", false},
{"urn:urn:NSS", false},
{"urn:URN:NSS", false},
{"urn:white space:NSS", false},
{"urn:concat:no spaces", false},
{"urn:a:%", false},
{"urn:", false},
}

tag := "urn_rfc2141"

validate := New()

for i, test := range tests {

errs := validate.Var(test.param, tag)

if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d URN failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d URN failed Error: %s", i, errs)
} else {
val := getError(errs, "", "")
if val.Tag() != tag {
t.Fatalf("Index: %d URN failed Error: %s", i, errs)
}
}
}
}

i := 1
PanicMatches(t, func() { validate.Var(i, tag) }, "Bad field type int")
}

func TestUrl(t *testing.T) {

var tests = []struct {
Expand Down