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

Request validator checks ReadOnly Properties when using AllOf #925

Open
neumantm opened this issue Mar 18, 2024 · 1 comment
Open

Request validator checks ReadOnly Properties when using AllOf #925

neumantm opened this issue Mar 18, 2024 · 1 comment

Comments

@neumantm
Copy link

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.

@neumantm
Copy link
Author

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")
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant