aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/App/AppStore/Fetcher/Fetcher.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/App/AppStore/Fetcher/Fetcher.php')
-rw-r--r--lib/private/App/AppStore/Fetcher/Fetcher.php123
1 files changed, 47 insertions, 76 deletions
diff --git a/lib/private/App/AppStore/Fetcher/Fetcher.php b/lib/private/App/AppStore/Fetcher/Fetcher.php
index 788f15c183f..24876675d60 100644
--- a/lib/private/App/AppStore/Fetcher/Fetcher.php
+++ b/lib/private/App/AppStore/Fetcher/Fetcher.php
@@ -1,32 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2016 Lukas Reschke <lukas@statuscode.ch>
- *
- * @author Daniel Kesselberg <mail@danielkesselberg.de>
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- * @author Julius Härtl <jus@bitgrid.net>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Steffen Lindner <mail@steffen-lindner.de>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\App\AppStore\Fetcher;
@@ -38,47 +14,38 @@ use OCP\Files\IAppData;
use OCP\Files\NotFoundException;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
+use OCP\Server;
+use OCP\ServerVersion;
use OCP\Support\Subscription\IRegistry;
use Psr\Log\LoggerInterface;
abstract class Fetcher {
public const INVALIDATE_AFTER_SECONDS = 3600;
+ public const INVALIDATE_AFTER_SECONDS_UNSTABLE = 900;
public const RETRY_AFTER_FAILURE_SECONDS = 300;
+ public const APP_STORE_URL = 'https://apps.nextcloud.com/api/v1';
/** @var IAppData */
protected $appData;
- /** @var IClientService */
- protected $clientService;
- /** @var ITimeFactory */
- protected $timeFactory;
- /** @var IConfig */
- protected $config;
- /** @var LoggerInterface */
- protected $logger;
- /** @var IRegistry */
- protected $registry;
/** @var string */
protected $fileName;
/** @var string */
protected $endpointName;
- /** @var string */
- protected $version;
- /** @var string */
- protected $channel;
-
- public function __construct(Factory $appDataFactory,
- IClientService $clientService,
- ITimeFactory $timeFactory,
- IConfig $config,
- LoggerInterface $logger,
- IRegistry $registry) {
+ /** @var ?string */
+ protected $version = null;
+ /** @var ?string */
+ protected $channel = null;
+
+ public function __construct(
+ Factory $appDataFactory,
+ protected IClientService $clientService,
+ protected ITimeFactory $timeFactory,
+ protected IConfig $config,
+ protected LoggerInterface $logger,
+ protected IRegistry $registry,
+ ) {
$this->appData = $appDataFactory->get('appstore');
- $this->clientService = $clientService;
- $this->timeFactory = $timeFactory;
- $this->config = $config;
- $this->logger = $logger;
- $this->registry = $registry;
}
/**
@@ -89,7 +56,7 @@ abstract class Fetcher {
*
* @return array
*/
- protected function fetch($ETag, $content) {
+ protected function fetch($ETag, $content, $allowUnstable = false) {
$appstoreenabled = $this->config->getSystemValueBool('appstoreenabled', true);
if ((int)$this->config->getAppValue('settings', 'appstore-fetcher-lastFailure', '0') > time() - self::RETRY_AFTER_FAILURE_SECONDS) {
return [];
@@ -109,10 +76,13 @@ abstract class Fetcher {
];
}
- // If we have a valid subscription key, send it to the appstore
- $subscriptionKey = $this->config->getAppValue('support', 'subscription_key');
- if ($this->registry->delegateHasValidSubscription() && $subscriptionKey) {
- $options['headers']['X-NC-Subscription-Key'] = $subscriptionKey;
+ if ($this->config->getSystemValueString('appstoreurl', self::APP_STORE_URL) === self::APP_STORE_URL) {
+ // If we have a valid subscription key, send it to the appstore
+ $subscriptionKey = $this->config->getAppValue('support', 'subscription_key');
+ if ($this->registry->delegateHasValidSubscription() && $subscriptionKey) {
+ $options['headers'] ??= [];
+ $options['headers']['X-NC-Subscription-Key'] = $subscriptionKey;
+ }
}
$client = $this->clientService->newClient();
@@ -120,7 +90,8 @@ abstract class Fetcher {
$response = $client->get($this->getEndpoint(), $options);
} catch (ConnectException $e) {
$this->config->setAppValue('settings', 'appstore-fetcher-lastFailure', (string)time());
- throw $e;
+ $this->logger->error('Failed to connect to the app store', ['exception' => $e]);
+ return [];
}
$responseJson = [];
@@ -142,16 +113,18 @@ abstract class Fetcher {
}
/**
- * Returns the array with the categories on the appstore server
+ * Returns the array with the entries on the appstore server
*
* @param bool [$allowUnstable] Allow unstable releases
* @return array
*/
public function get($allowUnstable = false) {
$appstoreenabled = $this->config->getSystemValueBool('appstoreenabled', true);
- $internetavailable = $this->config->getSystemValue('has_internet_connection', true);
+ $internetavailable = $this->config->getSystemValueBool('has_internet_connection', true);
+ $isDefaultAppStore = $this->config->getSystemValueString('appstoreurl', self::APP_STORE_URL) === self::APP_STORE_URL;
- if (!$appstoreenabled || !$internetavailable) {
+ if (!$appstoreenabled || (!$internetavailable && $isDefaultAppStore)) {
+ $this->logger->info('AppStore is disabled or this instance has no Internet connection to access the default app store', ['app' => 'appstoreFetcher']);
return [];
}
@@ -165,14 +138,17 @@ abstract class Fetcher {
$file = $rootFolder->getFile($this->fileName);
$jsonBlob = json_decode($file->getContent(), true);
- // Always get latests apps info if $allowUnstable
- if (!$allowUnstable && is_array($jsonBlob)) {
-
+ if (is_array($jsonBlob)) {
// No caching when the version has been updated
if (isset($jsonBlob['ncversion']) && $jsonBlob['ncversion'] === $this->getVersion()) {
-
// If the timestamp is older than 3600 seconds request the files new
- if ((int)$jsonBlob['timestamp'] > ($this->timeFactory->getTime() - self::INVALIDATE_AFTER_SECONDS)) {
+ $invalidateAfterSeconds = self::INVALIDATE_AFTER_SECONDS;
+
+ if ($allowUnstable) {
+ $invalidateAfterSeconds = self::INVALIDATE_AFTER_SECONDS_UNSTABLE;
+ }
+
+ if ((int)$jsonBlob['timestamp'] > ($this->timeFactory->getTime() - $invalidateAfterSeconds)) {
return $jsonBlob['data'];
}
@@ -191,15 +167,10 @@ abstract class Fetcher {
try {
$responseJson = $this->fetch($ETag, $content, $allowUnstable);
- if (empty($responseJson)) {
+ if (empty($responseJson) || empty($responseJson['data'])) {
return [];
}
- // Don't store the apps request file
- if ($allowUnstable) {
- return $responseJson['data'];
- }
-
$file->putContent(json_encode($responseJson));
return json_decode($file->getContent(), true)['data'];
} catch (ConnectException $e) {
@@ -220,7 +191,7 @@ abstract class Fetcher {
*/
protected function getVersion() {
if ($this->version === null) {
- $this->version = $this->config->getSystemValue('version', '0.0.0');
+ $this->version = $this->config->getSystemValueString('version', '0.0.0');
}
return $this->version;
}
@@ -239,7 +210,7 @@ abstract class Fetcher {
*/
protected function getChannel() {
if ($this->channel === null) {
- $this->channel = \OC_Util::getChannel();
+ $this->channel = Server::get(ServerVersion::class)->getChannel();
}
return $this->channel;
}
@@ -253,6 +224,6 @@ abstract class Fetcher {
}
protected function getEndpoint(): string {
- return $this->config->getSystemValue('appstoreurl', 'https://apps.nextcloud.com/api/v1') . '/' . $this->endpointName;
+ return $this->config->getSystemValueString('appstoreurl', 'https://apps.nextcloud.com/api/v1') . '/' . $this->endpointName;
}
}