From 5fa8bf583d82452d48d588997097a47aedfa324c Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Fri, 12 Jul 2024 19:05:56 -0300 Subject: [PATCH] fix: use linux distro when build Signed-off-by: Vitor Mattos --- lib/Command/Developer/SignSetup.php | 11 +-- lib/Service/Install/InstallService.php | 16 +--- lib/Service/Install/SignSetupService.php | 85 +++++++++++++++---- .../Service/Install/SignSetupServiceTest.php | 44 ++++++---- 4 files changed, 96 insertions(+), 60 deletions(-) diff --git a/lib/Command/Developer/SignSetup.php b/lib/Command/Developer/SignSetup.php index e40d55ba78..2d6b29a8bf 100644 --- a/lib/Command/Developer/SignSetup.php +++ b/lib/Command/Developer/SignSetup.php @@ -80,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($this->installService->getAvailableResources() as $resource) { if ($resource === 'java') { foreach (['linux', 'alpine-linux'] as $distro) { - $this->installService->setDistro($distro); + $this->signSetupService->setDistro($distro); $this->writeAppSignature($architecture, $resource); } continue; @@ -97,15 +97,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int } private function writeAppSignature(string $architecture, string $resource): void { - $this->installService - ->setArchitecture($architecture) - ->setResource($resource); - $this->signSetupService->setInstallPath( - $this->installService->getInstallPath() - ); - $this->signSetupService->setSignatureFileName( - $this->installService->getSignatureFileName() - ); $this->signSetupService->writeAppSignature($architecture, $resource); } } diff --git a/lib/Service/Install/InstallService.php b/lib/Service/Install/InstallService.php index be9b2ea593..5698092bcf 100644 --- a/lib/Service/Install/InstallService.php +++ b/lib/Service/Install/InstallService.php @@ -364,12 +364,7 @@ private function writeAppSignature(): void { return; } - $this->signSetupService->setSignatureFileName( - $this->getSignatureFileName() - ); - $this->signSetupService->setInstallPath( - $this->getInstallPath() - ); + $this->signSetupService->setDistro($this->getLinuxDistributionToDownloadJava()); $this->signSetupService->writeAppSignature($this->architecture, $this->resource); } @@ -451,15 +446,6 @@ public function getInstallPath(): string { return ''; } - public function getSignatureFileName(): string { - $path[] = 'install-' . $this->architecture; - if ($this->resource === 'java') { - $path[] = $this->getLinuxDistributionToDownloadJava(); - } - $path[] = $this->resource . '.json'; - return implode('-', $path); - } - /** * Return linux or alpine-linux */ diff --git a/lib/Service/Install/SignSetupService.php b/lib/Service/Install/SignSetupService.php index d0c7120b5e..15a3505a42 100644 --- a/lib/Service/Install/SignSetupService.php +++ b/lib/Service/Install/SignSetupService.php @@ -15,15 +15,13 @@ use OCA\Libresign\Exception\InvalidSignatureException; use OCA\Libresign\Exception\SignatureDataNotFoundException; use OCP\App\IAppManager; -use OCP\Files\AppData\IAppDataFactory; -use OCP\Files\IAppData; +use OCP\AppFramework\Services\IAppConfig; use OCP\Files\NotFoundException; use OCP\IConfig; use phpseclib\Crypt\RSA; use phpseclib\File\X509; class SignSetupService { - private IAppData $appData; private array $exclude = [ 'openssl_config', 'cfssl_config', @@ -33,18 +31,16 @@ class SignSetupService { private string $resource; private array $signatureData = []; private bool $willUseLocalCert = false; - private string $signatureFileName = ''; - private string $installPath = ''; + private string $distro = ''; private ?X509 $x509 = null; private ?RSA $rsa = null; public function __construct( private EnvironmentHelper $environmentHelper, private FileAccessHelper $fileAccessHelper, private IConfig $config, - private IAppDataFactory $appDataFactory, + private IAppConfig $appConfig, private IAppManager $appManager, ) { - $this->appData = $appDataFactory->get('libresign'); } public function getArchitectures(): array { @@ -109,7 +105,7 @@ public function writeAppSignature( $this->architecture = $architecture; $this->resource = $resource; try { - $iterator = $this->getFolderIterator($this->installPath); + $iterator = $this->getFolderIterator($this->getInstallPath()); $hashes = $this->generateHashes($iterator); $signature = $this->createSignatureData($hashes); $this->fileAccessHelper->file_put_contents( @@ -132,19 +128,72 @@ public function writeAppSignature( } } - public function setInstallPath(string $installPath): self { - $this->installPath = $installPath; - return $this; + public function getInstallPath(): string { + switch ($this->resource) { + case 'java': + $path = $this->appConfig->getAppValue('java_path'); + $installPath = substr($path, 0, -strlen('/bin/java')); + if (!str_contains($installPath, $this->distro)) { + $installPath = preg_replace( + '/\/' . $this->architecture . '\/(\w+)/i', + '/' . $this->architecture . '/'.$this->distro, + $installPath + ); + } + break; + case 'jsignpdf': + $path = $this->appConfig->getAppValue('jsignpdf_jar_path'); + $installPath = substr($path, 0, -strlen('/JSignPdf.jar')); + break; + case 'pdftk': + $path = $this->appConfig->getAppValue('pdftk_path'); + $installPath = substr($path, 0, -strlen('/pdftk.jar')); + break; + case 'cfssl': + $path = $this->appConfig->getAppValue('cfssl_bin'); + $installPath = substr($path, 0, -strlen('/cfssl')); + break; + default: + $installPath = ''; + } + if (!str_contains($installPath, $this->architecture)) { + $installPath = preg_replace('/\/libresign\/(\w+)/i', '/libresign/'.$this->architecture, $installPath); + } + return $installPath; + } + + private function getFileName(): string { + $appInfoDir = $this->getAppInfoDirectory(); + return $appInfoDir . '/' . $this->getSignatureFileName(); + } + + public function getSignatureFileName(): string { + $path[] = 'install-' . $this->architecture; + if ($this->resource === 'java') { + $path[] = $this->getLinuxDistributionToDownloadJava(); + } + $path[] = $this->resource . '.json'; + return implode('-', $path); } - public function setSignatureFileName(string $signatureFileName): self { - $this->signatureFileName = $signatureFileName; + public function setDistro(string $distro): self { + $this->distro = $distro; return $this; } - private function getFileName(): string { - $appInfoDir = $this->getAppInfoDirectory(); - return $appInfoDir . '/' . $this->signatureFileName; + /** + * Return linux or alpine-linux + */ + public function getLinuxDistributionToDownloadJava(): string { + if ($this->distro) { + return $this->distro; + } + $distribution = shell_exec('cat /etc/*-release'); + preg_match('/^ID=(?.*)$/m', $distribution, $matches); + if (isset($matches['version']) && strtolower($matches['version']) === 'alpine') { + return 'alpine-linux'; + } + return 'linux'; } protected function getAppInfoDirectory(): string { @@ -249,7 +298,7 @@ public function verify(string $architecture, $resource): array { try { $expectedHashes = $this->getHashesOfResource(); // Compare the list of files which are not identical - $currentInstanceHashes = $this->generateHashes($this->getFolderIterator($this->installPath), $this->installPath); + $currentInstanceHashes = $this->generateHashes($this->getFolderIterator($this->getInstallPath())); } catch (EmptySignatureDataException $th) { return [ 'EMPTY_SIGNATURE_DATA' => $th->getMessage(), @@ -331,7 +380,7 @@ private function getFolderIterator(string $folderToIterate): \RecursiveIteratorI private function generateHashes(\RecursiveIteratorIterator $iterator): array { $hashes = []; - $baseDirectoryLength = \strlen($this->installPath); + $baseDirectoryLength = \strlen($this->getInstallPath()); foreach ($iterator as $filename => $data) { /** @var \DirectoryIterator $data */ if ($data->isDir()) { diff --git a/tests/Unit/Service/Install/SignSetupServiceTest.php b/tests/Unit/Service/Install/SignSetupServiceTest.php index ac3e4db3e1..aab43fccf6 100644 --- a/tests/Unit/Service/Install/SignSetupServiceTest.php +++ b/tests/Unit/Service/Install/SignSetupServiceTest.php @@ -13,7 +13,7 @@ use OC\IntegrityCheck\Helpers\FileAccessHelper; use OCA\Libresign\Service\Install\SignSetupService; use OCP\App\IAppManager; -use OCP\Files\AppData\IAppDataFactory; +use OCP\AppFramework\Services\IAppConfig; use OCP\IConfig; use phpseclib\Crypt\RSA; use phpseclib\File\X509; @@ -23,15 +23,15 @@ final class SignSetupServiceTest extends \OCA\Libresign\Tests\Unit\TestCase { private EnvironmentHelper&MockObject $environmentHelper; private FileAccessHelper $fileAccessHelper; private IConfig&MockObject $config; - private IAppDataFactory&MockObject $appDataFactory; + private IAppConfig&MockObject $appConfig; private IAppManager&MockObject $appManager; public function setUp(): void { $this->environmentHelper = $this->createMock(EnvironmentHelper::class); $this->fileAccessHelper = new FileAccessHelper(); - $this->config = $this->createMock(IConfig::class); - $this->appDataFactory = $this->createMock(IAppDataFactory::class); $this->appManager = $this->createMock(IAppManager::class); + $this->config = $this->createMock(IConfig::class); + $this->appConfig = $this->createMock(IAppConfig::class); } /** @@ -43,7 +43,7 @@ private function getInstance(array $methods = []) { $this->environmentHelper, $this->fileAccessHelper, $this->config, - $this->appDataFactory, + $this->appConfig, $this->appManager, ]) ->onlyMethods($methods) @@ -82,14 +82,20 @@ private function writeAppSignature(string $architecture, $resource): SignSetupSe $this->environmentHelper->method('getServerRoot') ->willReturn('vfs://home'); + $this->appConfig + ->method('getAppValue') + ->willReturnCallback(function ($key, $default) use ($architecture):string { + return match ($key) { + 'java_path' => 'vfs://home/data/libresign/' . $architecture . '/linux/java/bin/java', + default => '', + }; + }); $signSetupService = $this->getInstance([ 'getAppInfoDirectory', ]); $signSetupService->expects($this->any()) ->method('getAppInfoDirectory') ->willReturn('vfs://home/appinfo'); - $signSetupService->setSignatureFileName('install-' . $architecture . '-' . $resource . '.json'); - $signSetupService->setInstallPath('vfs://home/data/libresign/' . $resource); $this->appManager->method('getAppInfo') ->willReturn(['dependencies' => ['architecture' => [$architecture]]]); @@ -105,10 +111,14 @@ private function writeAppSignature(string $architecture, $resource): SignSetupSe $structure = [ 'data' => [ 'libresign' => [ - 'java' => [ - 'fakeFile01' => 'content', - 'fakeFile02' => 'content', - ], + $architecture => [ + 'linux' => [ + 'java' => [ + 'fakeFile01' => 'content', + 'fakeFile02' => 'content', + ], + ] + ] ], ], 'resources' => [ @@ -121,12 +131,12 @@ private function writeAppSignature(string $architecture, $resource): SignSetupSe $root = vfsStream::setup('home', null, $structure); $signSetupService->writeAppSignature($architecture, $resource); - $this->assertFileExists('vfs://home/appinfo/install-' . $architecture . '-' . $resource . '.json'); - $json = file_get_contents('vfs://home/appinfo/install-' . $architecture . '-' . $resource . '.json'); + $this->assertFileExists('vfs://home/appinfo/install-' . $architecture . '-linux-' . $resource . '.json'); + $json = file_get_contents('vfs://home/appinfo/install-' . $architecture . '-linux-' . $resource . '.json'); $signatureContent = json_decode($json, true); $this->assertArrayHasKey('hashes', $signatureContent); $this->assertCount(2, $signatureContent['hashes']); - $expected = hash('sha512', $structure['data']['libresign'][$resource]['fakeFile01']); + $expected = hash('sha512', $structure['data']['libresign'][$architecture]['linux'][$resource]['fakeFile01']); $this->assertArrayHasKey('fakeFile01', $signatureContent['hashes']); $actual = $signatureContent['hashes']['fakeFile01']; $this->assertEquals($expected, $actual); @@ -152,9 +162,9 @@ public static function dataWriteAppSignature(): array { public function testVerify(): void { $architecture = 'x86_64'; $signSetupService = $this->writeAppSignature($architecture, 'java'); - unlink('vfs://home/data/libresign/java/fakeFile01'); - file_put_contents('vfs://home/data/libresign/java/fakeFile02', 'invalidContent'); - file_put_contents('vfs://home/data/libresign/java/fakeFile03', 'invalidContent'); + unlink('vfs://home/data/libresign/' . $architecture . '/linux/java/fakeFile01'); + file_put_contents('vfs://home/data/libresign/' . $architecture . '/linux/java/fakeFile02', 'invalidContent'); + file_put_contents('vfs://home/data/libresign/' . $architecture . '/linux/java/fakeFile03', 'invalidContent'); $expected = json_encode([ 'FILE_MISSING' => [ 'fakeFile01' => [