diff --git a/app/Http/Controllers/FileAccessController.php b/app/Http/Controllers/FileAccessController.php index 45023b36..0ccc0f40 100644 --- a/app/Http/Controllers/FileAccessController.php +++ b/app/Http/Controllers/FileAccessController.php @@ -102,21 +102,19 @@ class FileAccessController extends Controller */ public function get_zip($id) { - $zip = Zip::where('id', $id) + $zip = Zip::whereId($id) ->where('user_id', Auth::id()) - ->first(); + ->firstOrFail(); - $zip_path = 'zip/' . $zip->basename; + $disk = Storage::disk('local'); - $header = [ + return $disk->download("zip/$zip->basename", $zip->basename, [ "Content-Type" => 'application/zip', - "Content-Length" => Storage::disk('local')->size($zip_path), + "Content-Length" => $disk->size("zip/$zip->basename"), "Accept-Ranges" => "bytes", - "Content-Range" => "bytes 0-600/" . Storage::disk('local')->size($zip_path), - "Content-Disposition" => "attachment; filename=" . $zip->basename, - ]; - - return Storage::disk('local')->download($zip_path, $zip->basename, $header); + "Content-Range" => "bytes 0-600/" . $disk->size("zip/$zip->basename"), + "Content-Disposition" => "attachment; filename=$zip->basename", + ]); } /** diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 3aa6dba5..8adf49de 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -50,6 +50,8 @@ class RouteServiceProvider extends ServiceProvider $this->mapMaintenanceRoutes(); + $this->mapFileRoutes(); + $this->mapWebRoutes(); } @@ -74,6 +76,13 @@ class RouteServiceProvider extends ServiceProvider ->group(base_path('routes/maintenance.php')); } + protected function mapFileRoutes() + { + Route::middleware('web') + ->namespace($this->namespace) + ->group(base_path('routes/file.php')); + } + /** * Define the "api" routes for the application. * diff --git a/routes/file.php b/routes/file.php new file mode 100644 index 00000000..c90e6ee2 --- /dev/null +++ b/routes/file.php @@ -0,0 +1,20 @@ +name('avatar'); +Route::get('/system/{image}', [FileAccessController::class, 'get_system_image']); + +// TODO: testy +// Get public thumbnails and files +Route::get('/thumbnail/{name}/public/{token}', [FileAccessController::class, 'get_thumbnail_public']); +Route::get('/file/{name}/public/{token}', [FileAccessController::class, 'get_file_public']); +Route::get('/zip/{id}/public/{token}', [FileAccessController::class, 'get_zip_public'])->name('zip_public'); + +// User master,editor,visitor access to image thumbnails and file downloads +Route::group(['middleware' => ['auth:sanctum']], function () { + Route::get('/thumbnail/{name}', [FileAccessController::class, 'get_thumbnail'])->name('thumbnail'); + Route::get('/file/{name}', [FileAccessController::class, 'get_file'])->name('file'); + Route::get('/zip/{id}', [FileAccessController::class, 'get_zip'])->name('zip'); +}); \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 58c48814..3b653b9c 100644 --- a/routes/web.php +++ b/routes/web.php @@ -10,23 +10,6 @@ use App\Http\Controllers\WebhookController; Route::post('/stripe/webhook', [WebhookController::class, 'handleWebhook']); Route::post('/admin-setup', [SetupWizardController::class, 'create_admin_account']); -// Get avatars and system images -Route::get('/avatars/{avatar}', [FileAccessController::class, 'get_avatar'])->name('avatar'); -Route::get('/system/{image}', [FileAccessController::class, 'get_system_image']); - -// Get public thumbnails and files -// TODO: testy -Route::get('/thumbnail/{name}/public/{token}', [FileAccessController::class, 'get_thumbnail_public']); -Route::get('/file/{name}/public/{token}', [FileAccessController::class, 'get_file_public']); -Route::get('/zip/{id}/public/{token}', [FileAccessController::class, 'get_zip_public'])->name('zip_public'); - -// User master,editor,visitor access to image thumbnails and file downloads -Route::group(['middleware' => ['auth:sanctum']], function () { - Route::get('/thumbnail/{name}', [FileAccessController::class, 'get_thumbnail'])->name('thumbnail'); - Route::get('/file/{name}', [FileAccessController::class, 'get_file'])->name('file'); - Route::get('/zip/{id}', [FileAccessController::class, 'get_zip'])->name('zip'); -}); - // Get user invoice Route::group(['middleware' => ['auth:sanctum']], function () { Route::get('/invoice/{customer}/{token}', [InvoiceController::class, 'show']); diff --git a/tests/Feature/FileAccessTest.php b/tests/Feature/FileAccessTest.php index b5552b5b..bb9cce2e 100644 --- a/tests/Feature/FileAccessTest.php +++ b/tests/Feature/FileAccessTest.php @@ -4,6 +4,8 @@ namespace Tests\Feature; use App\Models\File; use App\Models\User; +use App\Models\Zip; +use Carbon\Carbon; use Illuminate\Foundation\Testing\DatabaseMigrations; use App\Services\SetupService; use Illuminate\Http\UploadedFile; @@ -89,31 +91,14 @@ class FileAccessTest extends TestCase ->assertOk(); } + /** * @test */ public function guest_try_to_get_private_user_file() { - Storage::fake('local'); - - $this->setup->create_directories(); - - $user = User::factory(User::class) - ->create(); - - $file = UploadedFile::fake() - ->create(Str::random() . '-fake-file.pdf', 1200, 'application/pdf'); - - Storage::putFileAs("files/$user->id", $file, $file->name); - - File::factory(File::class) - ->create([ - 'basename' => $file->name, - 'name' => 'fake-file.pdf', - ]); - - $this->get("file/$file->name") - ->assertStatus(302); + $this->get("file/fake-file.pdf") + ->assertRedirect(); } /** @@ -144,4 +129,68 @@ class FileAccessTest extends TestCase $this->get("file/$file->name") ->assertNotFound(); } + + /** + * @test + */ + public function it_get_private_user_zip() + { + Storage::fake('local'); + + $this->setup->create_directories(); + + $user = User::factory(User::class) + ->create(); + + Sanctum::actingAs($user); + + $file = UploadedFile::fake() + ->create('archive.zip', 2000, 'application/zip'); + + Storage::putFileAs('zip', $file, 'EHWKcuvKzA4Gv29v-archive.zip'); + + $zip = Zip::factory(Zip::class)->create([ + 'basename' => 'EHWKcuvKzA4Gv29v-archive.zip', + 'user_id' => $user->id, + ]); + + $this->get("zip/$zip->id") + ->assertOk(); + } + + /** + * @test + */ + public function logged_user_try_to_get_another_private_user_zip() + { + Storage::fake('local'); + + $this->setup->create_directories(); + + $user = User::factory(User::class) + ->create(); + + Sanctum::actingAs($user); + + $file = UploadedFile::fake() + ->create('archive.zip', 2000, 'application/zip'); + + Storage::putFileAs('zip', $file, 'EHWKcuvKzA4Gv29v-archive.zip'); + + $zip = Zip::factory(Zip::class)->create([ + 'basename' => 'EHWKcuvKzA4Gv29v-archive.zip', + ]); + + $this->get("zip/$zip->id") + ->assertNotFound(); + } + + /** + * @test + */ + public function guest_try_to_get_private_user_zip() + { + $this->get("zip/EHWKcuvKzA4Gv29v-archive.zip") + ->assertRedirect(); + } }