Fix on multiparse request data
* bug fixin * refactoring Change-Id: I78d990c630a9149d8e762fdebdae9e908d3f194b
This commit is contained in:
parent
eedb771250
commit
c75aa1f10b
@ -11,6 +11,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
use App\Http\Utils\FileTypes;
|
||||||
use libs\utils\HTMLCleaner;
|
use libs\utils\HTMLCleaner;
|
||||||
use models\exceptions\EntityNotFoundException;
|
use models\exceptions\EntityNotFoundException;
|
||||||
use models\exceptions\ValidationException;
|
use models\exceptions\ValidationException;
|
||||||
@ -640,7 +642,13 @@ final class OAuth2PresentationApiController extends OAuth2ProtectedController
|
|||||||
'description',
|
'description',
|
||||||
];
|
];
|
||||||
|
|
||||||
$slide = $this->presentation_service->addSlideTo($request, $presentation_id, HTMLCleaner::cleanData($data, $fields));
|
$slide = $this->presentation_service->addSlideTo
|
||||||
|
(
|
||||||
|
$request,
|
||||||
|
$presentation_id,
|
||||||
|
HTMLCleaner::cleanData($data, $fields),
|
||||||
|
array_merge(FileTypes::ImagesExntesions, FileTypes::SlidesExtensions)
|
||||||
|
);
|
||||||
|
|
||||||
return $this->created(SerializerRegistry::getInstance()->getSerializer($slide)->serialize());
|
return $this->created(SerializerRegistry::getInstance()->getSerializer($slide)->serialize());
|
||||||
}
|
}
|
||||||
@ -675,25 +683,7 @@ final class OAuth2PresentationApiController extends OAuth2ProtectedController
|
|||||||
if (is_null($summit)) return $this->error404();
|
if (is_null($summit)) return $this->error404();
|
||||||
|
|
||||||
|
|
||||||
$content_type = $request->headers->has('Content-Type') ? strtolower( $request->headers->get('Content-Type')) : null;
|
|
||||||
|
|
||||||
if (false !== $pos = strpos($content_type, ';')) {
|
|
||||||
$content_type = substr($content_type, 0, $pos);
|
|
||||||
}
|
|
||||||
$file = null;
|
|
||||||
$data = $request->all();
|
$data = $request->all();
|
||||||
Log::debug("updatePresentationSlide: data ".var_dump($data));
|
|
||||||
if(strstr($content_type, 'multipart/form-data')) {
|
|
||||||
Log::debug("updatePresentationSlide: has multipart/form-data");
|
|
||||||
$parser = new ParseMultiPartFormDataInputStream(file_get_contents('php://input'));
|
|
||||||
$input = $parser->getInput();
|
|
||||||
Log::debug("updatePresentationSlide: input ".var_dump($input));
|
|
||||||
$data = $input['parameters'];
|
|
||||||
$files = $input['files'];
|
|
||||||
$file = null;
|
|
||||||
if (isset($files['file']))
|
|
||||||
$file = $files['file'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$rules = [
|
$rules = [
|
||||||
'link' => 'nullable|url',
|
'link' => 'nullable|url',
|
||||||
@ -720,7 +710,11 @@ final class OAuth2PresentationApiController extends OAuth2ProtectedController
|
|||||||
|
|
||||||
$slide = $this->presentation_service->updateSlide
|
$slide = $this->presentation_service->updateSlide
|
||||||
(
|
(
|
||||||
$request, $presentation_id, $slide_id, HTMLCleaner::cleanData($data, $fields), $file
|
$request,
|
||||||
|
$presentation_id,
|
||||||
|
$slide_id,
|
||||||
|
HTMLCleaner::cleanData($data, $fields),
|
||||||
|
array_merge(FileTypes::ImagesExntesions, FileTypes::SlidesExtensions)
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->updated(SerializerRegistry::getInstance()->getSerializer($slide)->serialize());
|
return $this->updated(SerializerRegistry::getInstance()->getSerializer($slide)->serialize());
|
||||||
|
@ -1932,28 +1932,10 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
|
|||||||
|
|
||||||
$summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id);
|
$summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id);
|
||||||
if (is_null($summit)) return $this->error404();
|
if (is_null($summit)) return $this->error404();
|
||||||
|
$data = $request->all();
|
||||||
$content_type = $request->headers->has('Content-Type') ? strtolower( $request->headers->get('Content-Type')) : null;
|
$rules = SummitLocationImageValidationRulesFactory::build(true);
|
||||||
|
|
||||||
if (false !== $pos = strpos($content_type, ';')) {
|
|
||||||
$content_type = substr($content_type, 0, $pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!strstr($content_type, 'multipart/form-data'))
|
|
||||||
return $this->error400();
|
|
||||||
|
|
||||||
$parser = new ParseMultiPartFormDataInputStream(file_get_contents('php://input'));
|
|
||||||
$input = $parser->getInput();
|
|
||||||
$metadata = $input['parameters'];
|
|
||||||
$files = $input['files'];
|
|
||||||
$file = null;
|
|
||||||
|
|
||||||
if(isset($files['file']))
|
|
||||||
$file = $files['file'];
|
|
||||||
|
|
||||||
$rules = SummitLocationImageValidationRulesFactory::build(true);
|
|
||||||
// Creates a Validator instance and validates the data.
|
// Creates a Validator instance and validates the data.
|
||||||
$validation = Validator::make($metadata, $rules);
|
$validation = Validator::make($data, $rules);
|
||||||
|
|
||||||
if ($validation->fails()) {
|
if ($validation->fails()) {
|
||||||
$messages = $validation->messages()->toArray();
|
$messages = $validation->messages()->toArray();
|
||||||
@ -1971,9 +1953,9 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
|
|||||||
$map_id,
|
$map_id,
|
||||||
HTMLCleaner::cleanData
|
HTMLCleaner::cleanData
|
||||||
(
|
(
|
||||||
$metadata, ['description']
|
$data, ['description']
|
||||||
),
|
),
|
||||||
$file
|
$request->hasFile('file') ? $request->file('file'):null
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->updated(SerializerRegistry::getInstance()->getSerializer($map)->serialize());
|
return $this->updated(SerializerRegistry::getInstance()->getSerializer($map)->serialize());
|
||||||
@ -2148,28 +2130,10 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
|
|||||||
try {
|
try {
|
||||||
$summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id);
|
$summit = SummitFinderStrategyFactory::build($this->repository, $this->resource_server_context)->find($summit_id);
|
||||||
if (is_null($summit)) return $this->error404();
|
if (is_null($summit)) return $this->error404();
|
||||||
|
$data = $request->all();
|
||||||
$content_type = $request->headers->has('Content-Type') ? strtolower( $request->headers->get('Content-Type')) : null;
|
$rules = SummitLocationImageValidationRulesFactory::build(true);
|
||||||
|
|
||||||
if (false !== $pos = strpos($content_type, ';')) {
|
|
||||||
$content_type = substr($content_type, 0, $pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!strstr($content_type, 'multipart/form-data'))
|
|
||||||
return $this->error400();
|
|
||||||
|
|
||||||
$parser = new ParseMultiPartFormDataInputStream(file_get_contents('php://input'));
|
|
||||||
$input = $parser->getInput();
|
|
||||||
$metadata = $input['parameters'];
|
|
||||||
$files = $input['files'];
|
|
||||||
$file = null;
|
|
||||||
|
|
||||||
if(isset($files['file']))
|
|
||||||
$file = $files['file'];
|
|
||||||
|
|
||||||
$rules = SummitLocationImageValidationRulesFactory::build(true);
|
|
||||||
// Creates a Validator instance and validates the data.
|
// Creates a Validator instance and validates the data.
|
||||||
$validation = Validator::make($metadata, $rules);
|
$validation = Validator::make($data, $rules);
|
||||||
|
|
||||||
if ($validation->fails()) {
|
if ($validation->fails()) {
|
||||||
$messages = $validation->messages()->toArray();
|
$messages = $validation->messages()->toArray();
|
||||||
@ -2187,9 +2151,9 @@ final class OAuth2SummitLocationsApiController extends OAuth2ProtectedController
|
|||||||
$image_id,
|
$image_id,
|
||||||
HTMLCleaner::cleanData
|
HTMLCleaner::cleanData
|
||||||
(
|
(
|
||||||
$metadata, ['description']
|
$data, ['description']
|
||||||
),
|
),
|
||||||
$file
|
$request->hasFile('file') ? $request->file('file'):null
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->updated(SerializerRegistry::getInstance()->getSerializer($image)->serialize());
|
return $this->updated(SerializerRegistry::getInstance()->getSerializer($image)->serialize());
|
||||||
|
@ -21,6 +21,7 @@ class Kernel extends HttpKernel
|
|||||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||||
\App\Http\Middleware\CORSMiddleware::class,
|
\App\Http\Middleware\CORSMiddleware::class,
|
||||||
\App\Http\Middleware\SecurityHTTPHeadersWriterMiddleware::class,
|
\App\Http\Middleware\SecurityHTTPHeadersWriterMiddleware::class,
|
||||||
|
\App\Http\Middleware\ParseMultipartFormDataInputForNonPostRequests::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
<?php namespace App\Http\Middleware;
|
||||||
|
/**
|
||||||
|
* Copyright 2019 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use Closure;
|
||||||
|
use utils\ParseMultiPartFormDataInputStream;
|
||||||
|
/**
|
||||||
|
* Class ParseMultipartFormDataInputForNonPostRequests
|
||||||
|
* @package App\Http\Middleware
|
||||||
|
*/
|
||||||
|
final class ParseMultipartFormDataInputForNonPostRequests
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Content-Type: multipart/form-data - only works for POST requests. All others fail, this is a bug in PHP since 2011.
|
||||||
|
* See comments here: https://github.com/laravel/framework/issues/13457
|
||||||
|
*
|
||||||
|
* This middleware converts all multi-part/form-data for NON-POST requests, into a properly formatted
|
||||||
|
* request variable for Laravel 5.6. It uses the ParseInputStream class, found here:
|
||||||
|
* https://gist.github.com/devmycloud/df28012101fbc55d8de1737762b70348
|
||||||
|
*/
|
||||||
|
public function handle($request, Closure $next)
|
||||||
|
{
|
||||||
|
if ($request->method() == 'POST' OR $request->method() == 'GET') {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preg_match('/multipart\/form-data/', $request->headers->get('Content-Type')) or
|
||||||
|
preg_match('/multipart\/form-data/', $request->headers->get('content-type'))
|
||||||
|
) {
|
||||||
|
$parser = new ParseMultiPartFormDataInputStream(file_get_contents('php://input'));
|
||||||
|
$params = $parser->getInput();
|
||||||
|
$files = [];
|
||||||
|
$parameters = [];
|
||||||
|
foreach ($params as $key => $param) {
|
||||||
|
if ($param instanceof \Symfony\Component\HttpFoundation\File\UploadedFile) {
|
||||||
|
$files[$key] = $param;
|
||||||
|
} else {
|
||||||
|
$parameters[$key] = $param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count($files) > 0) {
|
||||||
|
$request->files->add($files);
|
||||||
|
}
|
||||||
|
if (count($parameters) > 0) {
|
||||||
|
$request->request->add($parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
24
app/Http/Utils/FileTypes.php
Normal file
24
app/Http/Utils/FileTypes.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php namespace App\Http\Utils;
|
||||||
|
/**
|
||||||
|
* Copyright 2019 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class FileTypes
|
||||||
|
* @package App\Http\Utils
|
||||||
|
*/
|
||||||
|
final class FileTypes
|
||||||
|
{
|
||||||
|
const SlidesExtensions = ['ppt', 'pptx', 'xps', 'key', 'pdf'];
|
||||||
|
const ImagesExntesions = ['jpg', 'jpeg', 'png', 'svg', 'bmp', 'tga', 'tiff', 'gif'];
|
||||||
|
}
|
@ -235,7 +235,7 @@ final class ParseMultiPartFormDataInputStream
|
|||||||
{
|
{
|
||||||
$string = trim($string);
|
$string = trim($string);
|
||||||
$data = [];
|
$data = [];
|
||||||
if ( preg_match('/name=\"(.*)\"\n*(.*)$/s', $string, $match) ) {
|
if ( preg_match('name=\"([^\"]*)\"[\n|\r]+([^\n\r].*)$', $string, $match) ) {
|
||||||
if (preg_match('/^(.*)\[\]$/i', $match[1], $tmp)) {
|
if (preg_match('/^(.*)\[\]$/i', $match[1], $tmp)) {
|
||||||
$data[$tmp[1]][] = ($match[2] !== NULL ? $match[2] : '');
|
$data[$tmp[1]][] = ($match[2] !== NULL ? $match[2] : '');
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<?php namespace services\model;
|
<?php namespace services\model;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copyright 2016 OpenStack Foundation
|
* Copyright 2016 OpenStack Foundation
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
@ -21,7 +20,6 @@ use models\summit\PresentationSlide;
|
|||||||
use models\summit\PresentationVideo;
|
use models\summit\PresentationVideo;
|
||||||
use models\summit\Summit;
|
use models\summit\Summit;
|
||||||
use Illuminate\Http\Request as LaravelRequest;
|
use Illuminate\Http\Request as LaravelRequest;
|
||||||
use Illuminate\Http\UploadedFile;
|
|
||||||
/**
|
/**
|
||||||
* Interface IPresentationService
|
* Interface IPresentationService
|
||||||
* @package services\model
|
* @package services\model
|
||||||
@ -107,7 +105,7 @@ interface IPresentationService
|
|||||||
LaravelRequest $request,
|
LaravelRequest $request,
|
||||||
$presentation_id,
|
$presentation_id,
|
||||||
array $slide_data,
|
array $slide_data,
|
||||||
array $allowed_extensions = ['ppt', 'pptx', 'xps', 'key', 'pdf', 'jpg', 'jpeg', 'png', 'svg', 'bmp', 'tga', 'tiff', 'gif'],
|
array $allowed_extensions = [],
|
||||||
$max_file_size = 10485760
|
$max_file_size = 10485760
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -116,7 +114,6 @@ interface IPresentationService
|
|||||||
* @param int $presentation_id
|
* @param int $presentation_id
|
||||||
* @param int $slide_id
|
* @param int $slide_id
|
||||||
* @param array $slide_data
|
* @param array $slide_data
|
||||||
* @param UploadedFile $file
|
|
||||||
* @param array $allowed_extensions
|
* @param array $allowed_extensions
|
||||||
* @param int $max_file_size
|
* @param int $max_file_size
|
||||||
* @return mixed|PresentationSlide
|
* @return mixed|PresentationSlide
|
||||||
@ -128,8 +125,7 @@ interface IPresentationService
|
|||||||
$presentation_id,
|
$presentation_id,
|
||||||
$slide_id,
|
$slide_id,
|
||||||
array $slide_data,
|
array $slide_data,
|
||||||
UploadedFile $file = null,
|
array $allowed_extensions = [],
|
||||||
array $allowed_extensions = ['ppt', 'pptx', 'xps', 'key', 'pdf', 'jpg', 'jpeg', 'png', 'svg', 'bmp', 'tga', 'tiff', 'gif'],
|
|
||||||
$max_file_size = 10485760
|
$max_file_size = 10485760
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -623,7 +623,7 @@ final class PresentationService
|
|||||||
LaravelRequest $request,
|
LaravelRequest $request,
|
||||||
$presentation_id,
|
$presentation_id,
|
||||||
array $slide_data,
|
array $slide_data,
|
||||||
array $allowed_extensions = ['ppt', 'pptx', 'xps', 'key', 'pdf', 'jpg', 'jpeg', 'png', 'svg', 'bmp', 'tga', 'tiff', 'gif'],
|
array $allowed_extensions = [],
|
||||||
$max_file_size = 10485760
|
$max_file_size = 10485760
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -653,7 +653,7 @@ final class PresentationService
|
|||||||
$slide = PresentationSlideFactory::build($slide_data);
|
$slide = PresentationSlideFactory::build($slide_data);
|
||||||
|
|
||||||
// check if there is any file sent
|
// check if there is any file sent
|
||||||
if($request->hasFile('file')){
|
if($hasFile){
|
||||||
$file = $request->file('file');
|
$file = $request->file('file');
|
||||||
if (!in_array($file->extension(), $allowed_extensions)) {
|
if (!in_array($file->extension(), $allowed_extensions)) {
|
||||||
throw new ValidationException(
|
throw new ValidationException(
|
||||||
@ -684,7 +684,6 @@ final class PresentationService
|
|||||||
* @param int $presentation_id
|
* @param int $presentation_id
|
||||||
* @param int $slide_id
|
* @param int $slide_id
|
||||||
* @param array $slide_data
|
* @param array $slide_data
|
||||||
* @param UploadedFile $file
|
|
||||||
* @param array $allowed_extensions
|
* @param array $allowed_extensions
|
||||||
* @param int $max_file_size
|
* @param int $max_file_size
|
||||||
* @return mixed|PresentationSlide
|
* @return mixed|PresentationSlide
|
||||||
@ -696,8 +695,7 @@ final class PresentationService
|
|||||||
$presentation_id,
|
$presentation_id,
|
||||||
$slide_id,
|
$slide_id,
|
||||||
array $slide_data,
|
array $slide_data,
|
||||||
UploadedFile $file = null,
|
array $allowed_extensions = [],
|
||||||
array $allowed_extensions = ['ppt', 'pptx', 'xps', 'key', 'pdf', 'jpg', 'jpeg', 'png', 'svg', 'bmp', 'tga', 'tiff', 'gif'],
|
|
||||||
$max_file_size = 10485760
|
$max_file_size = 10485760
|
||||||
){
|
){
|
||||||
|
|
||||||
@ -708,8 +706,7 @@ final class PresentationService
|
|||||||
$slide_data,
|
$slide_data,
|
||||||
$max_file_size,
|
$max_file_size,
|
||||||
$allowed_extensions,
|
$allowed_extensions,
|
||||||
$slide_id,
|
$slide_id
|
||||||
$file
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
$presentation = $this->presentation_repository->getById($presentation_id);
|
$presentation = $this->presentation_repository->getById($presentation_id);
|
||||||
@ -730,7 +727,7 @@ final class PresentationService
|
|||||||
|
|
||||||
|
|
||||||
$hasLink = isset($slide_data['link']) && !empty($slide_data['link']);
|
$hasLink = isset($slide_data['link']) && !empty($slide_data['link']);
|
||||||
$hasFile = !is_null($file);
|
$hasFile = $request->hasFile('file');
|
||||||
|
|
||||||
if($hasFile && $hasLink){
|
if($hasFile && $hasLink){
|
||||||
throw new ValidationException("you must provide a file or a link, not both.");
|
throw new ValidationException("you must provide a file or a link, not both.");
|
||||||
@ -751,6 +748,7 @@ final class PresentationService
|
|||||||
|
|
||||||
// check if there is any file sent
|
// check if there is any file sent
|
||||||
if($hasFile){
|
if($hasFile){
|
||||||
|
$file = $request->file('file');
|
||||||
if (!in_array($file->extension(), $allowed_extensions)) {
|
if (!in_array($file->extension(), $allowed_extensions)) {
|
||||||
throw new ValidationException(
|
throw new ValidationException(
|
||||||
sprintf("file does not has a valid extension '(%s)'.", implode("','", $allowed_extensions)));
|
sprintf("file does not has a valid extension '(%s)'.", implode("','", $allowed_extensions)));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user