diff options
Diffstat (limited to 'apps/federation/lib')
-rw-r--r-- | apps/federation/lib/AppInfo/Application.php | 28 | ||||
-rw-r--r-- | apps/federation/lib/BackgroundJob/GetSharedSecret.php | 74 | ||||
-rw-r--r-- | apps/federation/lib/BackgroundJob/RequestSharedSecret.php | 41 | ||||
-rw-r--r-- | apps/federation/lib/Command/SyncFederationAddressBooks.php | 35 | ||||
-rw-r--r-- | apps/federation/lib/Controller/OCSAuthAPIController.php | 104 | ||||
-rw-r--r-- | apps/federation/lib/Controller/SettingsController.php | 133 | ||||
-rw-r--r-- | apps/federation/lib/DAV/FedAuth.php | 34 | ||||
-rw-r--r-- | apps/federation/lib/DbHandler.php | 46 | ||||
-rw-r--r-- | apps/federation/lib/Listener/SabrePluginAuthInitListener.php | 28 | ||||
-rw-r--r-- | apps/federation/lib/Middleware/AddServerMiddleware.php | 79 | ||||
-rw-r--r-- | apps/federation/lib/Migration/Version1010Date20200630191302.php | 22 | ||||
-rw-r--r-- | apps/federation/lib/Settings/Admin.php | 38 | ||||
-rw-r--r-- | apps/federation/lib/SyncFederationAddressBooks.php | 68 | ||||
-rw-r--r-- | apps/federation/lib/SyncJob.php | 41 | ||||
-rw-r--r-- | apps/federation/lib/TrustedServers.php | 87 |
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; |