bug and media fixes

This commit is contained in:
Dennis Eichhorn 2021-10-29 14:49:55 +02:00
parent aee00aa2a9
commit 005a269bc9
5 changed files with 50 additions and 36 deletions

View File

@ -58,6 +58,10 @@ final class Installer extends InstallerAbstract
*/ */
public static function install(DatabasePool $dbPool, ModuleInfo $info, SettingsInterface $cfgHandler) : void public static function install(DatabasePool $dbPool, ModuleInfo $info, SettingsInterface $cfgHandler) : void
{ {
if (!\is_dir(__DIR__ . '/../Files')) {
\mkdir(__DIR__ . '/../Files');
}
parent::install($dbPool, $info, $cfgHandler); parent::install($dbPool, $info, $cfgHandler);
// Create directory for admin account // Create directory for admin account
@ -255,12 +259,13 @@ final class Installer extends InstallerAbstract
} }
} }
$upload = new UploadFile(); $upload = new UploadFile();
$upload->outputDir = empty($data['path'] ?? '') $upload->preserveFileName = $data['fixed_names'] ?? true;
$upload->outputDir = empty($data['path'] ?? '')
? ApiController::createMediaPath() ? ApiController::createMediaPath()
: __DIR__ . '/../../..' . $data['path']; : __DIR__ . '/../../..' . $data['path'];
$status = $upload->upload($files, [$data['name']], true); $status = $upload->upload($files, ($data['fixed_names'] ?? true) ? [] : [$data['name']], true);
$mediaFiles = []; $mediaFiles = [];
foreach ($status as $uFile) { foreach ($status as $uFile) {

View File

@ -70,7 +70,8 @@ final class ApiController extends Controller
public function apiMediaUpload(RequestAbstract $request, ResponseAbstract $response, $data = null) : void public function apiMediaUpload(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{ {
$uploads = $this->uploadFiles( $uploads = $this->uploadFiles(
[$request->getData('name') === null ? '' : $request->getData('name')], $request->getDataList('names') ?? [],
$request->getDataList('filenames') ?? [],
$request->getFiles(), $request->getFiles(),
$request->header->account, $request->header->account,
__DIR__ . '/../../../Modules/Media/Files' . \urldecode((string) ($request->getData('path') ?? '')), __DIR__ . '/../../../Modules/Media/Files' . \urldecode((string) ($request->getData('path') ?? '')),
@ -119,7 +120,8 @@ final class ApiController extends Controller
/** /**
* Upload a media file * Upload a media file
* *
* @param array $names Name * @param array $names Database names
* @param array $fileNames FileNames
* @param array $files Files * @param array $files Files
* @param int $account Uploader * @param int $account Uploader
* @param string $basePath Base path. The path which is used for the upload. * @param string $basePath Base path. The path which is used for the upload.
@ -138,6 +140,7 @@ final class ApiController extends Controller
*/ */
public function uploadFiles( public function uploadFiles(
array $names, array $names,
array $fileNames,
array $files, array $files,
int $account, int $account,
string $basePath = '/Modules/Media/Files', string $basePath = '/Modules/Media/Files',
@ -164,10 +167,17 @@ final class ApiController extends Controller
return []; return [];
} }
$upload = new UploadFile(); $upload = new UploadFile();
$upload->outputDir = $outputDir; $upload->outputDir = $outputDir;
$status = $upload->upload($files, $names, $absolute, $encryptionKey); $status = $upload->upload($files, $fileNames, $absolute, $encryptionKey);
$sameLength = \count($names) === \count($status);
$nCounter = -1;
foreach ($status as &$stat) {
++$nCounter;
$stat['name'] = $sameLength ? $names[$nCounter] : $stat['filename'];
}
return $this->createDbEntries($status, $account, $virtualPath, $type); return $this->createDbEntries($status, $account, $virtualPath, $type);
} }
@ -175,9 +185,9 @@ final class ApiController extends Controller
/** /**
* Uploads a file to a destination * Uploads a file to a destination
* *
* @param array $files Files to upload * @param array $files Files to upload
* @param array $names Name of the file (only if a single file is provided) * @param array $fileNames Names on the directory
* @param string $path Upload path * @param string $path Upload path
* *
* @return array * @return array
* *
@ -185,14 +195,14 @@ final class ApiController extends Controller
*/ */
public static function uploadFilesToDestination( public static function uploadFilesToDestination(
array $files, array $files,
array $names = [], array $fileNames = [],
string $path = '', string $path = '',
) : array ) : array
{ {
$upload = new UploadFile(); $upload = new UploadFile();
$upload->outputDir = $path; $upload->outputDir = $path;
$status = $upload->upload($files, $names, true, ''); $status = $upload->upload($files, $fileNames, true, '');
return $status; return $status;
} }

View File

@ -83,7 +83,7 @@ class UploadFile
* Upload file to server. * Upload file to server.
* *
* @param array $files File data ($_FILE) * @param array $files File data ($_FILE)
* @param string[] $names File name * @param string[] $fileNames File name
* @param bool $absolute Use absolute path * @param bool $absolute Use absolute path
* @param string $encryptionKey Encryption key * @param string $encryptionKey Encryption key
* @param string $encoding Encoding used for uploaded file. Empty string will not convert file content. * @param string $encoding Encoding used for uploaded file. Empty string will not convert file content.
@ -96,13 +96,14 @@ class UploadFile
*/ */
public function upload( public function upload(
array $files, array $files,
array $names = [], array $fileNames = [],
bool $absolute = false, bool $absolute = false,
string $encryptionKey = '', string $encryptionKey = '',
string $encoding = 'UTF-8' string $encoding = 'UTF-8'
) : array ) : array
{ {
$result = []; $result = [];
$fileNames = $this->preserveFileName || \count($files) !== \count($fileNames) ? [] : $fileNames;
if (\count($files) === \count($files, \COUNT_RECURSIVE)) { if (\count($files) === \count($files, \COUNT_RECURSIVE)) {
$files = [$files]; $files = [$files];
@ -114,11 +115,9 @@ class UploadFile
$path = $this->outputDir; $path = $this->outputDir;
$fCounter = -1; $fCounter = -1;
$areNamed = \count($files) === \count($names);
foreach ($files as $key => $f) { foreach ($files as $key => $f) {
++$fCounter; ++$fCounter;
$name = $areNamed ? $names[$fCounter] : '';
if ($path === '') { if ($path === '') {
$path = File::dirpath($f['tmp_name']); $path = File::dirpath($f['tmp_name']);
@ -151,15 +150,17 @@ class UploadFile
return $result; return $result;
} }
$split = \explode('.', $f['name']); $split = \explode('.', $f['name']);
$result[$key]['filename'] = !empty($name) && !$this->preserveFileName ? $name : $f['name']; $result[$key]['filename'] = !empty($fileNames) ? $fileNames[$fCounter] : $f['name'];
$result[$key]['extension'] = ($c = \count($split)) > 1 ? $split[$c - 1] : '';
$extension = \count($split) > 1 ? $split[\count($split) - 1] : '';
$result[$key]['extension'] = $extension;
if (!$this->preserveFileName || \is_file($path . '/' . $result[$key]['filename'])) { if (!$this->preserveFileName || \is_file($path . '/' . $result[$key]['filename'])) {
try { try {
$result[$key]['filename'] = $this->createFileName($path, $f['tmp_name'], $extension); $result[$key]['filename'] = $this->createFileName(
$path,
$this->preserveFileName ? $result[$key]['filename'] : '',
$result[$key]['extension']
);
} catch (\Exception $e) { } catch (\Exception $e) {
$result[$key]['filename'] = $f['name']; $result[$key]['filename'] = $f['name'];
$result[$key]['status'] = UploadStatus::FAILED_HASHING; $result[$key]['status'] = UploadStatus::FAILED_HASHING;
@ -168,12 +169,8 @@ class UploadFile
} }
} }
$result[$key]['name'] = empty($name) ? $result[$key]['filename'] : $name;
if (!\is_dir($path)) { if (!\is_dir($path)) {
$created = Directory::create($path, 0755, true); if (!Directory::create($path, 0755, true)) {
if (!$created) {
FileLogger::getInstance()->error('Couldn\t upload media file. There maybe is a problem with your permission or uploaded file.'); FileLogger::getInstance()->error('Couldn\t upload media file. There maybe is a problem with your permission or uploaded file.');
} }
} }
@ -244,10 +241,13 @@ class UploadFile
private function createFileName(string $path, string $tempName, string $extension) : string private function createFileName(string $path, string $tempName, string $extension) : string
{ {
$rnd = ''; $rnd = '';
$limit = 0; $limit = -1;
$nameWithoutExtension = empty($tempName) ? '' : \substr($tempName, 0, -\strlen($extension) - 1);
do { do {
$sha = \sha1($tempName . $rnd); ++$limit;
$sha = empty($nameWithoutExtension) ? \sha1($tempName . $rnd) : $nameWithoutExtension . '_' . $rnd;
if ($sha === false) { if ($sha === false) {
throw new \Exception('No file path could be found. Potential attack!'); throw new \Exception('No file path could be found. Potential attack!');
@ -256,7 +256,6 @@ class UploadFile
$sha .= '.' . $extension; $sha .= '.' . $extension;
$fileName = $sha; $fileName = $sha;
$rnd = \mt_rand(); $rnd = \mt_rand();
++$limit;
} while (\is_file($path . '/' . $fileName) && $limit < self::PATH_GENERATION_LIMIT); } while (\is_file($path . '/' . $fileName) && $limit < self::PATH_GENERATION_LIMIT);
if ($limit >= self::PATH_GENERATION_LIMIT) { if ($limit >= self::PATH_GENERATION_LIMIT) {

View File

@ -392,4 +392,4 @@ function phpServe() : void
}); });
} }
phpServe(); \phpServe();

View File

@ -172,7 +172,7 @@ trait ApiControllerMediaTrait
{ {
self::assertEquals( self::assertEquals(
[], [],
$this->module->uploadFiles(['test'], ['test'], 1, '/test', '', null, '', '', 99) $this->module->uploadFiles(['test'], ['test'], ['test'], 1, '/test', '', null, '', '', 99)
); );
} }