From 102591b009d254b100278326aaaaf524c888b79f Mon Sep 17 00:00:00 2001 From: Brady Wetherington Date: Wed, 30 Jun 2021 14:53:08 -0700 Subject: [PATCH 01/12] Better debugging output, and remove non-PHP-7.3-compatible option --- app/Console/Commands/RestoreFromBackup.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Console/Commands/RestoreFromBackup.php b/app/Console/Commands/RestoreFromBackup.php index b59eceacc..06c99ec08 100644 --- a/app/Console/Commands/RestoreFromBackup.php +++ b/app/Console/Commands/RestoreFromBackup.php @@ -61,7 +61,7 @@ class RestoreFromBackup extends Command $za = new ZipArchive(); - $errcode = $za->open($filename, ZipArchive::RDONLY); + $errcode = $za->open($filename/* , ZipArchive::RDONLY */); // that constant only exists in PHP 7.4 and higher if ($errcode !== true) { $errors = [ ZipArchive::ER_EXISTS => "File already exists.", @@ -248,8 +248,13 @@ class RestoreFromBackup extends Command } fclose($pipes[0]); fclose($sql_contents); + + $this->line(stream_get_contents($pipes[1])); fclose($pipes[1]); + + $this->error(stream_get_contents($pipes[2])); fclose($pipes[2]); + //wait, have to do fclose() on all pipes first? $close_results = proc_close($proc_results); if($close_results != 0) { From e15159b9c3e0342a330b16e5dcae4f5ba7b0fc4d Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Fri, 2 Jul 2021 10:17:29 +0300 Subject: [PATCH 02/12] trait base64 encoded files --- app/Http/Traits/ConvertsBase64toFiles.php | 111 ++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 app/Http/Traits/ConvertsBase64toFiles.php diff --git a/app/Http/Traits/ConvertsBase64toFiles.php b/app/Http/Traits/ConvertsBase64toFiles.php new file mode 100644 index 000000000..5d4f20b5a --- /dev/null +++ b/app/Http/Traits/ConvertsBase64toFiles.php @@ -0,0 +1,111 @@ +request; + } + + /** + * Helper method to get the uploaded files bag. + * + * @return FileBag + */ + private function uploadFilesBag(): FileBag + { + return $this->files; + } + + /** + * Pulls the Base64 contents for each file key and creates + * an UploadedFile instance from it and sets it on the + * request. + * + * @return void + */ + protected function prepareForValidation() + { + $flattened = Arr::dot($this->base64FileKeys()); + + Collection::make($flattened)->each(function ($filename, $key) { + rescue(function () use ($key, $filename) { + // dont process plain files + if ( $this->file($key)){ + return; + } + + $base64Contents = $this->input($key); + + if (!$base64Contents) { + return; + } + + // autogenerate filenames + if ($filename == 'auto'){ + $header = explode(';', $base64Contents, 2)[0]; + // Grab the image type from the header while we're at it. + $filename = $key . '.' . substr($header, strpos($header, '/')+1); + } + + // Generate a temporary path to store the Base64 contents + $tempFilePath = tempnam(sys_get_temp_dir(), $filename); + + // Store the contents using a stream, or by decoding manually + if (Str::startsWith($base64Contents, 'data:') && count(explode(',', $base64Contents)) > 1) { + $source = fopen($base64Contents, 'r'); + $destination = fopen($tempFilePath, 'w'); + + stream_copy_to_stream($source, $destination); + + fclose($source); + fclose($destination); + } else { + file_put_contents($tempFilePath, base64_decode($base64Contents, true)); + } + + $uploadedFile = new UploadedFile($tempFilePath, $filename, null, null, true); + + $body = $this->bodyParametersBag()->all(); + Arr::forget($body, $key); + $this->bodyParametersBag()->replace($body); + + $files = $this->uploadFilesBag()->all(); + Arr::set($files, $key, $uploadedFile); + $this->uploadFilesBag()->replace($files); + }, null, false); + }); + } +} +/** + * This file based on https://github.com/protonemedia/laravel-mixins/tree/master/src/Request + * + * MIT License + * + * Copyright (c) Protone Media B.V. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ \ No newline at end of file From e846e6ac76c989dd00335bd0cf5fa45b8fd11615 Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Fri, 2 Jul 2021 10:18:18 +0300 Subject: [PATCH 03/12] trait base64 encoded files --- app/Http/Requests/ImageUploadRequest.php | 19 +++++++++++++++---- app/Http/Traits/ConvertsBase64toFiles.php | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/Http/Requests/ImageUploadRequest.php b/app/Http/Requests/ImageUploadRequest.php index 3f4a7b64b..73ffc8eed 100644 --- a/app/Http/Requests/ImageUploadRequest.php +++ b/app/Http/Requests/ImageUploadRequest.php @@ -5,10 +5,13 @@ namespace App\Http\Requests; use App\Models\SnipeModel; use Intervention\Image\Facades\Image; use enshrined\svgSanitize\Sanitizer; +use App\Traits\ConvertsBase64ToFiles; use Storage; class ImageUploadRequest extends Request { + use ConvertsBase64ToFiles; + /** * Determine if the user is authorized to make this request. * @@ -26,10 +29,11 @@ class ImageUploadRequest extends Request */ public function rules() { - return [ - 'image' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp', - 'avatar' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp', - ]; + + return [ + 'image' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp', + 'avatar' => 'mimes:png,gif,jpg,jpeg,svg,bmp,svg+xml,webp', + ]; } public function response(array $errors) @@ -37,6 +41,13 @@ class ImageUploadRequest extends Request return $this->redirector->back()->withInput()->withErrors($errors, $this->errorBag); } + protected function base64FileKeys(): array + { + return [ + 'image' => 'auto', + ]; + } + /** * Handle and store any images attached to request * @param SnipeModel $item Item the image is associated with diff --git a/app/Http/Traits/ConvertsBase64toFiles.php b/app/Http/Traits/ConvertsBase64toFiles.php index 5d4f20b5a..71d316f84 100644 --- a/app/Http/Traits/ConvertsBase64toFiles.php +++ b/app/Http/Traits/ConvertsBase64toFiles.php @@ -1,6 +1,6 @@ Date: Fri, 2 Jul 2021 10:29:26 +0300 Subject: [PATCH 04/12] trait base64 encoded files --- app/Http/Requests/ImageUploadRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Requests/ImageUploadRequest.php b/app/Http/Requests/ImageUploadRequest.php index 73ffc8eed..1bde3edf9 100644 --- a/app/Http/Requests/ImageUploadRequest.php +++ b/app/Http/Requests/ImageUploadRequest.php @@ -5,7 +5,7 @@ namespace App\Http\Requests; use App\Models\SnipeModel; use Intervention\Image\Facades\Image; use enshrined\svgSanitize\Sanitizer; -use App\Traits\ConvertsBase64ToFiles; +use App\Http\Traits\ConvertsBase64ToFiles; use Storage; class ImageUploadRequest extends Request From f59f3dbde435a720360a7eef85c66d9c296239f5 Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Fri, 2 Jul 2021 10:43:15 +0300 Subject: [PATCH 05/12] case case again.. --- .../{ConvertsBase64toFiles.php => ConvertsBase64ToFiles.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/Http/Traits/{ConvertsBase64toFiles.php => ConvertsBase64ToFiles.php} (100%) diff --git a/app/Http/Traits/ConvertsBase64toFiles.php b/app/Http/Traits/ConvertsBase64ToFiles.php similarity index 100% rename from app/Http/Traits/ConvertsBase64toFiles.php rename to app/Http/Traits/ConvertsBase64ToFiles.php From d48a9d549df244202a659a861a8644869b72c15a Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Sun, 4 Jul 2021 13:37:05 +0300 Subject: [PATCH 06/12] Try without trait --- app/Http/Requests/ImageUploadRequest.php | 90 +++++++++++++++++++++++- 1 file changed, 87 insertions(+), 3 deletions(-) diff --git a/app/Http/Requests/ImageUploadRequest.php b/app/Http/Requests/ImageUploadRequest.php index 1bde3edf9..fe1a0897d 100644 --- a/app/Http/Requests/ImageUploadRequest.php +++ b/app/Http/Requests/ImageUploadRequest.php @@ -5,12 +5,11 @@ namespace App\Http\Requests; use App\Models\SnipeModel; use Intervention\Image\Facades\Image; use enshrined\svgSanitize\Sanitizer; -use App\Http\Traits\ConvertsBase64ToFiles; + use Storage; class ImageUploadRequest extends Request { - use ConvertsBase64ToFiles; /** * Determine if the user is authorized to make this request. @@ -40,7 +39,10 @@ class ImageUploadRequest extends Request { return $this->redirector->back()->withInput()->withErrors($errors, $this->errorBag); } - + + /** + * Fields that should be traited from base64 to files + */ protected function base64FileKeys(): array { return [ @@ -176,4 +178,86 @@ class ImageUploadRequest extends Request return $item; } + + + /** + * Helper method to get the body parameters bag. + * + * @return \Symfony\Component\HttpFoundation\ParameterBag + */ + private function bodyParametersBag(): ParameterBag + { + return $this->request; + } + + /** + * Helper method to get the uploaded files bag. + * + * @return FileBag + */ + private function uploadFilesBag(): FileBag + { + return $this->files; + } + + /** + * Pulls the Base64 contents for each file key and creates + * an UploadedFile instance from it and sets it on the + * request. + * + * @return void + */ + protected function prepareForValidation() + { + $flattened = Arr::dot($this->base64FileKeys()); + + Collection::make($flattened)->each(function ($filename, $key) { + rescue(function () use ($key, $filename) { + // dont process plain files + if ( $this->file($key)){ + return; + } + + $base64Contents = $this->input($key); + + if (!$base64Contents) { + return; + } + + // autogenerate filenames + if ($filename == 'auto'){ + $header = explode(';', $base64Contents, 2)[0]; + // Grab the image type from the header while we're at it. + $filename = $key . '.' . substr($header, strpos($header, '/')+1); + } + + // Generate a temporary path to store the Base64 contents + $tempFilePath = tempnam(sys_get_temp_dir(), $filename); + + // Store the contents using a stream, or by decoding manually + if (Str::startsWith($base64Contents, 'data:') && count(explode(',', $base64Contents)) > 1) { + $source = fopen($base64Contents, 'r'); + $destination = fopen($tempFilePath, 'w'); + + stream_copy_to_stream($source, $destination); + + fclose($source); + fclose($destination); + } else { + file_put_contents($tempFilePath, base64_decode($base64Contents, true)); + } + + $uploadedFile = new UploadedFile($tempFilePath, $filename, null, null, true); + + $body = $this->bodyParametersBag()->all(); + Arr::forget($body, $key); + $this->bodyParametersBag()->replace($body); + + $files = $this->uploadFilesBag()->all(); + Arr::set($files, $key, $uploadedFile); + $this->uploadFilesBag()->replace($files); + }, null, false); + }); + } + } From 02fb7ac03e591a9441e544d8e31b3379662f5842 Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Sun, 4 Jul 2021 13:39:46 +0300 Subject: [PATCH 07/12] Try without trait --- app/Http/Requests/ImageUploadRequest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Http/Requests/ImageUploadRequest.php b/app/Http/Requests/ImageUploadRequest.php index fe1a0897d..39d8287d5 100644 --- a/app/Http/Requests/ImageUploadRequest.php +++ b/app/Http/Requests/ImageUploadRequest.php @@ -5,7 +5,11 @@ namespace App\Http\Requests; use App\Models\SnipeModel; use Intervention\Image\Facades\Image; use enshrined\svgSanitize\Sanitizer; - +use Illuminate\Support\Arr; +use Illuminate\Support\Collection; +use Illuminate\Support\Str; +use Symfony\Component\HttpFoundation\FileBag; +use Symfony\Component\HttpFoundation\ParameterBag; use Storage; class ImageUploadRequest extends Request From 013df747d7aa77bf1f338eb998887fea8cea5d01 Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Mon, 5 Jul 2021 09:59:19 +0300 Subject: [PATCH 08/12] debug trait --- app/Http/Requests/ImageUploadRequest.php | 88 +---------------------- app/Http/Traits/ConvertsBase64ToFiles.php | 4 ++ 2 files changed, 6 insertions(+), 86 deletions(-) diff --git a/app/Http/Requests/ImageUploadRequest.php b/app/Http/Requests/ImageUploadRequest.php index 39d8287d5..a6da2e3e4 100644 --- a/app/Http/Requests/ImageUploadRequest.php +++ b/app/Http/Requests/ImageUploadRequest.php @@ -5,15 +5,12 @@ namespace App\Http\Requests; use App\Models\SnipeModel; use Intervention\Image\Facades\Image; use enshrined\svgSanitize\Sanitizer; -use Illuminate\Support\Arr; -use Illuminate\Support\Collection; -use Illuminate\Support\Str; -use Symfony\Component\HttpFoundation\FileBag; -use Symfony\Component\HttpFoundation\ParameterBag; +use App\Http\Traits\ConvertsBase64ToFiles; use Storage; class ImageUploadRequest extends Request { + use ConvertsBase64ToFiles; /** * Determine if the user is authorized to make this request. @@ -182,86 +179,5 @@ class ImageUploadRequest extends Request return $item; } - - /** - * Helper method to get the body parameters bag. - * - * @return \Symfony\Component\HttpFoundation\ParameterBag - */ - private function bodyParametersBag(): ParameterBag - { - return $this->request; - } - - /** - * Helper method to get the uploaded files bag. - * - * @return FileBag - */ - private function uploadFilesBag(): FileBag - { - return $this->files; - } - - /** - * Pulls the Base64 contents for each file key and creates - * an UploadedFile instance from it and sets it on the - * request. - * - * @return void - */ - protected function prepareForValidation() - { - $flattened = Arr::dot($this->base64FileKeys()); - - Collection::make($flattened)->each(function ($filename, $key) { - rescue(function () use ($key, $filename) { - // dont process plain files - if ( $this->file($key)){ - return; - } - - $base64Contents = $this->input($key); - - if (!$base64Contents) { - return; - } - - // autogenerate filenames - if ($filename == 'auto'){ - $header = explode(';', $base64Contents, 2)[0]; - // Grab the image type from the header while we're at it. - $filename = $key . '.' . substr($header, strpos($header, '/')+1); - } - - // Generate a temporary path to store the Base64 contents - $tempFilePath = tempnam(sys_get_temp_dir(), $filename); - - // Store the contents using a stream, or by decoding manually - if (Str::startsWith($base64Contents, 'data:') && count(explode(',', $base64Contents)) > 1) { - $source = fopen($base64Contents, 'r'); - $destination = fopen($tempFilePath, 'w'); - - stream_copy_to_stream($source, $destination); - - fclose($source); - fclose($destination); - } else { - file_put_contents($tempFilePath, base64_decode($base64Contents, true)); - } - - $uploadedFile = new UploadedFile($tempFilePath, $filename, null, null, true); - - $body = $this->bodyParametersBag()->all(); - Arr::forget($body, $key); - $this->bodyParametersBag()->replace($body); - - $files = $this->uploadFilesBag()->all(); - Arr::set($files, $key, $uploadedFile); - $this->uploadFilesBag()->replace($files); - }, null, false); - }); - } - } diff --git a/app/Http/Traits/ConvertsBase64ToFiles.php b/app/Http/Traits/ConvertsBase64ToFiles.php index 71d316f84..13c939e4d 100644 --- a/app/Http/Traits/ConvertsBase64ToFiles.php +++ b/app/Http/Traits/ConvertsBase64ToFiles.php @@ -88,10 +88,14 @@ trait ConvertsBase64ToFiles $body = $this->bodyParametersBag()->all(); Arr::forget($body, $key); $this->bodyParametersBag()->replace($body); + \Log::debug("Trait: file field $key replaced:". $request->has($key)); + $files = $this->uploadFilesBag()->all(); Arr::set($files, $key, $uploadedFile); $this->uploadFilesBag()->replace($files); + \Log::debug("Trait: file field $key inserted:". $request->hasFile($key)); + }, null, false); }); } From d66ef233bfd46549f5cc1d8f8a49f994e53a9ad9 Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Tue, 6 Jul 2021 06:25:37 +0300 Subject: [PATCH 09/12] handle files via standard field --- app/Http/Requests/ImageUploadRequest.php | 16 +++++++++++++--- app/Http/Traits/ConvertsBase64ToFiles.php | 19 ++++++++----------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/app/Http/Requests/ImageUploadRequest.php b/app/Http/Requests/ImageUploadRequest.php index a6da2e3e4..46f47e748 100644 --- a/app/Http/Requests/ImageUploadRequest.php +++ b/app/Http/Requests/ImageUploadRequest.php @@ -6,6 +6,7 @@ use App\Models\SnipeModel; use Intervention\Image\Facades\Image; use enshrined\svgSanitize\Sanitizer; use App\Http\Traits\ConvertsBase64ToFiles; +use Illuminate\Http\UploadedFile; use Storage; class ImageUploadRequest extends Request @@ -91,14 +92,23 @@ class ImageUploadRequest extends Request \Log::debug('Form fieldname is: '.$form_fieldname); \Log::debug('DB fieldname is: '.$use_db_field); \Log::debug('Trying to upload to '. $path); + + // ConvertBase64ToFiles just changes object type, + // as it cannot currently insert files to $this->files + if ($this->offsetGet($form_fieldname) instanceof UploadedFile) { + $image=$this->offsetGet($form_fieldname); + } else { + if ($this->hasFile($form_fieldname)) { + $image = $this->file($form_fieldname); + } + } - \Log::debug($this->file()); + \Log::debug($image); - if ($this->hasFile($form_fieldname)) { + if (isset($image)) { if (!config('app.lock_passwords')) { - $image = $this->file($form_fieldname); $ext = $image->getClientOriginalExtension(); $file_name = $type.'-'.$form_fieldname.'-'.str_random(10).'.'.$ext; diff --git a/app/Http/Traits/ConvertsBase64ToFiles.php b/app/Http/Traits/ConvertsBase64ToFiles.php index 13c939e4d..793746dbb 100644 --- a/app/Http/Traits/ConvertsBase64ToFiles.php +++ b/app/Http/Traits/ConvertsBase64ToFiles.php @@ -85,17 +85,14 @@ trait ConvertsBase64ToFiles $uploadedFile = new UploadedFile($tempFilePath, $filename, null, null, true); - $body = $this->bodyParametersBag()->all(); - Arr::forget($body, $key); - $this->bodyParametersBag()->replace($body); - \Log::debug("Trait: file field $key replaced:". $request->has($key)); - - - $files = $this->uploadFilesBag()->all(); - Arr::set($files, $key, $uploadedFile); - $this->uploadFilesBag()->replace($files); - \Log::debug("Trait: file field $key inserted:". $request->hasFile($key)); - + \Log::debug("Trait: uploadedfile ". $tempFilePath); + $this->offsetUnset($key); + \Log::debug("Trait: encoded field \"$key\" removed" ); + + //Inserting new file to $this-files does not work so have to deal this after + $this->offsetSet($key,$uploadedFile); + \Log::debug("Trait: encoded field \"$key\" inserted" ); + }, null, false); }); } From e3166c2209669d5329c30eb99e8d74d1ffdd74bd Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Tue, 6 Jul 2021 06:41:37 +0300 Subject: [PATCH 10/12] fix debug placement --- app/Http/Requests/ImageUploadRequest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Http/Requests/ImageUploadRequest.php b/app/Http/Requests/ImageUploadRequest.php index 46f47e748..6ad002f9b 100644 --- a/app/Http/Requests/ImageUploadRequest.php +++ b/app/Http/Requests/ImageUploadRequest.php @@ -103,9 +103,8 @@ class ImageUploadRequest extends Request } } - \Log::debug($image); - if (isset($image)) { + \Log::debug($image); if (!config('app.lock_passwords')) { From c1bc2486ad2d1561844ff9992b76f49c195c146c Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Tue, 6 Jul 2021 06:49:19 +0300 Subject: [PATCH 11/12] keep using request --- app/Http/Controllers/Api/ComponentsController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Http/Controllers/Api/ComponentsController.php b/app/Http/Controllers/Api/ComponentsController.php index 62618a29d..66b1bd447 100644 --- a/app/Http/Controllers/Api/ComponentsController.php +++ b/app/Http/Controllers/Api/ComponentsController.php @@ -7,6 +7,7 @@ use App\Http\Controllers\Controller; use App\Http\Transformers\ComponentsTransformer; use App\Models\Company; use App\Models\Component; +use App\Http\Requests\Request; use App\Http\Requests\ImageUploadRequest; use App\Events\CheckoutableCheckedIn; use App\Events\ComponentCheckedIn; From c21b29148419e12520f88d1d6d56239198dd2d0d Mon Sep 17 00:00:00 2001 From: Petri Asikainen Date: Tue, 6 Jul 2021 06:51:07 +0300 Subject: [PATCH 12/12] keep using request --- app/Http/Controllers/Api/ComponentsController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ComponentsController.php b/app/Http/Controllers/Api/ComponentsController.php index 66b1bd447..4f0821898 100644 --- a/app/Http/Controllers/Api/ComponentsController.php +++ b/app/Http/Controllers/Api/ComponentsController.php @@ -7,7 +7,7 @@ use App\Http\Controllers\Controller; use App\Http\Transformers\ComponentsTransformer; use App\Models\Company; use App\Models\Component; -use App\Http\Requests\Request; +use Illuminate\Http\Request; use App\Http\Requests\ImageUploadRequest; use App\Events\CheckoutableCheckedIn; use App\Events\ComponentCheckedIn;