PayU / openapi-validator-middleware

Input validation using Swagger (Open API) and ajv
Apache License 2.0
144 stars 50 forks source link

Make it optional to add basurl to path in _getParameters - Express #125

Open hpl002 opened 4 years ago

hpl002 commented 4 years ago

would it be possible to make the concat optional based on prop form options obj?

using this with routing and would have to append basePath to all paths in schema for paths to match, could avoid this if it was possible to avoid baseurl.

my routes go via /api, but paths in schema do not have this prefixed, thus causing a mismatch that results in the request not being validated.

Req points to /api/somewhere While path goes directly to /somewhere

ref:

function _getParameters(req) { const requestOptions = {}; const path = req.baseUrl.concat(req.route.path); requestOptions.path = path.endsWith('/') ? path.substring(0, path.length - 1) : path; requestOptions.headers = req.headers; requestOptions.params = req.params; requestOptions.query = req.query; requestOptions.files = req.files; requestOptions.method = req.method; requestOptions.body = req.body;

return requestOptions;

}

I could create a PR on this if this is interesting? Would certainly help me out

kibertoad commented 4 years ago

What do you have baseUrl for in this case? Swagger spec explicitly says: All API endpoints are relative to the base URL, so if your spec is structured otherwise, you are in a violation of spec.

kibertoad commented 4 years ago

@hpl002 Wait, it should be the other way around. You can add api/ as baseUrl in your spec and it will be concatted automatically when doing the matching.

Would be easier to understand situation if you shared (potentially with scrambled names) relevant fragments of your spec.

hpl002 commented 4 years ago

Thanks for getting back to me.

Here is a derivative of your pets.yaml spec

openapi: 3.0.0
servers:
  - url: "https://api.paymentsos.com/"
info:
  title: PaymentsOS API
  version: 1.0.0
x-flow-proxies:
  accounts:
    target: http://localhost:3020
paths:
  /accounts:
    x-flow-proxy: accounts  
    get:
      summary: get all pets

      tags:
        - pets
      operationId: listPets
      responses:
        "200":
          description: list of pets
          headers:
            x-zooz-request-id:
              description: request id
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/pets"

components:
  schemas:
    error_model:
      required:
        - description
        - category
      properties:
        category:
          type: string
          description: Error code.
        description:
          type: string
          description: Error message for the developer.
        more_info:
          type: string
          description: "More info about the error, can include link to the documentation."
    pet:
      description: pet
      type: object
      oneOf:
        - $ref: "#/components/schemas/dog_object"
        - $ref: "#/components/schemas/cat_object"
    pet2:
      description: pet
      type: object
      oneOf:
        - $ref: "#/components/schemas/dog_object2"
        - $ref: "#/components/schemas/cat_object"
    pets:
      type: array
      items:
        $ref: "#/components/schemas/pet"
    pet-discriminator-on-child:
      description: pet
      type: object
      required:
        - pet
      properties:
        pet:
          $ref: "#/components/schemas/pet-discriminator"
    pet-discriminator:
      description: pet
      type: object
      oneOf:
        - $ref: "#/components/schemas/dog_object"
        - $ref: "#/components/schemas/cat_object"
      discriminator:
        propertyName: type
    pet-discriminator-multiple:
      description: pet
      type: object
      oneOf:
        - $ref: "#/components/schemas/dog_multiple"
        - $ref: "#/components/schemas/cat_object"
      discriminator:
        propertyName: type
      properties:
        name:
          type: string
      required:
        - name
    pet-discriminator-mapping:
      description: pet
      type: object
      oneOf:
        - $ref: "#/components/schemas/dog_multiple"
        - $ref: "#/components/schemas/cat_object"
      discriminator:
        propertyName: type
        mapping:
          mapped_dog: "#/components/schemas/dog_multiple"
          mapped_cat: "#/components/schemas/cat_object"
      properties:
        name:
          type: string
      required:
        - name
    dog_object:
      type: object
      required:
        - bark
      properties:
        bark:
          type: string
    dog_object2:
      type: object
      required:
        - bark
      properties:
        bark:
          type: string
          enum:
            - foo
            - bar
    dog_multiple:
      type: object
      required:
        - dog_age
      discriminator:
        propertyName: model
      oneOf:
        - $ref: "#/components/schemas/small_dog"
        - $ref: "#/components/schemas/big_dog"
      properties:
        dog_age:
          type: string
    cat_object:
      type: object
      required:
        - fur
      properties:
        fur:
          type: string
          pattern: '^\d+$'

    small_dog:
      type: object
      required:
        - max_length
      properties:
        max_length:
          type: string
    big_dog:
      type: object
      required:
        - min_length
      properties:
        min_length:
          type: string
    medium_dog:
      type: object
      required:
        - min_length
        - max_length
      additionalProperties: false
      properties:
        max_length:
          type: string
        min_length:
          type: string

if have to set basepath for use with my other middleware. This creates a conflict when calling const methodSchema = schemaEndpointResolver.getMethodSchema(schemas, path, method) paths in schemas and path do not align, thus resulting in undefined and no validation.

Edit: Endpoints in schemas object are not prefixed with basepath Screenshot 2020-05-12 at 21 18 52

kibertoad commented 4 years ago

And when you change server to

servers:
  - url: "https://api.paymentsos.com/api"

that doesn't help?

hpl002 commented 4 years ago

No,still same result.

Did however bypass this by just forecefully setting the baseurl to nothing before sending it in. Works, but not ideal..

  return async (req, res, next) => {
    const currBase = req.baseUrl;
    req.baseUrl = "";
    inputValidation.init(gatewayConfiguration.configPath);
    inputValidation.validate(req, res, next);
    req.baseUrl = currBase;
    next();
  };
}
hpl002 commented 4 years ago

Feel free to close the issue is you're not planning to address it further. Forcefully setting the baseUrl works..

kibertoad commented 4 years ago

no-no, I still need to look into it