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

Add spec validators for the WRP messages (BAD BRANCH) #82

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
dfeee98
Add VSCode to .gitignore
denopink May 24, 2022
7f8bad0
Initial WRP Validation Framework
denopink May 25, 2022
9319c12
formatting
denopink May 25, 2022
209ffdb
formatting
denopink May 25, 2022
ddd0acf
convert alwaysInvalidMsg to literal func
denopink May 25, 2022
a2a4093
Formating and exported alwaysInvalidMsg
denopink May 25, 2022
f5a2e90
Decouple error from api
denopink May 25, 2022
eb5bf9b
Updates based on PR review
denopink May 26, 2022
afa08cb
removed duplicated test
denopink May 26, 2022
8cb0fa7
Fix type test name
denopink May 26, 2022
10afaa2
Fix type test name
denopink May 26, 2022
1923ec7
Add missing test/edge cases for Validators
denopink May 26, 2022
98c4b4a
Updated defaultValidator to work as a variadic for multi-default supp…
denopink May 26, 2022
3197568
rename test var `name` to `description`
denopink May 26, 2022
1ee6c2e
Merge branch 'denopink/FR-WRPValidationFramework' of https://github.c…
denopink May 26, 2022
9208a8f
update examples
denopink May 26, 2022
f80ac92
Doc/var update
denopink May 26, 2022
c0cceaa
Add test for `Nil default Validators` edge case
denopink May 26, 2022
7e454c4
update examples output
denopink May 26, 2022
1909c2a
doc update
denopink May 26, 2022
ee29bf3
formatting
denopink May 26, 2022
607066e
Updates based on PR review
denopink May 31, 2022
d943b60
Add multierr to Validator
denopink Jun 1, 2022
793d6f4
Squash: examples, docs, multierr updates
denopink May 26, 2022
22ca097
formatting
denopink Jun 3, 2022
7c8a66f
Merge branch 'denopink/FR-WRPValidationFramework' into denopink/featu…
denopink Jun 3, 2022
5ff49e3
Add missing test for `AlwaysValid` func
denopink Jun 3, 2022
6f3eb8d
Merge branch 'denopink/FR-WRPValidationFramework' into denopink/featu…
denopink Jun 3, 2022
25d4468
First pass of spec validators
denopink Jun 3, 2022
b2c6baa
Add an example for SpecValidators
denopink Jun 3, 2022
8ec49b1
Remove println from UTF8 validate func
denopink Jun 3, 2022
2e2cd23
Add missing tests for MessageType
denopink Jun 3, 2022
8e83772
Update docs
denopink Jun 3, 2022
87a8481
Updates based on PR Feedback
denopink Jun 6, 2022
1f1aa67
Updates based on PR feedback
denopink Jun 7, 2022
1645a22
Update testUTF8Validator test and rename var `value` to `msg` for Mes…
denopink Jun 7, 2022
df7e2ff
Update based on PR review
denopink Jun 8, 2022
ffd531f
Move exported fields to the top
denopink Jun 8, 2022
13a9a57
update tests to include correct mac length
denopink Jun 8, 2022
3ac1d02
`testAlwaysValid` & `testAlwaysInvalid` ensure a non-existing message…
denopink Jun 8, 2022
e553e7e
`testTypeValidatorFactory` swap `assert.Zero/NotZero`
denopink Jun 8, 2022
dff0053
Improve Test descriptions, improved & added missing tests, improved e…
denopink Jun 8, 2022
0f0c07f
Merge branch 'denopink/FR-WRPValidationFramework' into denopink/featu…
denopink Jun 8, 2022
8e6882b
Add missing scheme to source fields & add missing `assert.ErrorIs` to…
denopink Jun 8, 2022
b1316d0
Merge branch 'denopink/FR-WRPValidationFramework' into denopink/featu…
denopink Jun 8, 2022
cadaeea
Move exported tests to the top
denopink Jun 8, 2022
8e68b95
Updated defaultValidator to work as a variadic for multi-default supp…
denopink May 26, 2022
bbee089
update examples
denopink May 26, 2022
803ff98
Doc/var update
denopink May 26, 2022
31f9479
Add test for `Nil default Validators` edge case
denopink May 26, 2022
30373c0
update examples output
denopink May 26, 2022
72518e4
doc update
denopink May 26, 2022
0e4b691
formatting
denopink May 26, 2022
505d92f
Updates based on PR review
denopink May 31, 2022
998528b
Add multierr to Validator
denopink Jun 1, 2022
f2cd00e
formatting
denopink Jun 3, 2022
17a1c8b
Add missing test for `AlwaysValid` func
denopink Jun 3, 2022
390e74d
First pass of spec validators
denopink Jun 3, 2022
e3bd2ce
Add an example for SpecValidators
denopink Jun 3, 2022
63ec769
Remove println from UTF8 validate func
denopink Jun 3, 2022
27b59bd
Add missing tests for MessageType
denopink Jun 3, 2022
76593e0
Update docs
denopink Jun 3, 2022
fd7f29c
Updates based on PR Feedback
denopink Jun 6, 2022
665db75
Update testUTF8Validator test and rename var `value` to `msg` for Mes…
denopink Jun 7, 2022
5b65251
Improve Test descriptions, improved & added missing tests, improved e…
denopink Jun 8, 2022
d7f98bb
Updates based on PR feedback
denopink Jun 7, 2022
bc26b1e
Update based on PR review
denopink Jun 8, 2022
db62e6f
Move exported fields to the top
denopink Jun 8, 2022
4252c2d
update tests to include correct mac length
denopink Jun 8, 2022
77033c6
`testAlwaysValid` & `testAlwaysInvalid` ensure a non-existing message…
denopink Jun 8, 2022
f2dc8a4
`testTypeValidatorFactory` swap `assert.Zero/NotZero`
denopink Jun 8, 2022
5294947
Add missing scheme to source fields & add missing `assert.ErrorIs` to…
denopink Jun 8, 2022
2428b8a
Move exported tests to the top
denopink Jun 8, 2022
e34c963
Merge branch 'denopink/feature/SpecValidators' of https://github.com/…
denopink Jun 8, 2022
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ report.json

