set('FILES_WEB_SERVER_READABLE', $webServerReadable ? 'true' : 'false'); // Required rather than read through config(), so the env() call in it // is evaluated now, against the flag just set. $shipped = require base_path('config/filesystems.php'); config(['filesystems.disks.files' => [...$shipped['disks']['files'], 'root' => $root]]); Storage::forgetDisk('files'); return $root; } function modeOf(string $path): string { clearstatcache(true, $path); return substr(sprintf('%o', fileperms($path)), -4); } beforeEach(function () { $this->originalUmask = umask(); // Also before: a run killed mid-test leaves its tree behind, and these // cases read modes off directories they expect to have created. File::deleteDirectory(filesPermissionRoot()); }); afterEach(function () { umask($this->originalUmask); File::deleteDirectory(filesPermissionRoot()); Env::getRepository()->clear('FILES_WEB_SERVER_READABLE'); Storage::forgetDisk('files'); }); test('by default an upload lands in a directory only its owner can traverse', function () { umask(0022); $root = filesDiskWith(webServerReadable: false); Storage::disk('files')->put('2026/08/report.pdf', 'contents'); // 0700: a web server running as another user cannot open anything // underneath this, whatever the file's own mode says. expect(modeOf($root.'/2026/08'))->toBe('0700'); }); test('the flag opens both the file and the directory for another user', function () { umask(0022); $root = filesDiskWith(webServerReadable: true); Storage::disk('files')->put('2026/08/report.pdf', 'contents'); expect(modeOf($root.'/2026/08/report.pdf'))->toBe('0644') ->and(modeOf($root.'/2026/08'))->toBe('0755'); }); // Both halves of the same claim, on a pool that denies group and other by // default. The file still comes out readable because it is chmod'ed after the // write; the directory does not, because mkdir() masked it — so the flag alone // does not rescue a host like this and INSTALL.md has to say so. test('a restrictive umask still caps the directory, though not the file', function () { umask(0077); $root = filesDiskWith(webServerReadable: true); Storage::disk('files')->put('2026/08/report.pdf', 'contents'); expect(modeOf($root.'/2026/08/report.pdf'))->toBe('0644') ->and(modeOf($root.'/2026/08'))->toBe('0700'); });