microsoft / restler-fuzzer

RESTler is the first stateful REST API fuzzing tool for automatically testing cloud services through their REST APIs and finding security and reliability bugs in these services.
MIT License
2.59k stars 296 forks source link

Annotation fails to interpret correctly a producer with oneOf #721

Open adrienboulle opened 1 year ago

adrienboulle commented 1 year ago

Description

If a producer POST:/foo produces A or B, and both have the id property:

oneOf: [
  <Schema A with property id: number>,
  <Schema B with property id: number>
]

I should be able to specify the following annotation:

{
  "producer_method": "POST",
  "producer_endpoint": "/foo",
  "consumer_param": "A_or_B_id",
  "producer_resource_name": "/id"
}

but this seems not do be interpreted as a correct annotation.

Note1: it does work with allOf It seems that when we have allOf the code checks for one of the schemas to match the producer_resource_name If we have oneOf it should do the same check but for each of the schemas.

Note2: this should also work: producer POST:/foo produces:

{
  content: {
    oneOf: [
      <Schema A with property /content/id: number>,
      <Schema B with property /content/id: number>
    ]
  }
}

with

{
  "producer_method": "POST",
  "producer_endpoint": "/foo",
  "consumer_param": "A_or_B_id",
  "producer_resource_name": "/content/id"
}

Steps to reproduce

This spec: ``` { "openapi": "3.1.0", "paths": { "/companies/{companyId}/contacts": { "post": { "parameters": [ { "name": "companyId", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "oneOf": [ { "$ref": "#/components/schemas/Person" }, { "$ref": "#/components/schemas/Company" } ] } } } } }, "operationId": "createContact", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PersonCreate" } } } } } }, "/contacts/{contactId}": { "delete": { "parameters": [ { "name": "contactId", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "boolean" } } } } } } }, "operationId": "deleteContact" } } }, "components": { "schemas": { "PersonCreate": { "type": "object", "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" } }, "required": [ "firstName", "lastName" ] }, "Person": { "type": "object", "properties": { "id": { "minimum": 1, "type": "integer" }, "firstName": { "type": "string" }, "lastName": { "type": "string" } }, "required": [ "id", "firstName", "lastName" ] }, "Company": { "type": "object", "properties": { "id": { "minimum": 1, "type": "integer" }, "name": { "type": "string" } }, "required": [ "id", "name" ] } } }, "x-restler-global-annotations": [ { "producer_method": "POST", "producer_endpoint": "/companies/{companyId}/contacts", "consumer_param": "contactId", "producer_resource_name": "/id" } ] } ```

Produces those dependencies when compiled:

{
  "/companies/{companyId}/contacts": {
    "POST": {
      "Path": [
        {
          "producer_endpoint": "",
          "producer_method": "",
          "producer_resource_name": "",
          "consumer_param": "companyId"
        }
      ],
      "Body": [
        {
          "producer_endpoint": "",
          "producer_method": "",
          "producer_resource_name": "",
          "consumer_param": "firstName"
        },
        {
          "producer_endpoint": "",
          "producer_method": "",
          "producer_resource_name": "",
          "consumer_param": "lastName"
        }
      ]
    }
  },
  "/contacts/{contactId}": {
    "DELETE": {
      "Path": [
        {
          "producer_endpoint": "",
          "producer_method": "",
          "producer_resource_name": "",
          "consumer_param": "contactId"
        }
      ]
    }
  }
}

Expected results

No response

Actual results

No response

Environment details

Using docker on linux