Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configuration option to configure permissions of local temporary directory (and files) #3767

Merged
merged 10 commits into from
Nov 6, 2023
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ All notable changes to this project will be documented in this file.
- Fix output of `WithFormatData` in combination with `SkipsEmptyRows` (#3760)

### Changed

- Cast empty headings to indexed integer
- Adds `isEmptyWhen` to customize is row empty logic.
- Cast empty headings to indexed integer (#3646)
- Adds `isEmptyWhen` to customize is row empty logic. (#3645)
- Support temporary file and directory rights configuration (#3766)

### Fixed

Expand Down
23 changes: 20 additions & 3 deletions config/excel.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,26 @@
|
| When exporting and importing files, we use a temporary file, before
| storing reading or downloading. Here you can customize that path.
| permissions is an array with the permission flags for the directory (dir)
| and the create file (file).
|
*/
'local_path' => storage_path('framework/cache/laravel-excel'),
'local_path' => storage_path('framework/cache/laravel-excel'),

/*
|--------------------------------------------------------------------------
| Local Temporary Path Permissions
|--------------------------------------------------------------------------
|
| Permissions is an array with the permission flags for the directory (dir)
| and the create file (file).
| If omitted the default permissions of the filesystem will be used.
|
*/
'local_permissions' => [
// 'dir' => 0770,
patrickbrouwers marked this conversation as resolved.
Show resolved Hide resolved
// 'file' => 0640,
patrickbrouwers marked this conversation as resolved.
Show resolved Hide resolved
],

/*
|--------------------------------------------------------------------------
Expand All @@ -310,8 +327,8 @@
| in conjunction with queued imports and exports.
|
*/
'remote_disk' => null,
'remote_prefix' => null,
'remote_disk' => null,
'remote_prefix' => null,

/*
|--------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions src/Files/LocalTemporaryFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ class LocalTemporaryFile extends TemporaryFile
public function __construct(string $filePath)
{
touch($filePath);
if (($rights = config('excel.temporary_files.local_permissions.file', null)) !== null) {
chmod($filePath, $rights);
}

$this->filePath = realpath($filePath);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Files/TemporaryFileFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function make(string $fileExtension = null): TemporaryFile
*/
public function makeLocal(string $fileName = null, string $fileExtension = null): LocalTemporaryFile
{
if (!file_exists($this->temporaryPath) && !mkdir($concurrentDirectory = $this->temporaryPath) && !is_dir($concurrentDirectory)) {
if (!file_exists($this->temporaryPath) && !mkdir($concurrentDirectory = $this->temporaryPath, config('excel.temporary_files.local_permissions.dir', 0777)) && !is_dir($concurrentDirectory)) {
patrickbrouwers marked this conversation as resolved.
Show resolved Hide resolved
throw new \RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory));
}

Expand Down
16 changes: 16 additions & 0 deletions tests/Helpers/FileHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,20 @@ public static function absolutePath($fileName, $diskName)
{
return config('filesystems.disks.' . $diskName . '.root') . DIRECTORY_SEPARATOR . $fileName;
}

public static function recursiveDelete($fileName)
patrickbrouwers marked this conversation as resolved.
Show resolved Hide resolved
{
if (is_file($fileName)) {
return @unlink($fileName);
}

if (is_dir($fileName)) {
$scan = glob(rtrim($fileName, '/') . '/*');
foreach ($scan as $path) {
self::recursiveDelete($path);
}

return @rmdir($fileName);
}
}
}
93 changes: 93 additions & 0 deletions tests/TemporaryFileTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace Maatwebsite\Excel\Tests;

use Maatwebsite\Excel\Files\TemporaryFileFactory;
use Maatwebsite\Excel\Tests\Helpers\FileHelper;

class TemporaryFileTest extends TestCase
{
private $defaultDirectoryPermissions;
private $defaultFilePermissions;

/**
* Setup the test environment.
*/
protected function setUp(): void
{
parent::setUp();

$path = FileHelper::absolutePath('rights-test-permissions', 'local');
mkdir($path);
$this->defaultDirectoryPermissions = substr(sprintf('%o', fileperms($path)), -4);

$filePath = $path . DIRECTORY_SEPARATOR . 'file-permissions';
touch($filePath);
$this->defaultFilePermissions = substr(sprintf('%o', fileperms($filePath)), -4);

@unlink($filePath);
@rmdir($path);
patrickbrouwers marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* @test
*/
public function can_use_default_rights()
{
$path = FileHelper::absolutePath('rights-test', 'local');
FileHelper::recursiveDelete($path);

config()->set('excel.temporary_files.local_path', $path);

$temporaryFileFactory = app(TemporaryFileFactory::class);

$temporaryFile = $temporaryFileFactory->makeLocal(null, 'txt');
$temporaryFile->put('data-set');

$this->assertFileExists($temporaryFile->getLocalPath());
$this->assertEquals($this->defaultDirectoryPermissions, substr(sprintf('%o', fileperms(dirname($temporaryFile->getLocalPath()))), -4));
$this->assertEquals($this->defaultFilePermissions, substr(sprintf('%o', fileperms($temporaryFile->getLocalPath())), -4));
}

/**
* @test
*/
public function can_use_dir_rights()
{
$path = FileHelper::absolutePath('rights-test', 'local');
FileHelper::recursiveDelete($path);

config()->set('excel.temporary_files.local_path', $path);
config()->set('excel.temporary_files.local_permissions.dir', 0700);

$temporaryFileFactory = app(TemporaryFileFactory::class);

$temporaryFile = $temporaryFileFactory->makeLocal(null, 'txt');
$temporaryFile->put('data-set');

$this->assertFileExists($temporaryFile->getLocalPath());
$this->assertEquals('0700', substr(sprintf('%o', fileperms(dirname($temporaryFile->getLocalPath()))), -4));
$this->assertEquals($this->defaultFilePermissions, substr(sprintf('%o', fileperms($temporaryFile->getLocalPath())), -4));
}

/**
* @test
*/
public function can_use_file_rights()
{
$path = FileHelper::absolutePath('rights-test', 'local');
FileHelper::recursiveDelete($path);

config()->set('excel.temporary_files.local_path', $path);
config()->set('excel.temporary_files.local_permissions.file', 0600);

$temporaryFileFactory = app(TemporaryFileFactory::class);

$temporaryFile = $temporaryFileFactory->makeLocal(null, 'txt');
$temporaryFile->put('data-set');

$this->assertFileExists($temporaryFile->getLocalPath());
$this->assertEquals($this->defaultDirectoryPermissions, substr(sprintf('%o', fileperms(dirname($temporaryFile->getLocalPath()))), -4));
$this->assertEquals('0600', substr(sprintf('%o', fileperms($temporaryFile->getLocalPath())), -4));
}
}
Loading