From 0073441b4576f4ba1b0a6cd25e4daac92fe4c5b8 Mon Sep 17 00:00:00 2001 From: Tom Wezepoel Date: Wed, 28 Oct 2026 12:00:21 +0100 Subject: [PATCH 1/3] feat(federation): add occ command to manage trusted servers Signed-off-by: Tom Wezepoel --- apps/federation/appinfo/info.xml | 1 + .../composer/composer/autoload_classmap.php | 1 + .../composer/composer/autoload_static.php | 1 + .../lib/Command/ManageTrustedServers.php | 148 ++++++++++++++++++ 4 files changed, 151 insertions(+) create mode 100644 apps/federation/lib/Command/ManageTrustedServers.php diff --git a/apps/federation/appinfo/info.xml b/apps/federation/appinfo/info.xml index fa4ba4f4ee3e2..d8df4c3d1594d 100644 --- a/apps/federation/appinfo/info.xml +++ b/apps/federation/appinfo/info.xml @@ -30,6 +30,7 @@ + OCA\Federation\Command\ManageTrustedServers OCA\Federation\Command\SyncFederationAddressBooks OCA\Federation\Command\SyncFederationCalendars diff --git a/apps/federation/composer/composer/autoload_classmap.php b/apps/federation/composer/composer/autoload_classmap.php index deca7ce3f04c8..b0f31ce46a260 100644 --- a/apps/federation/composer/composer/autoload_classmap.php +++ b/apps/federation/composer/composer/autoload_classmap.php @@ -10,6 +10,7 @@ 'OCA\\Federation\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php', 'OCA\\Federation\\BackgroundJob\\GetSharedSecret' => $baseDir . '/../lib/BackgroundJob/GetSharedSecret.php', 'OCA\\Federation\\BackgroundJob\\RequestSharedSecret' => $baseDir . '/../lib/BackgroundJob/RequestSharedSecret.php', + 'OCA\\Federation\\Command\\ManageTrustedServers' => $baseDir . '/../lib/Command/ManageTrustedServers.php', 'OCA\\Federation\\Command\\SyncFederationAddressBooks' => $baseDir . '/../lib/Command/SyncFederationAddressBooks.php', 'OCA\\Federation\\Command\\SyncFederationCalendars' => $baseDir . '/../lib/Command/SyncFederationCalendars.php', 'OCA\\Federation\\Controller\\OCSAuthAPIController' => $baseDir . '/../lib/Controller/OCSAuthAPIController.php', diff --git a/apps/federation/composer/composer/autoload_static.php b/apps/federation/composer/composer/autoload_static.php index edae4c88ab97d..8b5ffbd056401 100644 --- a/apps/federation/composer/composer/autoload_static.php +++ b/apps/federation/composer/composer/autoload_static.php @@ -25,6 +25,7 @@ class ComposerStaticInitFederation 'OCA\\Federation\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php', 'OCA\\Federation\\BackgroundJob\\GetSharedSecret' => __DIR__ . '/..' . '/../lib/BackgroundJob/GetSharedSecret.php', 'OCA\\Federation\\BackgroundJob\\RequestSharedSecret' => __DIR__ . '/..' . '/../lib/BackgroundJob/RequestSharedSecret.php', + 'OCA\\Federation\\Command\\ManageTrustedServers' => __DIR__ . '/..' . '/../lib/Command/ManageTrustedServers.php', 'OCA\\Federation\\Command\\SyncFederationAddressBooks' => __DIR__ . '/..' . '/../lib/Command/SyncFederationAddressBooks.php', 'OCA\\Federation\\Command\\SyncFederationCalendars' => __DIR__ . '/..' . '/../lib/Command/SyncFederationCalendars.php', 'OCA\\Federation\\Controller\\OCSAuthAPIController' => __DIR__ . '/..' . '/../lib/Controller/OCSAuthAPIController.php', diff --git a/apps/federation/lib/Command/ManageTrustedServers.php b/apps/federation/lib/Command/ManageTrustedServers.php new file mode 100644 index 0000000000000..c3ed31cb4bc61 --- /dev/null +++ b/apps/federation/lib/Command/ManageTrustedServers.php @@ -0,0 +1,148 @@ + 'ok', + TrustedServers::STATUS_PENDING => 'pending', + TrustedServers::STATUS_FAILURE => 'failure', + TrustedServers::STATUS_ACCESS_REVOKED => 'access revoked', + ]; + + public function __construct( + private TrustedServers $trustedServersManager, + ) { + } + + #[AsCommand( + name: 'federation:trusted-servers:add', + description: 'Add trusted servers', + )] + public function add( + IOutput $output, + #[Argument(description: 'space-separated list of server URLs to add to the trusted servers list')] + array $servers = [], + ): ExitCode { + if (empty($servers)) { + $output->writeln('You must provide at least one server URL.'); + return ExitCode::Invalid; + } + + $output->writeln('Adding trusted servers:'); + $hasFailure = false; + foreach ($servers as $server) { + if ($this->trustedServersManager->isTrustedServer($server)) { + $output->writeln(" - $server already trusted, skipping"); + continue; + } + + try { + $this->trustedServersManager->addServer($server); + $output->writeln(" - $server added"); + } catch (\Exception $e) { + $output->writeln(" - $server failed: " . $e->getMessage()); + $hasFailure = true; + } + } + + return $hasFailure ? ExitCode::Failure : ExitCode::Success; + } + + #[AsCommand( + name: 'federation:trusted-servers:remove', + description: 'Remove trusted servers', + )] + public function remove( + IOutput $output, + #[Argument(description: 'space-separated list of server URLs to remove from the trusted servers list')] + array $servers = [], + ): ExitCode { + if (empty($servers)) { + $output->writeln('You must provide at least one server URL.'); + return ExitCode::Invalid; + } + + $output->writeln('Removing trusted servers:'); + $hasFailure = false; + foreach ($servers as $server) { + $id = $this->findServerId($server); + if ($id === null) { + $output->writeln(" - $server not found, skipping"); + continue; + } + + try { + $this->trustedServersManager->removeServer($id); + $output->writeln(" - $server removed"); + } catch (\Exception $e) { + $output->writeln(" - $server failed: " . $e->getMessage()); + $hasFailure = true; + } + } + + return $hasFailure ? ExitCode::Failure : ExitCode::Success; + } + + #[AsCommand( + name: 'federation:trusted-servers:list', + description: 'List trusted servers', + supportsOutputFormat: true, + )] + public function list( + IOutput $output, + ): ExitCode { + $servers = $this->trustedServersManager->getServers(); + + if (empty($servers)) { + $output->writeln('No trusted servers configured.'); + return ExitCode::Success; + } + + $output->writeTableInOutputFormat( + array_map(fn (array $server) => [ + 'id' => $server['id'], + 'url' => $server['url'], + 'status' => self::STATUS_LABELS[$server['status']] ?? (string)$server['status'], + ], $servers), + ); + + return ExitCode::Success; + } + + /** + * Trusted servers are stored with a normalized (https:// prefixed, + * trailing-slash trimmed) URL, so removal has to look up the id by + * matching that same normalization rather than the raw user input. + */ + private function findServerId(string $url): ?int { + $normalized = rtrim( + (str_starts_with($url, 'http://') || str_starts_with($url, 'https://')) + ? $url + : 'https://' . $url, + '/' + ); + + foreach ($this->trustedServersManager->getServers() ?? [] as $server) { + if (rtrim($server['url'], '/') === $normalized) { + return $server['id']; + } + } + + return null; + } +} From c7c9d00f24af205381cf86fc06d4a973192e00c8 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 28 Oct 2026 19:07:08 +0100 Subject: [PATCH 2/3] Update apps/federation/lib/Command/ManageTrustedServers.php Co-authored-by: Cristian Scheid <74515775+cristianscheid@users.noreply.github.com> Signed-off-by: Tom --- apps/federation/lib/Command/ManageTrustedServers.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/federation/lib/Command/ManageTrustedServers.php b/apps/federation/lib/Command/ManageTrustedServers.php index c3ed31cb4bc61..1c2fa1ba9052b 100644 --- a/apps/federation/lib/Command/ManageTrustedServers.php +++ b/apps/federation/lib/Command/ManageTrustedServers.php @@ -3,7 +3,7 @@ declare(strict_types=1); /** - * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */ From 18c6ceb9dd0b4e5fe460cb89bfe3809aaae15ba0 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 28 Oct 2026 19:07:43 +0100 Subject: [PATCH 3/3] Apply suggestion from @cristianscheid Co-authored-by: Cristian Scheid <74515775+cristianscheid@users.noreply.github.com> Signed-off-by: Tom --- apps/federation/lib/Command/ManageTrustedServers.php | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/federation/lib/Command/ManageTrustedServers.php b/apps/federation/lib/Command/ManageTrustedServers.php index 1c2fa1ba9052b..b84960bd1d349 100644 --- a/apps/federation/lib/Command/ManageTrustedServers.php +++ b/apps/federation/lib/Command/ManageTrustedServers.php @@ -4,7 +4,6 @@ /** * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors - * SPDX-FileCopyrightText: 2016 ownCloud, Inc. * SPDX-License-Identifier: AGPL-3.0-only */