diff options
Diffstat (limited to 'lib/private/OCM/OCMDiscoveryService.php')
-rw-r--r-- | lib/private/OCM/OCMDiscoveryService.php | 95 |
1 files changed, 31 insertions, 64 deletions
diff --git a/lib/private/OCM/OCMDiscoveryService.php b/lib/private/OCM/OCMDiscoveryService.php index ac9bf2a3965..a151bbc753c 100644 --- a/lib/private/OCM/OCMDiscoveryService.php +++ b/lib/private/OCM/OCMDiscoveryService.php @@ -3,29 +3,13 @@ declare(strict_types=1); /** - * @copyright 2023, Maxence Lange <maxence@artificial-owl.com> - * - * @author Maxence Lange <maxence@artificial-owl.com> - * - * @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: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace OC\OCM; +use GuzzleHttp\Exception\ConnectException; use JsonException; use OCP\AppFramework\Http; use OCP\Http\Client\IClientService; @@ -33,8 +17,8 @@ use OCP\ICache; use OCP\ICacheFactory; use OCP\IConfig; use OCP\OCM\Exceptions\OCMProviderException; +use OCP\OCM\ICapabilityAwareOCMProvider; use OCP\OCM\IOCMDiscoveryService; -use OCP\OCM\IOCMProvider; use Psr\Log\LoggerInterface; /** @@ -42,18 +26,12 @@ use Psr\Log\LoggerInterface; */ class OCMDiscoveryService implements IOCMDiscoveryService { private ICache $cache; - private array $supportedAPIVersion = - [ - '1.0-proposal1', - '1.0', - '1.1' - ]; public function __construct( ICacheFactory $cacheFactory, private IClientService $clientService, private IConfig $config, - private IOCMProvider $provider, + private ICapabilityAwareOCMProvider $provider, private LoggerInterface $logger, ) { $this->cache = $cacheFactory->createDistributed('ocm-discovery'); @@ -64,18 +42,29 @@ class OCMDiscoveryService implements IOCMDiscoveryService { * @param string $remote * @param bool $skipCache * - * @return IOCMProvider + * @return ICapabilityAwareOCMProvider * @throws OCMProviderException */ - public function discover(string $remote, bool $skipCache = false): IOCMProvider { + public function discover(string $remote, bool $skipCache = false): ICapabilityAwareOCMProvider { $remote = rtrim($remote, '/'); + if (!str_starts_with($remote, 'http://') && !str_starts_with($remote, 'https://')) { + // if scheme not specified, we test both; + try { + return $this->discover('https://' . $remote, $skipCache); + } catch (OCMProviderException|ConnectException) { + return $this->discover('http://' . $remote, $skipCache); + } + } if (!$skipCache) { try { - $this->provider->import(json_decode($this->cache->get($remote) ?? '', true, 8, JSON_THROW_ON_ERROR) ?? []); - if ($this->supportedAPIVersion($this->provider->getApiVersion())) { - return $this->provider; // if cache looks valid, we use it + $cached = $this->cache->get($remote); + if ($cached === false) { + throw new OCMProviderException('Previous discovery failed.'); } + + $this->provider->import(json_decode($cached ?? '', true, 8, JSON_THROW_ON_ERROR) ?? []); + return $this->provider; } catch (JsonException|OCMProviderException $e) { // we ignore cache on issues } @@ -83,14 +72,14 @@ class OCMDiscoveryService implements IOCMDiscoveryService { $client = $this->clientService->newClient(); try { - $response = $client->get( - $remote . '/ocm-provider/', - [ - 'timeout' => 10, - 'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates'), - 'connect_timeout' => 10, - ] - ); + $options = [ + 'timeout' => 10, + 'connect_timeout' => 10, + ]; + if ($this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates') === true) { + $options['verify'] = false; + } + $response = $client->get($remote . '/ocm-provider/', $options); if ($response->getStatusCode() === Http::STATUS_OK) { $body = $response->getBody(); @@ -99,8 +88,10 @@ class OCMDiscoveryService implements IOCMDiscoveryService { $this->cache->set($remote, $body, 60 * 60 * 24); } } catch (JsonException|OCMProviderException $e) { + $this->cache->set($remote, false, 5 * 60); throw new OCMProviderException('data returned by remote seems invalid - ' . ($body ?? '')); } catch (\Exception $e) { + $this->cache->set($remote, false, 5 * 60); $this->logger->warning('error while discovering ocm provider', [ 'exception' => $e, 'remote' => $remote @@ -108,30 +99,6 @@ class OCMDiscoveryService implements IOCMDiscoveryService { throw new OCMProviderException('error while requesting remote ocm provider'); } - if (!$this->supportedAPIVersion($this->provider->getApiVersion())) { - throw new OCMProviderException('API version not supported'); - } - return $this->provider; } - - /** - * Check the version from remote is supported. - * The minor version of the API will be ignored: - * 1.0.1 is identified as 1.0 - * - * @param string $version - * - * @return bool - */ - private function supportedAPIVersion(string $version): bool { - $dot1 = strpos($version, '.'); - $dot2 = strpos($version, '.', $dot1 + 1); - - if ($dot2 > 0) { - $version = substr($version, 0, $dot2); - } - - return (in_array($version, $this->supportedAPIVersion)); - } } |