From d35a29e4ac6930cd1238325266fe48e5f779501d Mon Sep 17 00:00:00 2001 From: Niklas Grieger <55093258+bmgrieger@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:31:05 +0200 Subject: [PATCH] Use file streaming for output to prevent large files from exhausting PHP memory limit (#203) * [TASK] Use file streaming for output to prevent large files from exhausting PHP memory limit [TER-194] [TER-195] * [TASK] Raise upper PHP requirement in ext_emconf.php [TER-194] [TER-195] * [TASK] Update php-cs-fixer configuration [TER-194] [TER-195] * [TASK] Run php-cs-fixer [TER-194] [TER-195] * [BUGFIX] Add missing use statement [TER-194] [TER-195] * [BUGFIX] Add missing use statement [TER-194] [TER-195] * [TASK] Remove old comments and run php-cs-fixer [TER-194] [TER-195] * [TASK] Prepare release of version 6.0.3 [TER-194] [TER-195] --- .gitattributes | 2 +- .php-cs-fixer.php | 34 ++++++++++ .php_cs | 61 ----------------- Classes/Cache/AbstractCache.php | 11 ++-- Classes/Cache/DecodeCache.php | 15 ++--- Classes/Cache/EncodeCache.php | 11 ++-- Classes/Controller/LogController.php | 14 ++-- Classes/Domain/Model/Log.php | 11 ++-- Classes/Domain/Repository/LogRepository.php | 16 ++--- .../Domain/Repository/StorageRepository.php | 11 ++-- .../Transfer/ExtensionConfiguration.php | 17 +++-- Classes/Domain/Transfer/Filter.php | 17 +++-- Classes/Domain/Transfer/Statistic.php | 15 ++--- .../Domain/Transfer/Token/AbstractToken.php | 15 ++--- .../Domain/Transfer/Token/DefaultToken.php | 11 ++-- .../SecureDownloadsEventListener.php | 15 ++--- Classes/Exception/ClassNotFoundException.php | 15 ++--- Classes/Exception/InvalidClassException.php | 15 ++--- Classes/Factory/Event/EnrichPayloadEvent.php | 15 ++--- Classes/Factory/SecureLinkFactory.php | 13 ++-- Classes/Middleware/FileDeliveryMiddleware.php | 11 ++-- Classes/Middleware/TokenRefreshMiddleware.php | 11 ++-- Classes/MimeTypes.php | 11 ++-- Classes/Registry/AbstractRegistry.php | 11 ++-- Classes/Registry/CheckRegistry.php | 11 ++-- Classes/Registry/TokenRegistry.php | 11 ++-- .../Resource/Driver/SecureDownloadsDriver.php | 17 +++-- .../Event/AfterFileRetrievedEvent.php | 11 ++-- .../Resource/Event/BeforeReadDeliverEvent.php | 11 ++-- .../Event/OutputInitializationEvent.php | 11 ++-- Classes/Resource/FileDelivery.php | 66 ++++++++++--------- Classes/Security/AbstractCheck.php | 11 ++-- Classes/Security/UserCheck.php | 15 ++--- Classes/Security/UserGroupCheck.php | 11 ++-- Classes/Service/SecureDownloadService.php | 11 ++-- Classes/UserFunctions/CheckConfiguration.php | 11 ++-- Configuration/Icons.php | 13 ---- Documentation/About/ChangeLog/6-0-3.rst | 47 +++++++++++++ Documentation/About/ChangeLog/Index.rst | 1 + .../Middleware/TokenRefreshMiddlewareTest.php | 13 +++- .../Service/SecureDownloadServiceTest.php | 9 +++ .../UserFunctions/CheckConfigurationTest.php | 9 +++ composer.json | 5 ++ ext_emconf.php | 5 +- 44 files changed, 338 insertions(+), 339 deletions(-) create mode 100644 .php-cs-fixer.php delete mode 100644 .php_cs create mode 100755 Documentation/About/ChangeLog/6-0-3.rst diff --git a/.gitattributes b/.gitattributes index 417a160..098d6be 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,5 +4,5 @@ /Tests/ export-ignore /.gitattributes export-ignore /.gitignore export-ignore -/.php_cs export-ignore +/.php-cs-fixer.php export-ignore /Resources/Private/Examples/ export-ignore diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..3a1f68d --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,34 @@ +, Leuchtfeuer Digital Marketing +COMMENT; + +$config = CsFixerConfig::create(); +$config + ->setHeader($headerComment, true) + ->getFinder() + ->name('*.php') + ->exclude('Configuration') + ->exclude('Libraries') + ->exclude('Resources') + ->exclude('Migrations') + ->notName('ext_emconf.php') + ->notName('ext_tables.php') + ->notName('ext_localconf.php') + ->in(dirname(__DIR__)); + +return $config; diff --git a/.php_cs b/.php_cs deleted file mode 100644 index ece9fe6..0000000 --- a/.php_cs +++ /dev/null @@ -1,61 +0,0 @@ -setRiskyAllowed(true) - ->setRules([ - '@DoctrineAnnotation' => true, - '@PSR2' => true, - 'array_syntax' => ['syntax' => 'short'], - 'cast_spaces' => ['space' => 'none'], - 'concat_space' => ['spacing' => 'one'], - 'declare_equal_normalize' => ['space' => 'single'], - 'dir_constant' => true, - 'function_typehint_space' => true, - 'hash_to_slash_comment' => true, - 'lowercase_cast' => true, - 'modernize_types_casting' => true, - 'native_function_casing' => true, - 'no_alias_functions' => true, - 'no_blank_lines_after_phpdoc' => true, - 'no_empty_phpdoc' => true, - 'no_empty_statement' => true, - 'no_extra_consecutive_blank_lines' => true, - 'no_leading_import_slash' => true, - 'no_leading_namespace_whitespace' => true, - 'no_null_property_initialization' => true, - 'no_short_bool_cast' => true, - 'no_singleline_whitespace_before_semicolons' => true, - 'no_superfluous_elseif' => true, - 'no_trailing_comma_in_singleline_array' => true, - 'no_unneeded_control_parentheses' => true, - 'no_unused_imports' => true, - 'no_useless_else' => true, - 'no_whitespace_in_blank_line' => true, - 'ordered_imports' => true, - 'php_unit_construct' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame'], - 'php_unit_mock_short_will_return' => true, - 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], - 'phpdoc_no_access' => true, - 'phpdoc_no_empty_return' => true, - 'phpdoc_no_package' => true, - 'phpdoc_scalar' => true, - 'phpdoc_trim' => true, - 'phpdoc_types' => true, - 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], - 'return_type_declaration' => ['space_before' => 'none'], - 'single_quote' => true, - 'whitespace_after_comma_in_array' => true, - ]) - ->setFinder( - PhpCsFixer\Finder::create() - ->in(__DIR__) - ->exclude('Resources') - ->exclude('Libraries') - ->notName('ext_emconf.php') - ->notName('ext_tables.php') - ->notName('ext_localconf.php') - ); diff --git a/Classes/Cache/AbstractCache.php b/Classes/Cache/AbstractCache.php index 896aefb..5906dce 100644 --- a/Classes/Cache/AbstractCache.php +++ b/Classes/Cache/AbstractCache.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Cache; use TYPO3\CMS\Core\SingletonInterface; diff --git a/Classes/Cache/DecodeCache.php b/Classes/Cache/DecodeCache.php index 4b4b9e1..e9ef07b 100644 --- a/Classes/Cache/DecodeCache.php +++ b/Classes/Cache/DecodeCache.php @@ -1,20 +1,19 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Cache; + +use Leuchtfeuer\SecureDownloads\Domain\Transfer\Token\AbstractToken; /** * Stores decoded JSON web token data. diff --git a/Classes/Cache/EncodeCache.php b/Classes/Cache/EncodeCache.php index e274121..4853e69 100644 --- a/Classes/Cache/EncodeCache.php +++ b/Classes/Cache/EncodeCache.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Cache; /** * Stores encoded JSON web token data. diff --git a/Classes/Controller/LogController.php b/Classes/Controller/LogController.php index 769065a..5011389 100644 --- a/Classes/Controller/LogController.php +++ b/Classes/Controller/LogController.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Controller; use Doctrine\DBAL\Exception; use Leuchtfeuer\SecureDownloads\Domain\Repository\LogRepository; @@ -33,8 +32,7 @@ class LogController extends ActionController public function __construct( protected ModuleTemplateFactory $moduleTemplateFactory, protected LogRepository $logRepository, - ) { - } + ) {} /** * @return ResponseInterface diff --git a/Classes/Domain/Model/Log.php b/Classes/Domain/Model/Log.php index 878a2b8..ca7c8a0 100644 --- a/Classes/Domain/Model/Log.php +++ b/Classes/Domain/Model/Log.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Domain\Model; use Doctrine\DBAL\Exception; use TYPO3\CMS\Core\Database\ConnectionPool; diff --git a/Classes/Domain/Repository/LogRepository.php b/Classes/Domain/Repository/LogRepository.php index 6cd2fd0..73fc6e6 100644 --- a/Classes/Domain/Repository/LogRepository.php +++ b/Classes/Domain/Repository/LogRepository.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Domain\Repository; use Leuchtfeuer\SecureDownloads\Domain\Model\Log; use Leuchtfeuer\SecureDownloads\Domain\Transfer\Filter; @@ -29,13 +28,12 @@ class LogRepository extends Repository { - const TABLENAME = 'tx_securedownloads_domain_model_log'; + public const TABLENAME = 'tx_securedownloads_domain_model_log'; public function __construct( private readonly ConnectionPool $connectionPool, private readonly DataMapper $dataMapper - ) { - } + ) {} public function createQueryBuilder(): QueryBuilder { diff --git a/Classes/Domain/Repository/StorageRepository.php b/Classes/Domain/Repository/StorageRepository.php index e975fc6..340b176 100644 --- a/Classes/Domain/Repository/StorageRepository.php +++ b/Classes/Domain/Repository/StorageRepository.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Domain\Repository; use Doctrine\DBAL\Exception; use Leuchtfeuer\SecureDownloads\Resource\Driver\SecureDownloadsDriver; diff --git a/Classes/Domain/Transfer/ExtensionConfiguration.php b/Classes/Domain/Transfer/ExtensionConfiguration.php index 9dc6a68..948c2bc 100644 --- a/Classes/Domain/Transfer/ExtensionConfiguration.php +++ b/Classes/Domain/Transfer/ExtensionConfiguration.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Domain\Transfer; use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException; use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException; @@ -24,11 +23,11 @@ */ class ExtensionConfiguration implements SingletonInterface { - const FILE_TYPES_WILDCARD = '*'; + public const FILE_TYPES_WILDCARD = '*'; - const OUTPUT_STREAM = 'stream'; + public const OUTPUT_STREAM = 'stream'; - const OUTPUT_NGINX = 'x-accel-redirect'; + public const OUTPUT_NGINX = 'x-accel-redirect'; /** * The value will be added to configured cache lifetime of the page, where the resource is embedded in. diff --git a/Classes/Domain/Transfer/Filter.php b/Classes/Domain/Transfer/Filter.php index 4662e6b..0784bdb 100644 --- a/Classes/Domain/Transfer/Filter.php +++ b/Classes/Domain/Transfer/Filter.php @@ -1,24 +1,23 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Domain\Transfer; class Filter { - const USER_TYPE_ALL = 0; - const USER_TYPE_LOGGED_ON = -1; - const USER_TYPE_LOGGED_OFF = -2; + public const USER_TYPE_ALL = 0; + public const USER_TYPE_LOGGED_ON = -1; + public const USER_TYPE_LOGGED_OFF = -2; /** * @var string The file type. diff --git a/Classes/Domain/Transfer/Statistic.php b/Classes/Domain/Transfer/Statistic.php index d5f5de9..cab7e23 100644 --- a/Classes/Domain/Transfer/Statistic.php +++ b/Classes/Domain/Transfer/Statistic.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Domain\Transfer; use Leuchtfeuer\SecureDownloads\Domain\Repository\LogRepository; @@ -22,9 +21,7 @@ public function __construct( protected \DateTime $from = new \DateTime(), protected \DateTime $till = new \DateTime(), protected float $traffic = 0.00 - ) - { - } + ) {} public function calc(Filter $filter, LogRepository $logRepository): void { diff --git a/Classes/Domain/Transfer/Token/AbstractToken.php b/Classes/Domain/Transfer/Token/AbstractToken.php index 999e20a..dadc470 100644 --- a/Classes/Domain/Transfer/Token/AbstractToken.php +++ b/Classes/Domain/Transfer/Token/AbstractToken.php @@ -2,18 +2,17 @@ declare(strict_types=1); -namespace Leuchtfeuer\SecureDownloads\Domain\Transfer\Token; - -/*** - * +/* * This file is part of the "Secure Downloads" Extension for TYPO3 CMS. * * For the full copyright and license information, please read the * LICENSE.txt file that was distributed with this source code. * - * (c) 2020 Dev , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Domain\Transfer\Token; + abstract class AbstractToken { /** @@ -53,7 +52,7 @@ abstract class AbstractToken public function __construct() { $this->iat = time(); - $this->implementationClassName = get_called_class(); + $this->implementationClassName = static::class; } abstract public function encode(?array $payload = null): string; diff --git a/Classes/Domain/Transfer/Token/DefaultToken.php b/Classes/Domain/Transfer/Token/DefaultToken.php index 79d7985..e1244fb 100644 --- a/Classes/Domain/Transfer/Token/DefaultToken.php +++ b/Classes/Domain/Transfer/Token/DefaultToken.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Domain\Transfer\Token; use Firebase\JWT\JWT; use Firebase\JWT\Key; diff --git a/Classes/EventListener/SecureDownloadsEventListener.php b/Classes/EventListener/SecureDownloadsEventListener.php index 6699879..e8d2a0b 100644 --- a/Classes/EventListener/SecureDownloadsEventListener.php +++ b/Classes/EventListener/SecureDownloadsEventListener.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\EventListener; use Leuchtfeuer\SecureDownloads\Resource\Driver\SecureDownloadsDriver; use Leuchtfeuer\SecureDownloads\Service\SecureDownloadService; @@ -31,9 +30,7 @@ */ class SecureDownloadsEventListener implements SingletonInterface { - public function __construct(protected SecureDownloadService $secureDownloadService) - { - } + public function __construct(protected SecureDownloadService $secureDownloadService) {} /** * This will secure a link when given file is underneath a protected directory and the file type matches the configured diff --git a/Classes/Exception/ClassNotFoundException.php b/Classes/Exception/ClassNotFoundException.php index bf0d65d..20ab524 100644 --- a/Classes/Exception/ClassNotFoundException.php +++ b/Classes/Exception/ClassNotFoundException.php @@ -1,19 +1,16 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Exception; -class ClassNotFoundException extends \Exception -{ -} +class ClassNotFoundException extends \Exception {} diff --git a/Classes/Exception/InvalidClassException.php b/Classes/Exception/InvalidClassException.php index 6965cff..1fda90d 100644 --- a/Classes/Exception/InvalidClassException.php +++ b/Classes/Exception/InvalidClassException.php @@ -1,19 +1,16 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Exception; -class InvalidClassException extends \Exception -{ -} +class InvalidClassException extends \Exception {} diff --git a/Classes/Factory/Event/EnrichPayloadEvent.php b/Classes/Factory/Event/EnrichPayloadEvent.php index dc62f1a..fc66719 100644 --- a/Classes/Factory/Event/EnrichPayloadEvent.php +++ b/Classes/Factory/Event/EnrichPayloadEvent.php @@ -1,20 +1,19 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Factory\Event; + +use Leuchtfeuer\SecureDownloads\Domain\Transfer\Token\AbstractToken; /** * You can use this event for extending or manipulating the payload of the JSON Web Token. This event is executed immediately diff --git a/Classes/Factory/SecureLinkFactory.php b/Classes/Factory/SecureLinkFactory.php index 81e9db0..c6df927 100644 --- a/Classes/Factory/SecureLinkFactory.php +++ b/Classes/Factory/SecureLinkFactory.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Factory; use Leuchtfeuer\SecureDownloads\Cache\EncodeCache; use Leuchtfeuer\SecureDownloads\Domain\Transfer\ExtensionConfiguration; @@ -32,7 +31,7 @@ class SecureLinkFactory implements SingletonInterface { - const DEFAULT_CACHE_LIFETIME = 86400; + public const DEFAULT_CACHE_LIFETIME = 86400; /** * @var EventDispatcher diff --git a/Classes/Middleware/FileDeliveryMiddleware.php b/Classes/Middleware/FileDeliveryMiddleware.php index 2c81fac..41e51d2 100644 --- a/Classes/Middleware/FileDeliveryMiddleware.php +++ b/Classes/Middleware/FileDeliveryMiddleware.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Middleware; use Leuchtfeuer\SecureDownloads\Domain\Transfer\ExtensionConfiguration; use Leuchtfeuer\SecureDownloads\Resource\FileDelivery; diff --git a/Classes/Middleware/TokenRefreshMiddleware.php b/Classes/Middleware/TokenRefreshMiddleware.php index 60f3a62..58e5823 100644 --- a/Classes/Middleware/TokenRefreshMiddleware.php +++ b/Classes/Middleware/TokenRefreshMiddleware.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Middleware; use Firebase\JWT\JWT; use Firebase\JWT\Key; diff --git a/Classes/MimeTypes.php b/Classes/MimeTypes.php index 7a377fa..e6e1587 100644 --- a/Classes/MimeTypes.php +++ b/Classes/MimeTypes.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads; final class MimeTypes { diff --git a/Classes/Registry/AbstractRegistry.php b/Classes/Registry/AbstractRegistry.php index 630e2c2..664c378 100644 --- a/Classes/Registry/AbstractRegistry.php +++ b/Classes/Registry/AbstractRegistry.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Registry; use TYPO3\CMS\Core\SingletonInterface; diff --git a/Classes/Registry/CheckRegistry.php b/Classes/Registry/CheckRegistry.php index d549ea3..9dd2318 100644 --- a/Classes/Registry/CheckRegistry.php +++ b/Classes/Registry/CheckRegistry.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Registry; use Leuchtfeuer\SecureDownloads\Exception\ClassNotFoundException; use Leuchtfeuer\SecureDownloads\Exception\InvalidClassException; diff --git a/Classes/Registry/TokenRegistry.php b/Classes/Registry/TokenRegistry.php index 030dbe8..632a85b 100644 --- a/Classes/Registry/TokenRegistry.php +++ b/Classes/Registry/TokenRegistry.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Registry; use Leuchtfeuer\SecureDownloads\Domain\Transfer\Token\AbstractToken; use Leuchtfeuer\SecureDownloads\Exception\ClassNotFoundException; diff --git a/Classes/Resource/Driver/SecureDownloadsDriver.php b/Classes/Resource/Driver/SecureDownloadsDriver.php index d476893..715c382 100644 --- a/Classes/Resource/Driver/SecureDownloadsDriver.php +++ b/Classes/Resource/Driver/SecureDownloadsDriver.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Resource\Driver; use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Resource\Driver\LocalDriver; @@ -23,11 +22,11 @@ */ class SecureDownloadsDriver extends LocalDriver { - const DRIVER_SHORT_NAME = 'sdl'; + public const DRIVER_SHORT_NAME = 'sdl'; - const DRIVER_NAME = 'Secure Downloads'; + public const DRIVER_NAME = 'Secure Downloads'; - const BASE_PATH = 'sdl/'; + public const BASE_PATH = 'sdl/'; public function determineSecureDownloadsDriverBaseUrl(): void { diff --git a/Classes/Resource/Event/AfterFileRetrievedEvent.php b/Classes/Resource/Event/AfterFileRetrievedEvent.php index e36a51f..dab1423 100644 --- a/Classes/Resource/Event/AfterFileRetrievedEvent.php +++ b/Classes/Resource/Event/AfterFileRetrievedEvent.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Resource\Event; /** * This event is executed after the access checks has been performed and both the file and the file name have been read from the diff --git a/Classes/Resource/Event/BeforeReadDeliverEvent.php b/Classes/Resource/Event/BeforeReadDeliverEvent.php index 1534a6e..151ccaf 100644 --- a/Classes/Resource/Event/BeforeReadDeliverEvent.php +++ b/Classes/Resource/Event/BeforeReadDeliverEvent.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Resource\Event; /** * This event is executed just before the file is sent to the browser. It is the last chance to influence both the output diff --git a/Classes/Resource/Event/OutputInitializationEvent.php b/Classes/Resource/Event/OutputInitializationEvent.php index 0a340fd..db8cd06 100644 --- a/Classes/Resource/Event/OutputInitializationEvent.php +++ b/Classes/Resource/Event/OutputInitializationEvent.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Resource\Event; use Leuchtfeuer\SecureDownloads\Domain\Transfer\Token\AbstractToken; diff --git a/Classes/Resource/FileDelivery.php b/Classes/Resource/FileDelivery.php index 2e0dbac..99b2a4c 100644 --- a/Classes/Resource/FileDelivery.php +++ b/Classes/Resource/FileDelivery.php @@ -1,20 +1,18 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Resource; -use Firebase\JWT\JWT; use Leuchtfeuer\SecureDownloads\Cache\DecodeCache; use Leuchtfeuer\SecureDownloads\Domain\Transfer\ExtensionConfiguration; use Leuchtfeuer\SecureDownloads\Domain\Transfer\Token\AbstractToken; @@ -31,9 +29,11 @@ use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Error\Http\PageNotFoundException; -use TYPO3\CMS\Core\EventDispatcher\EventDispatcher; use TYPO3\CMS\Core\Http\Response; use TYPO3\CMS\Core\Http\Stream; +use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException; +use TYPO3\CMS\Core\Resource\File; +use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Type\File\FileInfo; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -42,31 +42,15 @@ class FileDelivery implements SingletonInterface { - /** - * @var ExtensionConfiguration - */ - protected ExtensionConfiguration $extensionConfiguration; - - /** - * @var EventDispatcherInterface - */ - protected EventDispatcherInterface $eventDispatcher; - - /** - * @var AbstractToken - */ protected AbstractToken $token; - /** - * @var array - */ protected array $header = []; - public function __construct(ExtensionConfiguration $extensionConfiguration, EventDispatcher $eventDispatcher) - { - $this->extensionConfiguration = $extensionConfiguration; - $this->eventDispatcher = $eventDispatcher; - } + public function __construct( + protected ExtensionConfiguration $extensionConfiguration, + protected EventDispatcherInterface $eventDispatcher, + protected ResourceFactory $resourceFactory + ) {} /** * Delivers the file to the browser if all checks pass and file exists. @@ -76,7 +60,7 @@ public function __construct(ExtensionConfiguration $extensionConfiguration, Even * * @return ResponseInterface Either the valid file as a stream or an error response * - * @throws PageNotFoundException + * @throws PageNotFoundException|ResourceDoesNotExistException */ public function deliver(string $jsonWebToken, ServerRequestInterface $request): ResponseInterface { @@ -100,7 +84,25 @@ public function deliver(string $jsonWebToken, ServerRequestInterface $request): $this->dispatchAfterFileRetrievedEvent($file, $fileName); if (file_exists($file)) { - return new Response($this->getResponseBody($file, $fileName), 200, $this->header, ''); + $fileObject = $this->resourceFactory->retrieveFileOrFolderObject($this->token->getFile()); + if ($fileObject instanceof File) { + $response = $fileObject + ->getStorage() + ->streamFile( + $fileObject, + $this->shouldForceDownload($fileObject->getExtension()) + ); + ob_end_clean(); + + return $response; + } + + return new Response( + $this->getResponseBody($file, $fileName), + 200, + $this->header, + '' + ); } return $this->getFileNotFoundResponse($request, 'File does not exist!'); @@ -289,7 +291,7 @@ protected function getFileHeader(string $mimeType, string $fileName, bool $force protected function outputFile(string $outputFunction, string $file): ?StreamInterface { if ($outputFunction === ExtensionConfiguration::OUTPUT_NGINX) { - if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'nginx') === 0) { + if (isset($_SERVER['SERVER_SOFTWARE']) && str_starts_with($_SERVER['SERVER_SOFTWARE'], 'nginx')) { $this->header['X-Accel-Redirect'] = sprintf( '%s/%s', rtrim($this->extensionConfiguration->getProtectedPath(), '/'), diff --git a/Classes/Security/AbstractCheck.php b/Classes/Security/AbstractCheck.php index 13ec42d..6b75923 100644 --- a/Classes/Security/AbstractCheck.php +++ b/Classes/Security/AbstractCheck.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Security; use Leuchtfeuer\SecureDownloads\Domain\Transfer\ExtensionConfiguration; use Leuchtfeuer\SecureDownloads\Domain\Transfer\Token\AbstractToken; diff --git a/Classes/Security/UserCheck.php b/Classes/Security/UserCheck.php index 75c1a6b..4fee115 100644 --- a/Classes/Security/UserCheck.php +++ b/Classes/Security/UserCheck.php @@ -1,20 +1,19 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Security; + +use TYPO3\CMS\Core\Context\Exception\AspectPropertyNotFoundException; class UserCheck extends AbstractCheck { diff --git a/Classes/Security/UserGroupCheck.php b/Classes/Security/UserGroupCheck.php index f5c95cf..894d59f 100644 --- a/Classes/Security/UserGroupCheck.php +++ b/Classes/Security/UserGroupCheck.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Security; use TYPO3\CMS\Core\Context\Exception\AspectPropertyNotFoundException; use TYPO3\CMS\Core\Utility\GeneralUtility; diff --git a/Classes/Service/SecureDownloadService.php b/Classes/Service/SecureDownloadService.php index 552ae4b..0784c2f 100644 --- a/Classes/Service/SecureDownloadService.php +++ b/Classes/Service/SecureDownloadService.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\Service; use Leuchtfeuer\SecureDownloads\Domain\Transfer\ExtensionConfiguration; use Leuchtfeuer\SecureDownloads\Factory\SecureLinkFactory; diff --git a/Classes/UserFunctions/CheckConfiguration.php b/Classes/UserFunctions/CheckConfiguration.php index 1358d42..1ad6f5a 100644 --- a/Classes/UserFunctions/CheckConfiguration.php +++ b/Classes/UserFunctions/CheckConfiguration.php @@ -1,18 +1,17 @@ , Leuchtfeuer Digital Marketing - * - ***/ + * (c) Dev , Leuchtfeuer Digital Marketing + */ + +namespace Leuchtfeuer\SecureDownloads\UserFunctions; use GuzzleHttp\Client; use Leuchtfeuer\SecureDownloads\Domain\Transfer\ExtensionConfiguration; diff --git a/Configuration/Icons.php b/Configuration/Icons.php index 66cd559..f7aec77 100644 --- a/Configuration/Icons.php +++ b/Configuration/Icons.php @@ -1,18 +1,5 @@ `__ or from +`GitHub `__. + +Added +===== + +Changed +======= +* Use file streaming for output to prevent large files from exhausting PHP memory limit + +Deprecated +========== + +Removed +======= + +All Changes +=========== +This is a list of all changes in this release:: + + 2024-04-04 [TASK] Remove old comments and run php-cs-fixer [TER-194] [TER-195] (Commit 20c58f6 by Niklas Grieger) + 2024-04-04 [BUGFIX] Add missing use statement [TER-194] [TER-195] (Commit bcf608d by Niklas Grieger) + 2024-04-04 [BUGFIX] Add missing use statement [TER-194] [TER-195] (Commit f48f133 by Niklas Grieger) + 2024-04-04 [TASK] Run php-cs-fixer [TER-194] [TER-195] (Commit 0f6ab30 by Niklas Grieger) + 2024-04-04 [TASK] Update php-cs-fixer configuration [TER-194] [TER-195] (Commit 0472c5c by Niklas Grieger) + 2024-04-04 [TASK] Raise upper PHP requirement in ext_emconf.php [TER-194] [TER-195] (Commit a33aa86 by Niklas Grieger) + 2024-04-04 [TASK] Use file streaming for output to prevent large files from exhausting PHP memory limit [TER-194] [TER-195] (Commit 12f1b8f by Niklas Grieger) + +Contributors +============ +Following people have contributed to this release: + +* Oliver Heins +* Niklas Grieger + +Thank you very much for your support. The next drink is on us! 🍻 diff --git a/Documentation/About/ChangeLog/Index.rst b/Documentation/About/ChangeLog/Index.rst index e642145..cdec46b 100755 --- a/Documentation/About/ChangeLog/Index.rst +++ b/Documentation/About/ChangeLog/Index.rst @@ -17,6 +17,7 @@ List of versions :titlesonly: :glob: + 6-0-3 6-0-2 6-0-1 6-0-0 diff --git a/Tests/Unit/Middleware/TokenRefreshMiddlewareTest.php b/Tests/Unit/Middleware/TokenRefreshMiddlewareTest.php index 7c47526..655c317 100644 --- a/Tests/Unit/Middleware/TokenRefreshMiddlewareTest.php +++ b/Tests/Unit/Middleware/TokenRefreshMiddlewareTest.php @@ -1,5 +1,14 @@ , Leuchtfeuer Digital Marketing + */ + namespace Leuchtfeuer\SecureDownloads\Tests\Unit\Middleware; use Leuchtfeuer\SecureDownloads\Domain\Transfer\ExtensionConfiguration; @@ -324,7 +333,7 @@ public function whenALinkWithTheSameUserIDofTheCurrentUserLinkResponseBodyIsNotM $this->setProtectedProperty($secureLinkFactory, 'userId', 1); $this->setProtectedProperty($secureLinkFactory, 'userGroups', [0, -2, 1]); $this->setProtectedProperty($secureLinkFactory, 'pageId', 1); - $this->setProtectedProperty($secureLinkFactory, 'linkTimeout', time()+60); + $this->setProtectedProperty($secureLinkFactory, 'linkTimeout', time() + 60); $this->setProtectedProperty($secureLinkFactory, 'resourceUri', 'fileadmin/foo.txt'); $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = 'secret'; @@ -419,7 +428,7 @@ public function whenALinkWithAnOtherUserIDofTheCurrentUserLinkResponseBodyIsModi $secureLinkFactory->withUser(1) ->withGroups([0, -2, 1]) ->withPage(1) - ->withLinkTimeout(time() +60) + ->withLinkTimeout(time() + 60) ->withResourceUri('fileadmin/secure/document.pdf'); $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = 'my-secret'; diff --git a/Tests/Unit/Service/SecureDownloadServiceTest.php b/Tests/Unit/Service/SecureDownloadServiceTest.php index 79bf469..e42f521 100644 --- a/Tests/Unit/Service/SecureDownloadServiceTest.php +++ b/Tests/Unit/Service/SecureDownloadServiceTest.php @@ -1,5 +1,14 @@ , Leuchtfeuer Digital Marketing + */ + use Leuchtfeuer\SecureDownloads\Domain\Transfer\ExtensionConfiguration; use Leuchtfeuer\SecureDownloads\Service\SecureDownloadService; use PHPUnit\Framework\TestCase; diff --git a/Tests/Unit/UserFunctions/CheckConfigurationTest.php b/Tests/Unit/UserFunctions/CheckConfigurationTest.php index 4843e46..64c3a82 100644 --- a/Tests/Unit/UserFunctions/CheckConfigurationTest.php +++ b/Tests/Unit/UserFunctions/CheckConfigurationTest.php @@ -1,5 +1,14 @@ , Leuchtfeuer Digital Marketing + */ + namespace Leuchtfeuer\SecureDownloads\Tests\Unit\UserFunctions; use Leuchtfeuer\SecureDownloads\Domain\Transfer\ExtensionConfiguration; diff --git a/composer.json b/composer.json index 49dbe0e..4f65963 100644 --- a/composer.json +++ b/composer.json @@ -57,6 +57,8 @@ } }, "require-dev": { + "friendsofphp/php-cs-fixer": "^3.10", + "typo3/coding-standards": "^0.7.1", "typo3/testing-framework": "^8.0.1" }, "config": { @@ -64,5 +66,8 @@ "typo3/class-alias-loader": true, "typo3/cms-composer-installers": true } + }, + "scripts":{ + "fix:cs": "./vendor/bin/php-cs-fixer fix --config ./.php-cs-fixer.php --using-cache no --show-progress dots -v --diff --format=txt" } } diff --git a/ext_emconf.php b/ext_emconf.php index 9d26485..36423cf 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -4,15 +4,14 @@ 'title' => 'Secure Downloads', 'description' => '"Secure Download": Apply TYPO3 access rights to ALL file assets (PDFs, TGZs or JPGs etc. - configurable) - protect them from direct access.', 'category' => 'fe', - 'version' => '6.0.2', + 'version' => '6.0.3', 'state' => 'stable', - 'clearCacheOnLoad' => true, 'author' => 'Dev Leuchtfeuer', 'author_email' => 'dev@Leuchtfeuer.com', 'author_company' => 'Leuchtfeuer Digital Marketing', 'constraints' => [ 'depends' => [ - 'php' => '8.1.0-8.1.99', + 'php' => '8.1.0-8.3.99', 'typo3' => '12.4.0-12.9.99', ], 'conflicts' => [