diff --git a/apps/federation/appinfo/info.xml b/apps/federation/appinfo/info.xml
index 5dbdc03a26d3..6116f7c607d4 100644
--- a/apps/federation/appinfo/info.xml
+++ b/apps/federation/appinfo/info.xml
@@ -21,6 +21,9 @@
OCA\Federation\Command\SyncFederationAddressBooks
+ OCA\Federation\Command\TrustedServerAdd
+ OCA\Federation\Command\TrustedServerList
+ OCA\Federation\Command\TrustedServerRemove
OCA\Federation\Panels\Admin
diff --git a/apps/federation/lib/Command/TrustedServerAdd.php b/apps/federation/lib/Command/TrustedServerAdd.php
new file mode 100644
index 000000000000..56ed63b085c9
--- /dev/null
+++ b/apps/federation/lib/Command/TrustedServerAdd.php
@@ -0,0 +1,75 @@
+
+ *
+ */
+namespace OCA\Federation\Command;
+
+use OCA\Federation\TrustedServers;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class TrustedServerAdd extends Command {
+ public const ERROR_ALREADY_TRUSTED = 1;
+ public const ERROR_NO_OWNCLOUD_FOUND = 2;
+
+ /** @var TrustedServers */
+ private $trustedServers;
+
+ /**
+ * @param TrustedServers $trustedServers
+ */
+ public function __construct(TrustedServers $trustedServers) {
+ parent::__construct();
+ $this->trustedServers = $trustedServers;
+ }
+
+ protected function configure() {
+ $this
+ ->setName('federation:trusted-servers:add')
+ ->setDescription('Adds a new trusted server')
+ ->addArgument(
+ 'url',
+ InputArgument::REQUIRED,
+ 'The url pointing to the server, such as https://myserver:8888/server/owncloud'
+ );
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return int
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ $url = $input->getArgument('url');
+ if ($this->trustedServers->isTrustedServer($url)) {
+ $output->writeln('The server is already in the list of trusted servers.');
+ return self::ERROR_ALREADY_TRUSTED;
+ }
+
+ if (!$this->trustedServers->isOwnCloudServer($url)) {
+ $output->writeln('No ownCloud server found');
+ return self::ERROR_NO_OWNCLOUD_FOUND;
+ }
+
+ $id = $this->trustedServers->addServer($url);
+ $output->writeln("Server added with id {$id}");
+
+ return 0;
+ }
+}
diff --git a/apps/federation/lib/Command/TrustedServerList.php b/apps/federation/lib/Command/TrustedServerList.php
new file mode 100644
index 000000000000..232a6261dbd9
--- /dev/null
+++ b/apps/federation/lib/Command/TrustedServerList.php
@@ -0,0 +1,69 @@
+
+ *
+ */
+namespace OCA\Federation\Command;
+
+use OCA\Federation\TrustedServers;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\Table;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class TrustedServerList extends Command {
+ /** @var TrustedServers */
+ private $trustedServers;
+
+ /**
+ * @param TrustedServers $trustedServers
+ */
+ public function __construct(TrustedServers $trustedServers) {
+ parent::__construct();
+ $this->trustedServers = $trustedServers;
+ }
+
+ protected function configure() {
+ $this
+ ->setName('federation:trusted-servers:list')
+ ->setDescription('List the trusted servers');
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return int
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ $servers = $this->trustedServers->getServers();
+
+ $statusMap = [
+ TrustedServers::STATUS_OK => 'OK',
+ TrustedServers::STATUS_PENDING => 'Pending',
+ TrustedServers::STATUS_FAILURE => 'Failure',
+ TrustedServers::STATUS_ACCESS_REVOKED => 'Revoked',
+ ];
+
+ $table = new Table($output);
+ $table->setHeaders(['id', 'server', 'status']);
+ foreach ($servers as $server) {
+ $table->addRow([$server['id'], $server['url'], $statusMap[$server['status']] ?? 'Unknown']);
+ }
+ $table->render();
+ return 0;
+ }
+}
diff --git a/apps/federation/lib/Command/TrustedServerRemove.php b/apps/federation/lib/Command/TrustedServerRemove.php
new file mode 100644
index 000000000000..e122f2bda719
--- /dev/null
+++ b/apps/federation/lib/Command/TrustedServerRemove.php
@@ -0,0 +1,66 @@
+
+ *
+ */
+namespace OCA\Federation\Command;
+
+use OCA\Federation\TrustedServers;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class TrustedServerRemove extends Command {
+ /** @var TrustedServers */
+ private $trustedServers;
+
+ /**
+ * @param TrustedServers $trustedServers
+ */
+ public function __construct(TrustedServers $trustedServers) {
+ parent::__construct();
+ $this->trustedServers = $trustedServers;
+ }
+
+ protected function configure() {
+ $this
+ ->setName('federation:trusted-servers:remove')
+ ->setDescription('Remove a trusted server')
+ ->addArgument(
+ 'id',
+ InputArgument::REQUIRED,
+ 'The id of the server. Check with occ federation:trusted-servers:list'
+ );
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return int
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ $id = (int)$input->getArgument('id');
+ try {
+ $this->trustedServers->removeServer($id);
+ $output->writeln("Removed server with id {$id}");
+ } catch (\Exception $e) {
+ $output->writeln("{$e->getMessage()}");
+ return 1;
+ }
+ return 0;
+ }
+}
diff --git a/apps/federation/tests/Command/TrustedServerAddTest.php b/apps/federation/tests/Command/TrustedServerAddTest.php
new file mode 100644
index 000000000000..e656b99e09b4
--- /dev/null
+++ b/apps/federation/tests/Command/TrustedServerAddTest.php
@@ -0,0 +1,71 @@
+
+ *
+ */
+
+namespace OCA\Federation\Tests\Command;
+
+use OCA\Federation\Command\TrustedServerAdd;
+use OCA\Federation\TrustedServers;
+use Symfony\Component\Console\Tester\CommandTester;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class TrustedServerAddTest extends TestCase {
+ /** @var TrustedServers */
+ private $trustedServers;
+
+ /** @var TrustedServerAdd */
+ private $command;
+
+ protected function setUp(): void {
+ $this->trustedServers = $this->createMock(TrustedServers::class);
+
+ $this->command = new CommandTester(new TrustedServerAdd($this->trustedServers));
+ }
+
+ public function testExecuteAlreadyTrusted() {
+ $this->trustedServers->method('isTrustedServer')->willReturn(true);
+
+ $this->command->execute(['url' => 'https://some.server/path/owncloud']);
+ $this->assertSame(TrustedServerAdd::ERROR_ALREADY_TRUSTED, $this->command->getStatusCode());
+ }
+
+ public function testExecuteNotFound() {
+ $this->trustedServers->method('isTrustedServer')->willReturn(false);
+ $this->trustedServers->method('isOwnCloudServer')->willReturn(false);
+
+ $this->command->execute(['url' => 'https://some.server/path/owncloud']);
+ $this->assertSame(TrustedServerAdd::ERROR_NO_OWNCLOUD_FOUND, $this->command->getStatusCode());
+ }
+
+ public function testExecute() {
+ $server = 'https://some.server/path/owncloud';
+
+ $this->trustedServers->method('isTrustedServer')->willReturn(false);
+ $this->trustedServers->method('isOwnCloudServer')->willReturn(true);
+ $this->trustedServers->expects($this->once())
+ ->method('addServer')
+ ->with($server)
+ ->willReturn(33);
+
+ $this->command->execute(['url' => $server]);
+ $this->assertSame(0, $this->command->getStatusCode());
+ }
+}
diff --git a/apps/federation/tests/Command/TrustedServerListTest.php b/apps/federation/tests/Command/TrustedServerListTest.php
new file mode 100644
index 000000000000..231857958add
--- /dev/null
+++ b/apps/federation/tests/Command/TrustedServerListTest.php
@@ -0,0 +1,56 @@
+
+ *
+ */
+
+namespace OCA\Federation\Tests\Command;
+
+use OCA\Federation\Command\TrustedServerList;
+use OCA\Federation\TrustedServers;
+use Symfony\Component\Console\Tester\CommandTester;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class TrustedServerListTest extends TestCase {
+ /** @var TrustedServers */
+ private $trustedServers;
+
+ /** @var TrustedServerList */
+ private $command;
+
+ protected function setUp(): void {
+ $this->trustedServers = $this->createMock(TrustedServers::class);
+
+ $this->command = new CommandTester(new TrustedServerList($this->trustedServers));
+ }
+
+ public function testExecute() {
+ $this->trustedServers->method('getServers')
+ ->willReturn([
+ ['id' => 45, 'url' => 'https://my.server1', 'status' => 2],
+ ['id' => 55, 'url' => 'https://my.server22', 'status' => 1],
+ ]);
+
+ $this->command->execute([]);
+ $output = $this->command->getDisplay();
+ // expect the information of each server in the same row, no special formatting
+ $this->assertMatchesRegularExpression('/^.*45.*my\.server1.*Pending.*$/m', $output);
+ $this->assertMatchesRegularExpression('/^.*55.*my\.server22.*OK.*$/m', $output);
+ }
+}
diff --git a/apps/federation/tests/Command/TrustedServerRemoveTest.php b/apps/federation/tests/Command/TrustedServerRemoveTest.php
new file mode 100644
index 000000000000..7a8a9898b7be
--- /dev/null
+++ b/apps/federation/tests/Command/TrustedServerRemoveTest.php
@@ -0,0 +1,51 @@
+
+ *
+ */
+
+namespace OCA\Federation\Tests\Command;
+
+use OCA\Federation\Command\TrustedServerRemove;
+use OCA\Federation\TrustedServers;
+use Symfony\Component\Console\Tester\CommandTester;
+use Test\TestCase;
+
+/**
+ * @group DB
+ */
+class TrustedServerRemoveTest extends TestCase {
+ /** @var TrustedServers */
+ private $trustedServers;
+
+ /** @var TrustedServerRemove */
+ private $command;
+
+ protected function setUp(): void {
+ $this->trustedServers = $this->createMock(TrustedServers::class);
+
+ $this->command = new CommandTester(new TrustedServerRemove($this->trustedServers));
+ }
+
+ public function testExecute() {
+ $this->trustedServers->expects($this->once())
+ ->method('removeServer')
+ ->with(12);
+
+ $this->command->execute(['id' => 12]);
+ $this->assertSame(0, $this->command->getStatusCode());
+ }
+}
diff --git a/changelog/unreleased/40796 b/changelog/unreleased/40796
new file mode 100644
index 000000000000..f82c64b6f420
--- /dev/null
+++ b/changelog/unreleased/40796
@@ -0,0 +1,7 @@
+Enhancement: Add commands to handle the trusted servers from command line
+
+New occ commands have been added to handle the trusted servers for federation
+from command line. These commands will allow the admin to add list and remove
+trusted servers
+
+https://github.com/owncloud/core/pull/40796