Git Product home page Git Product logo

openapi-validation-middleware's People

Contributors

bvis avatar christheyounger avatar chrisyoungbrighte avatar cia1 avatar diego-ninja avatar francescozanoni avatar fredcido avatar hatxor avatar hkarlstrom avatar lezhnev74 avatar mohammed-fahad avatar paulogic avatar rutek avatar shadowhand avatar staabm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

openapi-validation-middleware's Issues

Boolean parameter in query string

Hi, man.

I've got this parameter declaration within my OpenAPI schema (full schema here):

components:
  parameters:
    withAudits:
      in: query
      name: with_audits
      schema:
        type: boolean
      required: false

but, when I use it within my request, e.g. curl http://localhost/annotations/1?with_audits=true, I get the following validation error:

# Output of print_r($validator->validateRequest($request, $path, $method, $pathParameters))

Array (
  [0] => Array (
    [name] => with_audits
    [code] => error_type
    [value] => true
    [in] => query
    [expected] => boolean
    [used] => string
  )
)

Thanks in advance.

Francesco

Crashes if the content type isnt specified in the request.

Argument 1 passed to HKarlstrom\Middleware\OpenApiValidation::isJsonMediaType() must be of the type string, null given, called in /app/vendor/hkarlstrom/openapi-validation-middleware/src/OpenApiValidation.php on line 275

Can be fixed with coalesce operator.

Unclear result related to unallowed additional model properties

Hi, man.

I've just added additionalProperties: false to models of my project (https://github.com/francescozanoni/students-api-php/blob/master/public/openapi.yaml.example).

As expected, when I add additional properties to models (within request body, in this case), request validation fails.

But the returned error is not very clear:

curl -X POST "http://localhost/students/1/annotations" \
   -H "accept: application/json" \
   -H "Content-Type: application/json" \
   -d "{\"title\":\"My title\",\"content\":\"My body\",\"user_id\":123,\"one_more_property\":\"one more value\"}"

# Output of print_r(OpenApiValidation->validateRequest($request, $path, $method, $pathParameters))
Array (
  [0] => Array (
    [name] => one_more_property
    [code] => error_$schema
    [value] => one more value
    [in] => body
    [schema] => false
  )
)

Could the error be made a bit more explicit?

Thanks in advance!

Required fields validation fail

Hi again!

I'm testing the lib with some data and it seems to be accepting an empty array as a valid request regardless some fields from the body are required.

I think the problem is here!

$errors = array_merge($errors, $this->validateObject($requestMediaType->schema, $requestBodyData));

An empty array is evaluated as true by empty().
$request->getParsedBody() returns null|array|object. So I think changing that line to
elseif (null !== $requestBodyData && $this->isJsonMediaType($mediaType)) will work.

Thanks!

Exception if required body is empty

Hi, man.
Here's what I've found: if I send no body (be aware: not an empty string) to an endpoint where body is required, the following exception is raised:

curl -X POST http://localhost/endpoint

Argument 1 passed to HKarlstrom/Middleware/OpenApiValidation::isJsonMediaType() must be of the type string, null given, called in
hkarlstrom/openapi-validation-middleware/src/OpenApiValidation.php on line 274
hkarlstrom/openapi-validation-middleware/src/OpenApiValidation.php on line 585

Of course I'm aware this cURL request has no meaning: it's just a test.

By reading other issues, I see issues #29 and #31 seem related.

Any questions, here I am!

Thanks in advance.

Francesco

Caching strategy

Any plans to implement caching with the library? We have an openapi specification that's over 3 thousand lines already and it's getting 3 seconds only to parse the yaml file on every request.

I can submit a PR for that using PSR-6 standard, any recommendations?

Path parameter not validated with POST and PUT

Hi, man.

Since release 0.3.1 path parameters seem not being validated with HTTP methods POST and PUT anymore.

