Skip to content

Commit

Permalink
fix: limit the depth when openapi params reference itself
Browse files Browse the repository at this point in the history
  • Loading branch information
emmanuelgautier committed Dec 1, 2024
1 parent a5b3361 commit 9be6691
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 7 deletions.
1 change: 1 addition & 0 deletions .github/workflows/scans.yml
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ jobs:
"simple_api_key.openapi.json",
"simple_http_bearer_jwt.openapi.json",
"simple_http_bearer.openapi.json",
"complex.openapi.json",
]

steps:
Expand Down
3 changes: 1 addition & 2 deletions openapi/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ func GetOperationPath(p string, params openapi3.Parameters) (string, error) {
if v.Value.In != "path" {
continue
}

subs[v.Value.Name] = getSchemaValue(v.Value.Schema.Value)
subs[v.Value.Name] = getSchemaValue(v.Value.Schema.Value, 0)
}

return stduritemplate.Expand(p, subs)
Expand Down
18 changes: 13 additions & 5 deletions openapi/param.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import (
"github.com/getkin/kin-openapi/openapi3"
)

const maximumDepth = 4

func getParameterValue(param *openapi3.Parameter) string {
if param.Schema != nil {
value := getSchemaValue(param.Schema.Value)
value := getSchemaValue(param.Schema.Value, 0)
switch {
case param.Schema.Value.Type.Is("string"):
return value.(string)
Expand Down Expand Up @@ -66,7 +68,7 @@ func getRequestBodyValue(requestBody *openapi3.RequestBody) (*bytes.Buffer, stri
if requestBody.Content != nil {
for mediaType, mediaTypeValue := range requestBody.Content {
if mediaTypeValue.Schema != nil {
body := getSchemaValue(mediaTypeValue.Schema.Value)
body := getSchemaValue(mediaTypeValue.Schema.Value, 0)
switch mediaType {
case "application/json":
return mapRequestBodyFakeValueToJSON(mediaTypeValue.Schema.Value, body), "application/json"
Expand All @@ -80,7 +82,7 @@ func getRequestBodyValue(requestBody *openapi3.RequestBody) (*bytes.Buffer, stri
return bytes.NewBuffer(nil), ""
}

func getSchemaValue(schema *openapi3.Schema) interface{} {
func getSchemaValue(schema *openapi3.Schema, depth int) interface{} {
if schema.Example != nil {
return schema.Example
} else if len(schema.Enum) > 0 {
Expand All @@ -94,11 +96,17 @@ func getSchemaValue(schema *openapi3.Schema) interface{} {
case schema.Type.Is("boolean"):
return gofakeit.Bool()
case schema.Type.Is("array"):
return []interface{}{getSchemaValue(schema.Items.Value)}
if depth > maximumDepth {
return []interface{}{}
}

Check warning on line 101 in openapi/param.go

View check run for this annotation

Codecov / codecov/patch

openapi/param.go#L100-L101

Added lines #L100 - L101 were not covered by tests
return []interface{}{getSchemaValue(schema.Items.Value, depth+1)}
case schema.Type.Is("object"):
object := map[string]interface{}{}
if depth > maximumDepth {
return object
}
for key, value := range schema.Properties {
object[key] = getSchemaValue(value.Value)
object[key] = getSchemaValue(value.Value, depth+1)
}
return object
case schema.Type.Is("string"):
Expand Down
14 changes: 14 additions & 0 deletions openapi/param_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,17 @@ func TestGetSchemaValue_WhenRequestBodyParametersWithObjectExampleAndArrayExampl
assert.NotNil(t, operations[0].Body)
assert.Equal(t, expected, operations[0].Body)
}

func TestRecursiveParameters(t *testing.T) {
openapiContract, operr := openapi.LoadFromData(
context.Background(),
[]byte(`{"openapi":"3.0.2","servers":[{"url":"http://localhost:8080"}],"paths":{"/":{"post":{"summary":"Create an item","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Item"}}}},"responses":{"201":{"description":"Item created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Item"}}}}}}}},"components":{"schemas":{"Item":{"type":"object","properties":{"details":{"type":"object","properties":{"description":{"type":"string"},"attributes":{"type":"array","items":{"$ref":"#/components/schemas/Attribute"}}}}}},"Attribute":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"},"subAttributes":{"type":"array","items":{"$ref":"#/components/schemas/Attribute"}}}}}}}}`),
)

securitySchemesMap, _ := openapiContract.SecuritySchemeMap(openapi.NewEmptySecuritySchemeValues())
operations, err := openapiContract.Operations(nil, securitySchemesMap)

assert.NoError(t, operr)
assert.NoError(t, err)
assert.NotNil(t, operations[0].Body)
}
155 changes: 155 additions & 0 deletions test/stub/complex.openapi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{
"openapi": "3.0.2",
"info": {
"title": "Complex API",
"description": "API with complex and recursive parameters",
"version": "1.0.0"
},
"servers": [
{
"url": "http://localhost:8080"
}
],
"paths": {
"/": {
"get": {
"summary": "Get items",
"parameters": [
{
"name": "filter",
"in": "query",
"required": false,
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
],
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Item"
}
}
}
}
}
},
"security": [
{
"bearer_auth": []
},
{
"api_key_auth": []
}
]
},
"post": {
"summary": "Create an item",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Item"
}
}
}
},
"responses": {
"201": {
"description": "Item created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Item"
}
}
}
}
},
"security": [
{
"bearer_auth": []
},
{
"api_key_auth": []
}
]
}
}
},
"components": {
"securitySchemes": {
"bearer_auth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
},
"api_key_auth": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key"
}
},
"schemas": {
"Item": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"details": {
"type": "object",
"properties": {
"description": {
"type": "string"
},
"attributes": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Attribute"
}
}
}
}
}
},
"Attribute": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "string"
},
"subAttributes": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Attribute"
}
}
}
}
}
}
}

0 comments on commit 9be6691

Please sign in to comment.