From 8a2ea971e16d2c043320cb3cd2f255bbb33820b8 Mon Sep 17 00:00:00 2001 From: Scarzy Date: Tue, 30 Apr 2024 21:30:45 +0100 Subject: [PATCH] Add an API assets files controller Based heavily on the Assets assets files controller. Added errors related to to the files management. Added the API endpoints for file upload and show, but only upload is currently tested/works. --- .../Controllers/Api/AssetFilesController.php | 171 ++++++++++++++++++ app/Http/Requests/UploadFileRequest.php | 2 + .../lang/en-GB/admin/hardware/message.php | 7 + routes/api.php | 17 +- 4 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 app/Http/Controllers/Api/AssetFilesController.php diff --git a/app/Http/Controllers/Api/AssetFilesController.php b/app/Http/Controllers/Api/AssetFilesController.php new file mode 100644 index 0000000000..f94e8afd83 --- /dev/null +++ b/app/Http/Controllers/Api/AssetFilesController.php @@ -0,0 +1,171 @@ +] + */ +class AssetFilesController extends Controller +{ + /** + * Accepts a POST to upload a file to the server. + * + * @param \App\Http\Requests\UploadFileRequest $request + * @param int $assetId + * @return \Illuminate\Http\JsonResponse + * @throws \Illuminate\Auth\Access\AuthorizationException + * @since [v6.0] + * @author [T. Scarsbrook] [] + */ + public function store(UploadFileRequest $request, $assetId = null) + { + if (! $asset = Asset::find($assetId)) { + return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.does_not_exist')), 500); + } + + $this->authorize('update', $asset); + + \Log::warning($request); + #\Log::warning($request['name']); + #\Log::warning($request['filename']); + #\Log::warning($request['contents']); + if ($request->hasFile('file')) { + \Log::warning("So, I am actually getting in here..."); + if (! Storage::exists('private_uploads/assets')) { + Storage::makeDirectory('private_uploads/assets', 775); + } + + \Log::warning("File is"); + \Log::warning($request->file('file')); + \Log::warning("File ends"); + foreach ($request->file('file') as $file) { + \Log::warning("Handling file "); + \Log::warning($file); + $file_name = $request->handleFile('private_uploads/assets/','hardware-'.$asset->id, $file); + + $asset->logUpload($file_name, e($request->get('notes'))); + } + \Log::warning("Done handling"); + #$request->IamAnOrange(); + + return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.upload.success'))); + } + + return response()->json(Helper::formatStandardApiResponse('error', null, "Bad bananas"), 500); + return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.upload.nofiles')), 500); + } + + /** + * Check for permissions and display the file. + * + * @param int $assetId + * @param int $fileId + * @return \Illuminate\Http\JsonResponse + * @throws \Illuminate\Auth\Access\AuthorizationException + * @since [v6.0] + * @author [T. Scarsbrook] [] + */ + public function show($assetId = null, $fileId = null) + { + $asset = Asset::find($assetId); + // the asset is valid + if (isset($asset->id)) { + $this->authorize('view', $asset); + + if (! $log = Actionlog::whereNotNull('filename')->where('item_id', $asset->id)->find($fileId)) { + return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.download.no_match', ['id' => $fileId])), 500); + } + + $file = 'private_uploads/assets/'.$log->filename; + \Log::debug('Checking for '.$file); + + if ($log->action_type == 'audit') { + $file = 'private_uploads/audits/'.$log->filename; + } + + if (! Storage::exists($file)) { + return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.download.does_not_exist', ['id' => $fileId])), 404); + } + + if (request('inline') == 'true') { + + $headers = [ + 'Content-Disposition' => 'inline', + ]; + + return Storage::download($file, $log->filename, $headers); + return response()->json(Helper::formatStandardApiResponse('success', $asset, trans('admin/hardware/message.upload.success'))); + } + + return StorageHelper::downloader($file); + } + + // Send back an error message + return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.download.error', ['id' => $fileId])), 500); + } + + /** + * Delete the associated file + * + * @param int $assetId + * @param int $fileId + * @return \Illuminate\Http\JsonResponse + * @throws \Illuminate\Auth\Access\AuthorizationException + * @since [v6.0] + * @author [T. Scarsbrook] [] + */ + public function destroy($assetId = null, $fileId = null) + { + $asset = Asset::find($assetId); + $this->authorize('update', $asset); + $rel_path = 'private_uploads/assets'; + + // the asset is valid + if (isset($asset->id)) { + $this->authorize('update', $asset); + $log = Actionlog::find($fileId); + if ($log) { + if (Storage::exists($rel_path.'/'.$log->filename)) { + Storage::delete($rel_path.'/'.$log->filename); + } + $log->delete(); + + return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success')); + } + + return redirect()->back()->with('success', trans('admin/hardware/message.deletefile.success')); + } + + // Redirect to the hardware management page + return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/hardware/message.deletefile.error')), 500); + } +} diff --git a/app/Http/Requests/UploadFileRequest.php b/app/Http/Requests/UploadFileRequest.php index d91d0bf0b8..4762e52b75 100644 --- a/app/Http/Requests/UploadFileRequest.php +++ b/app/Http/Requests/UploadFileRequest.php @@ -2,12 +2,14 @@ namespace App\Http\Requests; +use App\Http\Traits\ConvertsBase64ToFiles; use enshrined\svgSanitize\Sanitizer; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Log; class UploadFileRequest extends Request { + use ConvertsBase64ToFiles; /** * Determine if the user is authorized to make this request. * diff --git a/resources/lang/en-GB/admin/hardware/message.php b/resources/lang/en-GB/admin/hardware/message.php index 3af3dbc6e3..7185cd8dcf 100644 --- a/resources/lang/en-GB/admin/hardware/message.php +++ b/resources/lang/en-GB/admin/hardware/message.php @@ -51,6 +51,13 @@ return [ 'invalidfiles' => 'One or more of your files is too large or is a filetype that is not allowed. Allowed filetypes are png, gif, jpg, doc, docx, pdf, and txt.', ], + 'download' => [ + 'error' => 'File(s) not downloaded. Please try again.', + 'success' => 'File(s) successfully downloaded.', + 'does_not_exist' => 'No file exists', + 'no_match' => 'No matching record for that asset/file', + ], + 'import' => [ 'error' => 'Some items did not import correctly.', 'errorDetail' => 'The following Items were not imported because of errors.', diff --git a/routes/api.php b/routes/api.php index 8adb0af619..0d77aa6b9b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -544,13 +544,22 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi 'restore' ] )->name('api.assets.restore'); + Route::post('{asset_id}/files', + [ + Api\AssetFilesController::class, + 'store' + ] + )->name('api.assets.files'); + + Route::get('{asset_id}/files', + [ + Api\AssetFilesController::class, + 'show' + ] + )->name('api.assets.files'); }); - - - - Route::resource('hardware', Api\AssetsController::class, ['names' => [