Browse Source

Merge pull request #33007 from nextcloud/cleanup/federation-app

Summer cleanup of the federation app
Carl Schwan 1 year ago
parent
commit
41e6e0c646
27 changed files with 418 additions and 654 deletions
  1. 1 0
      apps/dav/composer/composer/autoload_classmap.php
  2. 1 0
      apps/dav/composer/composer/autoload_static.php
  3. 3 12
      apps/dav/lib/AppInfo/Application.php
  4. 2 6
      apps/dav/lib/CardDAV/CardDavBackend.php
  5. 17 71
      apps/dav/lib/CardDAV/SyncService.php
  6. 50 0
      apps/dav/lib/Listener/TrustedServerRemovedListener.php
  7. 22 45
      apps/federation/lib/BackgroundJob/GetSharedSecret.php
  8. 3 12
      apps/federation/lib/Command/SyncFederationAddressBooks.php
  9. 25 65
      apps/federation/lib/Controller/OCSAuthAPIController.php
  10. 12 30
      apps/federation/lib/Controller/SettingsController.php
  11. 57 101
      apps/federation/lib/DbHandler.php
  12. 1 2
      apps/federation/lib/Listener/SabrePluginAuthInitListener.php
  13. 7 18
      apps/federation/lib/Middleware/AddServerMiddleware.php
  14. 2 12
      apps/federation/lib/Settings/Admin.php
  15. 3 14
      apps/federation/lib/SyncFederationAddressBooks.php
  16. 9 16
      apps/federation/lib/SyncJob.php
  17. 46 96
      apps/federation/lib/TrustedServers.php
  18. 3 3
      apps/federation/tests/BackgroundJob/GetSharedSecretTest.php
  19. 7 19
      apps/federation/tests/Controller/OCSAuthAPIControllerTest.php
  20. 19 27
      apps/federation/tests/Controller/SettingsControllerTest.php
  21. 6 7
      apps/federation/tests/Middleware/AddServerMiddlewareTest.php
  22. 7 7
      apps/federation/tests/SyncFederationAddressbooksTest.php
  23. 65 80
      apps/federation/tests/TrustedServersTest.php
  24. 0 11
      build/psalm-baseline.xml
  25. 1 0
      lib/composer/composer/autoload_classmap.php
  26. 1 0
      lib/composer/composer/autoload_static.php
  27. 48 0
      lib/public/Federation/Events/TrustedServerRemovedEvent.php

+ 1 - 0
apps/dav/composer/composer/autoload_classmap.php

