From c5423e411681fbf1b24845dd95f777c270ba0ac5 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 4 Dec 2018 03:33:00 +0100 Subject: [PATCH 1/3] New: URN Signed-off-by: Leonardo Di Donato --- baked_in.go | 20 +++++++++++++ doc.go | 5 ++++ validator_test.go | 75 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/baked_in.go b/baked_in.go index 51b65f4..1fd3743 100644 --- a/baked_in.go +++ b/baked_in.go @@ -5,6 +5,7 @@ import ( "context" "crypto/sha256" "fmt" + urn "github.com/leodido/go-urn" "net" "net/url" "os" @@ -98,6 +99,7 @@ var ( "email": isEmail, "url": isURL, "uri": isURI, + "urn": isURN, // RFC 2141 "file": isFile, "base64": isBase64, "base64url": isBase64URL, @@ -1077,6 +1079,24 @@ func isURL(fl FieldLevel) bool { panic(fmt.Sprintf("Bad field type %T", field.Interface())) } +// isUrn is the validation function for validating if the current field's value is a valid URN as per RFC 2141. +func isURN(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() diff --git a/doc.go b/doc.go index 25bf2e7..be36368 100644 --- a/doc.go +++ b/doc.go @@ -610,6 +610,11 @@ This will accept any uri the golang request uri accepts Usage: uri +URN String + +This validataes that a string valud contains a valid URN +according to the RFC 2141 spec. + Base64 String This validates that a string value contains a valid base64 value. diff --git a/validator_test.go b/validator_test.go index 3a4b8f0..a9bcb54 100644 --- a/validator_test.go +++ b/validator_test.go @@ -5748,6 +5748,81 @@ func TestIsLte(t *testing.T) { NotEqual(t, errs, nil) } +func TestUrn(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}, + } + + validate := New() + + for i, test := range tests { + + errs := validate.Var(test.param, "urn") + + 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() != "urn" { + t.Fatalf("Index: %d URN failed Error: %s", i, errs) + } + } + } + } + + i := 1 + PanicMatches(t, func() { validate.Var(i, "urn") }, "Bad field type int") +} + func TestUrl(t *testing.T) { var tests = []struct { From 0482874b86ffbffda291b855d8a77fe5021f5126 Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 4 Dec 2018 10:35:01 +0100 Subject: [PATCH 2/3] Update: Rename urn tag into urn_rfc2141 Signed-off-by: Leonardo Di Donato --- baked_in.go | 6 +++--- validator_test.go | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/baked_in.go b/baked_in.go index 1fd3743..2a086fd 100644 --- a/baked_in.go +++ b/baked_in.go @@ -99,7 +99,7 @@ var ( "email": isEmail, "url": isURL, "uri": isURI, - "urn": isURN, // RFC 2141 + "urn_rfc2141": isUrnRFC2141, // RFC 2141 "file": isFile, "base64": isBase64, "base64url": isBase64URL, @@ -1079,8 +1079,8 @@ func isURL(fl FieldLevel) bool { panic(fmt.Sprintf("Bad field type %T", field.Interface())) } -// isUrn is the validation function for validating if the current field's value is a valid URN as per RFC 2141. -func isURN(fl FieldLevel) bool { +// 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() { diff --git a/validator_test.go b/validator_test.go index a9bcb54..7213d9b 100644 --- a/validator_test.go +++ b/validator_test.go @@ -5748,7 +5748,7 @@ func TestIsLte(t *testing.T) { NotEqual(t, errs, nil) } -func TestUrn(t *testing.T) { +func TestUrnRFC2141(t *testing.T) { var tests = []struct { param string @@ -5797,11 +5797,13 @@ func TestUrn(t *testing.T) { {"urn:", false}, } + tag := "urn_rfc2141" + validate := New() for i, test := range tests { - errs := validate.Var(test.param, "urn") + errs := validate.Var(test.param, tag) if test.expected { if !IsEqual(errs, nil) { @@ -5812,7 +5814,7 @@ func TestUrn(t *testing.T) { t.Fatalf("Index: %d URN failed Error: %s", i, errs) } else { val := getError(errs, "", "") - if val.Tag() != "urn" { + if val.Tag() != tag { t.Fatalf("Index: %d URN failed Error: %s", i, errs) } } @@ -5820,7 +5822,7 @@ func TestUrn(t *testing.T) { } i := 1 - PanicMatches(t, func() { validate.Var(i, "urn") }, "Bad field type int") + PanicMatches(t, func() { validate.Var(i, tag) }, "Bad field type int") } func TestUrl(t *testing.T) { From 2bb313f95735d276c6d98def272c6efc9b16760b Mon Sep 17 00:00:00 2001 From: Leonardo Di Donato Date: Tue, 4 Dec 2018 14:47:31 +0100 Subject: [PATCH 3/3] Docs: Update URN RFC2141 documentation Signed-off-by: Leonardo Di Donato --- doc.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc.go b/doc.go index be36368..dd4fde6 100644 --- a/doc.go +++ b/doc.go @@ -610,11 +610,13 @@ This will accept any uri the golang request uri accepts Usage: uri -URN String +Urn RFC 2141 String -This validataes that a string valud contains a valid URN +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.