kin-openapi
kin-openapi copied to clipboard
Request validator checks ReadOnly Properties when using AllOf
This is a follow-up to #71
I have a very similar problem to #71, in that the request validator enforces the existence of a readOnly property.
The difference is that the schema is split and then stitched together with a allOf:
components:
schemas:
Element:
type: object
properties:
id:
type: integer
readOnly: true
name:
type: string
description:
type: string
Element_full:
allOf:
- $ref: "#/components/schemas/Element"
- required:
- id
- name
With this schema the request validator currently enforces the existence of id and name (but then dissallows id because of readOnly).
However, the request validator should only enforce the the existence of name.
Runnable example
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"github.com/getkin/kin-openapi/openapi3"
"github.com/getkin/kin-openapi/openapi3filter"
"github.com/getkin/kin-openapi/routers/gorillamux"
)
var schema = []byte(`{
"openapi": "3.0.2",
"info": {
"version": "1.0.0",
"title": "title",
"description": "desc",
"contact": {
"email": "email"
}
},
"components": {
"schemas": {
"Element": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"readOnly": true
},
"name": {
"type": "string"
},
"description": {
"type": "string"
}
}
},
"Element_full": {
"allOf": [
{
"$ref": "#/components/schemas/Element"
},
{
"required": [
"id",
"name"
]
}
]
}
}
},
"paths": {
"/elements": {
"post": {
"description": "Create a new element",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Element_full"
}
}
}
}
},
"responses": {
"201": {
"description": "ok"
},
"400": {
"description": "The server could not understand the request due to invalid syntax",
}
}
}
}
}
`)
type Request struct {
Name string `json:"name"`
}
func main() {
loader := openapi3.NewLoader()
doc, _ := loader.LoadFromData(schema)
_ = doc.Validate(loader.Context)
router, _ := gorillamux.NewRouter(doc)
b, _ := json.Marshal(Request{Name: "test"})
httpReq, _ := http.NewRequest(http.MethodPost, "/elements", bytes.NewReader(b))
httpReq.Header.Add("Content-Type", "application/json")
route, pathParams, _ := router.FindRoute(httpReq)
requestValidationInput := &openapi3filter.RequestValidationInput{
Request: httpReq,
PathParams: pathParams,
Route: route,
}
if err := openapi3filter.ValidateRequest(loader.Context, requestValidationInput); err != nil {
panic(err)
}
fmt.Println("Did not fail")
}