Skip to content

Commit 21331f8

Browse files
fix: prevent generate a path without existing folder
If we have a path /libresign/path/of/folder, all floders need to be exists when we send this to save the downloaded file. Signed-off-by: Vitor Mattos <vitor@php.rio>
1 parent 13fa787 commit 21331f8

File tree

2 files changed

+67
-90
lines changed

2 files changed

+67
-90
lines changed

lib/Service/Install/InstallService.php

Lines changed: 49 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -133,17 +133,13 @@ private function getFolder(string $path = '', ?ISimpleFolder $folder = null, $ne
133133
throw new LibresignException(
134134
$e->getMessage() . '. ' .
135135
'Permission problems. ' .
136-
'Maybe this could fix: chown -R ' . $user['name'] . ' ' . $this->getDataDir()
136+
'Maybe this could fix: chown -R ' . $user['name'] . ' ' . $this->getInternalPathOfFolder($folder)
137137
);
138138
}
139139
}
140140
return $folder;
141141
}
142142

143-
private function getEmptyFolder(string $path): ISimpleFolder {
144-
return $this->getFolder($path, null, true);
145-
}
146-
147143
/**
148144
* @todo check a best solution to don't use reflection
149145
*/
@@ -153,7 +149,7 @@ private function getInternalPathOfFolder(ISimpleFolder $node): string {
153149
$reflectionProperty->setAccessible(true);
154150
$folder = $reflectionProperty->getValue($node);
155151
$path = $folder->getInternalPath();
156-
return $path;
152+
return $this->getDataDir() . '/' . $path;
157153
}
158154

159155
/**
@@ -172,19 +168,14 @@ private function getInternalPathOfFile(ISimpleFile $node): string {
172168
$file = $reflectionProperty->getValue($node);
173169
$path = $file->getPath();
174170
}
175-
return $path;
171+
return $this->getDataDir() . '/' . $path;
176172
}
177173

178174
private function getDataDir(): string {
179175
$dataDir = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/');
180176
return $dataDir;
181177
}
182178

183-
private function getFullPath(): string {
184-
$folder = $this->getFolder();
185-
return $this->getDataDir() . '/' . $this->getInternalPathOfFolder($folder);
186-
}
187-
188179
private function runAsync(): void {
189180
$resource = $this->resource;
190181
$process = new Process([OC::$SERVERROOT . '/occ', 'libresign:install', '--' . $resource]);
@@ -396,12 +387,8 @@ public function installJava(?bool $async = false): void {
396387
if (PHP_OS_FAMILY !== 'Linux') {
397388
throw new RuntimeException(sprintf('OS_FAMILY %s is incompatible with LibreSign.', PHP_OS_FAMILY));
398389
}
399-
$linuxDistribution = $this->getLinuxDistributionToDownloadJava();
400-
$extractDir = $this->getFullPath() . '/' . $linuxDistribution . '/' . $this->resource;
401390

402-
$downloadOk = $this->isDownloadedFilesOk();
403-
if (!$downloadOk) {
404-
$folder = $this->getEmptyFolder($this->resource);
391+
if (!$this->isDownloadedFilesOk()) {
405392
/**
406393
* Steps to update:
407394
* Check the compatible version of Java to use JSignPdf
@@ -410,6 +397,7 @@ public function installJava(?bool $async = false): void {
410397
* URL used to get the MD5 and URL to download:
411398
* https://jdk.java.net/java-se-ri/8-MR3
412399
*/
400+
$linuxDistribution = $this->getLinuxDistributionToDownloadJava();
413401
$slugfyVersionNumber = str_replace('+', '_', self::JAVA_URL_PATH_NAME);
414402
if ($this->architecture === 'x86_64') {
415403
$compressedFileName = 'OpenJDK21U-jre_x64_' . $linuxDistribution . '_hotspot_' . $slugfyVersionNumber . '.tar.gz';
@@ -418,26 +406,24 @@ public function installJava(?bool $async = false): void {
418406
$compressedFileName = 'OpenJDK21U-jre_aarch64_' . $linuxDistribution . '_hotspot_' . $slugfyVersionNumber . '.tar.gz';
419407
$url = 'https://github.com/adoptium/temurin21-binaries/releases/download/jdk-' . self::JAVA_URL_PATH_NAME . '/' . $compressedFileName;
420408
}
421-
$checksumUrl = $url . '.sha256.txt';
422-
$hash = $this->getHash($compressedFileName, $checksumUrl);
409+
$folder = $this->getFolder('/' . $linuxDistribution . '/' . $this->resource);
423410
try {
424411
$compressedFile = $folder->getFile($compressedFileName);
425412
} catch (NotFoundException $th) {
426413
$compressedFile = $folder->newFile($compressedFileName);
427414
}
428-
$comporessedInternalFileName = $this->getDataDir() . '/' . $this->getInternalPathOfFile($compressedFile);
429415

416+
$comporessedInternalFileName = $this->getInternalPathOfFile($compressedFile);
430417
$dependencyName = 'java ' . $this->architecture . ' ' . $linuxDistribution;
418+
$checksumUrl = $url . '.sha256.txt';
419+
$hash = $this->getHash($compressedFileName, $checksumUrl);
431420
$this->download($url, $dependencyName, $comporessedInternalFileName, $hash, 'sha256');
432421

433422
$extractor = new TAR($comporessedInternalFileName);
423+
$extractDir = $this->getInternalPathOfFolder($folder);
434424
$extractor->extract($extractDir);
435425
unlink($comporessedInternalFileName);
436-
$downloadOk = true;
437-
}
438-
439-
$this->appConfig->setValueString(Application::APP_ID, 'java_path', $extractDir . '/jdk-' . self::JAVA_URL_PATH_NAME . '-jre/bin/java');
440-
if ($downloadOk) {
426+
$this->appConfig->setValueString(Application::APP_ID, 'java_path', $extractDir . '/jdk-' . self::JAVA_URL_PATH_NAME . '-jre/bin/java');
441427
$this->writeAppSignature();
442428
}
443429
$this->removeDownloadProgress();
@@ -487,35 +473,31 @@ public function installJSignPdf(?bool $async = false): void {
487473
$this->runAsync();
488474
return;
489475
}
490-
$extractDir = $this->getFullPath() . '/' . $this->resource;
491476