Here's my test:

  • correct ID with GET:

    curl -X GET "http://localhost/students/1/annotations" -H "accept: application/json"
    
    {
      "status_code": 200,
      "status": "OK",
      "message": "Resource(s) found",
      "data": [
        {
          "id": 1,
          "title": "First title",
          "content": "First content",
          "user_id": 123,
          "created_at": "2019-01-01 01:00:00",
          "updated_at": "2019-01-01 01:00:00"
        }
      ]
    }
  • incorrect ID (letters instead of digits) with GET, expected validation error:

    curl -X GET "http://localhost/students/abc/annotations" -H "accept: application/json"
    
    # Output of print_r(json_decode($response->getBody()->__toString(), true)['errors'])
    Array (
      [0] => Array (
        [name] => id
        [code] => error_type
        [value] => abc
        [in] => path
        [expected] => integer
        [used] => string
      )
    )
  • correct ID with POST:

    curl -X POST "http://localhost/students/1/annotations" \
         -H "accept: application/json"
         -H "Content-Type: application/json"
         -d "{\"title\":\"Annotation title\",\"content\":\"Annotation body\",\"user_id\":123}"
    
    {
      "status_code": 200,
      "status": "OK",
      "message": "Resource successfully retrieved/created/modified",
      "data": {
        "id": 4,
        "title": "Annotation title",
        "content": "Annotation body",
        "user_id": 123,
        "created_at": "2019-01-31 11:58:11",
        "updated_at": "2019-01-31 11:58:11"
      }
    }
  • incorrect ID (letters instead of digits) with POST, unexpected empty validation error list:

    curl -X POST "http://localhost/students/abc/annotations"
         -H "accept: application/json"
         -H "Content-Type: application/json"
         -d "{\"title\":\"Annotation title\",\"content\":\"Annotation body\",\"user_id\":123}"
    
    # Output of print_r(json_decode($response->getBody()->__toString(), true)['errors'])
    Array (
    )

If you need, my OpenAPI schema is always here: https://github.com/francescozanoni/students-api-php/blob/master/public/openapi.yaml.example

I'm quite sure it's related to the latest package release, since it's the only thing I've changed within my project.

Thanks in advance!

PHP 8 support

Installing PHP 8.0 is prohibited, only 7.x are allowed in the composer.json.

Support nullable values (nullable:true)

I just stumbled upon this problem. Looks like nullable validation is not performed correctly.

Specification contains this schema:

"before_sale_price": {
  "type": "integer",
  "minimum": 0,
  "nullable": true,
  "description": "A price before discounts applied"
}

When I run the validation process, I get this error:

{
        "name": "data.data.0.before_sale_price",
        "code": "error_type",
        "value": null,
        "in": "body",
        "expected": "integer",
        "used": "null"
}

I think this is related to #8 because canonic JSON Schema supports this format:

"before_sale_price": {
  "type": ["integer",null]
},

Do you think I should convert the schema to JSON Schema first here?

Empty request validation

Hi there!

I'm trying to send a request with an empty array to an endpoint with required bodyRequest and I got a required-type error. An empty array is a valid, non-empty body, it has information.

I think the problem is here!