# Images
*.png

# VSCode
*.code-workspace
.vscode/*
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ require (
github.com/go-kit/kit v0.8.0
github.com/go-logfmt/logfmt v0.3.0 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/google/uuid v1.3.0
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 // indirect
github.com/stretchr/testify v1.7.0
github.com/ugorji/go/codec v1.2.6
github.com/xmidt-org/httpaux v0.3.0
github.com/xmidt-org/webpa-common v1.3.2
go.uber.org/multierr v1.8.0
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2i
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -25,6 +27,10 @@ github.com/xmidt-org/httpaux v0.3.0 h1:JdV4QceiE8EMA1Qf5rnJzHdkIPzQV12ddARHLU8hr
github.com/xmidt-org/httpaux v0.3.0/go.mod h1:mviIlg5fHGb3lAv3l0sbiwVG/q9rqvXaudEYxVrzXdE=
github.com/xmidt-org/webpa-common v1.3.2 h1:dE1Fi+XVnkt3tMGMjH7/hN/UGcaQ/ukKriXuMDyCWnM=
github.com/xmidt-org/webpa-common v1.3.2/go.mod h1:oCpKzOC+9h2vYHVzAU/06tDTQuBN4RZz+rhgIXptpOI=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
6 changes: 0 additions & 6 deletions header_wrp.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@

package wrp

import (
"errors"
)

// Constant HTTP header strings representing WRP fields
const (
MsgTypeHeader = "X-Midt-Msg-Type"
Expand All @@ -34,8 +30,6 @@ const (
SourceHeader = "X-Midt-Source"
)

var ErrInvalidMsgType = errors.New("Invalid Message Type")

// Map string to MessageType int
/*
func StringToMessageType(str string) MessageType {
Expand Down
147 changes: 147 additions & 0 deletions spec_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/**
* Copyright (c) 2022 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package wrp

import (
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"unicode"

"github.com/google/uuid"
)

const (
serialPrefix = "serial"
uuidPrefix = "uuid"
eventPrefix = "event"
dnsPrefix = "dns"
)

var (
ErrorInvalidMessageEncoding = errors.New("invalid message encoding")
ErrorInvalidMessageType = errors.New("invalid message type")
ErrorInvalidSource = errors.New("invalid Source name")
ErrorInvalidDestination = errors.New("invalid Destination name")
)

// locatorPattern is the precompiled regular expression that all source and dest locators must match.
// Matching is partial, as everything after the authority (ID) is ignored. https://xmidt.io/docs/wrp/basics/#locators
var LocatorPattern = regexp.MustCompile(
`^(?P<scheme>(?i)` + macPrefix + `|` + uuidPrefix + `|` + eventPrefix + `|` + dnsPrefix + `|` + serialPrefix + `):(?P<authority>[^/]+)?`,
)

// SpecValidators is a WRP validator that ensures messages are valid based on
// each spec validator in the list. Only validates the opinionated portions of the spec.
func SpecValidators() Validators {
return Validators{UTF8Validator, MessageTypeValidator, SourceValidator, DestinationValidator}
}

// UTF8Validator is a WRP validator that takes messages and validates that it contains UTF-8 strings.
var UTF8Validator ValidatorFunc = func(m Message) error {
if err := UTF8(m); err != nil {
return fmt.Errorf("%w: %v", ErrorInvalidMessageEncoding, err)
}

return nil
}

// MessageTypeValidator is a WRP validator that takes messages and validates their Type.
var MessageTypeValidator ValidatorFunc = func(m Message) error {
t := m.MessageType()
if t < Invalid0MessageType || t > lastMessageType {
return ErrorInvalidMessageType
}

switch t {
case Invalid0MessageType, Invalid1MessageType, lastMessageType:
return ErrorInvalidMessageType
}

return nil
}

// SourceValidator is a WRP validator that takes messages and validates their Source.
// Only mac and uuid sources are validated. Serial, event and dns sources are
// not validated.
var SourceValidator ValidatorFunc = func(m Message) error {
if err := validateLocator(m.Source); err != nil {
return fmt.Errorf("%w: %v", ErrorInvalidSource, err)
}

return nil
}

// DestinationValidator is a WRP validator that takes messages and validates their Destination.
// Only mac and uuid destinations are validated. Serial, event and dns destinations are
// not validated.
var DestinationValidator ValidatorFunc = func(m Message) error {
if err := validateLocator(m.Destination); err != nil {
return fmt.Errorf("%w: %v", ErrorInvalidDestination, err)
}

return nil
}

// validateLocator validates a given locator's scheme and authority (ID).
// Only mac and uuid schemes' IDs are validated. IDs from serial, event and dns schemes are
// not validated.
func validateLocator(l string) error {
match := LocatorPattern.FindStringSubmatch(l)
if match == nil {
return fmt.Errorf("spec scheme not found")
}

idPart := match[2]
switch strings.ToLower(match[1]) {
case macPrefix:
var invalidCharacter rune = -1
idPart = strings.Map(
func(r rune) rune {
switch {
case strings.ContainsRune(hexDigits, r):
return unicode.ToLower(r)
case strings.ContainsRune(macDelimiters, r):
return -1
default:
invalidCharacter = r
return -1
}
},
idPart,
)

if invalidCharacter != -1 {
return fmt.Errorf("invalid character %v", strconv.QuoteRune(invalidCharacter))
} else if len(idPart) != macLength {
return errors.New("invalid mac length")
}
case uuidPrefix:
if _, err := uuid.Parse(idPart); err != nil {
return err
}
case serialPrefix, eventPrefix, dnsPrefix:
if len(idPart) == 0 {
return fmt.Errorf("invalid %v empty authority (ID)", serialPrefix)
}
}

return nil
}
Loading