From 91e64db64f82c440a735beb01f691f5e236af617 Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Tue, 10 Feb 2026 15:09:17 +0000 Subject: [PATCH 1/2] wip --- .../Controllers/CP/Assets/PdfController.php | 8 +- .../Controllers/CP/Assets/SvgController.php | 6 +- .../CP/Assets/ThumbnailController.php | 2 + tests/Feature/Assets/ImageThumbnailTest.php | 84 +++++++++++++++++++ tests/Feature/Assets/PdfThumbnailTest.php | 84 +++++++++++++++++++ tests/Feature/Assets/SvgThumbnailTest.php | 84 +++++++++++++++++++ 6 files changed, 262 insertions(+), 6 deletions(-) create mode 100644 tests/Feature/Assets/ImageThumbnailTest.php create mode 100644 tests/Feature/Assets/PdfThumbnailTest.php create mode 100644 tests/Feature/Assets/SvgThumbnailTest.php diff --git a/src/Http/Controllers/CP/Assets/PdfController.php b/src/Http/Controllers/CP/Assets/PdfController.php index a65e49a4d38..c180413118c 100644 --- a/src/Http/Controllers/CP/Assets/PdfController.php +++ b/src/Http/Controllers/CP/Assets/PdfController.php @@ -15,9 +15,11 @@ class PdfController extends Controller */ public function show($encodedAssetId) { - if (! $contents = $this->asset($encodedAssetId)->contents()) { - abort(500); - } + $asset = $this->asset($encodedAssetId); + + abort_if(! $contents = $asset->contents(), 500); + + $this->authorize('view', $asset); return response($contents)->header('Content-Type', 'application/pdf'); } diff --git a/src/Http/Controllers/CP/Assets/SvgController.php b/src/Http/Controllers/CP/Assets/SvgController.php index 606755957ed..f1a714bee63 100644 --- a/src/Http/Controllers/CP/Assets/SvgController.php +++ b/src/Http/Controllers/CP/Assets/SvgController.php @@ -17,9 +17,9 @@ public function show($asset) { $asset = $this->asset($asset); - if (! $contents = $asset->disk()->get($asset->path())) { - abort(500); - } + abort_if(! $contents = $asset->disk()->get($asset->path()), 500); + + $this->authorize('view', $asset); return response($contents)->header('Content-Type', 'image/svg+xml'); } diff --git a/src/Http/Controllers/CP/Assets/ThumbnailController.php b/src/Http/Controllers/CP/Assets/ThumbnailController.php index 6a9245c601c..6e529e1bd88 100644 --- a/src/Http/Controllers/CP/Assets/ThumbnailController.php +++ b/src/Http/Controllers/CP/Assets/ThumbnailController.php @@ -65,6 +65,8 @@ public function show($asset, $size = null, $orientation = null) $this->orientation = $orientation; $this->asset = $this->asset($asset); + $this->authorize('view', $this->asset); + if ($placeholder = $this->getPlaceholderResponse()) { return $placeholder; } diff --git a/tests/Feature/Assets/ImageThumbnailTest.php b/tests/Feature/Assets/ImageThumbnailTest.php new file mode 100644 index 00000000000..c7f3fb57620 --- /dev/null +++ b/tests/Feature/Assets/ImageThumbnailTest.php @@ -0,0 +1,84 @@ + [ + 'driver' => 'local', + 'root' => $this->tempDir = __DIR__.'/tmp', + ]]); + } + + public function tearDown(): void + { + app('files')->deleteDirectory($this->tempDir); + + parent::tearDown(); + } + + #[Test] + public function it_returns_thumbnail() + { + $container = AssetContainer::make('test')->disk('test')->save(); + $container + ->makeAsset('one.png') + ->upload(UploadedFile::fake()->image('one.png')); + + $this->setTestRoles(['test' => ['access cp', 'view test assets']]); + $user = User::make()->assignRole('test')->save(); + + $this + ->actingAs($user) + ->getJson('/cp/thumbnails/'.base64_encode('test::one.png')) + ->assertSuccessful(); + } + + #[Test] + public function it_404s_when_the_asset_doesnt_exist() + { + $container = AssetContainer::make('test')->disk('test')->save(); + + $this->setTestRoles(['test' => ['access cp', 'view test assets']]); + $user = User::make()->assignRole('test')->save(); + + $this + ->actingAs($user) + ->getJson('/cp/thumbnails/'.base64_encode('test::unknown.png')) + ->assertNotFound(); + } + + #[Test] + public function it_denies_access_without_permission_to_view_asset() + { + $container = AssetContainer::make('test')->disk('test')->save(); + $container + ->makeAsset('one.png') + ->upload(UploadedFile::fake()->image('one.png')); + + $this->setTestRoles(['test' => ['access cp']]); + $user = User::make()->assignRole('test')->save(); + + $this + ->actingAs($user) + ->getJson('/cp/thumbnails/'.base64_encode('test::one.png')) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Assets/PdfThumbnailTest.php b/tests/Feature/Assets/PdfThumbnailTest.php new file mode 100644 index 00000000000..d845420539d --- /dev/null +++ b/tests/Feature/Assets/PdfThumbnailTest.php @@ -0,0 +1,84 @@ + [ + 'driver' => 'local', + 'root' => $this->tempDir = __DIR__.'/tmp', + ]]); + } + + public function tearDown(): void + { + app('files')->deleteDirectory($this->tempDir); + + parent::tearDown(); + } + + #[Test] + public function it_returns_thumbnail() + { + $container = AssetContainer::make('test')->disk('test')->save(); + $container + ->makeAsset('one.pdf') + ->upload(UploadedFile::fake()->createWithContent('one.pdf', ' ')); + + $this->setTestRoles(['test' => ['access cp', 'view test assets']]); + $user = User::make()->assignRole('test')->save(); + + $this + ->actingAs($user) + ->getJson('/cp/pdfs/'.base64_encode('test::one.pdf')) + ->assertSuccessful(); + } + + #[Test] + public function it_404s_when_the_asset_doesnt_exist() + { + $container = AssetContainer::make('test')->disk('test')->save(); + + $this->setTestRoles(['test' => ['access cp', 'view test assets']]); + $user = User::make()->assignRole('test')->save(); + + $this + ->actingAs($user) + ->getJson('/cp/pdfs/'.base64_encode('test::unknown.pdf')) + ->assertNotFound(); + } + + #[Test] + public function it_denies_access_without_permission_to_view_asset() + { + $container = AssetContainer::make('test')->disk('test')->save(); + $container + ->makeAsset('one.pdf') + ->upload(UploadedFile::fake()->createWithContent('one.pdf', ' ')); + + $this->setTestRoles(['test' => ['access cp']]); + $user = User::make()->assignRole('test')->save(); + + $this + ->actingAs($user) + ->getJson('/cp/pdfs/'.base64_encode('test::one.pdf')) + ->assertForbidden(); + } +} diff --git a/tests/Feature/Assets/SvgThumbnailTest.php b/tests/Feature/Assets/SvgThumbnailTest.php new file mode 100644 index 00000000000..882d8af6ce1 --- /dev/null +++ b/tests/Feature/Assets/SvgThumbnailTest.php @@ -0,0 +1,84 @@ + [ + 'driver' => 'local', + 'root' => $this->tempDir = __DIR__.'/tmp', + ]]); + } + + public function tearDown(): void + { + app('files')->deleteDirectory($this->tempDir); + + parent::tearDown(); + } + + #[Test] + public function it_returns_thumbnail() + { + $container = AssetContainer::make('test')->disk('test')->save(); + $container + ->makeAsset('one.png') + ->upload(UploadedFile::fake()->createWithContent('one.svg', '')); + + $this->setTestRoles(['test' => ['access cp', 'view test assets']]); + $user = User::make()->assignRole('test')->save(); + + $this + ->actingAs($user) + ->getJson('/cp/svgs/'.base64_encode('test::one.svg')) + ->assertSuccessful(); + } + + #[Test] + public function it_404s_when_the_asset_doesnt_exist() + { + $container = AssetContainer::make('test')->disk('test')->save(); + + $this->setTestRoles(['test' => ['access cp', 'view test assets']]); + $user = User::make()->assignRole('test')->save(); + + $this + ->actingAs($user) + ->getJson('/cp/svgs/'.base64_encode('test::unknown.svg')) + ->assertNotFound(); + } + + #[Test] + public function it_denies_access_without_permission_to_view_asset() + { + $container = AssetContainer::make('test')->disk('test')->save(); + $container + ->makeAsset('one.svg') + ->upload(UploadedFile::fake()->createWithContent('one.svg', '')); + + $this->setTestRoles(['test' => ['access cp']]); + $user = User::make()->assignRole('test')->save(); + + $this + ->actingAs($user) + ->getJson('/cp/svgs/'.base64_encode('test::one.svg')) + ->assertForbidden(); + } +} From 4126612aa3aa2f3f7921dd15a18d197fa3f8e874 Mon Sep 17 00:00:00 2001 From: Duncan McClean Date: Tue, 10 Feb 2026 15:23:30 +0000 Subject: [PATCH 2/2] wip --- routes/cp.php | 1 - src/Http/Controllers/CP/Assets/FoldersController.php | 5 ----- 2 files changed, 6 deletions(-) diff --git a/routes/cp.php b/routes/cp.php index 314f85be466..15c26304afc 100644 --- a/routes/cp.php +++ b/routes/cp.php @@ -229,7 +229,6 @@ Route::resource('asset-containers', AssetContainersController::class); Route::post('asset-containers/{asset_container}/folders', [FoldersController::class, 'store']); - Route::patch('asset-containers/{asset_container}/folders/{path}', [FoldersController::class, 'update'])->where('path', '.*'); Route::get('asset-containers/{asset_container}/blueprint', [AssetContainerBlueprintController::class, 'edit'])->name('asset-containers.blueprint.edit'); Route::patch('asset-containers/{asset_container}/blueprint', [AssetContainerBlueprintController::class, 'update'])->name('asset-containers.blueprint.update'); Route::post('assets/actions', [AssetActionController::class, 'run'])->name('assets.actions.run'); diff --git a/src/Http/Controllers/CP/Assets/FoldersController.php b/src/Http/Controllers/CP/Assets/FoldersController.php index 9b86c5d54f9..ffe31234dec 100644 --- a/src/Http/Controllers/CP/Assets/FoldersController.php +++ b/src/Http/Controllers/CP/Assets/FoldersController.php @@ -37,9 +37,4 @@ public function store(Request $request, $container) return $container->assetFolder($path)->save(); } - - public function update(Request $request, $container, $folder) - { - return $container->assetFolder($folder)->save(); - } }