492-
$downloadOk = $this->isDownloadedFilesOk();
493-
if (!$downloadOk) {
494-
$folder = $this->getEmptyFolder($this->resource);
477+
if (!$this->isDownloadedFilesOk()) {
478+
$folder = $this->getFolder($this->resource);
495479
$compressedFileName = 'jsignpdf-' . JSignPdfHandler::VERSION . '.zip';
496480
try {
497481
$compressedFile = $folder->getFile($compressedFileName);
498482
} catch (\Throwable $th) {
499483
$compressedFile = $folder->newFile($compressedFileName);
500484
}
501-
$comporessedInternalFileName = $this->getDataDir() . '/' . $this->getInternalPathOfFile($compressedFile);
485+
$comporessedInternalFileName = $this->getInternalPathOfFile($compressedFile);
502486
$url = 'https://github.com/intoolswetrust/jsignpdf/releases/download/JSignPdf_' . str_replace('.', '_', JSignPdfHandler::VERSION) . '/jsignpdf-' . JSignPdfHandler::VERSION . '.zip';
503487
/** WHEN UPDATE version: generate this hash handmade and update here */
504488
$hash = 'd239658ea50a39eb35169d8392feaffb';
505489

506490
$this->download($url, 'JSignPdf', $comporessedInternalFileName, $hash);
507491

492+
$extractDir = $this->getInternalPathOfFolder($folder);
508493
$zip = new ZIP($extractDir . '/' . $compressedFileName);
509494
$zip->extract($extractDir);
510495
unlink($extractDir . '/' . $compressedFileName);
511-
$downloadOk = true;
512-
}
513-
514-
$fullPath = $extractDir . '/jsignpdf-' . JSignPdfHandler::VERSION . '/JSignPdf.jar';
515-
$this->appConfig->setValueString(Application::APP_ID, 'jsignpdf_jar_path', $fullPath);
516-
if ($downloadOk) {
496+
$fullPath = $extractDir . '/jsignpdf-' . JSignPdfHandler::VERSION . '/JSignPdf.jar';
497+
$this->appConfig->setValueString(Application::APP_ID, 'jsignpdf_jar_path', $fullPath);
517498
$this->writeAppSignature();
518499
}
500+
519501
$this->removeDownloadProgress();
520502
}
521503

