3declare(strict_types=1);
5require_once dirname(__DIR__) .
'/include/dbxUpdateService.class.php';
12 throw new RuntimeException($message);
18 $directory = dirname(
$file);
19 if (!is_dir($directory) && !mkdir($directory, 0775,
true) && !is_dir($directory)) {
20 throw new RuntimeException(
'Testverzeichnis konnte nicht erstellt werden.');
23 throw new RuntimeException(
'Testdatei konnte nicht geschrieben werden.');
29 if (!is_dir($directory)) {
32 $iterator =
new RecursiveIteratorIterator(
33 new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS),
34 RecursiveIteratorIterator::CHILD_FIRST
37 if ($item->isDir() && !$item->isLink()) {
38 rmdir($item->getPathname());
40 unlink($item->getPathname());
49 foreach ($contents as $path =>
$content) {
52 $files[
'.dbx-release-files.json'] =
null;
54 return json_encode(array(
56 'product' =>
'dbxapp',
59 ), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL;
66 string $extraPath =
''
68 $zip = new ZipArchive();
69 if ($zip->open(
$zipFile, ZipArchive::CREATE | ZipArchive::OVERWRITE) !==
true) {
70 throw new RuntimeException(
'Test-ZIP konnte nicht erzeugt werden.');
73 $zip->addFromString($path,
$content);
76 '.dbx-release-files.json',
79 if ($extraPath !==
'') {
80 $zip->addFromString($extraPath,
'unsafe');
92 . DIRECTORY_SEPARATOR . (string)
$manifest[
'version'];
96 $zip =
new ZipArchive();
101 $work . DIRECTORY_SEPARATOR .
'staged.json',
104 'staged_at' => gmdate(
'c'),
109 ), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
114$root = sys_get_temp_dir() . DIRECTORY_SEPARATOR
115 .
'dbx-update-service-' . bin2hex(random_bytes(6));
118 $oldContents = array(
119 'VERSION' =>
"4.0.1\n",
120 'index.php' =>
"<?php echo 'old';\n",
121 'dbx/include/dbxApi.php' =>
"<?php // old api\n",
122 'obsolete.php' =>
"<?php // obsolete\n",
124 foreach ($oldContents as $path =>
$content) {
126 $root . DIRECTORY_SEPARATOR . str_replace(
'/', DIRECTORY_SEPARATOR, $path),
131 $root . DIRECTORY_SEPARATOR .
'.dbx-release-files.json',
136 $root . DIRECTORY_SEPARATOR .
'files' . DIRECTORY_SEPARATOR .
'keep.txt',
140 $root . DIRECTORY_SEPARATOR .
'dbx' . DIRECTORY_SEPARATOR .
'modules'
141 . DIRECTORY_SEPARATOR .
'demo' . DIRECTORY_SEPARATOR .
'cfg'
142 . DIRECTORY_SEPARATOR .
'config.local.php',
147 'VERSION' =>
"4.0.2\n",
148 'index.php' =>
"<?php echo 'new';\n",
149 'dbx/include/dbxApi.php' =>
"<?php // new api\n",
150 'new.php' =>
"<?php // new file\n",
152 $work =
$root . DIRECTORY_SEPARATOR .
'files' . DIRECTORY_SEPARATOR .
'update';
154 . DIRECTORY_SEPARATOR .
'dbxapp-4.0.2.zip';
156 mkdir(dirname(
$zipFile), 0775,
true);
162 'product' =>
'dbxapp',
163 'channel' =>
'stable',
164 'version' =>
'4.0.2',
165 'release_url' =>
'https://github.com/ecb-dbxApp/dbxapp/releases/tag/v4.0.2',
166 'zip_url' =>
'https://github.com/ecb-dbxApp/dbxapp/releases/download/v4.0.2/dbxapp-4.0.2.zip',
167 'sha256' => hash_file(
'sha256',
$zipFile),
170 'extensions' => array(
'json',
'pdo',
'zip'),
177 in_array(
'new.php',
$package[
'files'],
true),
178 'Gültige Paketdatei fehlt in der Prüfung.'
182 $badManifest[
'zip_url'] =
'https://github.com/other/project/releases/download/v4.0.2/dbxapp-4.0.2.zip';
185 throw new RuntimeException(
'Fremde GitHub-Release-URL wurde zugelassen.');
186 }
catch (RuntimeException $exception) {
188 str_contains($exception->getMessage(),
'Vertrauensgrenze'),
189 'Falscher Fehler für fremde Release-URL.'
194 . DIRECTORY_SEPARATOR .
'unsafe.zip';
198 throw new RuntimeException(
'ZIP-Pfad-Traversal wurde zugelassen.');
199 }
catch (RuntimeException $exception) {
201 str_contains($exception->getMessage(),
'Pfad-Traversal'),
202 'Falscher Fehler für ZIP-Pfad-Traversal.'
208 !empty(
$service->status()[
'stop_available']),
209 'Vorbereitetes Update kann laut Status nicht gestoppt werden.'
217 empty(
$service->status()[
'stop_available']),
218 'Status bietet Stoppen nach dem Abbruch weiterhin an.'
224 $work . DIRECTORY_SEPARATOR .
'staged.json',
227 'staged_at' => gmdate(
'c'),
228 'zip_file' =>
$work . DIRECTORY_SEPARATOR .
'downloads'
229 . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR .
'..'
230 . DIRECTORY_SEPARATOR .
'..' . DIRECTORY_SEPARATOR
231 .
'outside-stop-guard.txt',
232 'staging_directory' =>
$work . DIRECTORY_SEPARATOR .
'staging'
233 . DIRECTORY_SEPARATOR .
'missing',
236 ), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
240 throw new RuntimeException(
'Manipulierter Stop-Pfad wurde zugelassen.');
241 }
catch (RuntimeException $exception) {
243 str_contains($exception->getMessage(),
'Status ist ungültig'),
244 'Falscher Fehler für manipulierten Stop-Pfad.'
249 'Stop-Pfad hat eine Datei außerhalb des Updatebereichs entfernt.'
251 unlink(
$work . DIRECTORY_SEPARATOR .
'staged.json');
258 update_test_assert(trim((
string)file_get_contents(
$root .
'/VERSION')) ===
'4.0.2',
'VERSION wurde nicht aktualisiert.');
261 update_test_assert((
string)file_get_contents(
$root .
'/files/keep.txt') ===
'runtime',
'Laufzeitdatei wurde verändert.');
264 is_dir((
string)
$installed[
'backup_directory']),
265 'Dateisicherung wurde nicht erzeugt.'
272 update_test_assert(trim((
string)file_get_contents(
$root .
'/VERSION')) ===
'4.0.1',
'Rollback hat VERSION nicht wiederhergestellt.');
276 (
string)file_get_contents(
$root .
'/dbx/modules/demo/cfg/config.local.php') ===
"<?php // local\n",
277 'Lokale Modulkonfiguration wurde verändert.'
280 echo
"dbxUpdateService: Paketprüfung, Stop, Installation und Rollback erfolgreich.\n";
Sicherer dbxApp Release-Updater fuer Dateien und optionale DB-Migrationen.
if(preg_match('/core\.js\? foreach[^"\']*v=(\d+)/', $designTemplate, $assetMatch) !== 1 || !str_contains($shopReference, 'dbxapp-Asset-Version ' . $assetMatch[1])) foreach (array( 'reference\\archive', 'provision_docs_content.php', 'dbxSelfTest') as $needle)(array('Installation'=> $installation, 'Installations-Tutorial'=> $installationTutorial, 'SelfTest'=> $selfTest) as $label=> $html)
catch(RuntimeException $exception) $staging
update_test_package(string $zipFile, string $version, array $contents, string $extraPath='')
catch(RuntimeException $exception) $unsafeZip
update_test_assert(bool $condition, string $message)
update_test_write(string $file, string $content)
update_test_remove_tree(string $directory)
update_test_inventory(string $version, array $contents)
update_test_stage(string $work, string $zipFile, array $manifest, array $package)