@@ -246,6 +246,7 @@ return array(
     'OCA\\DAV\\Listener\\CardListener' => $baseDir . '/../lib/Listener/CardListener.php',
     'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => $baseDir . '/../lib/Listener/ClearPhotoCacheListener.php',
     'OCA\\DAV\\Listener\\SubscriptionListener' => $baseDir . '/../lib/Listener/SubscriptionListener.php',
+    'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => $baseDir . '/../lib/Listener/TrustedServerRemovedListener.php',
     'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndex.php',
     'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => $baseDir . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
     'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => $baseDir . '/../lib/Migration/BuildSocialSearchIndex.php',

+ 1 - 0
apps/dav/composer/composer/autoload_static.php

@@ -261,6 +261,7 @@ class ComposerStaticInitDAV
         'OCA\\DAV\\Listener\\CardListener' => __DIR__ . '/..' . '/../lib/Listener/CardListener.php',
         'OCA\\DAV\\Listener\\ClearPhotoCacheListener' => __DIR__ . '/..' . '/../lib/Listener/ClearPhotoCacheListener.php',
         'OCA\\DAV\\Listener\\SubscriptionListener' => __DIR__ . '/..' . '/../lib/Listener/SubscriptionListener.php',
+        'OCA\\DAV\\Listener\\TrustedServerRemovedListener' => __DIR__ . '/..' . '/../lib/Listener/TrustedServerRemovedListener.php',
         'OCA\\DAV\\Migration\\BuildCalendarSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndex.php',
         'OCA\\DAV\\Migration\\BuildCalendarSearchIndexBackgroundJob' => __DIR__ . '/..' . '/../lib/Migration/BuildCalendarSearchIndexBackgroundJob.php',
         'OCA\\DAV\\Migration\\BuildSocialSearchIndex' => __DIR__ . '/..' . '/../lib/Migration/BuildSocialSearchIndex.php',

+ 3 - 12
apps/dav/lib/AppInfo/Application.php

@@ -71,6 +71,7 @@ use OCA\DAV\Events\CardDeletedEvent;
 use OCA\DAV\Events\CardUpdatedEvent;
 use OCA\DAV\Events\SubscriptionCreatedEvent;
 use OCA\DAV\Events\SubscriptionDeletedEvent;
+use OCP\Federation\Events\TrustedServerRemovedEvent;
 use OCA\DAV\HookManager;
 use OCA\DAV\Listener\ActivityUpdaterListener;
 use OCA\DAV\Listener\AddressbookListener;
@@ -83,6 +84,7 @@ use OCA\DAV\Listener\CalendarShareUpdateListener;
 use OCA\DAV\Listener\CardListener;
 use OCA\DAV\Listener\ClearPhotoCacheListener;
 use OCA\DAV\Listener\SubscriptionListener;
+use OCA\DAV\Listener\TrustedServerRemovedListener;
 use OCA\DAV\Search\ContactsSearchProvider;
 use OCA\DAV\Search\EventsSearchProvider;
 use OCA\DAV\Search\TasksSearchProvider;
@@ -182,6 +184,7 @@ class Application extends App implements IBootstrap {
 		$context->registerEventListener(CardUpdatedEvent::class, BirthdayListener::class);
 		$context->registerEventListener(CardDeletedEvent::class, ClearPhotoCacheListener::class);
 		$context->registerEventListener(CardUpdatedEvent::class, ClearPhotoCacheListener::class);
+		$context->registerEventListener(TrustedServerRemovedEvent::class, TrustedServerRemovedListener::class);
 
 		$context->registerNotifierService(Notifier::class);
 
@@ -235,18 +238,6 @@ class Application extends App implements IBootstrap {
 			// Here we should recalculate if reminders should be sent to new or old sharees
 		});
 
-		$dispatcher->addListener('OCP\Federation\TrustedServerEvent::remove',
-			function (GenericEvent $event) {
-				/** @var CardDavBackend $cardDavBackend */
-				$cardDavBackend = \OC::$server->query(CardDavBackend::class);
-				$addressBookUri = $event->getSubject();
-				$addressBook = $cardDavBackend->getAddressBooksByUri('principals/system/system', $addressBookUri);
-				if (!is_null($addressBook)) {
-					$cardDavBackend->deleteAddressBook($addressBook['id']);
-				}
-			}
-		);
-
 		$eventHandler = function () use ($container, $serverContainer): void {
 			try {
 				/** @var UpdateCalendarResourcesRoomsBackgroundJob $job */

+ 2 - 6
apps/dav/lib/CardDAV/CardDavBackend.php

@@ -296,18 +296,14 @@ class CardDavBackend implements BackendInterface, SyncSupport {
 		return $addressBook;
 	}
 
-	/**
-	 * @param $addressBookUri
-	 * @return array|null
-	 */
-	public function getAddressBooksByUri($principal, $addressBookUri) {
+	public function getAddressBooksByUri(string $principal, string $addressBookUri): ?array {
 		$query = $this->db->getQueryBuilder();
 		$result = $query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken'])
 			->from('addressbooks')
 			->where($query->expr()->eq('uri', $query->createNamedParameter($addressBookUri)))
 			->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($principal)))
 			->setMaxResults(1)
-			->execute();
+			->executeQuery();
 
 		$row = $result->fetch();
 		$result->closeCursor();

+ 17 - 71
apps/dav/lib/CardDAV/SyncService.php

@@ -40,27 +40,13 @@ use Sabre\HTTP\ClientHttpException;
 use Sabre\VObject\Reader;
 
 class SyncService {
-
-	/** @var CardDavBackend */
-	private $backend;
-
-	/** @var IUserManager */
-	private $userManager;
-
+	private CardDavBackend $backend;
+	private IUserManager $userManager;
 	private LoggerInterface $logger;
+	private ?array $localSystemAddressBook = null;
+	private Converter $converter;
+	protected string $certPath;
 
-	/** @var array */
-	private $localSystemAddressBook;
-
-	/** @var Converter */
-	private $converter;
-
-	/** @var string */
-	protected $certPath;
-
-	/**
-	 * SyncService constructor.
-	 */
 	public function __construct(CardDavBackend $backend,
 								IUserManager $userManager,
 								LoggerInterface $logger,
@@ -73,20 +59,11 @@ class SyncService {
 	}
 
 	/**
-	 * @param string $url
-	 * @param string $userName
-	 * @param string $addressBookUrl
-	 * @param string $sharedSecret
-	 * @param string $syncToken
-	 * @param int $targetBookId
-	 * @param string $targetPrincipal
-	 * @param array $targetProperties
-	 * @return string
 	 * @throws \Exception
 	 */
-	public function syncRemoteAddressBook($url, $userName, $addressBookUrl, $sharedSecret, $syncToken, $targetBookId, $targetPrincipal, $targetProperties) {
+	public function syncRemoteAddressBook(string $url, string $userName, string $addressBookUrl, string $sharedSecret, ?string $syncToken, string $targetBookHash, string $targetPrincipal, array $targetProperties): string {
 		// 1. create addressbook
-		$book = $this->ensureSystemAddressBookExists($targetPrincipal, (string)$targetBookId, $targetProperties);
+		$book = $this->ensureSystemAddressBookExists($targetPrincipal, $targetBookHash, $targetProperties);
 		$addressBookId = $book['id'];
 
 		// 2. query changes
@@ -122,28 +99,23 @@ class SyncService {
 	}
 
 	/**
-	 * @param string $principal
-	 * @param string $id
-	 * @param array $properties
-	 * @return array|null
 	 * @throws \Sabre\DAV\Exception\BadRequest
 	 */
-	public function ensureSystemAddressBookExists($principal, $id, $properties) {
-		$book = $this->backend->getAddressBooksByUri($principal, $id);
+	public function ensureSystemAddressBookExists(string $principal, string $uri, array $properties): ?array {
+		$book = $this->backend->getAddressBooksByUri($principal, $uri);
 		if (!is_null($book)) {
 			return $book;
 		}
-		$this->backend->createAddressBook($principal, $id, $properties);
+		// FIXME This might break in clustered DB setup
+		$this->backend->createAddressBook($principal, $uri, $properties);
 
-		return $this->backend->getAddressBooksByUri($principal, $id);
+		return $this->backend->getAddressBooksByUri($principal, $uri);
 	}
 
 	/**
 	 * Check if there is a valid certPath we should use
-	 *
-	 * @return string
 	 */
-	protected function getCertPath() {
+	protected function getCertPath(): string {
 
 		// we already have a valid certPath
 		if ($this->certPath !== '') {
@@ -159,14 +131,7 @@ class SyncService {
 		return $this->certPath;
 	}
 
-	/**
-	 * @param string $url
-	 * @param string $userName
-	 * @param string $addressBookUrl
-	 * @param string $sharedSecret
-	 * @return Client
-	 */
-	protected function getClient($url, $userName, $sharedSecret) {
+	protected function getClient(string $url, string $userName, string $sharedSecret): Client {
 		$settings = [
 			'baseUri' => $url . '/',
 			'userName' => $userName,
@@ -183,15 +148,7 @@ class SyncService {
 		return $client;
 	}
 
-	/**
-	 * @param string $url
-	 * @param string $userName
-	 * @param string $addressBookUrl
-	 * @param string $sharedSecret
-	 * @param string $syncToken
-	 * @return array
-	 */
-	protected function requestSyncReport($url, $userName, $addressBookUrl, $sharedSecret, $syncToken) {
+	protected function requestSyncReport(string $url, string $userName, string $addressBookUrl, string $sharedSecret, ?string $syncToken): array {
 		$client = $this->getClient($url, $userName, $sharedSecret);
 
 		$body = $this->buildSyncCollectionRequestBody($syncToken);
@@ -203,23 +160,12 @@ class SyncService {
 		return $this->parseMultiStatus($response['body']);
 	}
 
-	/**
-	 * @param string $url
-	 * @param string $userName
-	 * @param string $sharedSecret
-	 * @param string $resourcePath
-	 * @return array
-	 */
-	protected function download($url, $userName, $sharedSecret, $resourcePath) {
+	protected function download(string $url, string $userName, string $sharedSecret, string $resourcePath): array {
 		$client = $this->getClient($url, $userName, $sharedSecret);
 		return $client->request('GET', $resourcePath);
 	}
 
-	/**
-	 * @param string|null $syncToken
-	 * @return string
-	 */
-	private function buildSyncCollectionRequestBody($syncToken) {
+	private function buildSyncCollectionRequestBody(?string $syncToken): string {
 		$dom = new \DOMDocument('1.0', 'UTF-8');
 		$dom->formatOutput = true;
 		$root = $dom->createElementNS('DAV:', 'd:sync-collection');

+ 50 - 0
apps/dav/lib/Listener/TrustedServerRemovedListener.php

@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2022 Carl Schwan <carl@carlschwan.eu>
+ *
+ * @author Carl Schwan <carl@carlschwan.eu>
+ *
+ * @license AGPL-3.0-or-later
+ *
+ * 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/>.
+ *
+ */
+namespace OCA\DAV\Listener;
+
+use OCA\DAV\CardDAV\CardDavBackend;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Federation\Events\TrustedServerRemovedEvent;
+
+class TrustedServerRemovedListener implements IEventListener {
+	private CardDavBackend $cardDavBackend;
+
+	public function __construct(CardDavBackend $cardDavBackend) {
+		$this->cardDavBackend = $cardDavBackend;
+	}
+
+	public function handle(Event $event): void {
+		if (!$event instanceof TrustedServerRemovedEvent) {
+			return;
+		}
+		$addressBookUri = $event->getUrlHash();
+		$addressBook = $this->cardDavBackend->getAddressBooksByUri('principals/system/system', $addressBookUri);
+		if (!is_null($addressBook)) {
+			$this->cardDavBackend->deleteAddressBook($addressBook['id']);
+		}
+	}
+}

+ 22 - 45
apps/federation/lib/BackgroundJob/GetSharedSecret.php

@@ -42,59 +42,34 @@ use OCP\Http\Client\IResponse;
 use OCP\ILogger;
 use OCP\IURLGenerator;
 use OCP\OCS\IDiscoveryService;
+use Psr\Log\LoggerInterface;
 
 /**
  * Class GetSharedSecret
  *
- * request shared secret from remote Nextcloud
+ * Request shared secret from remote Nextcloud
  *
  * @package OCA\Federation\Backgroundjob
  */
 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 */
+	private int $maxLifespan = 2592000;
 
-	/** @var IClient */
-	private $httpClient;
-
-	/** @var IJobList */
-	private $jobList;
-
-	/** @var IURLGenerator */
-	private $urlGenerator;
-
-	/** @var TrustedServers  */
-	private $trustedServers;
-
-	/** @var IDiscoveryService  */
-	private $ocsDiscoveryService;
-
-	/** @var ILogger */
-	private $logger;
-
-	/** @var bool */
-	protected $retainJob = false;
-
-	private $defaultEndPoint = '/ocs/v2.php/apps/federation/api/v1/shared-secret';
-
-	/** @var  int  30 day = 2592000sec */
-	private $maxLifespan = 2592000;
-
-	/**
-	 * RequestSharedSecret constructor.
-	 *
-	 * @param IClientService $httpClientService
-	 * @param IURLGenerator $urlGenerator
-	 * @param IJobList $jobList
-	 * @param TrustedServers $trustedServers
-	 * @param ILogger $logger
-	 * @param IDiscoveryService $ocsDiscoveryService
-	 * @param ITimeFactory $timeFactory
-	 */
 	public function __construct(
 		IClientService $httpClientService,
 		IURLGenerator $urlGenerator,
 		IJobList $jobList,
 		TrustedServers $trustedServers,
-		ILogger $logger,
+		LoggerInterface $logger,
 		IDiscoveryService $ocsDiscoveryService,
 		ITimeFactory $timeFactory
 	) {
@@ -128,7 +103,7 @@ class GetSharedSecret extends Job {
 	}
 
 	/**
-	 * call execute() method of parent
+	 * Call execute() method of parent
 	 *
 	 * @param IJobList $jobList
 	 * @param ILogger $logger
@@ -185,14 +160,16 @@ class GetSharedSecret extends Job {
 			}
 		} catch (RequestException $e) {
 			$status = -1; // There is no status code if we could not connect
-			$this->logger->logException($e, [
-				'message' => 'Could not connect to ' . $target,
-				'level' => ILogger::INFO,
+			$this->logger->info('Could not connect to ' . $target, [
+				'exception' => $e,
 				'app' => 'federation',
 			]);
 		} catch (\Throwable $e) {
 			$status = Http::STATUS_INTERNAL_SERVER_ERROR;
-			$this->logger->logException($e, ['app' => 'federation']);
+			$this->logger->error($e->getMessage(), [
+				'app' => 'federation',
+				'exception' => $e,
+			]);
 		}
 
 		// if we received a unexpected response we try again later
@@ -226,7 +203,7 @@ class GetSharedSecret extends Job {
 	 *
 	 * @param array $argument
 	 */
-	protected function reAddJob(array $argument) {
+	protected function reAddJob(array $argument): void {
 		$url = $argument['url'];
 		$created = isset($argument['created']) ? (int)$argument['created'] : $this->time->getTime();
 		$token = $argument['token'];

+ 3 - 12
apps/federation/lib/Command/SyncFederationAddressBooks.php

@@ -28,16 +28,12 @@ use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Helper\ProgressBar;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
+use OCA\Federation\SyncFederationAddressBooks as SyncService;
 
 class SyncFederationAddressBooks extends Command {
+	private SyncService $syncService;
 
-	/** @var \OCA\Federation\SyncFederationAddressBooks */
-	private $syncService;
-
-	/**
-	 * @param \OCA\Federation\SyncFederationAddressBooks $syncService
-	 */
-	public function __construct(\OCA\Federation\SyncFederationAddressBooks $syncService) {
+	public function __construct(SyncService $syncService) {
 		parent::__construct();
 
 		$this->syncService = $syncService;
@@ -49,11 +45,6 @@ class SyncFederationAddressBooks extends Command {
 			->setDescription('Synchronizes addressbooks of all federated clouds');
 	}
 
-	/**
-	 * @param InputInterface $input
-	 * @param OutputInterface $output
-	 * @return int
-	 */
 	protected function execute(InputInterface $input, OutputInterface $output): int {
 		$progress = new ProgressBar($output);
 		$progress->start();

+ 25 - 65
apps/federation/lib/Controller/OCSAuthAPIController.php

@@ -30,14 +30,14 @@ namespace OCA\Federation\Controller;
 
 use OCA\Federation\DbHandler;
 use OCA\Federation\TrustedServers;
-use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\DataResponse;
 use OCP\AppFramework\OCS\OCSForbiddenException;
 use OCP\AppFramework\OCSController;
 use OCP\AppFramework\Utility\ITimeFactory;
 use OCP\BackgroundJob\IJobList;
-use OCP\ILogger;
 use OCP\IRequest;
 use OCP\Security\ISecureRandom;
+use Psr\Log\LoggerInterface;
 
 /**
  * Class OCSAuthAPI
@@ -47,45 +47,21 @@ use OCP\Security\ISecureRandom;
  * @package OCA\Federation\Controller
  */
 class OCSAuthAPIController extends OCSController {
+	private ISecureRandom $secureRandom;
+	private IJobList $jobList;
+	private TrustedServers $trustedServers;
+	private DbHandler $dbHandler;
+	private LoggerInterface $logger;
+	private ITimeFactory $timeFactory;
 
-	/** @var ISecureRandom  */
-	private $secureRandom;
-
-	/** @var IJobList */
-	private $jobList;
-
-	/** @var TrustedServers */
-	private $trustedServers;
-
-	/** @var DbHandler */
-	private $dbHandler;
-
-	/** @var ILogger */
-	private $logger;
-
-	/** @var ITimeFactory */
-	private $timeFactory;
-
-	/**
-	 * OCSAuthAPI constructor.
-	 *
-	 * @param string $appName
-	 * @param IRequest $request
-	 * @param ISecureRandom $secureRandom
-	 * @param IJobList $jobList
-	 * @param TrustedServers $trustedServers
-	 * @param DbHandler $dbHandler
-	 * @param ILogger $logger
-	 * @param ITimeFactory $timeFactory
-	 */
 	public function __construct(
-		$appName,
+		string $appName,
 		IRequest $request,
 		ISecureRandom $secureRandom,
 		IJobList $jobList,
 		TrustedServers $trustedServers,
 		DbHandler $dbHandler,
-		ILogger $logger,
+		LoggerInterface $logger,
 		ITimeFactory $timeFactory
 	) {
 		parent::__construct($appName, $request);
@@ -99,48 +75,36 @@ class OCSAuthAPIController extends OCSController {
 	}
 
 	/**
+	 * Request received to ask remote server for a shared secret, for legacy end-points
+	 *
 	 * @NoCSRFRequired
 	 * @PublicPage
-	 *
-	 * request received to ask remote server for a shared secret, for legacy end-points
-	 *
-	 * @param string $url
-	 * @param string $token
-	 * @return Http\DataResponse
 	 * @throws OCSForbiddenException
 	 */
-	public function requestSharedSecretLegacy($url, $token) {
+	public function requestSharedSecretLegacy(string $url, string $token): DataResponse {
 		return $this->requestSharedSecret($url, $token);
 	}
 
 
 	/**
+	 * Create shared secret and return it, for legacy end-points
+	 *
 	 * @NoCSRFRequired
 	 * @PublicPage
-	 *
-	 * create shared secret and return it, for legacy end-points
-	 *
-	 * @param string $url
-	 * @param string $token
-	 * @return Http\DataResponse
 	 * @throws OCSForbiddenException
 	 */
-	public function getSharedSecretLegacy($url, $token) {
+	public function getSharedSecretLegacy(string $url, string $token): DataResponse {
 		return $this->getSharedSecret($url, $token);
 	}
 
 	/**
+	 * Request received to ask remote server for a shared secret
+	 *
 	 * @NoCSRFRequired
 	 * @PublicPage
-	 *
-	 * request received to ask remote server for a shared secret
-	 *
-	 * @param string $url
-	 * @param string $token
-	 * @return Http\DataResponse
 	 * @throws OCSForbiddenException
 	 */
-	public function requestSharedSecret($url, $token) {
+	public function requestSharedSecret(string $url, string $token): DataResponse {
 		if ($this->trustedServers->isTrustedServer($url) === false) {
 			$this->logger->error('remote server not trusted (' . $url . ') while requesting shared secret', ['app' => 'federation']);
 			throw new OCSForbiddenException();
@@ -166,21 +130,17 @@ class OCSAuthAPIController extends OCSController {
 			]
 		);
 
-		return new Http\DataResponse();
+		return new DataResponse();
 	}
 
 	/**
+	 * Create shared secret and return it
+	 *
 	 * @NoCSRFRequired
 	 * @PublicPage
-	 *
-	 * create shared secret and return it
-	 *
-	 * @param string $url
-	 * @param string $token
-	 * @return Http\DataResponse
 	 * @throws OCSForbiddenException
 	 */
-	public function getSharedSecret($url, $token) {
+	public function getSharedSecret(string $url, string $token): DataResponse {
 		if ($this->trustedServers->isTrustedServer($url) === false) {
 			$this->logger->error('remote server not trusted (' . $url . ') while getting shared secret', ['app' => 'federation']);
 			throw new OCSForbiddenException();
@@ -199,12 +159,12 @@ class OCSAuthAPIController extends OCSController {
 
 		$this->trustedServers->addSharedSecret($url, $sharedSecret);
 
-		return new Http\DataResponse([
+		return new DataResponse([
 			'sharedSecret' => $sharedSecret
 		]);
 	}
 
-	protected function isValidToken($url, $token) {
+	protected function isValidToken(string $url, string $token): bool {
 		$storedToken = $this->dbHandler->getToken($url);
 		return hash_equals($storedToken, $token);
 	}

+ 12 - 30
apps/federation/lib/Controller/SettingsController.php

@@ -31,20 +31,10 @@ use OCP\IL10N;
 use OCP\IRequest;
 
 class SettingsController extends Controller {
+	private IL10N $l;
+	private TrustedServers $trustedServers;
 
-	/** @var IL10N */
-	private $l;
-
-	/** @var  TrustedServers */
-	private $trustedServers;
-
-	/**
-	 * @param string $AppName
-	 * @param IRequest $request
-	 * @param IL10N $l10n
-	 * @param TrustedServers $trustedServers
-	 */
-	public function __construct($AppName,
+	public function __construct(string $AppName,
 								IRequest $request,
 								IL10N $l10n,
 								TrustedServers $trustedServers
@@ -59,31 +49,25 @@ class SettingsController extends Controller {
 	 * Add server to the list of trusted Nextclouds.
 	 *
 	 * @AuthorizedAdminSetting(settings=OCA\Federation\Settings\Admin)
-	 * @param string $url
-	 * @return DataResponse
 	 * @throws HintException
 	 */
-	public function addServer($url) {
+	public function addServer(string $url): DataResponse {
 		$this->checkServer($url);
 		$id = $this->trustedServers->addServer($url);
 
-		return new DataResponse(
-			[
-				'url' => $url,
-				'id' => $id,
-				'message' => $this->l->t('Added to the list of trusted servers')
-			]
-		);
+		return new DataResponse([
+			'url' => $url,
+			'id' => $id,
+			'message' => $this->l->t('Added to the list of trusted servers')
+		]);
 	}
 
 	/**
 	 * Add server to the list of trusted Nextclouds.
 	 *
 	 * @AuthorizedAdminSetting(settings=OCA\Federation\Settings\Admin)
-	 * @param int $id
-	 * @return DataResponse
 	 */
-	public function removeServer($id) {
+	public function removeServer(int $id): DataResponse {
 		$this->trustedServers->removeServer($id);
 		return new DataResponse();
 	}
@@ -92,18 +76,16 @@ class SettingsController extends Controller {
 	 * Check if the server should be added to the list of trusted servers or not.
 	 *
 	 * @AuthorizedAdminSetting(settings=OCA\Federation\Settings\Admin)
-	 * @param string $url
-	 * @return bool
 	 * @throws HintException
 	 */
-	protected function checkServer($url) {
+	protected function checkServer(string $url): bool {
 		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);
 		}
 
-		if ($this->trustedServers->isOwnCloudServer($url) === false) {
+		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);

+ 57 - 101
apps/federation/lib/DbHandler.php

@@ -30,31 +30,25 @@ namespace OCA\Federation;
 use OC\Files\Filesystem;
 use OCP\HintException;
 use OCP\IDBConnection;
+use OCP\DB\Exception as DBException;
+use OCP\DB\QueryBuilder\IQueryBuilder;
 use OCP\IL10N;
 
 /**
  * Class DbHandler
  *
- * handles all database calls for the federation app
+ * Handles all database calls for the federation app
+ *
+ * @todo Port to QBMapper
  *
  * @group DB
  * @package OCA\Federation
  */
 class DbHandler {
+	private IDBConnection $connection;
+	private IL10N $IL10N;
+	private string $dbTable = 'trusted_servers';
 
-	/** @var  IDBConnection */
-	private $connection;
-
-	/** @var  IL10N */
-	private $IL10N;
-
-	/** @var string  */
-	private $dbTable = 'trusted_servers';
-
-	/**
-	 * @param IDBConnection $connection
-	 * @param IL10N $il10n
-	 */
 	public function __construct(
 		IDBConnection $connection,
 		IL10N $il10n
@@ -64,27 +58,23 @@ class DbHandler {
 	}
 
 	/**
-	 * add server to the list of trusted servers
+	 * Add server to the list of trusted servers
 	 *
-	 * @param string $url
-	 * @return int
 	 * @throws HintException
 	 */
-	public function addServer($url) {
+	public function addServer(string $url): int {
 		$hash = $this->hash($url);
 		$url = rtrim($url, '/');
 		$query = $this->connection->getQueryBuilder();
 		$query->insert($this->dbTable)
-			->values(
-				[
-					'url' => $query->createParameter('url'),
-					'url_hash' => $query->createParameter('url_hash'),
-				]
-			)
+			->values([
+				'url' => $query->createParameter('url'),
+				'url_hash' => $query->createParameter('url_hash'),
+			])
 			->setParameter('url', $url)
 			->setParameter('url_hash', $hash);
 
-		$result = $query->execute();
+		$result = $query->executeStatement();
 
 		if ($result) {
 			return $query->getLastInsertId();
@@ -93,35 +83,33 @@ class DbHandler {
 		$message = 'Internal failure, Could not add trusted server: ' . $url;
 		$message_t = $this->IL10N->t('Could not add server');
 		throw new HintException($message, $message_t);
+		return -1;
 	}
 
 	/**
-	 * remove server from the list of trusted servers
-	 *
-	 * @param int $id
+	 * Remove server from the list of trusted servers
 	 */
-	public function removeServer($id) {
+	public function removeServer(int $id): void {
 		$query = $this->connection->getQueryBuilder();
 		$query->delete($this->dbTable)
 			->where($query->expr()->eq('id', $query->createParameter('id')))
 			->setParameter('id', $id);
-		$query->execute();
+		$query->executeStatement();
 	}
 
 	/**
-	 * get trusted server with given ID
+	 * Get trusted server with given ID
 	 *
-	 * @param int $id
-	 * @return array
+	 * @return array{id: int, url: string, url_hash: string, token: ?string, shared_secret: ?string, status: int, sync_token: ?string}
 	 * @throws \Exception
 	 */
-	public function getServerById($id) {
+	public function getServerById(int $id): array {
 		$query = $this->connection->getQueryBuilder();
 		$query->select('*')->from($this->dbTable)
 			->where($query->expr()->eq('id', $query->createParameter('id')))
-			->setParameter('id', $id);
+			->setParameter('id', $id, IQueryBuilder::PARAM_INT);
 
-		$qResult = $query->execute();
+		$qResult = $query->executeQuery();
 		$result = $qResult->fetchAll();
 		$qResult->closeCursor();
 
@@ -133,34 +121,32 @@ class DbHandler {
 	}
 
 	/**
-	 * get all trusted servers
+	 * Get all trusted servers
 	 *
-	 * @return array
+	 * @return list<array{id: int, url: string, url_hash: string, shared_secret: ?string, status: int, sync_token: ?string}>
+	 * @throws DBException
 	 */
-	public function getAllServer() {
+	public function getAllServer(): array {
 		$query = $this->connection->getQueryBuilder();
 		$query->select(['url', 'url_hash', 'id', 'status', 'shared_secret', 'sync_token'])
 			->from($this->dbTable);
-		$statement = $query->execute();
+		$statement = $query->executeQuery();
 		$result = $statement->fetchAll();
 		$statement->closeCursor();
 		return $result;
 	}
 
 	/**
-	 * check if server already exists in the database table
-	 *
-	 * @param string $url
-	 * @return bool
+	 * Check if server already exists in the database table
 	 */
-	public function serverExists($url) {
+	public function serverExists(string $url): bool {
 		$hash = $this->hash($url);
 		$query = $this->connection->getQueryBuilder();
 		$query->select('url')
 			->from($this->dbTable)
 			->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
 			->setParameter('url_hash', $hash);
-		$statement = $query->execute();
+		$statement = $query->executeQuery();
 		$result = $statement->fetchAll();
 		$statement->closeCursor();
 
@@ -168,12 +154,9 @@ class DbHandler {
 	}
 
 	/**
-	 * write token to database. Token is used to exchange the secret
-	 *
-	 * @param string $url
-	 * @param string $token
+	 * Write token to database. Token is used to exchange the secret
 	 */
-	public function addToken($url, $token) {
+	public function addToken(string $url, string $token): void {
 		$hash = $this->hash($url);
 		$query = $this->connection->getQueryBuilder();
 		$query->update($this->dbTable)
@@ -181,24 +164,21 @@ class DbHandler {
 			->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
 			->setParameter('url_hash', $hash)
 			->setParameter('token', $token);
-		$query->execute();
+		$query->executeStatement();
 	}
 
 	/**
-	 * get token stored in database
-	 *
-	 * @param string $url
-	 * @return string
+	 * Get token stored in database
 	 * @throws \Exception
 	 */
-	public function getToken($url) {
+	public function getToken(string $url): string {
 		$hash = $this->hash($url);
 		$query = $this->connection->getQueryBuilder();
 		$query->select('token')->from($this->dbTable)
 			->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
 			->setParameter('url_hash', $hash);
 
-		$statement = $query->execute();
+		$statement = $query->executeQuery();
 		$result = $statement->fetch();
 		$statement->closeCursor();
 
@@ -210,12 +190,9 @@ class DbHandler {
 	}
 
 	/**
-	 * add shared Secret to database
-	 *
-	 * @param string $url
-	 * @param string $sharedSecret
+	 * Add shared Secret to database
 	 */
-	public function addSharedSecret($url, $sharedSecret) {
+	public function addSharedSecret(string $url, string $sharedSecret): void {
 		$hash = $this->hash($url);
 		$query = $this->connection->getQueryBuilder();
 		$query->update($this->dbTable)
@@ -223,36 +200,29 @@ class DbHandler {
 			->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
 			->setParameter('url_hash', $hash)
 			->setParameter('sharedSecret', $sharedSecret);
-		$query->execute();
+		$query->executeStatement();
 	}
 
 	/**
-	 * get shared secret from database
-	 *
-	 * @param string $url
-	 * @return string
+	 * Get shared secret from database
 	 */
-	public function getSharedSecret($url) {
+	public function getSharedSecret(string $url): string {
 		$hash = $this->hash($url);
 		$query = $this->connection->getQueryBuilder();
 		$query->select('shared_secret')->from($this->dbTable)
 			->where($query->expr()->eq('url_hash', $query->createParameter('url_hash')))
 			->setParameter('url_hash', $hash);
 
-		$statement = $query->execute();
+		$statement = $query->executeQuery();
 		$result = $statement->fetch();
 		$statement->closeCursor();
-		return $result['shared_secret'];
+		return (string)$result['shared_secret'];
 	}
 
 	/**
-	 * set server status
-	 *
-	 * @param string $url
-	 * @param int $status
-	 * @param string|null $token
+	 * Set server status
 	 */
-	public function setServerStatus($url, $status, $token = null) {
+	public function setServerStatus(string $url, int $status, ?string $token = null): void {
 		$hash = $this->hash($url);
 		$query = $this->connection->getQueryBuilder();
 		$query->update($this->dbTable)
@@ -261,46 +231,37 @@ class DbHandler {
 		if (!is_null($token)) {
 			$query->set('sync_token', $query->createNamedParameter($token));
 		}
-		$query->execute();
+		$query->executeStatement();
 	}
 
 	/**
-	 * get server status
-	 *
-	 * @param string $url
-	 * @return int
+	 * Get server status
 	 */
-	public function getServerStatus($url) {
+	public function getServerStatus(string $url): int {
 		$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);
 
-		$statement = $query->execute();
+		$statement = $query->executeQuery();
 		$result = $statement->fetch();
 		$statement->closeCursor();
 		return (int)$result['status'];
 	}
 
 	/**
-	 * create hash from URL
-	 *
-	 * @param string $url
-	 * @return string
+	 * Create hash from URL
 	 */
-	protected function hash($url) {
+	protected function hash(string $url): string {
 		$normalized = $this->normalizeUrl($url);
 		return sha1($normalized);
 	}
 
 	/**
-	 * normalize URL, used to create the sha1 hash
-	 *
-	 * @param string $url
-	 * @return string
+	 * Normalize URL, used to create the sha1 hash
 	 */
-	protected function normalizeUrl($url) {
+	protected function normalizeUrl(string $url): string {
 		$normalized = $url;
 
 		if (strpos($url, 'https://') === 0) {
@@ -315,12 +276,7 @@ class DbHandler {
 		return $normalized;
 	}
 
-	/**
-	 * @param $username
-	 * @param $password
-	 * @return bool
-	 */
-	public function auth($username, $password) {
+	public function auth(string $username, string $password): bool {
 		if ($username !== 'system') {
 			return false;
 		}
@@ -328,7 +284,7 @@ class DbHandler {
 		$query->select('url')->from($this->dbTable)
 				->where($query->expr()->eq('shared_secret', $query->createNamedParameter($password)));
 
-		$statement = $query->execute();
+		$statement = $query->executeQuery();
 		$result = $statement->fetch();
 		$statement->closeCursor();
 		return !empty($result);

+ 1 - 2
apps/federation/lib/Listener/SabrePluginAuthInitListener.php

@@ -35,8 +35,7 @@ use Sabre\DAV\Auth\Plugin;
  * @since 20.0.0
  */
 class SabrePluginAuthInitListener implements IEventListener {
-	/** @var FedAuth */
-	private $fedAuth;
+	private FedAuth $fedAuth;
 
 	public function __construct(FedAuth $fedAuth) {
 		$this->fedAuth = $fedAuth;

+ 7 - 18
apps/federation/lib/Middleware/AddServerMiddleware.php

@@ -35,25 +35,14 @@ use OCP\AppFramework\Http\JSONResponse;
 use OCP\AppFramework\Middleware;
 use OCP\HintException;
 use OCP\IL10N;
-use OCP\ILogger;
+use Psr\Log\LoggerInterface;
 
 class AddServerMiddleware extends Middleware {
+	protected string $appName;
+	protected IL10N $l;
+	protected LoggerInterface $logger;
 
-	/** @var  string */
-	protected $appName;
-
-	/** @var  IL10N */
-	protected $l;
-
-	/** @var  ILogger */
-	protected $logger;
-
-	/**
-	 * @param string $appName
-	 * @param IL10N $l
-	 * @param ILogger $logger
-	 */
-	public function __construct($appName, IL10N $l, ILogger $logger) {
+	public function __construct(string $appName, IL10N $l, LoggerInterface $logger) {
 		$this->appName = $appName;
 		$this->l = $l;
 		$this->logger = $logger;
@@ -72,9 +61,9 @@ class AddServerMiddleware extends Middleware {
 		if (($controller instanceof SettingsController) === false) {
 			throw $exception;
 		}
-		$this->logger->logException($exception, [
-			'level' => ILogger::ERROR,
+		$this->logger->error($exception->getMessage(), [
 			'app' => $this->appName,
+			'exception' => $exception,
 		]);
 		if ($exception instanceof HintException) {
 			$message = $exception->getHint();

+ 2 - 12
apps/federation/lib/Settings/Admin.php

@@ -28,19 +28,9 @@ use OCP\IL10N;
 use OCP\Settings\IDelegatedSettings;
 
 class Admin implements IDelegatedSettings {
+	private TrustedServers $trustedServers;
+	private IL10N $l;
 
-	/** @var TrustedServers */
-	private $trustedServers;
-
-	/** @var IL10N */
-	private $l;
-
-	/**
-	 * Admin constructor.
-	 *
-	 * @param TrustedServers $trustedServers
-	 * @param IL10N $l
-	 */
 	public function __construct(TrustedServers $trustedServers, IL10N $l) {
 		$this->trustedServers = $trustedServers;
 		$this->l = $l;

+ 3 - 14
apps/federation/lib/SyncFederationAddressBooks.php

@@ -31,21 +31,10 @@ use OCP\AppFramework\Http;
 use OCP\OCS\IDiscoveryService;
 
 class SyncFederationAddressBooks {
+	protected DbHandler $dbHandler;
+	private SyncService $syncService;
+	private DiscoveryService $ocsDiscoveryService;
 
-	/** @var DbHandler */
-	protected $dbHandler;
-
-	/** @var SyncService */
-	private $syncService;
-
-	/** @var  DiscoveryService */
-	private $ocsDiscoveryService;
-
-	/**
-	 * @param DbHandler $dbHandler
-	 * @param SyncService $syncService
-	 * @param IDiscoveryService $ocsDiscoveryService
-	 */
 	public function __construct(DbHandler $dbHandler,
 								SyncService $syncService,
 								IDiscoveryService $ocsDiscoveryService

+ 9 - 16
apps/federation/lib/SyncJob.php

@@ -25,22 +25,16 @@
  */
 namespace OCA\Federation;
 
-use OC\BackgroundJob\TimedJob;
-use OCP\ILogger;
+use OCP\BackgroundJob\TimedJob;
+use OCP\AppFramework\Utility\ITimeFactory;
+use Psr\Log\LoggerInterface;
 
 class SyncJob extends TimedJob {
+	protected SyncFederationAddressBooks $syncService;
+	protected LoggerInterface $logger;
 
-	/** @var SyncFederationAddressBooks */
-	protected $syncService;
-
-	/** @var ILogger */
-	protected $logger;
-
-	/**
-	 * @param SyncFederationAddressBooks $syncService
-	 * @param ILogger $logger
-	 */
-	public function __construct(SyncFederationAddressBooks $syncService, ILogger $logger) {
+	public function __construct(SyncFederationAddressBooks $syncService, LoggerInterface $logger, ITimeFactory $timeFactory) {
+		parent::__construct($timeFactory);
 		// Run once a day
 		$this->setInterval(24 * 60 * 60);
 		$this->syncService = $syncService;
@@ -50,10 +44,9 @@ class SyncJob extends TimedJob {
 	protected function run($argument) {
 		$this->syncService->syncThemAll(function ($url, $ex) {
 			if ($ex instanceof \Exception) {
-				$this->logger->logException($ex, [
-					'message' => "Error while syncing $url.",
-					'level' => ILogger::INFO,
+				$this->logger->info("Error while syncing $url.", [
 					'app' => 'fed-sync',
+					'exception' => $ex,
 				]);
 			}
 		});

+ 46 - 96
apps/federation/lib/TrustedServers.php

@@ -34,10 +34,11 @@ use OCP\BackgroundJob\IJobList;
 use OCP\HintException;
 use OCP\Http\Client\IClientService;
 use OCP\IConfig;
-use OCP\ILogger;
 use OCP\Security\ISecureRandom;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-use Symfony\Component\EventDispatcher\GenericEvent;
+use OCP\DB\Exception as DBException;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Federation\Events\TrustedServerRemovedEvent;
+use Psr\Log\LoggerInterface;
 
 class TrustedServers {
 
@@ -50,48 +51,23 @@ class TrustedServers {
 	/** remote server revoked access */
 	public const STATUS_ACCESS_REVOKED = 4;
 
-	/** @var  dbHandler */
-	private $dbHandler;
+	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  IClientService */
-	private $httpClientService;
-
-	/** @var ILogger */
-	private $logger;
-
-	/** @var IJobList */
-	private $jobList;
-
-	/** @var ISecureRandom */
-	private $secureRandom;
-
-	/** @var IConfig */
-	private $config;
-
-	/** @var EventDispatcherInterface */
-	private $dispatcher;
-
-	/** @var ITimeFactory */
-	private $timeFactory;
-
-	/**
-	 * @param DbHandler $dbHandler
-	 * @param IClientService $httpClientService
-	 * @param ILogger $logger
-	 * @param IJobList $jobList
-	 * @param ISecureRandom $secureRandom
-	 * @param IConfig $config
-	 * @param EventDispatcherInterface $dispatcher
-	 * @param ITimeFactory $timeFactory
-	 */
 	public function __construct(
 		DbHandler $dbHandler,
 		IClientService $httpClientService,
-		ILogger $logger,
+		LoggerInterface $logger,
 		IJobList $jobList,
 		ISecureRandom $secureRandom,
 		IConfig $config,
-		EventDispatcherInterface $dispatcher,
+		IEventDispatcher $dispatcher,
 		ITimeFactory $timeFactory
 	) {
 		$this->dbHandler = $dbHandler;
@@ -105,12 +81,9 @@ class TrustedServers {
 	}
 
 	/**
-	 * add server to the list of trusted servers
-	 *
-	 * @param $url
-	 * @return int server id
+	 * Add server to the list of trusted servers
 	 */
-	public function addServer($url) {
+	public function addServer(string $url): int {
 		$url = $this->updateProtocol($url);
 		$result = $this->dbHandler->addServer($url);
 		if ($result) {
@@ -130,82 +103,62 @@ class TrustedServers {
 	}
 
 	/**
-	 * get shared secret for the given server
-	 *
-	 * @param string $url
-	 * @return string
+	 * Get shared secret for the given server
 	 */
-	public function getSharedSecret($url) {
+	public function getSharedSecret(string $url): string {
 		return $this->dbHandler->getSharedSecret($url);
 	}
 
 	/**
-	 * add shared secret for the given server
-	 *
-	 * @param string $url
-	 * @param $sharedSecret
+	 * Add shared secret for the given server
 	 */
-	public function addSharedSecret($url, $sharedSecret) {
+	public function addSharedSecret(string $url, string $sharedSecret): void {
 		$this->dbHandler->addSharedSecret($url, $sharedSecret);
 	}
 
 	/**
-	 * remove server from the list of trusted servers
-	 *
-	 * @param int $id
+	 * Remove server from the list of trusted servers
 	 */
-	public function removeServer($id) {
+	public function removeServer(int $id): void {
 		$server = $this->dbHandler->getServerById($id);
 		$this->dbHandler->removeServer($id);
-		$event = new GenericEvent($server['url_hash']);
-		$this->dispatcher->dispatch('OCP\Federation\TrustedServerEvent::remove', $event);
+		$this->dispatcher->dispatchTyped(new TrustedServerRemovedEvent($server['url_hash']));
 	}
 
 	/**
-	 * get all trusted servers
-	 *
-	 * @return array
+	 * Get all trusted servers
+	 * @return list<array{id: int, url: string, url_hash: string, shared_secret: string, status: int, sync_token: string}>
 	 */
 	public function getServers() {
 		return $this->dbHandler->getAllServer();
 	}
 
 	/**
-	 * check if given server is a trusted Nextcloud server
-	 *
-	 * @param string $url
-	 * @return bool
+	 * Check if given server is a trusted Nextcloud server
 	 */
-	public function isTrustedServer($url) {
+	public function isTrustedServer(string $url): bool {
 		return $this->dbHandler->serverExists($url);
 	}
 
 	/**
-	 * set server status
-	 *
-	 * @param string $url
-	 * @param int $status
+	 * Set server status
 	 */
-	public function setServerStatus($url, $status) {
+	public function setServerStatus(string $url, int $status): void {
 		$this->dbHandler->setServerStatus($url, $status);
 	}
 
 	/**
-	 * @param string $url
-	 * @return int
+	 * Get server status
 	 */
-	public function getServerStatus($url) {
+	public function getServerStatus(string $url): int {
 		return $this->dbHandler->getServerStatus($url);
 	}
 
 	/**
-	 * check if URL point to a ownCloud/Nextcloud server
-	 *
-	 * @param string $url
-	 * @return bool
+	 * Check if URL point to a ownCloud/Nextcloud server
 	 */
-	public function isOwnCloudServer($url) {
-		$isValidOwnCloud = false;
+	public function isNextcloudServer(string $url): bool {
+		$isValidNextcloud = false;
 		$client = $this->httpClientService->newClient();
 		try {
 			$result = $client->get(
@@ -216,28 +169,28 @@ class TrustedServers {
 				]
 			);
 			if ($result->getStatusCode() === Http::STATUS_OK) {
-				$isValidOwnCloud = $this->checkOwnCloudVersion($result->getBody());
+				$body = $result->getBody();
+				if (is_resource($body)) {
+					$body = stream_get_contents($body) ?: '';
+				}
+				$isValidNextcloud = $this->checkNextcloudVersion($body);
 			}
 		} catch (\Exception $e) {
-			\OC::$server->getLogger()->logException($e, [
-				'message' => 'No Nextcloud server.',
-				'level' => ILogger::DEBUG,
+			$this->logger->error('No Nextcloud server.', [
 				'app' => 'federation',
+				'exception' => $e,
 			]);
 			return false;
 		}
 
-		return $isValidOwnCloud;
+		return $isValidNextcloud;
 	}
 
 	/**
-	 * check if ownCloud version is >= 9.0
-	 *
-	 * @param $status
-	 * @return bool
+	 * Check if ownCloud/Nextcloud version is >= 9.0
 	 * @throws HintException
 	 */
-	protected function checkOwnCloudVersion($status) {
+	protected function checkNextcloudVersion(string $status): bool {
 		$decoded = json_decode($status, true);
 		if (!empty($decoded) && isset($decoded['version'])) {
 			if (!version_compare($decoded['version'], '9.0.0', '>=')) {
@@ -249,12 +202,9 @@ class TrustedServers {
 	}
 
 	/**
-	 * check if the URL contain a protocol, if not add https
-	 *
-	 * @param string $url
-	 * @return string
+	 * Check if the URL contain a protocol, if not add https
 	 */
-	protected function updateProtocol($url) {
+	protected function updateProtocol(string $url): string {
 		if (
 			strpos($url, 'https://') === 0
 			|| strpos($url, 'http://') === 0

+ 3 - 3
apps/federation/tests/BackgroundJob/GetSharedSecretTest.php

@@ -36,9 +36,9 @@ use OCP\BackgroundJob\IJobList;
 use OCP\Http\Client\IClient;
 use OCP\Http\Client\IClientService;
 use OCP\Http\Client\IResponse;
-use OCP\ILogger;
 use OCP\IURLGenerator;
 use OCP\OCS\IDiscoveryService;
+use Psr\Log\LoggerInterface;
 
 /**
  * Class GetSharedSecretTest
@@ -64,7 +64,7 @@ class GetSharedSecretTest extends TestCase {
 	/** @var \PHPUnit\Framework\MockObject\MockObject|TrustedServers  */
 	private $trustedServers;
 
-	/** @var \PHPUnit\Framework\MockObject\MockObject|ILogger */
+	/** @var \PHPUnit\Framework\MockObject\MockObject|LoggerInterface */
 	private $logger;
 
 	/** @var \PHPUnit\Framework\MockObject\MockObject|IResponse */
@@ -88,7 +88,7 @@ class GetSharedSecretTest extends TestCase {
 		$this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock();
 		$this->trustedServers = $this->getMockBuilder(TrustedServers::class)
 			->disableOriginalConstructor()->getMock();
-		$this->logger = $this->getMockBuilder(ILogger::class)->getMock();
+		$this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
 		$this->response = $this->getMockBuilder(IResponse::class)->getMock();
 		$this->discoverService = $this->getMockBuilder(IDiscoveryService::class)->getMock();
 		$this->timeFactory = $this->createMock(ITimeFactory::class);

+ 7 - 19
apps/federation/tests/Controller/OCSAuthAPIControllerTest.php

@@ -32,9 +32,9 @@ use OCA\Federation\DbHandler;
 use OCA\Federation\TrustedServers;
 use OCP\AppFramework\OCS\OCSForbiddenException;
 use OCP\AppFramework\Utility\ITimeFactory;
-use OCP\ILogger;
 use OCP\IRequest;
 use OCP\Security\ISecureRandom;
+use Psr\Log\LoggerInterface;
 use Test\TestCase;
 
 class OCSAuthAPIControllerTest extends TestCase {
@@ -60,12 +60,10 @@ class OCSAuthAPIControllerTest extends TestCase {
 	/** @var \PHPUnit\Framework\MockObject\MockObject|ITimeFactory */
 	private $timeFactory;
 
-
-	/** @var  OCSAuthAPIController */
-	private $ocsAuthApi;
+	private OCSAuthAPIController $ocsAuthApi;
 
 	/** @var int simulated timestamp */
-	private $currentTime = 1234567;
+	private int $currentTime = 1234567;
 
 	protected function setUp(): void {
 		parent::setUp();
@@ -75,10 +73,9 @@ class OCSAuthAPIControllerTest extends TestCase {
 		$this->trustedServers = $this->createMock(TrustedServers::class);
 		$this->dbHandler = $this->createMock(DbHandler::class);
 		$this->jobList = $this->createMock(JobList::class);
-		$this->logger = $this->createMock(ILogger::class);
+		$this->logger = $this->createMock(LoggerInterface::class);
 		$this->timeFactory = $this->createMock(ITimeFactory::class);
 
-
 		$this->ocsAuthApi = new OCSAuthAPIController(
 			'federation',
 			$this->request,
@@ -96,13 +93,8 @@ class OCSAuthAPIControllerTest extends TestCase {
 
 	/**
 	 * @dataProvider dataTestRequestSharedSecret
-	 *
-	 * @param string $token
-	 * @param string $localToken
-	 * @param bool $isTrustedServer
-	 * @param bool $ok
 	 */
-	public function testRequestSharedSecret($token, $localToken, $isTrustedServer, $ok) {
+	public function testRequestSharedSecret(string $token, string $localToken, bool $isTrustedServer, bool $ok): void {
 		$url = 'url';
 
 		$this->trustedServers
@@ -137,12 +129,8 @@ class OCSAuthAPIControllerTest extends TestCase {
 
 	/**
 	 * @dataProvider dataTestGetSharedSecret
-	 *
-	 * @param bool $isTrustedServer
-	 * @param bool $isValidToken
-	 * @param bool $ok
 	 */
-	public function testGetSharedSecret($isTrustedServer, $isValidToken, $ok) {
+	public function testGetSharedSecret(bool $isTrustedServer, bool $isValidToken, bool $ok): void {
 		$url = 'url';
 		$token = 'token';
 
@@ -171,7 +159,7 @@ class OCSAuthAPIControllerTest extends TestCase {
 			$this->secureRandom->expects($this->once())->method('generate')->with(32)
 				->willReturn('secret');
 			$this->trustedServers->expects($this->once())
-				->method('addSharedSecret')->willReturn($url, 'secret');
+				->method('addSharedSecret')->with($url, 'secret');
 		} else {
 			$this->secureRandom->expects($this->never())->method('generate');
 			$this->trustedServers->expects($this->never())->method('addSharedSecret');

+ 19 - 27
apps/federation/tests/Controller/SettingsControllerTest.php

@@ -5,6 +5,7 @@
  * @author Björn Schießle <bjoern@schiessle.org>
  * @author Morris Jobke <hey@morrisjobke.de>
  * @author Roeland Jago Douma <roeland@famdouma.nl>
+ * @author Carl Schwan <carl@carlschwan.eu>
  *
  * @license AGPL-3.0
  *
@@ -31,9 +32,7 @@ use OCP\IRequest;
 use Test\TestCase;
 
 class SettingsControllerTest extends TestCase {
-
-	/** @var SettingsController  */
-	private $controller;
+	private SettingsController $controller;
 
 	/** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\IRequest */
 	private $request;
@@ -60,7 +59,7 @@ class SettingsControllerTest extends TestCase {
 		);
 	}
 
-	public function testAddServer() {
+	public function testAddServer(): void {
 		$this->trustedServers
 			->expects($this->once())
 			->method('isTrustedServer')
@@ -68,7 +67,7 @@ class SettingsControllerTest extends TestCase {
 			->willReturn(false);
 		$this->trustedServers
 			->expects($this->once())
-			->method('isOwnCloudServer')
+			->method('isNextcloudServer')
 			->with('url')
 			->willReturn(true);
 
@@ -83,11 +82,8 @@ class SettingsControllerTest extends TestCase {
 
 	/**
 	 * @dataProvider checkServerFails
-	 *
-	 * @param bool $isTrustedServer
-	 * @param bool $isOwnCloud
 	 */
-	public function testAddServerFail($isTrustedServer, $isOwnCloud) {
+	public function testAddServerFail(bool $isTrustedServer, bool $isNextcloud): void {
 		$this->expectException(\OCP\HintException::class);
 
 		$this->trustedServers
@@ -97,22 +93,23 @@ class SettingsControllerTest extends TestCase {
 			->willReturn($isTrustedServer);
 		$this->trustedServers
 			->expects($this->any())
-			->method('isOwnCloudServer')
+			->method('isNextcloudServer')
 			->with('url')
-			->willReturn($isOwnCloud);
+			->willReturn($isNextcloud);
 
 		$this->controller->addServer('url');
 	}
 
-	public function testRemoveServer() {
-		$this->trustedServers->expects($this->once())->method('removeServer')
-		->with('url');
-		$result = $this->controller->removeServer('url');
+	public function testRemoveServer(): void {
+		$this->trustedServers->expects($this->once())
+			->method('removeServer')
+			->with(1);
+		$result = $this->controller->removeServer(1);
 		$this->assertTrue($result instanceof DataResponse);
 		$this->assertSame(200, $result->getStatus());
 	}
 
-	public function testCheckServer() {
+	public function testCheckServer(): void {
 		$this->trustedServers
 			->expects($this->once())
 			->method('isTrustedServer')
@@ -120,7 +117,7 @@ class SettingsControllerTest extends TestCase {
 			->willReturn(false);
 		$this->trustedServers
 			->expects($this->once())
-			->method('isOwnCloudServer')
+			->method('isNextcloudServer')
 			->with('url')
 			->willReturn(true);
 
@@ -131,11 +128,8 @@ class SettingsControllerTest extends TestCase {
 
 	/**
 	 * @dataProvider checkServerFails
-	 *
-	 * @param bool $isTrustedServer
-	 * @param bool $isOwnCloud
 	 */
-	public function testCheckServerFail($isTrustedServer, $isOwnCloud) {
+	public function testCheckServerFail(bool $isTrustedServer, bool $isNextcloud): void {
 		$this->expectException(\OCP\HintException::class);
 
 		$this->trustedServers
@@ -145,9 +139,9 @@ class SettingsControllerTest extends TestCase {
 			->willReturn($isTrustedServer);
 		$this->trustedServers
 			->expects($this->any())
-			->method('isOwnCloudServer')
+			->method('isNextcloudServer')
 			->with('url')
-			->willReturn($isOwnCloud);
+			->willReturn($isNextcloud);
 
 		$this->assertTrue(
 			$this->invokePrivate($this->controller, 'checkServer', ['url'])
@@ -155,11 +149,9 @@ class SettingsControllerTest extends TestCase {
 	}
 
 	/**
-	 * data to simulate checkServer fails
-	 *
-	 * @return array
+	 * Data to simulate checkServer fails
 	 */
-	public function checkServerFails() {
+	public function checkServerFails(): array {
 		return [
 			[true, true],
 			[false, false]

+ 6 - 7
apps/federation/tests/Middleware/AddServerMiddlewareTest.php

@@ -31,19 +31,18 @@ use OCA\Federation\Middleware\AddServerMiddleware;
 use OCP\AppFramework\Http;
 use OCP\HintException;
 use OCP\IL10N;
-use OCP\ILogger;
 use Test\TestCase;
+use Psr\Log\LoggerInterface;
 
 class AddServerMiddlewareTest extends TestCase {
 
-	/** @var  \PHPUnit\Framework\MockObject\MockObject | ILogger */
+	/** @var  \PHPUnit\Framework\MockObject\MockObject | LoggerInterface */
 	private $logger;
 
 	/** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\IL10N */
 	private $l10n;
 
-	/** @var  AddServerMiddleware */
-	private $middleware;
+	private AddServerMiddleware $middleware;
 
 	/** @var  \PHPUnit\Framework\MockObject\MockObject | SettingsController */
 	private $controller;
@@ -51,7 +50,7 @@ class AddServerMiddlewareTest extends TestCase {
 	protected function setUp(): void {
 		parent::setUp();
 
-		$this->logger = $this->getMockBuilder(ILogger::class)->getMock();
+		$this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
 		$this->l10n = $this->getMockBuilder(IL10N::class)->getMock();
 		$this->controller = $this->getMockBuilder(SettingsController::class)
 			->disableOriginalConstructor()->getMock();
@@ -70,11 +69,11 @@ class AddServerMiddlewareTest extends TestCase {
 	 * @param string $hint
 	 */
 	public function testAfterException($exception, $hint) {
-		$this->logger->expects($this->once())->method('logException');
+		$this->logger->expects($this->once())->method('error');
 
 		$this->l10n->expects($this->any())->method('t')
 			->willReturnCallback(
-				function ($message) {
+				function (string $message): string {
 					return $message;
 				}
 			);

+ 7 - 7
apps/federation/tests/SyncFederationAddressbooksTest.php

@@ -50,11 +50,11 @@ class SyncFederationAddressbooksTest extends \Test\TestCase {
 
 	public function testSync() {
 		/** @var DbHandler | \PHPUnit\Framework\MockObject\MockObject $dbHandler */
-		$dbHandler = $this->getMockBuilder('OCA\Federation\DbHandler')->
-			disableOriginalConstructor()->
-			getMock();
-		$dbHandler->method('getAllServer')->
-			willReturn([
+		$dbHandler = $this->getMockBuilder('OCA\Federation\DbHandler')
+			->disableOriginalConstructor()
+			->getMock();
+		$dbHandler->method('getAllServer')
+			->willReturn([
 				[
 					'url' => 'https://cloud.drop.box',
 					'url_hash' => 'sha1',
@@ -68,14 +68,14 @@ class SyncFederationAddressbooksTest extends \Test\TestCase {
 			->disableOriginalConstructor()
 			->getMock();
 		$syncService->expects($this->once())->method('syncRemoteAddressBook')
-			->willReturn(1);
+			->willReturn('1');
 
 		/** @var \OCA\DAV\CardDAV\SyncService $syncService */
 		$s = new SyncFederationAddressBooks($dbHandler, $syncService, $this->discoveryService);
 		$s->syncThemAll(function ($url, $ex) {
 			$this->callBacks[] = [$url, $ex];
 		});
-		$this->assertEquals(1, count($this->callBacks));
+		$this->assertEquals('1', count($this->callBacks));
 	}
 
 	public function testException() {

+ 65 - 80
apps/federation/tests/TrustedServersTest.php

@@ -35,10 +35,10 @@ use OCP\Http\Client\IClient;
 use OCP\Http\Client\IClientService;
 use OCP\Http\Client\IResponse;
 use OCP\IConfig;
-use OCP\ILogger;
 use OCP\Security\ISecureRandom;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use OCP\EventDispatcher\IEventDispatcher;
 use Test\TestCase;
+use Psr\Log\LoggerInterface;
 
 class TrustedServersTest extends TestCase {
 
@@ -69,7 +69,7 @@ class TrustedServersTest extends TestCase {
 	/** @var  \PHPUnit\Framework\MockObject\MockObject | IConfig */
 	private $config;
 
-	/** @var  \PHPUnit\Framework\MockObject\MockObject | EventDispatcherInterface */
+	/** @var  \PHPUnit\Framework\MockObject\MockObject | IEventDispatcher */
 	private $dispatcher;
 
 	/** @var \PHPUnit\Framework\MockObject\MockObject|ITimeFactory */
@@ -80,12 +80,12 @@ class TrustedServersTest extends TestCase {
 
 		$this->dbHandler = $this->getMockBuilder(DbHandler::class)
 			->disableOriginalConstructor()->getMock();
-		$this->dispatcher = $this->getMockBuilder(EventDispatcherInterface::class)
+		$this->dispatcher = $this->getMockBuilder(IEventDispatcher::class)
 			->disableOriginalConstructor()->getMock();
 		$this->httpClientService = $this->getMockBuilder(IClientService::class)->getMock();
 		$this->httpClient = $this->getMockBuilder(IClient::class)->getMock();
 		$this->response = $this->getMockBuilder(IResponse::class)->getMock();
-		$this->logger = $this->getMockBuilder(ILogger::class)->getMock();
+		$this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
 		$this->jobList = $this->getMockBuilder(IJobList::class)->getMock();
 		$this->secureRandom = $this->getMockBuilder(ISecureRandom::class)->getMock();
 		$this->config = $this->getMockBuilder(IConfig::class)->getMock();
@@ -103,12 +103,7 @@ class TrustedServersTest extends TestCase {
 		);
 	}
 
-	/**
-	 * @dataProvider dataTrueFalse
-	 *
-	 * @param bool $success
-	 */
-	public function testAddServer($success) {
+	public function testAddServer(): void {
 		/** @var \PHPUnit\Framework\MockObject\MockObject|TrustedServers $trustedServers */
 		$trustedServers = $this->getMockBuilder('OCA\Federation\TrustedServers')
 			->setConstructorArgs(
@@ -130,64 +125,56 @@ class TrustedServersTest extends TestCase {
 		$this->timeFactory->method('getTime')
 			->willReturn(1234567);
 		$this->dbHandler->expects($this->once())->method('addServer')->with('https://url')
-			->willReturn($success);
-
-		if ($success) {
-			$this->secureRandom->expects($this->once())->method('generate')
-				->willReturn('token');
-			$this->dbHandler->expects($this->once())->method('addToken')->with('https://url', 'token');
-			$this->jobList->expects($this->once())->method('add')
-				->with('OCA\Federation\BackgroundJob\RequestSharedSecret',
-						['url' => 'https://url', 'token' => 'token', 'created' => 1234567]);
-		} else {
-			$this->jobList->expects($this->never())->method('add');
-		}
-
-		$this->assertSame($success,
-			$trustedServers->addServer('url')
+			->willReturn(1);
+
+		$this->secureRandom->expects($this->once())->method('generate')
+			->willReturn('token');
+		$this->dbHandler->expects($this->once())->method('addToken')->with('https://url', 'token');
+		$this->jobList->expects($this->once())->method('add')
+			->with('OCA\Federation\BackgroundJob\RequestSharedSecret',
+					['url' => 'https://url', 'token' => 'token', 'created' => 1234567]);
+
+		$this->assertSame(
+			$trustedServers->addServer('url'),
+			1
 		);
 	}
 
-	public function dataTrueFalse() {
-		return [
-			[true],
-			[false]
-		];
-	}
-
-	public function testAddSharedSecret() {
+	public function testAddSharedSecret(): void {
 		$this->dbHandler->expects($this->once())->method('addSharedSecret')
 			->with('url', 'secret');
 		$this->trustedServers->addSharedSecret('url', 'secret');
 	}
 
-	public function testGetSharedSecret() {
-		$this->dbHandler->expects($this->once())->method('getSharedSecret')
-			->with('url')->willReturn(true);
-		$this->assertTrue(
-			$this->trustedServers->getSharedSecret('url')
+	public function testGetSharedSecret(): void {
+		$this->dbHandler->expects($this->once())
+				->method('getSharedSecret')
+				->with('url')
+				->willReturn('secret');
+		$this->assertSame(
+			$this->trustedServers->getSharedSecret('url'),
+			'secret'
 		);
 	}
 
-	public function testRemoveServer() {
+	public function testRemoveServer(): void {
 		$id = 42;
 		$server = ['url_hash' => 'url_hash'];
 		$this->dbHandler->expects($this->once())->method('removeServer')->with($id);
 		$this->dbHandler->expects($this->once())->method('getServerById')->with($id)
 			->willReturn($server);
-		$this->dispatcher->expects($this->once())->method('dispatch')
+		$this->dispatcher->expects($this->once())->method('dispatchTyped')
 			->willReturnCallback(
-				function ($eventId, $event) {
-					$this->assertSame($eventId, 'OCP\Federation\TrustedServerEvent::remove');
-					$this->assertInstanceOf('Symfony\Component\EventDispatcher\GenericEvent', $event);
-					/** @var \Symfony\Component\EventDispatcher\GenericEvent $event */
-					$this->assertSame('url_hash', $event->getSubject());
+				function ($event) {
+					$this->assertSame(get_class($event), \OCP\Federation\Events\TrustedServerRemovedEvent::class);
+					/** @var \OCP\Federated\Events\TrustedServerRemovedEvent $event */
+					$this->assertSame('url_hash', $event->getUrlHash());
 				}
 			);
 		$this->trustedServers->removeServer($id);
 	}
 
-	public function testGetServers() {
+	public function testGetServers(): void {
 		$this->dbHandler->expects($this->once())->method('getAllServer')->willReturn(['servers']);
 
 		$this->assertEquals(
@@ -197,8 +184,9 @@ class TrustedServersTest extends TestCase {
 	}
 
 
-	public function testIsTrustedServer() {
-		$this->dbHandler->expects($this->once())->method('serverExists')->with('url')
+	public function testIsTrustedServer(): void {
+		$this->dbHandler->expects($this->once())
+			->method('serverExists')->with('url')
 			->willReturn(true);
 
 		$this->assertTrue(
@@ -208,26 +196,23 @@ class TrustedServersTest extends TestCase {
 
 	public function testSetServerStatus() {
 		$this->dbHandler->expects($this->once())->method('setServerStatus')
-			->with('url', 'status');
-		$this->trustedServers->setServerStatus('url', 'status');
+			->with('url', 1);
+		$this->trustedServers->setServerStatus('url', 1);
 	}
 
 	public function testGetServerStatus() {
 		$this->dbHandler->expects($this->once())->method('getServerStatus')
-			->with('url')->willReturn(true);
-		$this->assertTrue(
-			$this->trustedServers->getServerStatus('url')
+			->with('url')->willReturn(1);
+		$this->assertSame(
+			$this->trustedServers->getServerStatus('url'),
+			1
 		);
 	}
 
 	/**
-	 * @dataProvider dataTestIsOwnCloudServer
-	 *
-	 * @param int $statusCode
-	 * @param bool $isValidOwnCloudVersion
-	 * @param bool $expected
+	 * @dataProvider dataTestIsNextcloudServer
 	 */
-	public function testIsOwnCloudServer($statusCode, $isValidOwnCloudVersion, $expected) {
+	public function testIsNextcloudServer(int $statusCode, bool $isValidNextcloudVersion, bool $expected): void {
 		$server = 'server1';
 
 		/** @var \PHPUnit\Framework\MockObject\MockObject | TrustedServers $trustedServers */
@@ -244,7 +229,7 @@ class TrustedServersTest extends TestCase {
 					$this->timeFactory
 				]
 			)
-			->setMethods(['checkOwnCloudVersion'])
+			->setMethods(['checkNextcloudVersion'])
 			->getMock();
 
 		$this->httpClientService->expects($this->once())->method('newClient')
@@ -257,18 +242,20 @@ class TrustedServersTest extends TestCase {
 			->willReturn($statusCode);
 
 		if ($statusCode === 200) {
-			$trustedServers->expects($this->once())->method('checkOwnCloudVersion')
-				->willReturn($isValidOwnCloudVersion);
+			$this->response->expects($this->once())->method('getBody')
+				->willReturn('');
+			$trustedServers->expects($this->once())->method('checkNextcloudVersion')
+				->willReturn($isValidNextcloudVersion);
 		} else {
-			$trustedServers->expects($this->never())->method('checkOwnCloudVersion');
+			$trustedServers->expects($this->never())->method('checkNextcloudVersion');
 		}
 
 		$this->assertSame($expected,
-			$trustedServers->isOwnCloudServer($server)
+			$trustedServers->isNextcloudServer($server)
 		);
 	}
 
-	public function dataTestIsOwnCloudServer() {
+	public function dataTestIsNextcloudServer(): array {
 		return [
 			[200, true, true],
 			[200, false, false],
@@ -279,7 +266,7 @@ class TrustedServersTest extends TestCase {
 	/**
 	 * @expectedExceptionMessage simulated exception
 	 */
-	public function testIsOwnCloudServerFail() {
+	public function testIsNextcloudServerFail(): void {
 		$server = 'server1';
 
 		$this->httpClientService->expects($this->once())->method('newClient')
@@ -290,17 +277,17 @@ class TrustedServersTest extends TestCase {
 				throw new \Exception('simulated exception');
 			});
 
-		$this->assertFalse($this->trustedServers->isOwnCloudServer($server));
+		$this->assertFalse($this->trustedServers->isNextcloudServer($server));
 	}
 
 	/**
-	 * @dataProvider dataTestCheckOwnCloudVersion
+	 * @dataProvider dataTestCheckNextcloudVersion
 	 */
-	public function testCheckOwnCloudVersion($status) {
-		$this->assertTrue($this->invokePrivate($this->trustedServers, 'checkOwnCloudVersion', [$status]));
+	public function testCheckNextcloudVersion($status): void {
+		$this->assertTrue($this->invokePrivate($this->trustedServers, 'checkNextcloudVersion', [$status]));
 	}
 
-	public function dataTestCheckOwnCloudVersion() {
+	public function dataTestCheckNextcloudVersion(): array {
 		return [
 			['{"version":"9.0.0"}'],
 			['{"version":"9.1.0"}']
@@ -308,16 +295,16 @@ class TrustedServersTest extends TestCase {
 	}
 
 	/**
-	 * @dataProvider dataTestCheckOwnCloudVersionTooLow
+	 * @dataProvider dataTestCheckNextcloudVersionTooLow
 	 */
-	public function testCheckOwnCloudVersionTooLow($status) {
+	public function testCheckNextcloudVersionTooLow(string $status): void {
 		$this->expectException(\OCP\HintException::class);
 		$this->expectExceptionMessage('Remote server version is too low. 9.0 is required.');
 
-		$this->invokePrivate($this->trustedServers, 'checkOwnCloudVersion', [$status]);
+		$this->invokePrivate($this->trustedServers, 'checkNextcloudVersion', [$status]);
 	}
 
-	public function dataTestCheckOwnCloudVersionTooLow() {
+	public function dataTestCheckNextcloudVersionTooLow(): array {
 		return [
 			['{"version":"8.2.3"}'],
 		];
@@ -325,16 +312,14 @@ class TrustedServersTest extends TestCase {
 
 	/**
 	 * @dataProvider dataTestUpdateProtocol
-	 * @param string $url
-	 * @param string $expected
 	 */
-	public function testUpdateProtocol($url, $expected) {
+	public function testUpdateProtocol(string $url, string $expected): void {
 		$this->assertSame($expected,
 			$this->invokePrivate($this->trustedServers, 'updateProtocol', [$url])
 		);
 	}
 
-	public function dataTestUpdateProtocol() {
+	public function dataTestUpdateProtocol(): array {
 		return [
 			['http://owncloud.org', 'http://owncloud.org'],
 			['https://owncloud.org', 'https://owncloud.org'],

+ 0 - 11
build/psalm-baseline.xml

@@ -951,17 +951,6 @@
       <code>null</code>
     </NullableReturnStatement>
   </file>
-  <file src="apps/federation/lib/TrustedServers.php">
-    <InvalidArgument occurrences="1">
-      <code>'OCP\Federation\TrustedServerEvent::remove'</code>
-    </InvalidArgument>
-    <InvalidClass occurrences="1">
-      <code>dbHandler</code>
-    </InvalidClass>
-    <TooManyArguments occurrences="1">
-      <code>dispatch</code>
-    </TooManyArguments>
-  </file>
   <file src="apps/files/ajax/download.php">
     <InvalidArgument occurrences="1">
       <code>$files_list</code>

+ 1 - 0
lib/composer/composer/autoload_classmap.php

@@ -224,6 +224,7 @@ return array(
     'OCP\\EventDispatcher\\GenericEvent' => $baseDir . '/lib/public/EventDispatcher/GenericEvent.php',
     'OCP\\EventDispatcher\\IEventDispatcher' => $baseDir . '/lib/public/EventDispatcher/IEventDispatcher.php',
     'OCP\\EventDispatcher\\IEventListener' => $baseDir . '/lib/public/EventDispatcher/IEventListener.php',
+    'OCP\\Federation\\Events\\TrustedServerRemovedEvent' => $baseDir . '/lib/public/Federation/Events/TrustedServerRemovedEvent.php',
     'OCP\\Federation\\Exceptions\\ActionNotSupportedException' => $baseDir . '/lib/public/Federation/Exceptions/ActionNotSupportedException.php',
     'OCP\\Federation\\Exceptions\\AuthenticationFailedException' => $baseDir . '/lib/public/Federation/Exceptions/AuthenticationFailedException.php',
     'OCP\\Federation\\Exceptions\\BadRequestException' => $baseDir . '/lib/public/Federation/Exceptions/BadRequestException.php',

+ 1 - 0
lib/composer/composer/autoload_static.php

@@ -257,6 +257,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
         'OCP\\EventDispatcher\\GenericEvent' => __DIR__ . '/../../..' . '/lib/public/EventDispatcher/GenericEvent.php',
         'OCP\\EventDispatcher\\IEventDispatcher' => __DIR__ . '/../../..' . '/lib/public/EventDispatcher/IEventDispatcher.php',
         'OCP\\EventDispatcher\\IEventListener' => __DIR__ . '/../../..' . '/lib/public/EventDispatcher/IEventListener.php',
+        'OCP\\Federation\\Events\\TrustedServerRemovedEvent' => __DIR__ . '/../../..' . '/lib/public/Federation/Events/TrustedServerRemovedEvent.php',
         'OCP\\Federation\\Exceptions\\ActionNotSupportedException' => __DIR__ . '/../../..' . '/lib/public/Federation/Exceptions/ActionNotSupportedException.php',
         'OCP\\Federation\\Exceptions\\AuthenticationFailedException' => __DIR__ . '/../../..' . '/lib/public/Federation/Exceptions/AuthenticationFailedException.php',
         'OCP\\Federation\\Exceptions\\BadRequestException' => __DIR__ . '/../../..' . '/lib/public/Federation/Exceptions/BadRequestException.php',

+ 48 - 0
lib/public/Federation/Events/TrustedServerRemovedEvent.php

@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2022 Carl Schwan <carl@carlschwan.eu>
+ *
+ * @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/>.
+ *
+ */
+namespace OCP\Federation\Events;
+
+use OCP\EventDispatcher\Event;
+
+/**
+ * @since 25.0.0
+ */
+class TrustedServerRemovedEvent extends Event {
+	private string $urlHash;
+
+	/**
+	 * @since 25.0.0
+	 */
+	public function __construct(string $urlHash) {
+		parent::__construct();
+		$this->urlHash = $urlHash;
+	}
+
+	/**
+	 * @since 25.0.0
+	 */
+	public function getUrlHash(): string {
+		return $this->urlHash;
+	}
+}