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

Incorect validation of nullable in allOf #171

Closed
Tracked by #318
pali opened this issue Feb 4, 2020 · 4 comments · Fixed by #253
Closed
Tracked by #318

Incorect validation of nullable in allOf #171

pali opened this issue Feb 4, 2020 · 4 comments · Fixed by #253

Comments

@pali
Copy link

pali commented Feb 4, 2020

When allOf contains two structures and both of them have defined "nullable" : true then validator should accept null value (as null value is valid for both defined structures).

But kin-openapi validator currently reject null value. Below is schema and test case.

{
    "openapi": "3.0.0",
    "info": {
        "version": "1.0.0",
        "title": "test"
    },
    "paths": {
        "/": {
            "get": {
                "responses": {
                    "200": {
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "value": {
                                            "$ref": "#/components/schemas/NULL"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components" : {
        "schemas" : {
            "NULL" : {
                "allOf" : [
                    {
                        "nullable" : true,
                        "type" : "boolean",
                        "enum" : [ false ]
                    },
                    {
                        "nullable" : true,
                        "type" : "boolean",
                        "enum" : [ true ]
                    }
                ]
            }
        }
    }
}

Test input: { "value" : null }. Validator should accept this input, but currently it rejects it.

Looks like that PR #169 did not fixed this case.

@arnaubennassar
Copy link

Same problem here:

I have this object that is used as a response:

    MyObject:
      type: object
      description: MyObject description
      properties:
        nullableRef:
          allOf:
            - $ref: '#/components/schemas/NotNullableObject'
            - nullable: true
            - description: nullableRef description
            - example: 5432
          required:
            - nullableRef
          additionalProperties: false

And when validating I'm geting the error: response body doesn't match the schema: Error at "nullableRef":Value is not nullable

@m-mohr
Copy link

m-mohr commented Nov 23, 2020

The example by @pali conflicts with https://github.com/OAI/OpenAPI-Specification/blob/master/proposals/003_Clarify-Nullable.md

nullable: true doesn't add "null" to the values of the enum and thus is not allowed. The allOf needs to look like this:

                "allOf" : [
                    {
                        "type" : "boolean",
                        "enum" : [ false ]
                    },
                    {
                        "type" : "boolean",
                        "enum" : [ true ]
                    },
                    {
                        "enum" : [ null ]
                    }
                ]

or simply:

                    {
                        "type" : "boolean",
                        "nullable": true
                    }

Still, we also have issues with allOf and nullable.

@micvbang
Copy link

micvbang commented Oct 25, 2022

I'm having a similar issue with validation of nullable values not working as I expect it to.

I have a few types declared that mostly shouldn't be null, but in a few cases should. I've tried to solve it using allOf with an anonymous, nullable type. Other tools accept this solution, but kin-openapi doesn't seem to.

I've created a minimal example showing my problem:

nullable_api.yml:

openapi: 3.0.1
info:
  title: "test"
  version: 0.0.0
paths:
  /not_nullable:
    get:
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotNullable"
  /nullable:
    get:
      responses:
        "200":
          description: ""
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/NotNullable"
                  - type: object
                    nullable: true
components:
  schemas:
    NotNullable:
      type: object
      properties:
        key:
          type: integer
          example: 1

I'd like to reuse the type NotNullable for both the endpoints, but for /nullable it should be nullable.

Here's an example program showing what I'm doing:

package main

import (
	"bytes"
	"context"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httptest"

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

func main() {
	const openAPISpec = "openapi/nullable_api.yml"
	ctx := context.Background()
	mockResponse := []byte(`null`)
	// mockResponse := []byte(`{"key": 1}`) // NOTE: it works with this body

	loader := &openapi3.Loader{Context: ctx, IsExternalRefsAllowed: true}
	doc, err := loader.LoadFromFile(openAPISpec)
	if err != nil {
		log.Fatalf("failed to load openapi spec: %s", err)
	}

	err = doc.Validate(ctx)
	if err != nil {
		log.Fatalf("failed to validate openapi spec: %s", err)
	}

	router, err := gorillamux.NewRouter(doc)
	if err != nil {
		log.Fatalf("failed to create gorilla router: %s", err)
	}

	httpReq := httptest.NewRequest(http.MethodGet, "http://127.0.0.1/nullable", nil)

	// Find route
	route, pathParams, err := router.FindRoute(httpReq)
	if err != nil {
		log.Fatalf("failed to find route: %s", err)
	}

	// Validate request
	requestValidationInput := &openapi3filter.RequestValidationInput{
		Request:    httpReq,
		PathParams: pathParams,
		Route:      route,
		Options: &openapi3filter.Options{
			AuthenticationFunc: openapi3filter.NoopAuthenticationFunc,
		},
	}
	err = openapi3filter.ValidateRequest(ctx, requestValidationInput)
	if err != nil {
		log.Fatalf("request not valid: %s", err)
	}

	// Validate response
	responseValidationInput := &openapi3filter.ResponseValidationInput{
		RequestValidationInput: requestValidationInput,
		Status:                 http.StatusOK,
		Header:                 http.Header{"Content-Type": []string{"application/json"}},
		Body:                   ioutil.NopCloser(bytes.NewReader(mockResponse)),
	}

	err = openapi3filter.ValidateResponse(ctx, responseValidationInput)
	if err != nil {
		log.Fatalf("response not valid: %s", err)
	}

	log.Printf("success!")
}

The above program outputs the following when I use null as the response:

response not valid: response body doesn't match the schema: Value is not nullable
Schema:
  {
    "allOf": [
      {
        "$ref": "#/components/schemas/NotNullable"
      },
      {
        "nullable": true,
        "type": "object"
      }
    ]
  }

Value:
  null

@Kellel
Copy link

Kellel commented May 25, 2023

I'm curious about the case of a nullable ref without allOf

For example the following:

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
paths:
  /pet:
    get:
      description: |
        Returns pet from the system that the user has access to
      responses:
        '200':
          description: pet response
          content:
            application/json:
              required:
              schema:
                $ref: '#/components/schemas/Pet'
                nullable: "true"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Pet:
      type: object
      required:
        - name
        - house
      properties:
        name:
          type: string
        tag:
          type: string
        house:
          nullable: true
          $ref: '#/components/schemas/House'

    House:
      type: object
      required:
        - address
      properties:
        address:
          type: string

    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string

Results in:

2023/05/25 10:48:59 Validation error: invalid paths: invalid path /pet: invalid operation GET: extra sibling fields: [nullable]

fenollp added a commit to fenollp/kin-openapi that referenced this issue Oct 20, 2023
Signed-off-by: Pierre Fenoll <[email protected]>
@fenollp fenollp linked a pull request Oct 20, 2023 that will close this issue
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

Successfully merging a pull request may close this issue.

5 participants