From f53db8ba754e283946e27e63d23087f48287503a Mon Sep 17 00:00:00 2001 From: snipe Date: Tue, 5 Sep 2023 18:28:01 +0100 Subject: [PATCH 1/4] Fixed #13562 - allow inline view for uploaded files Signed-off-by: snipe --- .../AccessoriesFilesController.php | 21 +++++++--------- .../AssetModelsFilesController.php | 13 +++++----- .../Assets/AssetFilesController.php | 13 +++++----- .../Components/ComponentsFilesController.php | 24 ++++++++----------- .../ConsumablesFilesController.php | 23 ++++++++---------- .../Licenses/LicenseFilesController.php | 20 +++++++--------- .../Controllers/Users/UserFilesController.php | 17 +++++++++---- resources/views/accessories/view.blade.php | 7 +++++- resources/views/components/view.blade.php | 7 +++++- resources/views/consumables/view.blade.php | 6 ++++- resources/views/hardware/view.blade.php | 13 ++++++++-- resources/views/licenses/view.blade.php | 7 +++++- resources/views/models/view.blade.php | 7 +++++- resources/views/users/view.blade.php | 6 ++++- 14 files changed, 109 insertions(+), 75 deletions(-) diff --git a/app/Http/Controllers/Accessories/AccessoriesFilesController.php b/app/Http/Controllers/Accessories/AccessoriesFilesController.php index ef701020d8..4f166b06d5 100644 --- a/app/Http/Controllers/Accessories/AccessoriesFilesController.php +++ b/app/Http/Controllers/Accessories/AccessoriesFilesController.php @@ -161,22 +161,19 @@ class AccessoriesFilesController extends Controller ->header('Content-Type', 'text/plain'); } else { + // Display the file inline + if (request('inline') == 'true') { + $headers = [ + 'Content-Disposition' => 'inline', + ]; + return Storage::download($file, $log->filename, $headers); + } + + // We have to override the URL stuff here, since local defaults in Laravel's Flysystem // won't work, as they're not accessible via the web if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer? return StorageHelper::downloader($file); - } else { - if ($download != 'true') { - \Log::debug('display the file'); - if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones - return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file))); - } - - return JsonResponse::create(['error' => 'Failed validation: '], 500); - } - - return StorageHelper::downloader($file); - } } } diff --git a/app/Http/Controllers/AssetModelsFilesController.php b/app/Http/Controllers/AssetModelsFilesController.php index a68ef482cc..9889cd29ca 100644 --- a/app/Http/Controllers/AssetModelsFilesController.php +++ b/app/Http/Controllers/AssetModelsFilesController.php @@ -78,7 +78,7 @@ class AssetModelsFilesController extends Controller * @return View * @throws \Illuminate\Auth\Access\AuthorizationException */ - public function show($modelId = null, $fileId = null, $download = true) + public function show($modelId = null, $fileId = null) { $model = AssetModel::find($modelId); // the asset is valid @@ -99,12 +99,13 @@ class AssetModelsFilesController extends Controller ->header('Content-Type', 'text/plain'); } - if ($download != 'true') { - if ($contents = file_get_contents(Storage::url($file))) { - return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file))); - } + if (request('inline') == 'true') { - return JsonResponse::create(['error' => 'Failed validation: '], 500); + $headers = [ + 'Content-Disposition' => 'inline', + ]; + + return Storage::download($file, $log->filename, $headers); } return StorageHelper::downloader($file); diff --git a/app/Http/Controllers/Assets/AssetFilesController.php b/app/Http/Controllers/Assets/AssetFilesController.php index 2c7d6ff9ec..a4e0605999 100644 --- a/app/Http/Controllers/Assets/AssetFilesController.php +++ b/app/Http/Controllers/Assets/AssetFilesController.php @@ -79,7 +79,7 @@ class AssetFilesController extends Controller * @return View * @throws \Illuminate\Auth\Access\AuthorizationException */ - public function show($assetId = null, $fileId = null, $download = true) + public function show($assetId = null, $fileId = null) { $asset = Asset::find($assetId); // the asset is valid @@ -103,12 +103,13 @@ class AssetFilesController extends Controller ->header('Content-Type', 'text/plain'); } - if ($download != 'true') { - if ($contents = file_get_contents(Storage::url($file))) { - return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file))); - } + if (request('inline') == 'true') { - return JsonResponse::create(['error' => 'Failed validation: '], 500); + $headers = [ + 'Content-Disposition' => 'inline', + ]; + + return Storage::download($file, $log->filename, $headers); } return StorageHelper::downloader($file); diff --git a/app/Http/Controllers/Components/ComponentsFilesController.php b/app/Http/Controllers/Components/ComponentsFilesController.php index 3fc93b74e5..d46dc05f9c 100644 --- a/app/Http/Controllers/Components/ComponentsFilesController.php +++ b/app/Http/Controllers/Components/ComponentsFilesController.php @@ -132,7 +132,7 @@ class ComponentsFilesController extends Controller * @return \Symfony\Component\HttpFoundation\Response * @throws \Illuminate\Auth\Access\AuthorizationException */ - public function show($componentId = null, $fileId = null, $download = true) + public function show($componentId = null, $fileId = null) { \Log::debug('Private filesystem is: '.config('filesystems.default')); $component = Component::find($componentId); @@ -157,21 +157,17 @@ class ComponentsFilesController extends Controller ->header('Content-Type', 'text/plain'); } else { + // Display the file inline + if (request('inline') == 'true') { + $headers = [ + 'Content-Disposition' => 'inline', + ]; + return Storage::download($file, $log->filename, $headers); + } + if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer? return StorageHelper::downloader($file); - } else { - if ($download != 'true') { - \Log::debug('display the file'); - if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones - return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file))); - } - - return JsonResponse::create(['error' => 'Failed validation: '], 500); - } - - return StorageHelper::downloader($file); - - } + } } } diff --git a/app/Http/Controllers/Consumables/ConsumablesFilesController.php b/app/Http/Controllers/Consumables/ConsumablesFilesController.php index 9b4007a43b..def1e0d8ed 100644 --- a/app/Http/Controllers/Consumables/ConsumablesFilesController.php +++ b/app/Http/Controllers/Consumables/ConsumablesFilesController.php @@ -131,7 +131,7 @@ class ConsumablesFilesController extends Controller * @return \Symfony\Consumable\HttpFoundation\Response * @throws \Illuminate\Auth\Access\AuthorizationException */ - public function show($consumableId = null, $fileId = null, $download = true) + public function show($consumableId = null, $fileId = null) { $consumable = Consumable::find($consumableId); @@ -155,22 +155,19 @@ class ConsumablesFilesController extends Controller ->header('Content-Type', 'text/plain'); } else { + // Display the file inline + if (request('inline') == 'true') { + $headers = [ + 'Content-Disposition' => 'inline', + ]; + return Storage::download($file, $log->filename, $headers); + } + + // We have to override the URL stuff here, since local defaults in Laravel's Flysystem // won't work, as they're not accessible via the web if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer? return StorageHelper::downloader($file); - } else { - if ($download != 'true') { - \Log::debug('display the file'); - if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones - return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file))); - } - - return JsonResponse::create(['error' => 'Failed validation: '], 500); - } - - return StorageHelper::downloader($file); - } } } diff --git a/app/Http/Controllers/Licenses/LicenseFilesController.php b/app/Http/Controllers/Licenses/LicenseFilesController.php index d457d4983a..442635669b 100644 --- a/app/Http/Controllers/Licenses/LicenseFilesController.php +++ b/app/Http/Controllers/Licenses/LicenseFilesController.php @@ -152,21 +152,19 @@ class LicenseFilesController extends Controller ->header('Content-Type', 'text/plain'); } else { + if (request('inline') == 'true') { + + $headers = [ + 'Content-Disposition' => 'inline', + ]; + + return Storage::download($file, $log->filename, $headers); + } + // We have to override the URL stuff here, since local defaults in Laravel's Flysystem // won't work, as they're not accessible via the web if (config('filesystems.default') == 'local') { // TODO - is there any way to fix this at the StorageHelper layer? return StorageHelper::downloader($file); - } else { - if ($download != 'true') { - \Log::debug('display the file'); - if ($contents = file_get_contents(Storage::url($file))) { // TODO - this will fail on private S3 files or large public ones - return Response::make(Storage::url($file)->header('Content-Type', mime_content_type($file))); - } - - return JsonResponse::create(['error' => 'Failed validation: '], 500); - } - - return StorageHelper::downloader($file); } } diff --git a/app/Http/Controllers/Users/UserFilesController.php b/app/Http/Controllers/Users/UserFilesController.php index cb49396324..a2fdcd0fe3 100644 --- a/app/Http/Controllers/Users/UserFilesController.php +++ b/app/Http/Controllers/Users/UserFilesController.php @@ -139,18 +139,25 @@ class UserFilesController extends Controller // the license is valid if (isset($user->id)) { + $this->authorize('view', $user); $log = Actionlog::find($fileId); - $file = $log->get_src('users'); + $file = 'private_uploads/users/'.$log->filename; + + // Display the file inline + if (request('inline') == 'true') { + $headers = [ + 'Content-Disposition' => 'inline', + ]; + return Storage::download($file, $log->filename, $headers); + } return Response::download($file); //FIXME this doesn't use the new StorageHelper yet, but it's complicated... } - // Prepare the error message - $error = trans('admin/users/message.user_not_found', ['id' => $userId]); - // Redirect to the licence management page - return redirect()->route('users.index')->with('error', $error); + // Redirect to the user management page if the user doesn't exist + return redirect()->route('users.index')->with('error', trans('admin/users/message.user_not_found', ['id' => $userId])); } } diff --git a/resources/views/accessories/view.blade.php b/resources/views/accessories/view.blade.php index 86b4ee7730..0810cbd740 100644 --- a/resources/views/accessories/view.blade.php +++ b/resources/views/accessories/view.blade.php @@ -210,10 +210,15 @@ @if ($file->filename) - + {{ trans('general.download') }} + + + + + @endif {{ $file->created_at }} diff --git a/resources/views/components/view.blade.php b/resources/views/components/view.blade.php index 70bd87948b..6c3c04511a 100644 --- a/resources/views/components/view.blade.php +++ b/resources/views/components/view.blade.php @@ -203,10 +203,15 @@ @if ($file->filename) - + {{ trans('general.download') }} + + + + + @endif {{ $file->created_at }} diff --git a/resources/views/consumables/view.blade.php b/resources/views/consumables/view.blade.php index fa9b5ab485..26265a3d74 100644 --- a/resources/views/consumables/view.blade.php +++ b/resources/views/consumables/view.blade.php @@ -160,10 +160,14 @@ @if ($file->filename) - + {{ trans('general.download') }} + + + + @endif {{ $file->created_at }} diff --git a/resources/views/hardware/view.blade.php b/resources/views/hardware/view.blade.php index a583602958..0383404e0e 100755 --- a/resources/views/hardware/view.blade.php +++ b/resources/views/hardware/view.blade.php @@ -1266,9 +1266,13 @@ @if (($file->filename) && (Storage::exists('private_uploads/assets/'.$file->filename))) - + + + + + @endif @@ -1363,9 +1367,14 @@ @if (($file->filename) && (Storage::exists('private_uploads/assetmodels/'.$file->filename))) - + + + + + + @endif diff --git a/resources/views/licenses/view.blade.php b/resources/views/licenses/view.blade.php index 8dcf10caf2..f25076e714 100755 --- a/resources/views/licenses/view.blade.php +++ b/resources/views/licenses/view.blade.php @@ -474,10 +474,15 @@ @if ($file->filename) - + {{ trans('general.download') }} + + + + + @endif {{ $file->created_at }} diff --git a/resources/views/models/view.blade.php b/resources/views/models/view.blade.php index 8bce7365fd..3a5fd9a6ba 100755 --- a/resources/views/models/view.blade.php +++ b/resources/views/models/view.blade.php @@ -168,9 +168,14 @@ @if (($file->filename) && (Storage::exists('private_uploads/assetmodels/'.$file->filename))) - + + + + + + @endif diff --git a/resources/views/users/view.blade.php b/resources/views/users/view.blade.php index ee0495a70a..5a9cf7ebfe 100755 --- a/resources/views/users/view.blade.php +++ b/resources/views/users/view.blade.php @@ -937,10 +937,14 @@ @if ($file->filename) @if (Storage::exists('private_uploads/users/'.$file->filename)) - + {{ trans('general.download') }} + + + + @endif @endif From 65a76c599c09b1b3384b1d279a42d082c3b9ce12 Mon Sep 17 00:00:00 2001 From: snipe Date: Tue, 5 Sep 2023 18:35:07 +0100 Subject: [PATCH 2/4] Added inline=true to image preview modal Signed-off-by: snipe --- resources/views/users/view.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/users/view.blade.php b/resources/views/users/view.blade.php index 5a9cf7ebfe..ea5e8d80df 100755 --- a/resources/views/users/view.blade.php +++ b/resources/views/users/view.blade.php @@ -913,7 +913,7 @@ @if (($file->filename) && (Storage::exists('private_uploads/users/'.$file->filename))) @if (Helper::checkUploadIsImage($file->get_src('users'))) - + @else {{ trans('general.preview_not_available') }} @endif From 894c34ff4f4fb619336d87f91fde016172c2a7a7 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 7 Sep 2023 20:22:14 +0100 Subject: [PATCH 3/4] Update to only use relative paths Signed-off-by: snipe --- app/Http/Controllers/Users/UserFilesController.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Users/UserFilesController.php b/app/Http/Controllers/Users/UserFilesController.php index a2fdcd0fe3..62726e9827 100644 --- a/app/Http/Controllers/Users/UserFilesController.php +++ b/app/Http/Controllers/Users/UserFilesController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Users; +use App\Helpers\StorageHelper; use App\Http\Controllers\Controller; use App\Http\Requests\AssetFileRequest; use App\Models\Actionlog; @@ -143,17 +144,17 @@ class UserFilesController extends Controller $this->authorize('view', $user); $log = Actionlog::find($fileId); - $file = 'private_uploads/users/'.$log->filename; // Display the file inline if (request('inline') == 'true') { $headers = [ 'Content-Disposition' => 'inline', ]; - return Storage::download($file, $log->filename, $headers); + return Storage::download('private_uploads/users/'.$log->filename, $log->filename, $headers); } - return Response::download($file); //FIXME this doesn't use the new StorageHelper yet, but it's complicated... + return Storage::download('private_uploads/users/'.$log->filename); + } // Redirect to the user management page if the user doesn't exist From abd2ed3b811afeb4564b10b80f0740fc220e155c Mon Sep 17 00:00:00 2001 From: Ivan Nieto Vivanco Date: Thu, 7 Sep 2023 13:39:16 -0600 Subject: [PATCH 4/4] Filter unaccepted assets that are not assigned to users --- app/Http/Controllers/ReportsController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/ReportsController.php b/app/Http/Controllers/ReportsController.php index 68ca88a2eb..6bb7aa35cf 100644 --- a/app/Http/Controllers/ReportsController.php +++ b/app/Http/Controllers/ReportsController.php @@ -1021,7 +1021,7 @@ class ReportsController extends Controller $assetsForReport = $acceptances ->filter(function ($acceptance) { - return $acceptance->checkoutable_type == 'App\Models\Asset'; + return $acceptance->checkoutable_type == 'App\Models\Asset' && $acceptance->checkoutable->checkedOutToUser(); }) ->map(function($acceptance) { return ['assetItem' => $acceptance->checkoutable, 'acceptance' => $acceptance];