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

Validation Option to disable strict path parameter uniqueness validation #157

Merged
merged 1 commit into from
Nov 20, 2023
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
2 changes: 1 addition & 1 deletion doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Reported as errors:

[x] definition can't declare a property that's already defined by one of its ancestors
[x] definition's ancestor can't be a descendant of the same model
[x] path uniqueness: each api path should be non-verbatim (account for path param names) unique per method
[x] path uniqueness: each api path should be non-verbatim (account for path param names) unique per method. Validation can be laxed by disabling StrictPathParamUniqueness.
[x] each security reference should contain only unique scopes
[x] each security scope in a security definition should be unique
[x] parameters in path must be unique
Expand Down
20 changes: 19 additions & 1 deletion options.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,28 @@ import "sync"
// NOTE: other options might be needed, for example a go-swagger specific mode.
type Opts struct {
ContinueOnErrors bool // true: continue reporting errors, even if spec is invalid

// StrictPathParamUniqueness enables a strict validation of paths that include
// path parameters. When true, it will enforce that for each method, the path
// is unique, regardless of path parameters such that GET:/petstore/{id} and
// GET:/petstore/{pet} anre considered duplicate paths.
//
// Consider disabling if path parameters can include slashes such as
// GET:/v1/{shelve} and GET:/v1/{book}, where the IDs are "shelve/*" and
// /"shelve/*/book/*" respectively.
StrictPathParamUniqueness bool
}

var (
defaultOpts = Opts{ContinueOnErrors: false} // default is to stop validation on errors
defaultOpts = Opts{
// default is to stop validation on errors
ContinueOnErrors: false,

// StrictPathParamUniqueness is defaulted to true. This maintains existing
// behavior.
StrictPathParamUniqueness: true,
}

defaultOptsMutex = &sync.Mutex{}
)

Expand Down
38 changes: 20 additions & 18 deletions spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@
func (s *SpecValidator) validateParameters() *Result {
// - for each method, path is unique, regardless of path parameters
// e.g. GET:/petstore/{id}, GET:/petstore/{pet}, GET:/petstore are
// considered duplicate paths
// considered duplicate paths, if StrictPathParamUniqueness is enabled.
// - each parameter should have a unique `name` and `type` combination
// - each operation should have only 1 parameter of type body
// - there must be at most 1 parameter in body
Expand All @@ -626,28 +626,30 @@
for method, pi := range s.expandedAnalyzer().Operations() {
methodPaths := make(map[string]map[string]string)
for path, op := range pi {
pathToAdd := pathHelp.stripParametersInPath(path)
if s.Options.StrictPathParamUniqueness {
pathToAdd := pathHelp.stripParametersInPath(path)

// Warn on garbled path afer param stripping
if rexGarbledPathSegment.MatchString(pathToAdd) {
res.AddWarnings(pathStrippedParamGarbledMsg(pathToAdd))
}
// Warn on garbled path afer param stripping
if rexGarbledPathSegment.MatchString(pathToAdd) {
res.AddWarnings(pathStrippedParamGarbledMsg(pathToAdd))
}

Check warning on line 635 in spec.go

View check run for this annotation

Codecov / codecov/patch

spec.go#L634-L635

Added lines #L634 - L635 were not covered by tests

// Check uniqueness of stripped paths
if _, found := methodPaths[method][pathToAdd]; found {
// Check uniqueness of stripped paths
if _, found := methodPaths[method][pathToAdd]; found {

// Sort names for stable, testable output
if strings.Compare(path, methodPaths[method][pathToAdd]) < 0 {
res.AddErrors(pathOverlapMsg(path, methodPaths[method][pathToAdd]))
// Sort names for stable, testable output
if strings.Compare(path, methodPaths[method][pathToAdd]) < 0 {
res.AddErrors(pathOverlapMsg(path, methodPaths[method][pathToAdd]))

Check warning on line 642 in spec.go

View check run for this annotation

Codecov / codecov/patch

spec.go#L642

Added line #L642 was not covered by tests
} else {
res.AddErrors(pathOverlapMsg(methodPaths[method][pathToAdd], path))
}
} else {
res.AddErrors(pathOverlapMsg(methodPaths[method][pathToAdd], path))
}
} else {
if _, found := methodPaths[method]; !found {
methodPaths[method] = map[string]string{}
}
methodPaths[method][pathToAdd] = path // Original non stripped path
if _, found := methodPaths[method]; !found {
methodPaths[method] = map[string]string{}
}
methodPaths[method][pathToAdd] = path // Original non stripped path

}
}

var bodyParams []string
Expand Down
5 changes: 5 additions & 0 deletions spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,11 @@ func TestSpec_ValidateParameters(t *testing.T) {
assert.Len(t, res.Errors, 1)
assert.Contains(t, res.Errors[0].Error(), "overlaps with")

// Disable strict path param uniqueness and ensure there is no error
validator.Options.StrictPathParamUniqueness = false
res = validator.validateParameters()
assert.Empty(t, res.Errors)

doc, _ = loads.Analyzed(PetStoreJSONMessage, "")
validator = NewSpecValidator(spec.MustLoadSwagger20Schema(), strfmt.Default)
validator.spec = doc
Expand Down
Loading