Skip to content

Commit 86bae22

Browse files
jacobm-splunkdaveshanley
authored andcommitted
Added base path stripping for the request path during path parameter validation
1 parent 3397867 commit 86bae22

File tree

3 files changed

+66
-18
lines changed

3 files changed

+66
-18
lines changed

parameters/path_parameters.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@ func (v *paramValidator) ValidatePathParams(request *http.Request) (bool, []*err
3333
foundPath = v.pathValue
3434
}
3535

36+
// split the path into segments
37+
submittedSegments := strings.Split(paths.StripRequestPath(request, v.document), helpers.Slash)
38+
pathSegments := strings.Split(foundPath, helpers.Slash)
39+
3640
// extract params for the operation
3741
var params = helpers.ExtractParamsForOperation(request, pathItem)
3842
var validationErrors []*errors.ValidationError
3943
for _, p := range params {
4044
if p.In == helpers.Path {
4145

42-
// split the path into segments
43-
submittedSegments := strings.Split(request.URL.Path, helpers.Slash)
44-
pathSegments := strings.Split(foundPath, helpers.Slash)
45-
4646
// var paramTemplate string
4747
for x := range pathSegments {
4848
if pathSegments[x] == "" { // skip empty segments

parameters/path_parameters_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,3 +1403,37 @@ paths:
14031403
assert.Equal(t, "Path parameter 'burgerId' does not match allowed values", errors[0].Message)
14041404
assert.Equal(t, "Instead of '22334', use one of the allowed values: '1, 2, 99, 100'", errors[0].HowToFix)
14051405
}
1406+
1407+
func TestNewValidator_FillInThis(t *testing.T) {
1408+
1409+
spec := `openapi: 3.1.0
1410+
servers:
1411+
- url: https://api.pb33f.io/lorem/ipsum
1412+
description: Live production endpoint for general use.
1413+
paths:
1414+
/burgers/{burger}/locate:
1415+
parameters:
1416+
- name: burger
1417+
in: path
1418+
schema:
1419+
type: object
1420+
properties:
1421+
id:
1422+
type: integer
1423+
vegetarian:
1424+
type: boolean
1425+
get:
1426+
operationId: locateBurger`
1427+
1428+
doc, _ := libopenapi.NewDocument([]byte(spec))
1429+
1430+
m, _ := doc.BuildV3Model()
1431+
1432+
v := NewParameterValidator(&m.Model)
1433+
1434+
request, _ := http.NewRequest(http.MethodGet, "https://things.com/lorem/ipsum/burgers/id,1234,vegetarian,true/locate", nil)
1435+
valid, errors := v.ValidatePathParams(request)
1436+
1437+
assert.True(t, valid)
1438+
assert.Len(t, errors, 0)
1439+
}

paths/paths.go

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,8 @@ import (
2424
func FindPath(request *http.Request, document *v3.Document) (*v3.PathItem, []*errors.ValidationError, string) {
2525
var validationErrors []*errors.ValidationError
2626

27-
// extract base path from document to check against paths.
28-
var basePaths []string
29-
for _, s := range document.Servers {
30-
u, _ := url.Parse(s.URL)
31-
if u != nil && u.Path != "" {
32-
basePaths = append(basePaths, u.Path)
33-
}
34-
}
35-
36-
// strip any base path
37-
stripped := stripBaseFromPath(request.URL.Path, basePaths)
38-
if request.URL.Fragment != "" {
39-
stripped = fmt.Sprintf("%s#%s", stripped, request.URL.Fragment)
40-
}
27+
basePaths := getBasePaths(request, document)
28+
stripped := StripRequestPath(request, document)
4129

4230
reqPathSegments := strings.Split(stripped, "/")
4331
if reqPathSegments[0] == "" {
@@ -205,6 +193,32 @@ pathFound:
205193
}
206194
}
207195

196+
func getBasePaths(request *http.Request, document *v3.Document) []string {
197+
// extract base path from document to check against paths.
198+
var basePaths []string
199+
for _, s := range document.Servers {
200+
u, _ := url.Parse(s.URL)
201+
if u != nil && u.Path != "" {
202+
basePaths = append(basePaths, u.Path)
203+
}
204+
}
205+
206+
return basePaths
207+
}
208+
209+
// StripRequestPath strips the base path from the request path, based on the server paths provided in the specification
210+
func StripRequestPath(request *http.Request, document *v3.Document) string {
211+
212+
basePaths := getBasePaths(request, document)
213+
214+
// strip any base path
215+
stripped := stripBaseFromPath(request.URL.Path, basePaths)
216+
if request.URL.Fragment != "" {
217+
stripped = fmt.Sprintf("%s#%s", stripped, request.URL.Fragment)
218+
}
219+
return stripped
220+
}
221+
208222
func checkPathAgainstBase(docPath, urlPath string, basePaths []string) bool {
209223
if docPath == urlPath {
210224
return true

0 commit comments

Comments
 (0)