mirror of
https://github.com/projectsend/projectsend.git
synced 2026-09-22 03:23:23 +00:00
7ce1e3487f
An installation that scans can still let files through: too large for the scanner, an archive it could not open, or an upload that arrived while the scanner was down. Both policies default to letting those through, and the count of them is on the settings screen and the dashboard. Everyone could see that except the one person it matters to. The uploader sees the state on their own file and staff see it in the library; whoever follows a public link saw the page a file that passed gets, having neither chosen the policy nor any way to see the setting. On the hosted free plan, where every upload is published behind a link, that is the whole audience. The share page and the public file page in all four themes now carry one line: "This file was not checked for viruses." Said plainly and without alarm — nothing is known to be wrong with the file; what is known is that nothing looked. Only where this installation scans, and only for the three reasons that mean a scanner let something past. A file from before scanning was switched on says nothing: on an installation that has only just switched it on that is every file, and saying it about all of them says it about none of them.
110 lines
4.1 KiB
PHP
110 lines
4.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\User;
|
|
use App\Modules\Files\Models\File;
|
|
use App\Modules\Files\Scanning\NotScannedReason;
|
|
use App\Modules\Files\Scanning\ScanStatus;
|
|
use App\Modules\Files\Sharing\CreateShareLink;
|
|
use App\Modules\Groups\Models\Group;
|
|
use App\Modules\Platform\Settings\Setting;
|
|
use App\Modules\Platform\Settings\Settings;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Inertia\Testing\AssertableInertia;
|
|
|
|
/**
|
|
* What somebody following a public link is told about a file nothing
|
|
* checked.
|
|
*
|
|
* An installation that scans can still let files through — too large for
|
|
* the scanner, an archive it could not open, or an upload that arrived
|
|
* while the scanner was down. The uploader sees that on their own file and
|
|
* staff see it in the library. The person holding the link sees the same
|
|
* page as for a file that passed, and they neither chose the policy nor
|
|
* can see the setting.
|
|
*/
|
|
beforeEach(function () {
|
|
Storage::fake('files');
|
|
$this->admin = User::factory()->create();
|
|
$this->settings = app(Settings::class);
|
|
|
|
$this->settings->set(Setting::VirusScanningEnabled, true);
|
|
$this->settings->set(Setting::VirusScannerAddress, 'tcp://scanner.test:3310');
|
|
$this->settings->set(Setting::PublicListingEnabled, true);
|
|
$this->settings->set(Setting::PublicListingSlug, 'public');
|
|
$this->settings->set(Setting::Theme, 'default');
|
|
});
|
|
|
|
/** The `unscanned` prop on the share page for a file in this state. */
|
|
function sharedFileNotice(array $scan): bool
|
|
{
|
|
$file = File::factory()->create(array_merge(['uploaded_by' => test()->admin->id], $scan));
|
|
$link = app(CreateShareLink::class)->for($file, test()->admin);
|
|
|
|
$notice = null;
|
|
|
|
test()->get("/s/{$link->token}")->assertInertia(function (AssertableInertia $page) use (&$notice) {
|
|
$notice = $page->toArray()['props']['unscanned'];
|
|
});
|
|
|
|
return $notice;
|
|
}
|
|
|
|
test('a link to a file nothing checked says so', function () {
|
|
expect(sharedFileNotice([
|
|
'scan_status' => ScanStatus::NotScanned,
|
|
'scan_note' => NotScannedReason::TooLarge->value,
|
|
]))->toBeTrue();
|
|
});
|
|
|
|
test('the same for a file that went out while the scanner was down, or that it could not open', function () {
|
|
foreach ([NotScannedReason::ScannerUnavailable, NotScannedReason::Encrypted] as $reason) {
|
|
expect(sharedFileNotice(['scan_status' => ScanStatus::NotScanned, 'scan_note' => $reason->value]))
|
|
->toBeTrue($reason->value);
|
|
}
|
|
});
|
|
|
|
test('a file that passed says nothing', function () {
|
|
expect(sharedFileNotice(['scan_status' => ScanStatus::Clean]))->toBeFalse();
|
|
});
|
|
|
|
test('a file from before this installation scanned says nothing', function () {
|
|
// Every file on an installation that has only just switched scanning
|
|
// on is in this state. Saying it about all of them says nothing about
|
|
// any of them.
|
|
expect(sharedFileNotice([
|
|
'scan_status' => ScanStatus::NotScanned,
|
|
'scan_note' => NotScannedReason::BeforeScanning->value,
|
|
]))->toBeFalse();
|
|
|
|
expect(sharedFileNotice(['scan_status' => ScanStatus::NotScanned, 'scan_note' => null]))->toBeFalse();
|
|
});
|
|
|
|
test('an installation that does not scan says nothing about any of it', function () {
|
|
$this->settings->set(Setting::VirusScanningEnabled, false);
|
|
|
|
expect(sharedFileNotice([
|
|
'scan_status' => ScanStatus::NotScanned,
|
|
'scan_note' => NotScannedReason::TooLarge->value,
|
|
]))->toBeFalse();
|
|
});
|
|
|
|
test('the public file page says it too, in every theme', function (string $theme) {
|
|
$this->settings->set(Setting::Theme, $theme);
|
|
|
|
$group = Group::query()->create(['name' => 'Showcase', 'public' => true]);
|
|
$file = File::factory()->public()->create([
|
|
'uploaded_by' => $this->admin->id,
|
|
'scan_status' => ScanStatus::NotScanned,
|
|
'scan_note' => NotScannedReason::ScannerUnavailable->value,
|
|
]);
|
|
shareFileWithGroup($file, $group);
|
|
|
|
$this->get("/public/files/{$file->slug}")->assertInertia(
|
|
fn (AssertableInertia $page) => $page
|
|
->component("public/themes/{$theme}/file")
|
|
->where('unscanned', true),
|
|
);
|
|
})->with(['default', 'compact', 'drive', 'gallery']);
|