From a383033ffafd3a27b3bed9cfe09af845ae782544 Mon Sep 17 00:00:00 2001 From: snipe Date: Thu, 21 May 2026 14:56:20 +0100 Subject: [PATCH] Chekc auth before assigning S3 temporary link --- app/Http/Controllers/ActionlogController.php | 5 +- tests/Feature/ActionLogs/DisplaySigTest.php | 81 ++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 tests/Feature/ActionLogs/DisplaySigTest.php diff --git a/app/Http/Controllers/ActionlogController.php b/app/Http/Controllers/ActionlogController.php index aab92cb810..12a74cdf28 100644 --- a/app/Http/Controllers/ActionlogController.php +++ b/app/Http/Controllers/ActionlogController.php @@ -4,7 +4,6 @@ namespace App\Http\Controllers; use App\Helpers\Helper; use App\Models\Actionlog; -use App\Models\Asset; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Response; use Illuminate\Support\Facades\Log; @@ -17,6 +16,9 @@ class ActionlogController extends Controller { $filename = basename((string) $filename); + $actionlog = Actionlog::where('accept_signature', $filename)->with('item')->firstOrFail(); + $this->authorize('view', $actionlog->item); + // PHP doesn't let you handle file not found errors well with // file_get_contents, so we set the error reporting for just this class error_reporting(0); @@ -29,7 +31,6 @@ class ActionlogController extends Controller return redirect()->away(Storage::disk($disk)->temporaryUrl($file, now()->addMinutes(5))); default: - $this->authorize('view', Asset::class); $file = config('app.private_uploads').'/signatures/'.$filename; $filetype = Helper::checkUploadIsImage($file); diff --git a/tests/Feature/ActionLogs/DisplaySigTest.php b/tests/Feature/ActionLogs/DisplaySigTest.php new file mode 100644 index 0000000000..ba823e5896 --- /dev/null +++ b/tests/Feature/ActionLogs/DisplaySigTest.php @@ -0,0 +1,81 @@ +acceptedSignature()->create(); + + $this->get(route('log.signature.view', ['filename' => $actionlog->accept_signature])) + ->assertRedirect(route('login')); + } + + public function test_nonexistent_filename_redirects_with_error(): void + { + $this->actingAs(User::factory()->superuser()->create()) + ->get(route('log.signature.view', ['filename' => 'does-not-exist.png'])) + ->assertRedirect(route('home')); + } + + public function test_user_without_view_permission_cannot_view_asset_signature(): void + { + $actionlog = Actionlog::factory()->acceptedSignature()->create(); + + $this->actingAs(User::factory()->create()) + ->get(route('log.signature.view', ['filename' => $actionlog->accept_signature])) + ->assertForbidden(); + } + + public function test_user_with_asset_view_permission_can_view_asset_signature(): void + { + $asset = Asset::factory()->create(); + $actionlog = Actionlog::factory()->create([ + 'action_type' => 'accepted', + 'item_id' => $asset->id, + 'item_type' => Asset::class, + 'accept_signature' => 'test-asset-sig-'.uniqid().'.png', + ]); + + $this->actingAs(User::factory()->viewAssets()->create()) + ->get(route('log.signature.view', ['filename' => $actionlog->accept_signature])) + ->assertOk(); + } + + public function test_user_with_asset_view_permission_cannot_view_license_signature(): void + { + $license = License::factory()->create(); + $actionlog = Actionlog::factory()->create([ + 'action_type' => 'accepted', + 'item_id' => $license->id, + 'item_type' => License::class, + 'accept_signature' => 'test-license-sig-'.uniqid().'.png', + ]); + + $this->actingAs(User::factory()->viewAssets()->create()) + ->get(route('log.signature.view', ['filename' => $actionlog->accept_signature])) + ->assertForbidden(); + } + + public function test_user_with_license_view_permission_can_view_license_signature(): void + { + $license = License::factory()->create(); + $actionlog = Actionlog::factory()->create([ + 'action_type' => 'accepted', + 'item_id' => $license->id, + 'item_type' => License::class, + 'accept_signature' => 'test-license-sig-'.uniqid().'.png', + ]); + + $this->actingAs(User::factory()->viewLicenses()->create()) + ->get(route('log.signature.view', ['filename' => $actionlog->accept_signature])) + ->assertOk(); + } +}