Skip to content

Commit b4f43fc

Browse files
skjnldsvbackportbot[bot]
authored andcommitted
feat: allow to provide manual URL
Signed-off-by: skjnldsv <skjnldsv@protonmail.com> [skip ci]
1 parent bbb3fee commit b4f43fc

4 files changed

Lines changed: 73 additions & 47 deletions

File tree

index.php

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -567,11 +567,9 @@ private function getUpdateServerResponse(): array {
567567
*
568568
* @throws \Exception
569569
*/
570-
public function downloadUpdate(): void {
570+
public function downloadUpdate(?string $url = null): void {
571571
$this->silentLog('[info] downloadUpdate()');
572572

573-
$response = $this->getUpdateServerResponse();
574-
575573
$storageLocation = $this->getUpdateDirectoryLocation() . '/updater-'.$this->getConfigOptionMandatoryString('instanceid') . '/downloads/';
576574
if (file_exists($storageLocation)) {
577575
$this->silentLog('[info] storage location exists');
@@ -582,12 +580,26 @@ public function downloadUpdate(): void {
582580
throw new \Exception('Could not mkdir storage location');
583581
}
584582

585-
if (!isset($response['url']) || !is_string($response['url'])) {
586-
throw new \Exception('Response from update server is missing url');
583+
$downloadURL = '';
584+
if ($url) {
585+
// If a URL is provided, use it directly
586+
$downloadURL = $url;
587+
} else {
588+
// Otherwise, get the download URLs from the update server
589+
$response = $this->getUpdateServerResponse();
590+
591+
if (!isset($response['url']) || !is_string($response['url'])) {
592+
throw new \Exception('Response from update server is missing url');
593+
}
594+
$downloadURL = $response['url'];
595+
}
596+
597+
if (!$downloadURL) {
598+
throw new \Exception('No download URL provided or available from update server');
587599
}
588600

589-
$fp = fopen($storageLocation . basename($response['url']), 'w+');
590-
$ch = curl_init($response['url']);
601+
$fp = fopen($storageLocation . basename($downloadURL), 'w+');
602+
$ch = curl_init($downloadURL);
591603
curl_setopt_array($ch, [
592604
CURLOPT_FILE => $fp,
593605
CURLOPT_USERAGENT => 'Nextcloud Updater',
@@ -629,7 +641,7 @@ public function downloadUpdate(): void {
629641
$message .= ' - curl error message: ' . $curlErrorMessage;
630642
}
631643

632-
$message .= ' - URL: ' . htmlentities($response['url']);
644+
$message .= ' - URL: ' . htmlentities($downloadURL);
633645

634646
throw new \Exception($message);
635647
}
@@ -662,14 +674,19 @@ private function getDownloadedFilePath(): string {
662674
*
663675
* @throws \Exception
664676
*/
665-
public function verifyIntegrity(): void {
677+
public function verifyIntegrity(?string $urlOverride = null): void {
666678
$this->silentLog('[info] verifyIntegrity()');
667679

668680
if ($this->getCurrentReleaseChannel() === 'daily') {
669681
$this->silentLog('[info] current channel is "daily" which is not signed. Skipping verification.');
670682
return;
671683
}
672684

685+
if ($urlOverride) {
686+
$this->silentLog('[info] custom download url provided, cannot verify signature');
687+
return;
688+
}
689+
673690
$response = $this->getUpdateServerResponse();
674691
if (empty($response['signature'])) {
675692
throw new \Exception('No signature specified for defined update');

lib/UpdateCommand.php

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class UpdateCommand extends Command {
3636
protected bool $shouldStop = false;
3737
protected bool $skipBackup = false;
3838
protected bool $skipUpgrade = false;
39+
protected string $urlOverride = '';
3940

4041
/** @var list<string> strings of text for stages of updater */
4142
protected array $checkTexts = [
@@ -60,7 +61,8 @@ protected function configure(): void {
6061
->setDescription('Updates the code of an Nextcloud instance')
6162
->setHelp("This command fetches the latest code that is announced via the updater server and safely replaces the existing code with the new one.")
6263
->addOption('no-backup', null, InputOption::VALUE_NONE, 'Skip backup of current Nextcloud version')
63-
->addOption('no-upgrade', null, InputOption::VALUE_NONE, "Don't automatically run occ upgrade");
64+
->addOption('no-upgrade', null, InputOption::VALUE_NONE, "Don't automatically run occ upgrade")
65+
->addOption('url', null, InputOption::VALUE_OPTIONAL, 'The URL of the Nextcloud release to download');
6466
}
6567

6668
public static function getUpdaterVersion(): string {
@@ -75,6 +77,7 @@ public static function getUpdaterVersion(): string {
7577
protected function execute(InputInterface $input, OutputInterface $output) {
7678
$this->skipBackup = (bool)$input->getOption('no-backup');
7779
$this->skipUpgrade = (bool)$input->getOption('no-upgrade');
80+
$this->urlOverride = (string)$input->getOption('url');
7881

7982
$version = static::getUpdaterVersion();
8083
$output->writeln('Nextcloud Updater - version: ' . $version);
@@ -148,7 +151,12 @@ protected function execute(InputInterface $input, OutputInterface $output) {
148151
$output->writeln('Current version is ' . $this->updater->getCurrentVersion() . '.');
149152

150153
// needs to be called that early because otherwise updateAvailable() returns false
151-
$updateString = $this->updater->checkForUpdate();
154+
if ($this->urlOverride) {
155+
$this->updater->log('[info] Using URL override: ' . $this->urlOverride);
156+
$updateString = 'Update check forced with URL override: ' . $this->urlOverride;
157+
} else {
158+
$updateString = $this->updater->checkForUpdate();
159+
}
152160

153161
$output->writeln('');
154162

@@ -161,9 +169,11 @@ protected function execute(InputInterface $input, OutputInterface $output) {
161169

162170
$output->writeln('');
163171

164-
if (!$this->updater->updateAvailable() && $stepNumber === 0) {
165-
$output->writeln('Nothing to do.');
166-
return 0;
172+
if (!$this->urlOverride) {
173+
if (!$this->updater->updateAvailable() && $stepNumber === 0) {
174+
$output->writeln('Nothing to do.');
175+
return 0;
176+
}
167177
}
168178

169179
$questionText = 'Start update';
@@ -375,10 +385,10 @@ protected function executeStep(int $step): array {
375385
}
376386
break;
377387
case 4:
378-
$this->updater->downloadUpdate();
388+
$this->updater->downloadUpdate($this->urlOverride);
379389
break;
380390
case 5:
381-
$this->updater->verifyIntegrity();
391+
$this->updater->verifyIntegrity($this->urlOverride);
382392
break;
383393
case 6:
384394
$this->updater->extractDownload();

lib/Updater.php

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,7 @@
11
<?php
22
/**
3-
* @copyright Copyright (c) 2016-2017 Lukas Reschke <lukas@statuscode.ch>
4-
* @copyright Copyright (c) 2016 Morris Jobke <hey@morrisjobke.de>
5-
* @copyright Copyright (c) 2018 Jonas Sulzer <jonas@violoncello.ch>
6-
*
7-
* @license GNU AGPL version 3 or any later version
8-
*
9-
* This program is free software: you can redistribute it and/or modify
10-
* it under the terms of the GNU Affero General Public License as
11-
* published by the Free Software Foundation, either version 3 of the
12-
* License, or (at your option) any later version.
13-
*
14-
* This program is distributed in the hope that it will be useful,
15-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17-
* GNU Affero General Public License for more details.
18-
*
19-
* You should have received a copy of the GNU Affero General Public License
20-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21-
*
3+
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
4+
* SPDX-License-Identifier: AGPL-3.0-or-later
225
*/
236

247
namespace NC\Updater;
@@ -529,11 +512,9 @@ private function getUpdateServerResponse(): array {
529512
*
530513
* @throws \Exception
531514
*/
532-
public function downloadUpdate(): void {
515+
public function downloadUpdate(?string $url = null): void {
533516
$this->silentLog('[info] downloadUpdate()');
534517

535-
$response = $this->getUpdateServerResponse();
536-
537518
$storageLocation = $this->getUpdateDirectoryLocation() . '/updater-'.$this->getConfigOptionMandatoryString('instanceid') . '/downloads/';
538519
if (file_exists($storageLocation)) {
539520
$this->silentLog('[info] storage location exists');
@@ -544,12 +525,26 @@ public function downloadUpdate(): void {
544525
throw new \Exception('Could not mkdir storage location');
545526
}
546527

547-
if (!isset($response['url']) || !is_string($response['url'])) {
548-
throw new \Exception('Response from update server is missing url');
528+
$downloadURL = '';
529+
if ($url) {
530+
// If a URL is provided, use it directly
531+
$downloadURL = $url;
532+
} else {
533+
// Otherwise, get the download URLs from the update server
534+
$response = $this->getUpdateServerResponse();
535+
536+
if (!isset($response['url']) || !is_string($response['url'])) {
537+
throw new \Exception('Response from update server is missing url');
538+
}
539+
$downloadURL = $response['url'];
540+
}
541+
542+
if (!$downloadURL) {
543+
throw new \Exception('No download URL provided or available from update server');
549544
}
550545

551-
$fp = fopen($storageLocation . basename($response['url']), 'w+');
552-
$ch = curl_init($response['url']);
546+
$fp = fopen($storageLocation . basename($downloadURL), 'w+');
547+
$ch = curl_init($downloadURL);
553548
curl_setopt_array($ch, [
554549
CURLOPT_FILE => $fp,
555550
CURLOPT_USERAGENT => 'Nextcloud Updater',
@@ -591,7 +586,7 @@ public function downloadUpdate(): void {
591586
$message .= ' - curl error message: ' . $curlErrorMessage;
592587
}
593588

594-
$message .= ' - URL: ' . htmlentities($response['url']);
589+
$message .= ' - URL: ' . htmlentities($downloadURL);
595590

596591
throw new \Exception($message);
597592
}
@@ -624,14 +619,19 @@ private function getDownloadedFilePath(): string {
624619
*
625620
* @throws \Exception
626621
*/
627-
public function verifyIntegrity(): void {
622+
public function verifyIntegrity(?string $urlOverride = null): void {
628623
$this->silentLog('[info] verifyIntegrity()');
629624

630625
if ($this->getCurrentReleaseChannel() === 'daily') {
631626
$this->silentLog('[info] current channel is "daily" which is not signed. Skipping verification.');
632627
return;
633628
}
634629

630+
if ($urlOverride) {
631+
$this->silentLog('[info] custom download url provided, cannot verify signature');
632+
return;
633+
}
634+
635635
$response = $this->getUpdateServerResponse();
636636
if (empty($response['signature'])) {
637637
throw new \Exception('No signature specified for defined update');

vendor/composer/platform_check.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
2020
}
2121
}
22-
trigger_error(
23-
'Composer detected issues in your platform: ' . implode(' ', $issues),
24-
E_USER_ERROR
22+
throw new \RuntimeException(
23+
'Composer detected issues in your platform: ' . implode(' ', $issues)
2524
);
2625
}

0 commit comments

Comments
 (0)