@@ -540,29 +522,20 @@ public function installPdftk(?bool $async = false): void {
540522
return;
541523
}
542524

543-
$downloadOk = $this->isDownloadedFilesOk();
544-
if ($downloadOk) {
525+
if (!$this->isDownloadedFilesOk()) {
545526
$folder = $this->getFolder($this->resource);
546-
$file = $folder->getFile('pdftk.jar');
547-
$fullPath = $this->getDataDir() . '/' . $this->getInternalPathOfFile($file);
548-
} else {
549-
$folder = $this->getEmptyFolder($this->resource);
550527
try {
551528
$file = $folder->getFile('pdftk.jar');
552529
} catch (\Throwable $th) {
553530
$file = $folder->newFile('pdftk.jar');
554531
}
555-
$fullPath = $this->getDataDir() . '/' . $this->getInternalPathOfFile($file);
532+
$fullPath = $this->getInternalPathOfFile($file);
556533
$url = 'https://gitlab.com/api/v4/projects/5024297/packages/generic/pdftk-java/v' . self::PDFTK_VERSION . '/pdftk-all.jar';
557-
/** WHEN UPDATE version: generate this hash handmade and update here */
534+
/** @todo WHEN UPDATE version: generate this hash handmade and update here */
558535
$hash = '59a28bed53b428595d165d52988bf4cf';
559536

560537
$this->download($url, 'pdftk', $fullPath, $hash);
561-
$downloadOk = true;
562-
}
563-
564-
$this->appConfig->setValueString(Application::APP_ID, 'pdftk_path', $fullPath);
565-
if ($downloadOk) {
538+
$this->appConfig->setValueString(Application::APP_ID, 'pdftk_path', $fullPath);
566539
$this->writeAppSignature();
567540
}
568541
$this->removeDownloadProgress();
@@ -602,43 +575,36 @@ public function installCfssl(?bool $async = false): void {
602575
}
603576

604577
private function installCfsslByArchitecture(string $architecture): void {
605-
$downloadOk = $this->isDownloadedFilesOk();
606-
if ($downloadOk) {
607-
$folder = $this->getFolder($this->resource);
608-
} else {
609-
$folder = $this->getEmptyFolder($this->resource);
610-
$downloads = [
611-
[
612-
'file' => 'cfssl_' . self::CFSSL_VERSION . '_linux_' . $architecture,
613-
'destination' => 'cfssl',
614-
],
615-
[
616-
'file' => 'cfssljson_' . self::CFSSL_VERSION . '_linux_' . $architecture,
617-
'destination' => 'cfssljson',
618-
],
619-
];
620-
$baseUrl = 'https://github.com/cloudflare/cfssl/releases/download/v' . self::CFSSL_VERSION . '/';
621-
$checksumUrl = 'https://github.com/cloudflare/cfssl/releases/download/v' . self::CFSSL_VERSION . '/cfssl_' . self::CFSSL_VERSION . '_checksums.txt';
622-
foreach ($downloads as $download) {
623-
$hash = $this->getHash($download['file'], $checksumUrl);
624-
625-
$file = $folder->newFile($download['destination']);
626-
$fullPath = $this->getDataDir() . '/' . $this->getInternalPathOfFile($file);
627-
628-
$dependencyName = $download['destination'] . ' ' . $architecture;
629-
$this->download($baseUrl . $download['file'], $dependencyName, $fullPath, $hash, 'sha256');
630-
631-
chmod($fullPath, 0700);
632-
}
633-
$downloadOk = true;
578+
if ($this->isDownloadedFilesOk()) {
579+
return;
634580
}
581+
$folder = $this->getFolder($this->resource);
582+
$downloads = [
583+
[
584+
'file' => 'cfssl_' . self::CFSSL_VERSION . '_linux_' . $architecture,
585+
'destination' => 'cfssl',
586+
],
587+
[
588+
'file' => 'cfssljson_' . self::CFSSL_VERSION . '_linux_' . $architecture,
589+
'destination' => 'cfssljson',
590+
],
591+
];
592+
$baseUrl = 'https://github.com/cloudflare/cfssl/releases/download/v' . self::CFSSL_VERSION . '/';
593+
$checksumUrl = 'https://github.com/cloudflare/cfssl/releases/download/v' . self::CFSSL_VERSION . '/cfssl_' . self::CFSSL_VERSION . '_checksums.txt';
594+
foreach ($downloads as $download) {
595+
$hash = $this->getHash($download['file'], $checksumUrl);
635596

636-
$cfsslBinPath = $this->getDataDir() . '/' .
637-
$this->getInternalPathOfFolder($folder) . '/cfssl';
638-
$this->appConfig->setValueString(Application::APP_ID, 'cfssl_bin', $cfsslBinPath);
639-
if ($downloadOk) {
640-
$this->writeAppSignature();
597+
$file = $folder->newFile($download['destination']);
598+
$fullPath = $this->getInternalPathOfFile($file);
599+
600+
$dependencyName = $download['destination'] . ' ' . $architecture;
601+
$this->download($baseUrl . $download['file'], $dependencyName, $fullPath, $hash, 'sha256');
602+
603+
chmod($fullPath, 0700);
641604
}
605+
$cfsslBinPath = $this->getInternalPathOfFolder($folder) . '/cfssl';
606+
$this->appConfig->setValueString(Application::APP_ID, 'cfssl_bin', $cfsslBinPath);
607+
$this->writeAppSignature();
642608
}
643609

644610
public function uninstallCfssl(): void {

tests/Unit/Service/InstallServiceTest.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -160,18 +160,29 @@ public function providerDownloadCli(): array {
160160
* @dataProvider providerGetFolder
161161
* @runInSeparateProcess
162162
*/
163-
public function testGetFolder(string $path): void {
163+
public function testGetFolder(string $architecture, string $path, string $expectedFolderName): void {
164164
$install = \OCP\Server::get(\OCA\Libresign\Service\Install\InstallService::class);
165-
self::invokePrivate($install, 'getFolder', [$path]);
166-
$this->expectNotToPerformAssertions();
165+
if (!empty($architecture)) {
166+
$install->setArchitecture($architecture);
167+
}
168+
$folder = self::invokePrivate($install, 'getFolder', [$path]);
169+
$this->assertEquals($folder->getName(), $expectedFolderName);
167170
}
168171

169172
public static function providerGetFolder(): array {
170173
return [
171-
[''],
172-
['test'],
173-
['test/folder1'],
174-
['test/folder1/folder2'],
174+
['', '', php_uname('m')],
175+
['', 'test', 'test'],
176+
['', 'test/folder1', 'folder1'],
177+
['', 'test/folder1/folder2', 'folder2'],
178+
['aarch64', '', 'aarch64'],
179+
['aarch64', 'test', 'test'],
180+
['aarch64', 'test/folder1', 'folder1'],
181+
['aarch64', 'test/folder1/folder2', 'folder2'],
182+
['x86_64', '', 'x86_64'],
183+
['x86_64', 'test', 'test'],
184+
['x86_64', 'test/folder1', 'folder1'],
185+
['x86_64', 'test/folder1/folder2', 'folder2'],
175186
];
176187
}
177188
}

0 commit comments

Comments
 (0)