aboutsummaryrefslogtreecommitdiffstats
path: root/apps/federation/lib
diff options
context:
space:
mode:
Diffstat (limited to 'apps/federation/lib')
-rw-r--r--apps/federation/lib/AppInfo/Application.php28
-rw-r--r--apps/federation/lib/BackgroundJob/GetSharedSecret.php74
-rw-r--r--apps/federation/lib/BackgroundJob/RequestSharedSecret.php41
-rw-r--r--apps/federation/lib/Command/SyncFederationAddressBooks.php35
-rw-r--r--apps/federation/lib/Controller/OCSAuthAPIController.php104
-rw-r--r--apps/federation/lib/Controller/SettingsController.php133
-rw-r--r--apps/federation/lib/DAV/FedAuth.php34
-rw-r--r--apps/federation/lib/DbHandler.php46
-rw-r--r--apps/federation/lib/Listener/SabrePluginAuthInitListener.php28
-rw-r--r--apps/federation/lib/Middleware/AddServerMiddleware.php79
-rw-r--r--apps/federation/lib/Migration/Version1010Date20200630191302.php22
-rw-r--r--apps/federation/lib/Settings/Admin.php38
-rw-r--r--apps/federation/lib/SyncFederationAddressBooks.php68
-rw-r--r--apps/federation/lib/SyncJob.php41
-rw-r--r--apps/federation/lib/TrustedServers.php87
15 files changed, 273 insertions, 585 deletions
diff --git a/apps/federation/lib/AppInfo/Application.php b/apps/federation/lib/AppInfo/Application.php
index d564fb4a20b..358e3f68d50 100644
--- a/apps/federation/lib/AppInfo/Application.php
+++ b/apps/federation/lib/AppInfo/Application.php
@@ -1,32 +1,14 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation\AppInfo;
use OCA\DAV\Events\SabrePluginAuthInitEvent;
use OCA\Federation\Listener\SabrePluginAuthInitListener;
-use OCA\Federation\Middleware\AddServerMiddleware;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
@@ -42,8 +24,6 @@ class Application extends App implements IBootstrap {
}
public function register(IRegistrationContext $context): void {
- $context->registerMiddleware(AddServerMiddleware::class);
-
$context->registerEventListener(SabrePluginAuthInitEvent::class, SabrePluginAuthInitListener::class);
}
diff --git a/apps/federation/lib/BackgroundJob/GetSharedSecret.php b/apps/federation/lib/BackgroundJob/GetSharedSecret.php
index b4ad46febc2..dc57db9fd62 100644
--- a/apps/federation/lib/BackgroundJob/GetSharedSecret.php
+++ b/apps/federation/lib/BackgroundJob/GetSharedSecret.php
@@ -1,31 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation\BackgroundJob;
@@ -39,6 +17,7 @@ use OCP\BackgroundJob\Job;
use OCP\Http\Client\IClient;
use OCP\Http\Client\IClientService;
use OCP\Http\Client\IResponse;
+use OCP\IConfig;
use OCP\IURLGenerator;
use OCP\OCS\IDiscoveryService;
use Psr\Log\LoggerInterface;
@@ -52,11 +31,6 @@ use Psr\Log\LoggerInterface;
*/
class GetSharedSecret extends Job {
private IClient $httpClient;
- private IJobList $jobList;
- private IURLGenerator $urlGenerator;
- private TrustedServers $trustedServers;
- private IDiscoveryService $ocsDiscoveryService;
- private LoggerInterface $logger;
protected bool $retainJob = false;
private string $defaultEndPoint = '/ocs/v2.php/apps/federation/api/v1/shared-secret';
/** 30 day = 2592000sec */
@@ -64,20 +38,16 @@ class GetSharedSecret extends Job {
public function __construct(
IClientService $httpClientService,
- IURLGenerator $urlGenerator,
- IJobList $jobList,
- TrustedServers $trustedServers,
- LoggerInterface $logger,
- IDiscoveryService $ocsDiscoveryService,
- ITimeFactory $timeFactory
+ private IURLGenerator $urlGenerator,
+ private IJobList $jobList,
+ private TrustedServers $trustedServers,
+ private LoggerInterface $logger,
+ private IDiscoveryService $ocsDiscoveryService,
+ ITimeFactory $timeFactory,
+ private IConfig $config,
) {
parent::__construct($timeFactory);
- $this->logger = $logger;
$this->httpClient = $httpClientService->newClient();
- $this->jobList = $jobList;
- $this->urlGenerator = $urlGenerator;
- $this->ocsDiscoveryService = $ocsDiscoveryService;
- $this->trustedServers = $trustedServers;
}
/**
@@ -112,6 +82,7 @@ class GetSharedSecret extends Job {
// kill job after 30 days of trying
$deadline = $currentTime - $this->maxLifespan;
if ($created < $deadline) {
+ $this->logger->warning("The job to get the shared secret job is too old and gets stopped now without retention. Setting server status of '{$target}' to failure.");
$this->retainJob = false;
$this->trustedServers->setServerStatus($target, TrustedServers::STATUS_FAILURE);
return;
@@ -128,14 +99,14 @@ class GetSharedSecret extends Job {
$result = $this->httpClient->get(
$url,
[
- 'query' =>
- [
- 'url' => $source,
- 'token' => $token,
- 'format' => 'json',
- ],
+ 'query' => [
+ 'url' => $source,
+ 'token' => $token,
+ 'format' => 'json',
+ ],
'timeout' => 3,
'connect_timeout' => 3,
+ 'verify' => !$this->config->getSystemValue('sharing.federation.allowSelfSignedCertificates', false),
]
);
@@ -143,9 +114,9 @@ class GetSharedSecret extends Job {
} catch (ClientException $e) {
$status = $e->getCode();
if ($status === Http::STATUS_FORBIDDEN) {
- $this->logger->info($target . ' refused to exchange a shared secret with you.', ['app' => 'federation']);
+ $this->logger->info($target . ' refused to exchange a shared secret with you.');
} else {
- $this->logger->info($target . ' responded with a ' . $status . ' containing: ' . $e->getMessage(), ['app' => 'federation']);
+ $this->logger->info($target . ' responded with a ' . $status . ' containing: ' . $e->getMessage());
}
} catch (RequestException $e) {
$status = -1; // There is no status code if we could not connect
@@ -177,8 +148,7 @@ class GetSharedSecret extends Job {
);
} else {
$this->logger->error(
- 'remote server "' . $target . '"" does not return a valid shared secret. Received data: ' . $body,
- ['app' => 'federation']
+ 'remote server "' . $target . '"" does not return a valid shared secret. Received data: ' . $body
);
$this->trustedServers->setServerStatus($target, TrustedServers::STATUS_FAILURE);
}
diff --git a/apps/federation/lib/BackgroundJob/RequestSharedSecret.php b/apps/federation/lib/BackgroundJob/RequestSharedSecret.php
index f8c25168b56..4d57d1f6aef 100644
--- a/apps/federation/lib/BackgroundJob/RequestSharedSecret.php
+++ b/apps/federation/lib/BackgroundJob/RequestSharedSecret.php
@@ -3,32 +3,9 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Côme Chilliet <come@chilliet.eu>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation\BackgroundJob;
@@ -41,6 +18,7 @@ use OCP\BackgroundJob\IJobList;
use OCP\BackgroundJob\Job;
use OCP\Http\Client\IClient;
use OCP\Http\Client\IClientService;
+use OCP\IConfig;
use OCP\IURLGenerator;
use OCP\OCS\IDiscoveryService;
use Psr\Log\LoggerInterface;
@@ -70,6 +48,7 @@ class RequestSharedSecret extends Job {
private IDiscoveryService $ocsDiscoveryService,
private LoggerInterface $logger,
ITimeFactory $timeFactory,
+ private IConfig $config,
) {
parent::__construct($timeFactory);
$this->httpClient = $httpClientService->newClient();
@@ -116,6 +95,7 @@ class RequestSharedSecret extends Job {
// kill job after 30 days of trying
$deadline = $currentTime - $this->maxLifespan;
if ($created < $deadline) {
+ $this->logger->warning("The job to request the shared secret job is too old and gets stopped now without retention. Setting server status of '{$target}' to failure.");
$this->retainJob = false;
$this->trustedServers->setServerStatus($target, TrustedServers::STATUS_FAILURE);
return;
@@ -138,6 +118,7 @@ class RequestSharedSecret extends Job {
],
'timeout' => 3,
'connect_timeout' => 3,
+ 'verify' => !$this->config->getSystemValue('sharing.federation.allowSelfSignedCertificates', false),
]
);
@@ -145,16 +126,16 @@ class RequestSharedSecret extends Job {
} catch (ClientException $e) {
$status = $e->getCode();
if ($status === Http::STATUS_FORBIDDEN) {
- $this->logger->info($target . ' refused to ask for a shared secret.', ['app' => 'federation']);
+ $this->logger->info($target . ' refused to ask for a shared secret.');
} else {
- $this->logger->info($target . ' responded with a ' . $status . ' containing: ' . $e->getMessage(), ['app' => 'federation']);
+ $this->logger->info($target . ' responded with a ' . $status . ' containing: ' . $e->getMessage());
}
} catch (RequestException $e) {
$status = -1; // There is no status code if we could not connect
- $this->logger->info('Could not connect to ' . $target, ['app' => 'federation']);
+ $this->logger->info('Could not connect to ' . $target);
} catch (\Throwable $e) {
$status = Http::STATUS_INTERNAL_SERVER_ERROR;
- $this->logger->error($e->getMessage(), ['app' => 'federation', 'exception' => $e]);
+ $this->logger->error($e->getMessage(), ['exception' => $e]);
}
// if we received a unexpected response we try again later
diff --git a/apps/federation/lib/Command/SyncFederationAddressBooks.php b/apps/federation/lib/Command/SyncFederationAddressBooks.php
index 614dd108a2a..36cb99473f7 100644
--- a/apps/federation/lib/Command/SyncFederationAddressBooks.php
+++ b/apps/federation/lib/Command/SyncFederationAddressBooks.php
@@ -1,26 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation\Command;
@@ -31,12 +14,10 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class SyncFederationAddressBooks extends Command {
- private SyncService $syncService;
-
- public function __construct(SyncService $syncService) {
+ public function __construct(
+ private SyncService $syncService,
+ ) {
parent::__construct();
-
- $this->syncService = $syncService;
}
protected function configure() {
@@ -48,7 +29,7 @@ class SyncFederationAddressBooks extends Command {
protected function execute(InputInterface $input, OutputInterface $output): int {
$progress = new ProgressBar($output);
$progress->start();
- $this->syncService->syncThemAll(function ($url, $ex) use ($progress, $output) {
+ $this->syncService->syncThemAll(function ($url, $ex) use ($progress, $output): void {
if ($ex instanceof \Exception) {
$output->writeln("Error while syncing $url : " . $ex->getMessage());
} else {
diff --git a/apps/federation/lib/Controller/OCSAuthAPIController.php b/apps/federation/lib/Controller/OCSAuthAPIController.php
index 63a5fbb3155..16b401be251 100644
--- a/apps/federation/lib/Controller/OCSAuthAPIController.php
+++ b/apps/federation/lib/Controller/OCSAuthAPIController.php
@@ -1,37 +1,19 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation\Controller;
use OCA\Federation\DbHandler;
use OCA\Federation\TrustedServers;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\BruteForceProtection;
+use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\Attribute\OpenAPI;
+use OCP\AppFramework\Http\Attribute\PublicPage;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\AppFramework\OCSController;
@@ -51,50 +33,33 @@ use Psr\Log\LoggerInterface;
*/
#[OpenAPI(scope: OpenAPI::SCOPE_FEDERATION)]
class OCSAuthAPIController extends OCSController {
- private ISecureRandom $secureRandom;
- private IJobList $jobList;
- private TrustedServers $trustedServers;
- private DbHandler $dbHandler;
- private LoggerInterface $logger;
- private ITimeFactory $timeFactory;
- private IThrottler $throttler;
-
public function __construct(
string $appName,
IRequest $request,
- ISecureRandom $secureRandom,
- IJobList $jobList,
- TrustedServers $trustedServers,
- DbHandler $dbHandler,
- LoggerInterface $logger,
- ITimeFactory $timeFactory,
- IThrottler $throttler
+ private ISecureRandom $secureRandom,
+ private IJobList $jobList,
+ private TrustedServers $trustedServers,
+ private DbHandler $dbHandler,
+ private LoggerInterface $logger,
+ private ITimeFactory $timeFactory,
+ private IThrottler $throttler,
) {
parent::__construct($appName, $request);
-
- $this->secureRandom = $secureRandom;
- $this->jobList = $jobList;
- $this->trustedServers = $trustedServers;
- $this->dbHandler = $dbHandler;
- $this->logger = $logger;
- $this->timeFactory = $timeFactory;
- $this->throttler = $throttler;
}
/**
* Request received to ask remote server for a shared secret, for legacy end-points
*
- * @NoCSRFRequired
- * @PublicPage
- * @BruteForceProtection(action=federationSharedSecret)
- *
* @param string $url URL of the server
* @param string $token Token of the server
- * @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
+ * @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
* @throws OCSForbiddenException Requesting shared secret is not allowed
*
* 200: Shared secret requested successfully
*/
+ #[NoCSRFRequired]
+ #[PublicPage]
+ #[BruteForceProtection(action: 'federationSharedSecret')]
public function requestSharedSecretLegacy(string $url, string $token): DataResponse {
return $this->requestSharedSecret($url, $token);
}
@@ -103,10 +68,6 @@ class OCSAuthAPIController extends OCSController {
/**
* Create shared secret and return it, for legacy end-points
*
- * @NoCSRFRequired
- * @PublicPage
- * @BruteForceProtection(action=federationSharedSecret)
- *
* @param string $url URL of the server
* @param string $token Token of the server
* @return DataResponse<Http::STATUS_OK, array{sharedSecret: string}, array{}>
@@ -114,6 +75,9 @@ class OCSAuthAPIController extends OCSController {
*
* 200: Shared secret returned
*/
+ #[NoCSRFRequired]
+ #[PublicPage]
+ #[BruteForceProtection(action: 'federationSharedSecret')]
public function getSharedSecretLegacy(string $url, string $token): DataResponse {
return $this->getSharedSecret($url, $token);
}
@@ -121,21 +85,20 @@ class OCSAuthAPIController extends OCSController {
/**
* Request received to ask remote server for a shared secret
*
- * @NoCSRFRequired
- * @PublicPage
- * @BruteForceProtection(action=federationSharedSecret)
- *
* @param string $url URL of the server
* @param string $token Token of the server
- * @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
+ * @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
* @throws OCSForbiddenException Requesting shared secret is not allowed
*
* 200: Shared secret requested successfully
*/
+ #[NoCSRFRequired]
+ #[PublicPage]
+ #[BruteForceProtection(action: 'federationSharedSecret')]
public function requestSharedSecret(string $url, string $token): DataResponse {
if ($this->trustedServers->isTrustedServer($url) === false) {
$this->throttler->registerAttempt('federationSharedSecret', $this->request->getRemoteAddress());
- $this->logger->error('remote server not trusted (' . $url . ') while requesting shared secret', ['app' => 'federation']);
+ $this->logger->error('remote server not trusted (' . $url . ') while requesting shared secret');
throw new OCSForbiddenException();
}
@@ -144,8 +107,7 @@ class OCSAuthAPIController extends OCSController {
$localToken = $this->dbHandler->getToken($url);
if (strcmp($localToken, $token) > 0) {
$this->logger->info(
- 'remote server (' . $url . ') presented lower token. We will initiate the exchange of the shared secret.',
- ['app' => 'federation']
+ 'remote server (' . $url . ') presented lower token. We will initiate the exchange of the shared secret.'
);
throw new OCSForbiddenException();
}
@@ -165,10 +127,6 @@ class OCSAuthAPIController extends OCSController {
/**
* Create shared secret and return it
*
- * @NoCSRFRequired
- * @PublicPage
- * @BruteForceProtection(action=federationSharedSecret)
- *
* @param string $url URL of the server
* @param string $token Token of the server
* @return DataResponse<Http::STATUS_OK, array{sharedSecret: string}, array{}>
@@ -176,10 +134,13 @@ class OCSAuthAPIController extends OCSController {
*
* 200: Shared secret returned
*/
+ #[NoCSRFRequired]
+ #[PublicPage]
+ #[BruteForceProtection(action: 'federationSharedSecret')]
public function getSharedSecret(string $url, string $token): DataResponse {
if ($this->trustedServers->isTrustedServer($url) === false) {
$this->throttler->registerAttempt('federationSharedSecret', $this->request->getRemoteAddress());
- $this->logger->error('remote server not trusted (' . $url . ') while getting shared secret', ['app' => 'federation']);
+ $this->logger->error('remote server not trusted (' . $url . ') while getting shared secret');
throw new OCSForbiddenException();
}
@@ -187,8 +148,7 @@ class OCSAuthAPIController extends OCSController {
$this->throttler->registerAttempt('federationSharedSecret', $this->request->getRemoteAddress());
$expectedToken = $this->dbHandler->getToken($url);
$this->logger->error(
- 'remote server (' . $url . ') didn\'t send a valid token (got "' . $token . '" but expected "'. $expectedToken . '") while getting shared secret',
- ['app' => 'federation']
+ 'remote server (' . $url . ') didn\'t send a valid token (got "' . $token . '" but expected "' . $expectedToken . '") while getting shared secret'
);
throw new OCSForbiddenException();
}
diff --git a/apps/federation/lib/Controller/SettingsController.php b/apps/federation/lib/Controller/SettingsController.php
index 85fabb4c7ff..27341eba815 100644
--- a/apps/federation/lib/Controller/SettingsController.php
+++ b/apps/federation/lib/Controller/SettingsController.php
@@ -1,60 +1,54 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation\Controller;
+use OCA\Federation\Settings\Admin;
use OCA\Federation\TrustedServers;
-use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\ApiRoute;
+use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting;
use OCP\AppFramework\Http\DataResponse;
-use OCP\HintException;
+use OCP\AppFramework\OCS\OCSException;
+use OCP\AppFramework\OCS\OCSNotFoundException;
+use OCP\AppFramework\OCSController;
use OCP\IL10N;
use OCP\IRequest;
+use Psr\Log\LoggerInterface;
-class SettingsController extends Controller {
- private IL10N $l;
- private TrustedServers $trustedServers;
-
- public function __construct(string $AppName,
+class SettingsController extends OCSController {
+ public function __construct(
+ string $AppName,
IRequest $request,
- IL10N $l10n,
- TrustedServers $trustedServers
+ private IL10N $l,
+ private TrustedServers $trustedServers,
+ private LoggerInterface $logger,
) {
parent::__construct($AppName, $request);
- $this->l = $l10n;
- $this->trustedServers = $trustedServers;
}
/**
- * Add server to the list of trusted Nextclouds.
+ * Add server to the list of trusted Nextcloud servers
+ *
+ * @param string $url The URL of the server to add
+ * @return DataResponse<Http::STATUS_OK, array{id: int, message: string, url: string}, array{}>|DataResponse<Http::STATUS_NOT_FOUND|Http::STATUS_CONFLICT, array{message: string}, array{}>
*
- * @AuthorizedAdminSetting(settings=OCA\Federation\Settings\Admin)
- * @throws HintException
+ * 200: Server added successfully
+ * 404: Server not found at the given URL
+ * 409: Server is already in the list of trusted servers
*/
+ #[AuthorizedAdminSetting(settings: Admin::class)]
+ #[ApiRoute(verb: 'POST', url: '/trusted-servers')]
public function addServer(string $url): DataResponse {
- $this->checkServer($url);
- $id = $this->trustedServers->addServer($url);
+ $this->checkServer(trim($url));
+ // Add the server to the list of trusted servers, all is well
+ $id = $this->trustedServers->addServer(trim($url));
return new DataResponse([
'url' => $url,
'id' => $id,
@@ -63,34 +57,69 @@ class SettingsController extends Controller {
}
/**
- * Add server to the list of trusted Nextclouds.
+ * Add server to the list of trusted Nextcloud servers
*
- * @AuthorizedAdminSetting(settings=OCA\Federation\Settings\Admin)
+ * @param int $id The ID of the trusted server to remove
+ * @return DataResponse<Http::STATUS_OK, array{id: int}, array{}>|DataResponse<Http::STATUS_NOT_FOUND, array{message: string}, array{}>
+ *
+ * 200: Server removed successfully
+ * 404: Server not found at the given ID
*/
+ #[AuthorizedAdminSetting(settings: Admin::class)]
+ #[ApiRoute(verb: 'DELETE', url: '/trusted-servers/{id}', requirements: ['id' => '\d+'])]
public function removeServer(int $id): DataResponse {
- $this->trustedServers->removeServer($id);
- return new DataResponse();
+ try {
+ $this->trustedServers->getServer($id);
+ } catch (\Exception $e) {
+ throw new OCSNotFoundException($this->l->t('No server found with ID: %s', [$id]));
+ }
+
+ try {
+ $this->trustedServers->removeServer($id);
+ return new DataResponse(['id' => $id]);
+ } catch (\Exception $e) {
+ $this->logger->error($e->getMessage(), ['e' => $e]);
+ throw new OCSException($this->l->t('Could not remove server'), Http::STATUS_INTERNAL_SERVER_ERROR);
+ }
}
/**
- * Check if the server should be added to the list of trusted servers or not.
+ * List all trusted servers
+ *
+ * @return DataResponse<Http::STATUS_OK, list<array{id: int, status: int, url: string}>, array{}>
*
- * @AuthorizedAdminSetting(settings=OCA\Federation\Settings\Admin)
- * @throws HintException
+ * 200: List of trusted servers
*/
- protected function checkServer(string $url): bool {
+ #[AuthorizedAdminSetting(settings: Admin::class)]
+ #[ApiRoute(verb: 'GET', url: '/trusted-servers')]
+ public function getServers(): DataResponse {
+ $servers = $this->trustedServers->getServers();
+
+ // obfuscate the shared secret
+ $servers = array_map(function ($server) {
+ return [
+ 'url' => $server['url'],
+ 'id' => $server['id'],
+ 'status' => $server['status'],
+ ];
+ }, $servers);
+
+ // return the list of trusted servers
+ return new DataResponse($servers);
+ }
+
+
+ /**
+ * Check if the server should be added to the list of trusted servers or not.
+ */
+ #[AuthorizedAdminSetting(settings: Admin::class)]
+ protected function checkServer(string $url): void {
if ($this->trustedServers->isTrustedServer($url) === true) {
- $message = 'Server is already in the list of trusted servers.';
- $hint = $this->l->t('Server is already in the list of trusted servers.');
- throw new HintException($message, $hint);
+ throw new OCSException($this->l->t('Server is already in the list of trusted servers.'), Http::STATUS_CONFLICT);
}
if ($this->trustedServers->isNextcloudServer($url) === false) {
- $message = 'No server to federate with found';
- $hint = $this->l->t('No server to federate with found');
- throw new HintException($message, $hint);
+ throw new OCSNotFoundException($this->l->t('No server to federate with found'));
}
-
- return true;
}
}
diff --git a/apps/federation/lib/DAV/FedAuth.php b/apps/federation/lib/DAV/FedAuth.php
index 003bd6d2485..45bf422c104 100644
--- a/apps/federation/lib/DAV/FedAuth.php
+++ b/apps/federation/lib/DAV/FedAuth.php
@@ -1,48 +1,32 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Joas Schilling <coding@schilljs.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation\DAV;
use OCA\Federation\DbHandler;
+use OCP\Defaults;
use Sabre\DAV\Auth\Backend\AbstractBasic;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
class FedAuth extends AbstractBasic {
- /** @var DbHandler */
- private $db;
-
/**
* FedAuth constructor.
*
* @param DbHandler $db
*/
- public function __construct(DbHandler $db) {
- $this->db = $db;
+ public function __construct(
+ private DbHandler $db,
+ ) {
$this->principalPrefix = 'principals/system/';
// setup realm
- $defaults = new \OCP\Defaults();
+ $defaults = new Defaults();
$this->realm = $defaults->getName();
}
diff --git a/apps/federation/lib/DbHandler.php b/apps/federation/lib/DbHandler.php
index 9e63f65986b..877663b058a 100644
--- a/apps/federation/lib/DbHandler.php
+++ b/apps/federation/lib/DbHandler.php
@@ -1,29 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <robin@icewind.nl>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors*
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation;
@@ -45,16 +25,12 @@ use OCP\IL10N;
* @package OCA\Federation
*/
class DbHandler {
- private IDBConnection $connection;
- private IL10N $IL10N;
private string $dbTable = 'trusted_servers';
public function __construct(
- IDBConnection $connection,
- IL10N $il10n
+ private IDBConnection $connection,
+ private IL10N $IL10N,
) {
- $this->connection = $connection;
- $this->IL10N = $il10n;
}
/**
@@ -226,8 +202,8 @@ class DbHandler {
$hash = $this->hash($url);
$query = $this->connection->getQueryBuilder();
$query->update($this->dbTable)
- ->set('status', $query->createNamedParameter($status))
- ->where($query->expr()->eq('url_hash', $query->createNamedParameter($hash)));
+ ->set('status', $query->createNamedParameter($status))
+ ->where($query->expr()->eq('url_hash', $query->createNamedParameter($hash)));
if (!is_null($token)) {
$query->set('sync_token', $query->createNamedParameter($token));
}
@@ -241,8 +217,8 @@ class DbHandler {
$hash = $this->hash($url);
$query = $this->connection->getQueryBuilder();
$query->select('status')->from($this->dbTable)
- ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
- ->setParameter('url_hash', $hash);
+ ->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
+ ->setParameter('url_hash', $hash);
$statement = $query->executeQuery();
$result = $statement->fetch();
@@ -282,7 +258,7 @@ class DbHandler {
}
$query = $this->connection->getQueryBuilder();
$query->select('url')->from($this->dbTable)
- ->where($query->expr()->eq('shared_secret', $query->createNamedParameter($password)));
+ ->where($query->expr()->eq('shared_secret', $query->createNamedParameter($password)));
$statement = $query->executeQuery();
$result = $statement->fetch();
diff --git a/apps/federation/lib/Listener/SabrePluginAuthInitListener.php b/apps/federation/lib/Listener/SabrePluginAuthInitListener.php
index 0add1799911..514a893fb39 100644
--- a/apps/federation/lib/Listener/SabrePluginAuthInitListener.php
+++ b/apps/federation/lib/Listener/SabrePluginAuthInitListener.php
@@ -3,25 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Morris Jobke <hey@morrisjobke.de>
- *
- * @author Morris Jobke <hey@morrisjobke.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: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Federation\Listener;
@@ -36,10 +19,9 @@ use Sabre\DAV\Auth\Plugin;
* @template-implements IEventListener<SabrePluginAuthInitEvent>
*/
class SabrePluginAuthInitListener implements IEventListener {
- private FedAuth $fedAuth;
-
- public function __construct(FedAuth $fedAuth) {
- $this->fedAuth = $fedAuth;
+ public function __construct(
+ private FedAuth $fedAuth,
+ ) {
}
public function handle(Event $event): void {
diff --git a/apps/federation/lib/Middleware/AddServerMiddleware.php b/apps/federation/lib/Middleware/AddServerMiddleware.php
deleted file mode 100644
index de964f1bd4a..00000000000
--- a/apps/federation/lib/Middleware/AddServerMiddleware.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
- */
-namespace OCA\Federation\Middleware;
-
-use OCA\Federation\Controller\SettingsController;
-use OCP\AppFramework\Controller;
-use OCP\AppFramework\Http;
-use OCP\AppFramework\Http\JSONResponse;
-use OCP\AppFramework\Middleware;
-use OCP\HintException;
-use OCP\IL10N;
-use Psr\Log\LoggerInterface;
-
-class AddServerMiddleware extends Middleware {
- protected string $appName;
- protected IL10N $l;
- protected LoggerInterface $logger;
-
- public function __construct(string $appName, IL10N $l, LoggerInterface $logger) {
- $this->appName = $appName;
- $this->l = $l;
- $this->logger = $logger;
- }
-
- /**
- * Log error message and return a response which can be displayed to the user
- *
- * @param Controller $controller
- * @param string $methodName
- * @param \Exception $exception
- * @return JSONResponse
- * @throws \Exception
- */
- public function afterException($controller, $methodName, \Exception $exception) {
- if (($controller instanceof SettingsController) === false) {
- throw $exception;
- }
- $this->logger->error($exception->getMessage(), [
- 'app' => $this->appName,
- 'exception' => $exception,
- ]);
- if ($exception instanceof HintException) {
- $message = $exception->getHint();
- } else {
- $message = $exception->getMessage();
- }
-
- return new JSONResponse(
- ['message' => $message],
- Http::STATUS_BAD_REQUEST
- );
- }
-}
diff --git a/apps/federation/lib/Migration/Version1010Date20200630191302.php b/apps/federation/lib/Migration/Version1010Date20200630191302.php
index d9f2214f96e..c1a7c38cfc7 100644
--- a/apps/federation/lib/Migration/Version1010Date20200630191302.php
+++ b/apps/federation/lib/Migration/Version1010Date20200630191302.php
@@ -3,26 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020 Joas Schilling <coding@schilljs.com>
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.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: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\Federation\Migration;
diff --git a/apps/federation/lib/Settings/Admin.php b/apps/federation/lib/Settings/Admin.php
index bbbed36ba4e..5cf5346bb85 100644
--- a/apps/federation/lib/Settings/Admin.php
+++ b/apps/federation/lib/Settings/Admin.php
@@ -1,24 +1,8 @@
<?php
+
/**
- * @copyright Copyright (c) 2016 Arthur Schiwon <blizzz@arthur-schiwon.de>
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.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 OCA\Federation\Settings;
@@ -28,12 +12,10 @@ use OCP\IL10N;
use OCP\Settings\IDelegatedSettings;
class Admin implements IDelegatedSettings {
- private TrustedServers $trustedServers;
- private IL10N $l;
-
- public function __construct(TrustedServers $trustedServers, IL10N $l) {
- $this->trustedServers = $trustedServers;
- $this->l = $l;
+ public function __construct(
+ private TrustedServers $trustedServers,
+ private IL10N $l,
+ ) {
}
/**
@@ -56,8 +38,8 @@ class Admin implements IDelegatedSettings {
/**
* @return int whether the form should be rather on the top or bottom of
- * the admin section. The forms are arranged in ascending order of the
- * priority values. It is required to return a value between 0 and 100.
+ * the admin section. The forms are arranged in ascending order of the
+ * priority values. It is required to return a value between 0 and 100.
*
* E.g.: 70
*/
@@ -66,7 +48,7 @@ class Admin implements IDelegatedSettings {
}
public function getName(): ?string {
- return $this->l->t("Trusted servers");
+ return $this->l->t('Trusted servers');
}
public function getAuthorizedAppConfig(): array {
diff --git a/apps/federation/lib/SyncFederationAddressBooks.php b/apps/federation/lib/SyncFederationAddressBooks.php
index 2c598241131..d11f92b76ef 100644
--- a/apps/federation/lib/SyncFederationAddressBooks.php
+++ b/apps/federation/lib/SyncFederationAddressBooks.php
@@ -1,27 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Lukas Reschke <lukas@statuscode.ch>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation;
@@ -32,20 +14,15 @@ use OCP\OCS\IDiscoveryService;
use Psr\Log\LoggerInterface;
class SyncFederationAddressBooks {
- protected DbHandler $dbHandler;
- private SyncService $syncService;
private DiscoveryService $ocsDiscoveryService;
- private LoggerInterface $logger;
- public function __construct(DbHandler $dbHandler,
- SyncService $syncService,
+ public function __construct(
+ protected DbHandler $dbHandler,
+ private SyncService $syncService,
IDiscoveryService $ocsDiscoveryService,
- LoggerInterface $logger
+ private LoggerInterface $logger,
) {
- $this->syncService = $syncService;
- $this->dbHandler = $dbHandler;
$this->ocsDiscoveryService = $ocsDiscoveryService;
- $this->logger = $logger;
}
/**
@@ -57,7 +34,7 @@ class SyncFederationAddressBooks {
$url = $trustedServer['url'];
$callback($url, null);
$sharedSecret = $trustedServer['shared_secret'];
- $syncToken = $trustedServer['sync_token'];
+ $oldSyncToken = $trustedServer['sync_token'];
$endPoints = $this->ocsDiscoveryService->discover($url, 'FEDERATED_SHARING');
$cardDavUser = $endPoints['carddav-user'] ?? 'system';
@@ -68,16 +45,35 @@ class SyncFederationAddressBooks {
continue;
}
$targetBookId = $trustedServer['url_hash'];
- $targetPrincipal = "principals/system/system";
+ $targetPrincipal = 'principals/system/system';
$targetBookProperties = [
'{DAV:}displayname' => $url
];
+
try {
- $newToken = $this->syncService->syncRemoteAddressBook($url, $cardDavUser, $addressBookUrl, $sharedSecret, $syncToken, $targetBookId, $targetPrincipal, $targetBookProperties);
- if ($newToken !== $syncToken) {
- $this->dbHandler->setServerStatus($url, TrustedServers::STATUS_OK, $newToken);
+ $syncToken = $oldSyncToken;
+
+ do {
+ [$syncToken, $truncated] = $this->syncService->syncRemoteAddressBook(
+ $url,
+ $cardDavUser,
+ $addressBookUrl,
+ $sharedSecret,
+ $syncToken,
+ $targetBookId,
+ $targetPrincipal,
+ $targetBookProperties
+ );
+ } while ($truncated);
+
+ if ($syncToken !== $oldSyncToken) {
+ $this->dbHandler->setServerStatus($url, TrustedServers::STATUS_OK, $syncToken);
} else {
$this->logger->debug("Sync Token for $url unchanged from previous sync");
+ // The server status might have been changed to a failure status in previous runs.
+ if ($this->dbHandler->getServerStatus($url) !== TrustedServers::STATUS_OK) {
+ $this->dbHandler->setServerStatus($url, TrustedServers::STATUS_OK);
+ }
}
} catch (\Exception $ex) {
if ($ex->getCode() === Http::STATUS_UNAUTHORIZED) {
diff --git a/apps/federation/lib/SyncJob.php b/apps/federation/lib/SyncJob.php
index d084b73c021..b802dfa9308 100644
--- a/apps/federation/lib/SyncJob.php
+++ b/apps/federation/lib/SyncJob.php
@@ -1,27 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Joas Schilling <coding@schilljs.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation;
@@ -30,22 +12,21 @@ use OCP\BackgroundJob\TimedJob;
use Psr\Log\LoggerInterface;
class SyncJob extends TimedJob {
- protected SyncFederationAddressBooks $syncService;
- protected LoggerInterface $logger;
-
- public function __construct(SyncFederationAddressBooks $syncService, LoggerInterface $logger, ITimeFactory $timeFactory) {
+ public function __construct(
+ protected SyncFederationAddressBooks $syncService,
+ protected LoggerInterface $logger,
+ ITimeFactory $timeFactory,
+ ) {
parent::__construct($timeFactory);
// Run once a day
$this->setInterval(24 * 60 * 60);
- $this->syncService = $syncService;
- $this->logger = $logger;
+ $this->setTimeSensitivity(self::TIME_INSENSITIVE);
}
protected function run($argument) {
- $this->syncService->syncThemAll(function ($url, $ex) {
+ $this->syncService->syncThemAll(function ($url, $ex): void {
if ($ex instanceof \Exception) {
$this->logger->error("Error while syncing $url.", [
- 'app' => 'fed-sync',
'exception' => $ex,
]);
}
diff --git a/apps/federation/lib/TrustedServers.php b/apps/federation/lib/TrustedServers.php
index b110be24aff..3d15cfac448 100644
--- a/apps/federation/lib/TrustedServers.php
+++ b/apps/federation/lib/TrustedServers.php
@@ -1,29 +1,9 @@
<?php
+
/**
- * @copyright Copyright (c) 2016, ownCloud, Inc.
- *
- * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
- * @author Bjoern Schiessle <bjoern@schiessle.org>
- * @author Björn Schießle <bjoern@schiessle.org>
- * @author Christoph Wurst <christoph@winzerhof-wurst.at>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Roeland Jago Douma <roeland@famdouma.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @license AGPL-3.0
- *
- * This code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * 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, version 3,
- * along with this program. If not, see <http://www.gnu.org/licenses/>
- *
+ * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
+ * SPDX-License-Identifier: AGPL-3.0-only
*/
namespace OCA\Federation;
@@ -51,36 +31,19 @@ class TrustedServers {
/** remote server revoked access */
public const STATUS_ACCESS_REVOKED = 4;
- private DbHandler $dbHandler;
- private IClientService $httpClientService;
- private LoggerInterface $logger;
- private IJobList $jobList;
- private ISecureRandom $secureRandom;
- private IConfig $config;
- private IEventDispatcher $dispatcher;
- private ITimeFactory $timeFactory;
-
/** @var list<array{id: int, url: string, url_hash: string, shared_secret: ?string, status: int, sync_token: ?string}>|null */
private ?array $trustedServersCache = null;
public function __construct(
- DbHandler $dbHandler,
- IClientService $httpClientService,
- LoggerInterface $logger,
- IJobList $jobList,
- ISecureRandom $secureRandom,
- IConfig $config,
- IEventDispatcher $dispatcher,
- ITimeFactory $timeFactory
+ private DbHandler $dbHandler,
+ private IClientService $httpClientService,
+ private LoggerInterface $logger,
+ private IJobList $jobList,
+ private ISecureRandom $secureRandom,
+ private IConfig $config,
+ private IEventDispatcher $dispatcher,
+ private ITimeFactory $timeFactory,
) {
- $this->dbHandler = $dbHandler;
- $this->httpClientService = $httpClientService;
- $this->logger = $logger;
- $this->jobList = $jobList;
- $this->secureRandom = $secureRandom;
- $this->config = $config;
- $this->dispatcher = $dispatcher;
- $this->timeFactory = $timeFactory;
}
/**
@@ -133,9 +96,9 @@ class TrustedServers {
* Get all trusted servers
*
* @return list<array{id: int, url: string, url_hash: string, shared_secret: ?string, status: int, sync_token: ?string}>
- * @throws Exception
+ * @throws \Exception
*/
- public function getServers() {
+ public function getServers(): ?array {
if ($this->trustedServersCache === null) {
$this->trustedServersCache = $this->dbHandler->getAllServer();
}
@@ -143,6 +106,26 @@ class TrustedServers {
}
/**
+ * Get a trusted server
+ *
+ * @return array{id: int, url: string, url_hash: string, shared_secret: ?string, status: int, sync_token: ?string}
+ * @throws Exception
+ */
+ public function getServer(int $id): ?array {
+ if ($this->trustedServersCache === null) {
+ $this->trustedServersCache = $this->dbHandler->getAllServer();
+ }
+
+ foreach ($this->trustedServersCache as $server) {
+ if ($server['id'] === $id) {
+ return $server;
+ }
+ }
+
+ throw new \Exception('No server found with ID: ' . $id);
+ }
+
+ /**
* Check if given server is a trusted Nextcloud server
*/
public function isTrustedServer(string $url): bool {
@@ -175,6 +158,7 @@ class TrustedServers {
[
'timeout' => 3,
'connect_timeout' => 3,
+ 'verify' => !$this->config->getSystemValue('sharing.federation.allowSelfSignedCertificates', false),
]
);
if ($result->getStatusCode() === Http::STATUS_OK) {
@@ -186,7 +170,6 @@ class TrustedServers {
}
} catch (\Exception $e) {
$this->logger->error('No Nextcloud server.', [
- 'app' => 'federation',
'exception' => $e,
]);
return false;