Skip to content

Commit

Permalink
Fix request validation for request only having uploaded file (#182)
Browse files Browse the repository at this point in the history
  • Loading branch information
bastien-phi authored Feb 2, 2024
1 parent ae3cfdb commit 388dc3b
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
26 changes: 13 additions & 13 deletions src/Validation/RequestValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,6 @@ protected function validateParameters()
protected function validateBody(): void
{
$expectedBody = $this->operation()->requestBody;
$actualBody = $this->request->getContent();

// If required, then body should be non-empty.
if ($expectedBody->required === true && empty($actualBody)) {
throw new RequestValidationException('Request body required.');
}

// Content types should match.
$contentType = $this->request->header('Content-Type');
Expand All @@ -164,14 +158,20 @@ protected function validateBody(): void

// Capture schemas for validation.
$expectedBodyRawSchema = $expectedBody->content[$contentType]->schema;
$actualBodySchema = $actualBody;
if ($expectedBodyRawSchema->type === 'object' || $expectedBodyRawSchema->type === 'array' || $expectedBodyRawSchema->oneOf || $expectedBodyRawSchema->anyOf) {
if (in_array($contentType, ['application/json', 'application/vnd.api+json'])) {
$actualBodySchema = json_decode($actualBodySchema);
} else {
$actualBodySchema = $this->parseBodySchema();
}
if (
($expectedBodyRawSchema->type === 'object' || $expectedBodyRawSchema->type === 'array' || $expectedBodyRawSchema->oneOf || $expectedBodyRawSchema->anyOf)
&& in_array($contentType, ['application/json', 'application/vnd.api+json'])
) {
$actualBodySchema = json_decode($this->request->getContent());
} else {
$actualBodySchema = $this->parseBodySchema();
}

// If required, then body should be non-empty.
if ($expectedBody->required === true && empty($actualBodySchema)) {
throw new RequestValidationException('Request body required!');
}

$expectedBodySchema = $this->prepareData($expectedBodyRawSchema, 'write');

// Run validation.
Expand Down
27 changes: 27 additions & 0 deletions tests/Fixtures/Upload.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
openapi: 3.0.0
info:
title: Upload.v1
version: '1.0'
servers:
- url: 'http://localhost:3000'
paths:
/upload:
post:
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
required:
- file
responses:
'204':
description: No Content

components:
schemas: {}
18 changes: 17 additions & 1 deletion tests/RequestValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,11 @@ public function test_handles_form_data(): void

$this->post(
'/users',
['name' => 'Adam Campbell', 'email' => '[email protected]', 'picture' => UploadedFile::fake()->image('test.jpg')],
[
'name' => 'Adam Campbell',
'email' => '[email protected]',
'picture' => UploadedFile::fake()->image('test.jpg'),
],
['Content-Type' => 'multipart/form-data']
)
->assertValidRequest();
Expand Down Expand Up @@ -838,6 +842,18 @@ public static function enumProvider(): array
],
];
}

public function test_validates_upload_file(): void
{
Spectator::using('Upload.yml');

Route::post('/upload', function () {
return response()->noContent();
})->middleware(Middleware::class);

$this->post('/upload', ['file' => UploadedFile::fake()->createWithContent('test.xlsx', 'Content')], ['Content-Type' => 'multipart/form-data'])
->assertValidRequest();
}
}

class TestUser extends Model
Expand Down

0 comments on commit 388dc3b

Please sign in to comment.