if (empty($requestBodyData) && $requestBody->required) {

An empty array is evaluated as true by empty().
$request->getParsedBody() returns null|array|object. So I think changing that line to
if (null === $requestBodyData && $requestBody->required) will work.

Thanks!

PHP 8.1 deprecation of null arguments

ERROR: mb_strlen(): Passing null to parameter #1 ($string) of type string is deprecated on line 559 in file /usr/share/nginx/html/vendor/hkarlstrom/openapi-validation-middleware/src/OpenApiValidation.php

Make `validateRequest` public

Hey!
I wonder if you think the method could be public (just like the other ones: validateResponseHeaders,validateResponseBody ), so the library can be used not as a middleware but rather as a validation library like this:

$validator = new OpenApiValidation(...);
$validator->validateRequest($request);

It feels that middleware is just a single application for the underlying validator.
There could be more. For example, validating of logged requests & responses.

Not able to return a plain boolean as a response

When I try to validate a response like this one:

responses: {
  200: {
    description: "Program replaced",
    content: {
      application/json: {
        schema: {
          type: "boolean"
        },
        example: true
     }
    }
  }
}

I traced the error and located in /vendor/hkarlstrom/openapi-validation-middleware/src/OpenApiValidation.php:359

private function validateObject(array $schema, array $value) : array

That method expects to always receive an array. It should be mixed because it could be a dimple string or in my case a simple boolean.

Request body with missing required fields in object passes validation

This issue is related to #31 and a proposed solution is offered below.

Hello,

I am testing some calls against a schema that are supposed to fail validation, but they validate without errors.

This would be the simplified schema:

  SomeAddress:
      type: object
      required:
        - country
      properties:
        country:
          type: string

  SomeCommand:
     type: object
     required:
       - from
     properties:
       from:
          $ref: '#/components/schemas/SomeAddress'

...
 requestBodies:
   ...
    schema:
       $ref: '.../SomeCommand'

Sending this in a POST as body, I correctly get a "missing country" error:

{
  "from": {
    "": 1
  }
}

But sending this, I get no error and the empty request gets to my application with unexpected empty fields:

{
  "from": {
  }
}

I have been digging a bit and I've found that this behavior is intentional:

if ('error_type' == $err['code'] && empty($err['value']) && 'object' == $err['expected'] && 'array' == $err['used']) {

I understand that the problem happens because PHP decodes JSON objects as array, so when it is empty there is no way to tell between {} and [] once it is decoded.
However, this is a great drawback because it allows empty objects to be considered valid although the specification says that an object with required properties MUST be received.

I have a suggestion: let the user decide if they want this behaviour or they want to carry on and signal a validation error when receiving empty objects where required properties are expected.
This would be simply providing an additional option, by default with the current library behavior.

This would be the implementation:

if ($this->options['strictEmptyArrayValidation']) {
    if ('error_type' == $err['code'] && empty($err['value']) && 'object' == $err['expected'] && 'array' == $err['used']) {
        return [];
    }
}

With this change the library would be usable for me.
If you like it, I have the code prepared to open a pull request including this, the option initialization and a new test to cover this option.

Thanks for your time.

Query parameters with "deepObject" and the "explode" keyword

Given the following parameters schema:

{
    "name": "filter",
    "in": "query",
    "style": "deepObject",
    "explode": false,
    "schema": {
        "type": "object",
        "properties": {
            "status": {
                "type": "array",
                "items": {
                    "type": "string",
                    "enum": ["open", "pending", "needs_attention", "done"]
                }
            }
        }
    }
}

I should would expect a query string filter[status]=open,pending to be parsed as:

[
    'filter' => [
        'status' => [
            'open',
            'pending',
        ]
]

However, it seems that this package does not respect the explode: false configuration and reports that the status parameter is a string.

allOf not supported on response validation

Hi, man.
This is the standard response of one of my endpoints (a simple GET /students/1), whereas all fields are required (except phone, which is not the matter here):

{
    "status_code": 200,
    "status": "OK",
    "message": "Resource successfully retrieved/created/modified",
    "data": {
        "id": 1,
        "first_name": "John",
        "last_name": "Doe",
        "e_mail": "[email protected]",
        "phone": "1234-567890",
        "nationality": "UK"
    }
}

I've added response validation to my app, via OpenApiValidation->validateResponseBody() method.

To test the functionality, I've removed "first_name": "John", from response, but I'm getting this validation error:

{
    "name": "data",
    "code": "error_allOf",
    "value": {
        "id": 1,
        "last_name": "Doe",
        "e_mail": "[email protected]",
        "phone": "1234-567890",
        "nationality": "UK"
    }
}

I expected an error related to first_name property mandatority, instead.

Was maybe allOf support added to request validation only?

Thanks once more.

(I suspect you could start hating me...)

Introduce Exception types for validation fails

This issue is for discussion.

Currently, if validation fails we get a general \Exception instance with a text message. I think it would be beneficial to have multiple exceptions. For example, PathMissedException is thrown when we make a request to an undocumented path. Along with the type, we can attach the path itself:

throw new PathMissedException($method, $path);

This typed exceptions allows a consumer to write highly customizable logic on top of the package.

Package needs upgrade to be compatible with php8

Opis/Json-Schema has moved to v2 from v1. In our system when we implemented custom validation it starts failing due to filter_var PHP function. Latest opis/json has made changes that makes it compatible.

using the nullable attribute on a property with a format causes crash when posting with form-data encoding

When I make a POST to my route using form-data encoding instead of JSON, and I am using the nullable attribute, and I have set a format, I receive a TypeError.

Argument 1 passed to HKarlstrom\Middleware\OpenApiValidation::checkFormat() must be of the type string, array given, called in /var/www/vendor/hkarlstrom/openapi-validation-middleware/src/OpenApiValidation.php on line 343
#0 /var/www/vendor/hkarlstrom/openapi-validation-middleware/src/OpenApiValidation.php(343): HKarlstrom\Middleware\OpenApiValidation->checkFormat(Array, 'date-time')

    MyObject:
      required:
        - amount
        - userId
        - methodId
        - date
        amount:
          type: number
        userId:
          type: integer
        methodId:
          description: 'Payment Method ID. Set to null to use existing method. Set to ''DD'' for direct debit'
          type: string
          nullable: true
        date:
          description: 'Date in ISO 8601 format. Set to null for immediate processing'
          type: string
          format: date-time
          nullable: true

Note this field still could be provided, but allowed to be null. It works fine when submitting a raw json request. https://swagger.io/docs/specification/data-models/data-types/#null

The problem appears to be here:

    private function validateProperties(array $properties) : ?array
    {
        $errors = [];
        foreach ($properties as $property) {
            if (isset($property->schema->type, $property->schema->format)) {
                $this->checkFormat($property->schema->type, $property->schema->format);
object(HKarlstrom\Middleware\OpenApiValidation\Property)[527]
  public 'name' => string 'date (length=11)
  public 'in' => string 'form-data' (length=9)
  public 'required' => boolean false
  public 'schema' => 
    object(stdClass)[528]
      public 'description' => string 'Date in ISO 8601 format. Set to null for immediate processing' (length=66)
      public 'type' => 
        array (size=2)
          0 => string 'string' (length=6)
          1 => string 'null' (length=4)
      public 'format' => string 'date-time' (length=9)
  public 'value' => null```

Need some help

I use this repository to verifiy incomming and outgoing json requests and responses.
I want to rework the error output to another json format.

Currently it is, as example:

Error 400: 
{
    "message": "Request validation failed",
    "errors": [
        {
            "name": "catalogus",
            "code": "error_format",
            "value": "",
            "in": "query",
            "type": "string",
            "format": "uri"
        }
    ]
}

I tried to catch this error so i can modify the repsonse like this:

$mw = new HKarlstrom\Middleware\OpenApiValidation(__DIR__.'/catalog_openapi.json');
$mw->addFormat('string','duration',new myDurationFormat());

$options = [
		'validateRequest'=> false,
		'exampleResponse' => true,
		 'beforeHandler' => function (\Psr\Http\Message\ServerRequestInterface $request, array $errors) : \Psr\Http\Message\ServerRequestInterface {
			// Alter request modifiy the json reponse here !!!
			echo "tadaaaa"; <- never outputted
			return $request;
		}
	];

And finally in my route:

$app->get('/v1/zaaktypen[/{params:.*}]',\App\Action\ZTCZaaktypenAction::class)->add($mw,$options);

But it never touches the before- or errorHandler.

Any ideas how to get this working?

Features. Load schema from json-array

I have already loaded schema from a file. Now I want to run validator. For that I have to load schema from a file again.
It will be excelent:

/**
 * Class HKarlstrom\Middleware\OpenApiValidation.php
 * @param string|array $filename
*/
OpenApiValidation::__construct($filename, array $options = [])

So, I can write somthing like this:

$schema = json_decode(file_get_contents($fileName));
$validator = new OpenApiValidation($schema)

Failing validation of allOf

Hi man,
I'm trying to validate my requests, but I'm getting this odd error with a PUT request, whereas the object schema to use is made of a allOf composition:

ERROR: Data validation failed for %s {"exception":"[object] (Respect\Validation\Exceptions\ValidationException(code: 0): [
    {
        "name": "",
        "code": "error_allOf",
        "value": {
            "id": 2,
            "first_name": "Jane",
            "last_name": "Doe",
            "e_mail": "[email protected]",
            "phone": "3333-11111111",
            "nationality": "IE"
        }
    }

This is the object schema:

schemas:
    NewStudent:
      type: object
      properties:
        first_name:
          type: string
          minLength: 2
        last_name:
          type: string
          minLength: 2
        e_mail:
          type: string
        phone:
          type: string
        nationality:
          type: string
          pattern: '^[A-Z]{2}$'
      required:
        - first_name
        - last_name
        - e_mail
        - nationality
    Student:
      allOf:
        - $ref: '#/components/schemas/NewStudent'
        - type: object
          properties:
            id:
              type: integer
          required:
            - id

And this is the modified version (no allOf) that works:

schemas:
    NewStudent:
      type: object
      properties:
        first_name:
          type: string
          minLength: 2
        last_name:
          type: string
          minLength: 2
        e_mail:
          type: string
        phone:
          type: string
        nationality:
          type: string
          pattern: '^[A-Z]{2}$'
      required:
        - first_name
        - last_name
        - e_mail
        - nationality
    Student:
      type: object
      properties:
        id:
          type: integer
        first_name:
          type: string
          minLength: 2
        last_name:
          type: string
          minLength: 2
        e_mail:
          type: string
        phone:
          type: string
        nationality:
          type: string
          pattern: '^[A-Z]{2}$'
      required:
        - id
        - first_name
        - last_name
        - e_mail
        - nationality

Header not properly validate

I am trying to use the lib to validate some headers in the request using Slim 3.12.
This is how the parameter looks like in my openapi:

components:
  parameters:
    X-Location-Code:
      in: header
      name: X-Location-Code
      schema:
        type: string
        pattern: '^[A-Z]{3}$'
      required: true

This is my request:

GET /references/en/SIPStatus HTTP/1.1
Host: localhost:8000
X-Location-Code: DIL

And still, I'm getting an error saying that the header X-Location-Code was not found. I know that Slim converts the header to lowecase and allow to fetch them regardless.
When checking the code, at the OpenApiValidation.php line 236, we can see:

$properties[] = Property::fromParameter($p, $values[$p->in][$p->name] ?? null);

But that $values variable doesn't seem to host the headers values.

No context in validation message

Hi man,
the two following requests have exactly the same output, although the incorrect {id} parameter is respectively a body and a path parameter:

  • wrong on body
    PUT http://localhost/students/1
    {
      "id": "abc",
      "first_name": "Jane",
      "last_name": "Doe",
      "e_mail": "[email protected]",
      "phone": "3333-11111111",
      "nationality": "IE"
    }
    
  • wrong on path
    PUT http://localhost/students/abc
    {
      "id": 2,
      "first_name": "Jane",
      "last_name": "Doe",
      "e_mail": "[email protected]",
      "phone": "3333-11111111",
      "nationality": "IE"
    }
    

Here is the common output, where I think a context flag is missing:

Array (
    [message] => Request validation failed
    [errors] => Array (
            [0] => Array (
                    [name] => id
                    [code] => error_type
                    [value] => abc
                    [expected] => integer
                    [used] => string
                )
        )
)

Thanks in advance once more!

MissingFormatException duration

Implemented this middleware and got the following error:

HKarlstrom\Middleware\OpenApiValidation\Exception\MissingFormatException
Message: Missing validator for type=string, format=duration
File:C:\inetpub\wwwroot\zocommongroundapidevelopment\vendor\hkarlstrom\openapi-validation-middleware\src\OpenApiValidation.php

Does the format: duration needs to be inlemented?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.