Skip to content

Request validation does not work correctly with discriminator  #80

@evgenykireev

Description

@evgenykireev

Discriminator property is not taken into account when validating request body.
Given example schema from https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
request body

{
  "pet_type": "Cat",
  "breed":    "Dingo",
  "bark":     true,
}

should not be valid, however it passes ValidateRequest.

Code to reproduce:

package main

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/getkin/kin-openapi/openapi3"
	"github.com/getkin/kin-openapi/openapi3filter"
)

const testSchema = `openapi: 3.0.0
info:
  title: ''
  version: 0.0.1
paths:
  /:
    post:
      requestBody:
        required: true
        content:
          application/json:
            schema:
              anyOf:
                - $ref: '#/components/schemas/Cat'
                - $ref: '#/components/schemas/Dog'
              discriminator:
                propertyName: pet_type

components:
  schemas:
    Pet:
      type: object
      required:
        - pet_type
      properties:
        pet_type:
          type: string
      discriminator:
        propertyName: pet_type

    Dog:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            breed:
              type: string
              enum: [Dingo, Husky, Retriever, Shepherd]
    Cat:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            hunts:
              type: boolean
            age:
              type: integer
`

func main() {
	payload := map[string]interface{}{
		"pet_type": "Cat",
		"breed":    "Dingo",
		"bark":     true,
	}

	p, _ := json.Marshal(payload)

	swagger, _ := openapi3.NewSwaggerLoader().LoadSwaggerFromData([]byte(testSchema))

	router := openapi3filter.NewRouter().WithSwagger(swagger)
	req, _ := http.NewRequest(http.MethodPost, "/", bytes.NewReader(p))
	route, pathParams, _ := router.FindRoute(req.Method, req.URL)
	req.Header.Set("Content-Type", "application/json")

	requestValidationInput := &openapi3filter.RequestValidationInput{
		Request:    req,
		PathParams: pathParams,
		Route:      route,
	}

	err := openapi3filter.ValidateRequest(context.TODO(), requestValidationInput)
	if err == nil {
		fmt.Println("Valid")
	} else {
		fmt.Println("NOT valid")
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions