Skip to content

Commit 6b93301

Browse files
committed
Addressed issue #75
1 parent 7e5d6b3 commit 6b93301

File tree

4 files changed

+153
-5
lines changed

4 files changed

+153
-5
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/pb33f/libopenapi-validator
33
go 1.21
44

55
require (
6-
github.com/pb33f/libopenapi v0.16.3
6+
github.com/pb33f/libopenapi v0.16.4
77
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
88
github.com/stretchr/testify v1.9.0
99
github.com/vmware-labs/yaml-jsonpath v0.3.2

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
5454
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
5555
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
5656
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
57-
github.com/pb33f/libopenapi v0.16.3 h1:ozo0vYdeP6r+qAXb+Kg1MOy6QrTxSgNpoD3nKuw/HA8=
58-
github.com/pb33f/libopenapi v0.16.3/go.mod h1:PEXNwvtT4KNdjrwudp5OYnD1ryqK6uJ68aMNyWvoMuc=
57+
github.com/pb33f/libopenapi v0.16.4 h1:mX81EkBS7cbJZeJiw2ovXchGGHCLvfj26gGs4jL1XDU=
58+
github.com/pb33f/libopenapi v0.16.4/go.mod h1:PEXNwvtT4KNdjrwudp5OYnD1ryqK6uJ68aMNyWvoMuc=
5959
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
6060
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
6161
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=

requests/validate_body_test.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package requests
66
import (
77
"bytes"
88
"encoding/json"
9+
"fmt"
910
"net/http"
1011
"testing"
1112

@@ -1194,3 +1195,139 @@ components:
11941195
assert.Equal(t, "invalid character '}' looking for beginning of object key string", errors[0].SchemaValidationErrors[0].Reason)
11951196

11961197
}
1198+
1199+
func TestValidateBody_SchemaNoType_Issue75(t *testing.T) {
1200+
1201+
spec := `{
1202+
"openapi": "3.0.1",
1203+
"info": {
1204+
"title": "testing",
1205+
"description": "<p>This is for testing purpose</p>",
1206+
"version": "1.0",
1207+
"x-targetEndpoint": "https://mocktarget.apigee.net/json"
1208+
},
1209+
"servers": [
1210+
{
1211+
"url": "https://some-url.com"
1212+
}
1213+
],
1214+
"paths": {
1215+
"/path1": {
1216+
"put": {
1217+
"requestBody": {
1218+
"required": true,
1219+
"content": {
1220+
"application/json": {
1221+
"schema": {
1222+
"anyOf": [
1223+
{
1224+
"type": "object",
1225+
"properties": {
1226+
"name": {
1227+
"type": "string",
1228+
"minLength": 1
1229+
},
1230+
"age": {
1231+
"type": "integer"
1232+
}
1233+
},
1234+
"required": [
1235+
"name"
1236+
]
1237+
},
1238+
{
1239+
"type": "object",
1240+
"properties": {
1241+
"email": {
1242+
"type": "string"
1243+
},
1244+
"address": {
1245+
"type": "string"
1246+
}
1247+
},
1248+
"required": [
1249+
"email"
1250+
]
1251+
}
1252+
]
1253+
}
1254+
}
1255+
}
1256+
},
1257+
"responses": {
1258+
"200": {
1259+
"description": "OK"
1260+
}
1261+
}
1262+
}
1263+
},
1264+
"/path2": {
1265+
"get": {
1266+
"parameters": [
1267+
{
1268+
"name": "X-My-Header",
1269+
"in": "header",
1270+
"required": true,
1271+
"schema": {
1272+
"type": "string"
1273+
}
1274+
}
1275+
],
1276+
"responses": {
1277+
"200": {
1278+
"description": "OK"
1279+
}
1280+
}
1281+
}
1282+
},
1283+
"/path3": {
1284+
"get": {
1285+
"parameters": [
1286+
{
1287+
"name": "id",
1288+
"in": "query",
1289+
"required": true,
1290+
"schema": {
1291+
"type": "integer"
1292+
}
1293+
}
1294+
],
1295+
"responses": {
1296+
"200": {
1297+
"description": "OK"
1298+
}
1299+
}
1300+
}
1301+
}
1302+
}
1303+
}
1304+
`
1305+
1306+
doc, err := libopenapi.NewDocument([]byte(spec))
1307+
if err != nil {
1308+
fmt.Println("error while creating open api spec document", err)
1309+
return
1310+
}
1311+
1312+
req, err := http.NewRequest("PUT", "/path1", nil)
1313+
if err != nil {
1314+
fmt.Println("error while creating new HTTP request", err)
1315+
return
1316+
}
1317+
1318+
req.Header.Set("Content-Type", "application/json")
1319+
1320+
v3Model, errs := doc.BuildV3Model()
1321+
if len(errs) > 0 {
1322+
fmt.Println("error while building a Open API spec V3 model", errs)
1323+
return
1324+
}
1325+
1326+
reqBodyValidator := NewRequestBodyValidator(&v3Model.Model)
1327+
isSuccess, valErrs := reqBodyValidator.ValidateRequestBody(req)
1328+
1329+
assert.False(t, isSuccess)
1330+
assert.Len(t, valErrs, 1)
1331+
assert.Equal(t, "PUT request body is empty for '/path1'", valErrs[0].Message)
1332+
1333+
}

requests/validate_request.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ func ValidateRequestSchema(
7474

7575
// no request body? but we do have a schema?
7676
if len(requestBody) <= 0 && len(jsonSchema) > 0 {
77+
78+
line := -1
79+
col := -1
80+
if schema.Type != nil {
81+
line = schema.GoLow().Type.KeyNode.Line
82+
col = schema.GoLow().Type.KeyNode.Column
83+
} else {
84+
line = schema.ParentProxy.GetSchemaKeyNode().Line
85+
col = schema.ParentProxy.GetSchemaKeyNode().Line
86+
}
87+
7788
// cannot decode the request body, so it's not valid
7889
violation := &errors.SchemaValidationFailure{
7990
Reason: "request body is empty, but there is a schema defined",
@@ -86,8 +97,8 @@ func ValidateRequestSchema(
8697
Message: fmt.Sprintf("%s request body is empty for '%s'",
8798
request.Method, request.URL.Path),
8899
Reason: "The request body is empty but there is a schema defined",
89-
SpecLine: schema.GoLow().Type.KeyNode.Line,
90-
SpecCol: schema.GoLow().Type.KeyNode.Line,
100+
SpecLine: line,
101+
SpecCol: col,
91102
SchemaValidationErrors: []*errors.SchemaValidationFailure{violation},
92103
HowToFix: errors.HowToFixInvalidSchema,
93104
Context: string(renderedSchema), // attach the rendered schema to the error

0 commit comments

Comments
 (0)