diff --git a/docs/settings.md b/docs/settings.md index 689e82b6834f..35b068585c7d 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -63,6 +63,7 @@ Legend: | `allowed_groups` | string[] | `[]` | Yes | 🖌️ | List of group ids that are allowed to use Talk | | `sip_bridge_groups` | string[] | `[]` | Yes | 🖌️ | List of group ids that are allowed to enable SIP dial-in in a conversation | | `start_conversations` | string[] | `[]` | Yes | 🖌️ | List of group ids that are allowed to create conversations | +| `federation_allowed_groups` | string[] | `[]` | Yes | 🖌️ | 🏗️ *Work in progress:* List of group ids that are allowed to invite federated users into their conversations (everyone when empty) | | `hosted-signaling-server-account` | array | `{}` | No | 🖌️ | Account information of the hosted signaling server | | `stun_servers` | array[] | `[]` | Yes | 🖌💻️ | List of STUN servers, should be configured via the web interface or the OCC commands | | `turn_servers` | array[] | `[]` | Yes | 🖌️💻 | List of TURN servers, should be configured via the web interface or the OCC commands | @@ -97,6 +98,9 @@ Legend: | `call_recording_transcription` | string
`yes` or `no` | `no` | No | | Whether call recordings should automatically be transcripted when a transcription provider is enabled. | | `sip_dialout` | string
`yes` or `no` | `no` | Yes | | SIP dial-out is allowed when a SIP bridge is configured | | `federation_enabled` | string
`yes` or `no` | `no` | Yes | | 🏗️ *Work in progress:* Whether or not federation with this instance is allowed | +| `federation_incoming_enabled` | string
`1` or `0` | `1` | Yes | | 🏗️ *Work in progress:* Whether users of this instance can be invited to federated conversations | +| `federation_outgoing_enabled` | string
`1` or `0` | `1` | Yes | | 🏗️ *Work in progress:* Whether users of this instance can invite federated users into conversations | +| `federation_only_trusted_servers` | string
`1` or `0` | `0` | Yes | | 🏗️ *Work in progress:* Whether federation should be limited to the list of "Trusted servers" | | `conversations_files` | string
`1` or `0` | `1` | No | 🖌️ | Whether the files app integration is enabled allowing to start conversations in the right sidebar | | `conversations_files_public_shares` | string
`1` or `0` | `1` | No | 🖌️ | Whether the public share integration is enabled allowing to start conversations in the right sidebar on the public share page (Requires `conversations_files` also to be enabled) | | `enable_matterbridge` | string
`1` or `0` | `0` | No | 🖌️ | Whether the Matterbridge integration is enabled and can be configured | diff --git a/lib/Config.php b/lib/Config.php index b5258674d301..9de026af9e19 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -27,6 +27,7 @@ use OCA\Talk\Model\Attendee; use OCA\Talk\Service\RecordingService; use OCA\Talk\Vendor\Firebase\JWT\JWT; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; @@ -56,6 +57,7 @@ class Config { public function __construct( protected IConfig $config, + protected IAppConfig $appConfig, private ISecureRandom $secureRandom, private IGroupManager $groupManager, private IUserManager $userManager, @@ -111,6 +113,16 @@ public function isFederationEnabled(): bool { return $this->config->getAppValue('spreed', 'federation_enabled', 'no') === 'yes'; } + public function isFederationEnabledForUserId(IUser $user): bool { + $allowedGroups = $this->appConfig->getAppValueArray('federation_allowed_groups', lazy: true); + if (empty($allowedGroups)) { + return true; + } + + $userGroups = $this->groupManager->getUserGroupIds($user); + return empty(array_intersect($allowedGroups, $userGroups)); + } + public function isBreakoutRoomsEnabled(): bool { return $this->config->getAppValue('spreed', 'breakout_rooms', 'yes') === 'yes'; } diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index 6f5818275d34..171747045560 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -154,6 +154,10 @@ protected function getTalkHashHeader(): array { $this->config->getAppValue('spreed', 'recording_consent'), $this->config->getAppValue('theming', 'cachebuster', '1'), $this->config->getUserValue($this->userId, 'theming', 'userCacheBuster', '0'), + $this->config->getAppValue('spreed', 'federation_incoming_enabled'), + $this->config->getAppValue('spreed', 'federation_outgoing_enabled'), + $this->config->getAppValue('spreed', 'federation_only_trusted_servers'), + $this->config->getAppValue('spreed', 'federation_allowed_groups', '[]'), ]; return [ diff --git a/lib/Federation/BackendNotifier.php b/lib/Federation/BackendNotifier.php index db4d9c9af2cc..9f2971a9a168 100644 --- a/lib/Federation/BackendNotifier.php +++ b/lib/Federation/BackendNotifier.php @@ -26,11 +26,15 @@ namespace OCA\Talk\Federation; use OCA\FederatedFileSharing\AddressHandler; +use OCA\Federation\TrustedServers; use OCA\Talk\AppInfo\Application; use OCA\Talk\BackgroundJob\RetryJob; +use OCA\Talk\Config; use OCA\Talk\Exceptions\RoomHasNoModeratorException; use OCA\Talk\Model\Attendee; use OCA\Talk\Room; +use OCP\App\IAppManager; +use OCP\AppFramework\Services\IAppConfig; use OCP\BackgroundJob\IJobList; use OCP\DB\Exception; use OCP\Federation\ICloudFederationFactory; @@ -40,6 +44,7 @@ use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserManager; +use OCP\Server; use Psr\Log\LoggerInterface; use SensitiveParameter; @@ -53,6 +58,9 @@ public function __construct( private IJobList $jobList, private IUserManager $userManager, private IURLGenerator $url, + private IAppManager $appManager, + private Config $talkConfig, + private IAppConfig $appConfig, ) { } @@ -68,8 +76,7 @@ public function sendRemoteShare( string $providerId, string $token, string $shareWith, - string $sharedBy, - string $sharedByFederatedId, + IUser $sharedBy, string $shareType, Room $room, Attendee $roomOwnerAttendee, @@ -81,13 +88,37 @@ public function sendRemoteShare( $roomToken = $room->getToken(); if (!($user && $remote)) { - $this->logger->info( - "could not share $roomToken, invalid contact $shareWith", - ['app' => Application::APP_ID] - ); + $this->logger->info("Could not share conversation $roomToken as the recipient is invalid: $shareWith"); + return false; + } + + if (!$this->appConfig->getAppValueBool('federation_outgoing_enabled', true)) { + $this->logger->info("Could not share conversation $roomToken as outgoing federation is disabled"); + return false; + } + + if (!$this->talkConfig->isFederationEnabledForUserId($sharedBy)) { + $this->logger->info('Talk federation not allowed for user ' . $sharedBy->getUID()); return false; } + if ($this->appConfig->getAppValueBool('federation_only_trusted_servers')) { + if (!$this->appManager->isEnabledForUser('federation')) { + $this->logger->error('Federation is limited to trusted servers but the "federation" app is disabled'); + return false; + } + + $trustedServers = Server::get(TrustedServers::class); + $serverUrl = $this->addressHandler->removeProtocolFromUrl($remote); + if (!$trustedServers->isTrustedServer($serverUrl)) { + $this->logger->warning( + 'Tried to send Talk federation invite to untrusted server {serverUrl}', + ['serverUrl' => $serverUrl] + ); + return false; + } + } + /** @var IUser|null $roomOwner */ $roomOwner = $this->userManager->get($roomOwnerAttendee->getActorId()); @@ -100,8 +131,8 @@ public function sendRemoteShare( $providerId, $roomOwner->getCloudId(), $roomOwner->getDisplayName(), - $sharedByFederatedId, - $sharedBy, + $sharedBy->getCloudId(), + $sharedBy->getDisplayName(), $token, $shareType, FederationManager::TALK_ROOM_RESOURCE @@ -118,10 +149,7 @@ public function sendRemoteShare( if (is_array($response)) { return true; } - $this->logger->info( - "failed sharing $roomToken with $shareWith", - ['app' => Application::APP_ID] - ); + $this->logger->info("Failed sharing $roomToken with $shareWith"); return false; } @@ -152,10 +180,7 @@ public function sendShareAccepted( ]); $response = $this->federationProviderManager->sendNotification($remote, $notification); if (!is_array($response)) { - $this->logger->info( - "failed to send share accepted notification for share from $remote", - ['app' => Application::APP_ID] - ); + $this->logger->info("Failed to send share accepted notification for share from $remote"); return false; } return true; @@ -186,10 +211,7 @@ public function sendShareDeclined( ); $response = $this->federationProviderManager->sendNotification($remote, $notification); if (!is_array($response)) { - $this->logger->info( - "failed to send share declined notification for share from $remote", - ['app' => Application::APP_ID] - ); + $this->logger->info("Failed to send share declined notification for share from $remote"); return false; } return true; diff --git a/lib/Federation/CloudFederationProviderTalk.php b/lib/Federation/CloudFederationProviderTalk.php index 224aad911281..0a331cdb466a 100644 --- a/lib/Federation/CloudFederationProviderTalk.php +++ b/lib/Federation/CloudFederationProviderTalk.php @@ -44,6 +44,7 @@ use OCA\Talk\Service\RoomService; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Http; +use OCP\AppFramework\Services\IAppConfig; use OCP\DB\Exception as DBException; use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\Exceptions\ActionNotSupportedException; @@ -68,6 +69,7 @@ public function __construct( private AddressHandler $addressHandler, private FederationManager $federationManager, private Config $config, + private IAppConfig $appConfig, private INotificationManager $notificationManager, private ParticipantService $participantService, private RoomService $roomService, @@ -97,6 +99,10 @@ public function shareReceived(ICloudFederationShare $share): string { $this->logger->debug('Received a federation invite but federation is disabled'); throw new ProviderCouldNotAddShareException('Server does not support talk federation', '', Http::STATUS_SERVICE_UNAVAILABLE); } + if (!$this->appConfig->getAppValueBool('federation_incoming_enabled', true)) { + $this->logger->warning('Received a federation invite but incoming federation is disabled'); + throw new ProviderCouldNotAddShareException('Server does not support talk federation', '', Http::STATUS_SERVICE_UNAVAILABLE); + } if (!in_array($share->getShareType(), $this->getSupportedShareTypes(), true)) { $this->logger->debug('Received a federation invite for invalid share type'); throw new ProviderCouldNotAddShareException('Support for sharing with non-users not implemented yet', '', Http::STATUS_NOT_IMPLEMENTED); @@ -135,6 +141,16 @@ public function shareReceived(ICloudFederationShare $share): string { throw new ProviderCouldNotAddShareException('User does not exist', '', Http::STATUS_BAD_REQUEST); } + if ($this->config->isDisabledForUser($shareWith)) { + $this->logger->debug('Received a federation invite for user that is not allowed to use Talk'); + throw new ProviderCouldNotAddShareException('User does not exist', '', Http::STATUS_BAD_REQUEST); + } + + if (!$this->config->isFederationEnabledForUserId($shareWith)) { + $this->logger->debug('Received a federation invite for user that is not allowed to use Talk Federation'); + throw new ProviderCouldNotAddShareException('User does not exist', '', Http::STATUS_BAD_REQUEST); + } + $invite = $this->federationManager->addRemoteRoom($shareWith, (int) $remoteId, $roomType, $roomName, $roomToken, $remote, $shareSecret); $this->notifyAboutNewShare($shareWith, (string) $invite->getId(), $sharedByFederatedId, $sharedBy, $roomName, $roomToken, $remote); diff --git a/lib/Service/ParticipantService.php b/lib/Service/ParticipantService.php index 5a455b981e17..62c23aacd639 100644 --- a/lib/Service/ParticipantService.php +++ b/lib/Service/ParticipantService.php @@ -507,7 +507,7 @@ public function addUsers(Room $room, array $participants, ?IUser $addedBy = null $this->attendeeMapper->insert($attendee); if ($attendee->getActorType() === Attendee::ACTOR_FEDERATED_USERS) { - $inviteSent = $this->backendNotifier->sendRemoteShare((string) $attendee->getId(), $attendee->getAccessToken(), $attendee->getActorId(), $addedBy->getDisplayName(), $addedBy->getCloudId(), 'user', $room, $this->getHighestPermissionAttendee($room)); + $inviteSent = $this->backendNotifier->sendRemoteShare((string) $attendee->getId(), $attendee->getAccessToken(), $attendee->getActorId(), $addedBy, 'user', $room, $this->getHighestPermissionAttendee($room)); if (!$inviteSent) { $this->attendeeMapper->delete($attendee); throw new CannotReachRemoteException(); diff --git a/psalm.xml b/psalm.xml index 531886820f83..3b0a03078cf5 100644 --- a/psalm.xml +++ b/psalm.xml @@ -91,6 +91,7 @@ + diff --git a/tests/php/ConfigTest.php b/tests/php/ConfigTest.php index 53a50019e73e..092fbd6b606f 100644 --- a/tests/php/ConfigTest.php +++ b/tests/php/ConfigTest.php @@ -25,6 +25,7 @@ use OCA\Talk\Tests\php\Mocks\GetTurnServerListener; use OCA\Talk\Vendor\Firebase\JWT\JWT; use OCA\Talk\Vendor\Firebase\JWT\Key; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; @@ -38,6 +39,8 @@ class ConfigTest extends TestCase { private function createConfig(IConfig $config) { + /** @var MockObject|IAppConfig $appConfig */ + $appConfig = $this->createMock(IAppConfig::class); /** @var MockObject|ITimeFactory $timeFactory */ $timeFactory = $this->createMock(ITimeFactory::class); /** @var MockObject|ISecureRandom $secureRandom */ @@ -51,7 +54,7 @@ private function createConfig(IConfig $config) { /** @var MockObject|IEventDispatcher $dispatcher */ $dispatcher = $this->createMock(IEventDispatcher::class); - $helper = new Config($config, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); + $helper = new Config($config, $appConfig, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); return $helper; } @@ -149,6 +152,8 @@ public function testGenerateTurnSettings() { ->method('getTime') ->willReturn(1479743025); + /** @var MockObject|IAppConfig $appConfig */ + $appConfig = $this->createMock(IAppConfig::class); /** @var MockObject|IGroupManager $groupManager */ $groupManager = $this->createMock(IGroupManager::class); /** @var MockObject|IUserManager $userManager */ @@ -165,7 +170,7 @@ public function testGenerateTurnSettings() { ->method('generate') ->with(16) ->willReturn('abcdefghijklmnop'); - $helper = new Config($config, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); + $helper = new Config($config, $appConfig, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); // $settings = $helper->getTurnSettings(); @@ -217,6 +222,9 @@ public function testGenerateTurnSettingsEvent() { ->with('spreed', 'turn_servers', '') ->willReturn(json_encode([])); + /** @var MockObject|IAppConfig $appConfig */ + $appConfig = $this->createMock(IAppConfig::class); + /** @var MockObject|ITimeFactory $timeFactory */ $timeFactory = $this->createMock(ITimeFactory::class); @@ -254,7 +262,7 @@ public function testGenerateTurnSettingsEvent() { $dispatcher->addServiceListener(BeforeTurnServersGetEvent::class, GetTurnServerListener::class); - $helper = new Config($config, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); + $helper = new Config($config, $appConfig, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); $settings = $helper->getTurnSettings(); $this->assertSame($servers, $settings); @@ -351,6 +359,8 @@ public static function dataTicketV2Algorithm() { public function testSignalingTicketV2User(string $algo): void { /** @var IConfig $config */ $config = \OC::$server->getConfig(); + /** @var MockObject|IAppConfig $appConfig */ + $appConfig = $this->createMock(IAppConfig::class); /** @var MockObject|ITimeFactory $timeFactory */ $timeFactory = $this->createMock(ITimeFactory::class); /** @var MockObject|ISecureRandom $secureRandom */ @@ -390,7 +400,7 @@ public function testSignalingTicketV2User(string $algo): void { ->method('getDisplayName') ->willReturn('Jane Doe'); - $helper = new Config($config, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); + $helper = new Config($config, $appConfig, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); $config->setAppValue('spreed', 'signaling_token_alg', $algo); // Make sure new keys are generated. @@ -415,6 +425,8 @@ public function testSignalingTicketV2User(string $algo): void { public function testSignalingTicketV2Anonymous(string $algo): void { /** @var IConfig $config */ $config = \OC::$server->getConfig(); + /** @var MockObject|IAppConfig $appConfig */ + $appConfig = $this->createMock(IAppConfig::class); /** @var MockObject|ITimeFactory $timeFactory */ $timeFactory = $this->createMock(ITimeFactory::class); /** @var MockObject|ISecureRandom $secureRandom */ @@ -439,7 +451,7 @@ public function testSignalingTicketV2Anonymous(string $algo): void { ->with('') ->willReturn('https://domain.invalid/nextcloud'); - $helper = new Config($config, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); + $helper = new Config($config, $appConfig, $secureRandom, $groupManager, $userManager, $urlGenerator, $timeFactory, $dispatcher); $config->setAppValue('spreed', 'signaling_token_alg', $algo); // Make sure new keys are generated. diff --git a/tests/php/Controller/SignalingControllerTest.php b/tests/php/Controller/SignalingControllerTest.php index 6118636504de..74e7b6715417 100644 --- a/tests/php/Controller/SignalingControllerTest.php +++ b/tests/php/Controller/SignalingControllerTest.php @@ -41,6 +41,7 @@ use OCA\Talk\Signaling\Messages; use OCA\Talk\TalkSession; use OCP\App\IAppManager; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; use OCP\EventDispatcher\IEventDispatcher; use OCP\Http\Client\IClientService; @@ -114,6 +115,8 @@ public function setUp(): void { $this->userId = 'testUser'; $this->secureRandom = \OC::$server->getSecureRandom(); + /** @var MockObject|IAppConfig $appConfig */ + $appConfig = $this->createMock(IAppConfig::class); $timeFactory = $this->createMock(ITimeFactory::class); $groupManager = $this->createMock(IGroupManager::class); $this->serverConfig = \OC::$server->getConfig(); @@ -125,7 +128,7 @@ public function setUp(): void { $this->userManager = $this->createMock(IUserManager::class); $this->dispatcher = \OC::$server->get(IEventDispatcher::class); $urlGenerator = $this->createMock(IURLGenerator::class); - $this->config = new Config($this->serverConfig, $this->secureRandom, $groupManager, $this->userManager, $urlGenerator, $timeFactory, $this->dispatcher); + $this->config = new Config($this->serverConfig, $appConfig, $this->secureRandom, $groupManager, $this->userManager, $urlGenerator, $timeFactory, $this->dispatcher); $this->session = $this->createMock(TalkSession::class); $this->dbConnection = \OC::$server->getDatabaseConnection(); $this->signalingManager = $this->createMock(\OCA\Talk\Signaling\Manager::class); diff --git a/tests/php/Federation/FederationTest.php b/tests/php/Federation/FederationTest.php index 3d639f24f0f8..8a7ee1fc5d1b 100644 --- a/tests/php/Federation/FederationTest.php +++ b/tests/php/Federation/FederationTest.php @@ -36,6 +36,8 @@ use OCA\Talk\Room; use OCA\Talk\Service\ParticipantService; use OCA\Talk\Service\RoomService; +use OCP\App\IAppManager; +use OCP\AppFramework\Services\IAppConfig; use OCP\BackgroundJob\IJobList; use OCP\EventDispatcher\IEventDispatcher; use OCP\Federation\ICloudFederationFactory; @@ -65,6 +67,7 @@ class FederationTest extends TestCase { /** @var Config|MockObject */ protected $config; + protected IAppConfig|MockObject $appConfig; /** @var LoggerInterface|MockObject */ protected $logger; @@ -75,6 +78,7 @@ class FederationTest extends TestCase { /** @var IUserManager|MockObject */ protected $userManager; + protected IAppManager|MockObject $appManager; /** @var IURLGenerator|MockObject */ protected $url; @@ -94,6 +98,8 @@ public function setUp(): void { $this->userManager = $this->createMock(IUserManager::class); $this->attendeeMapper = $this->createMock(AttendeeMapper::class); $this->config = $this->createMock(Config::class); + $this->appConfig = $this->createMock(IAppConfig::class); + $this->appManager = $this->createMock(IAppManager::class); $this->logger = $this->createMock(LoggerInterface::class); $this->url = $this->createMock(IURLGenerator::class); @@ -105,6 +111,9 @@ public function setUp(): void { $this->createMock(IJobList::class), $this->userManager, $this->url, + $this->appManager, + $this->config, + $this->appConfig, ); $this->federationManager = $this->createMock(FederationManager::class); @@ -115,6 +124,7 @@ public function setUp(): void { $this->addressHandler, $this->federationManager, $this->config, + $this->appConfig, $this->notificationManager, $this->createMock(ParticipantService::class), $this->createMock(RoomService::class), @@ -138,7 +148,7 @@ public function testSendRemoteShareWithOwner() { $owner = 'Owner\'s name'; $ownerId = 'owner'; $ownerFederatedId = $ownerId . '@test.local'; - $sharedBy = 'Owner\'s name'; + $sharedByDisplayName = 'Owner\'s name'; $sharedByFederatedId = 'owner@test.local'; $shareType = 'user'; $roomType = Room::TYPE_GROUP; @@ -147,6 +157,15 @@ public function testSendRemoteShareWithOwner() { $room = $this->createMock(Room::class); $attendee = $this->createStub(Attendee::class); $ownerUser = $this->createMock(IUser::class); + $sharedBy = $this->createMock(IUser::class); + $sharedBy->expects($this->once()) + ->method('getCloudId') + ->with() + ->willReturn($sharedByFederatedId); + $sharedBy->expects($this->once()) + ->method('getDisplayName') + ->with() + ->willReturn($sharedByDisplayName); $room->expects($this->once()) ->method('getName') @@ -187,7 +206,7 @@ public function testSendRemoteShareWithOwner() { $ownerFederatedId, $owner, $sharedByFederatedId, - $sharedBy, + $sharedByDisplayName, $token, $shareType, 'talk-room' @@ -203,7 +222,17 @@ public function testSendRemoteShareWithOwner() { ->with($shareWith) ->willReturn(['test', 'remote.test.local']); - $this->backendNotifier->sendRemoteShare($providerId, $token, $shareWith, $sharedBy, $sharedByFederatedId, $shareType, $room, $attendee); + $this->appConfig->method('getAppValueBool') + ->willReturnMap([ + ['federation_outgoing_enabled', true, false, true], + ['federation_only_trusted_servers', false, false, false], + ]); + + $this->config->method('isFederationEnabledForUserId') + ->with($sharedBy) + ->willReturn(true); + + $this->backendNotifier->sendRemoteShare($providerId, $token, $shareWith, $sharedBy, $shareType, $room, $attendee); } public function testReceiveRemoteShare() { @@ -256,6 +285,19 @@ public function testReceiveRemoteShare() { $this->config->method('isFederationEnabled') ->willReturn(true); + $this->appConfig->method('getAppValueBool') + ->willReturnMap([ + ['federation_incoming_enabled', true, false, true], + ]); + + $this->config->method('isDisabledForUser') + ->with($shareWithUser) + ->willReturn(false); + + $this->config->method('isFederationEnabledForUserId') + ->with($shareWithUser) + ->willReturn(true); + $this->addressHandler->expects($this->once()) ->method('splitUserRemote') ->with($ownerFederatedId) diff --git a/tests/php/Recording/BackendNotifierTest.php b/tests/php/Recording/BackendNotifierTest.php index 56874dfb2e6a..6a3aa2d5e8e5 100644 --- a/tests/php/Recording/BackendNotifierTest.php +++ b/tests/php/Recording/BackendNotifierTest.php @@ -34,6 +34,7 @@ use OCA\Talk\Service\RoomService; use OCA\Talk\TalkSession; use OCP\App\IAppManager; +use OCP\AppFramework\Services\IAppConfig; use OCP\AppFramework\Utility\ITimeFactory; use OCP\EventDispatcher\IEventDispatcher; use OCP\Http\Client\IClientService; @@ -102,12 +103,13 @@ public function setUp(): void { $this->secureRandom = \OC::$server->getSecureRandom(); $this->urlGenerator = $this->createMock(IURLGenerator::class); + $appConfig = $this->createMock(IAppConfig::class); $groupManager = $this->createMock(IGroupManager::class); $userManager = $this->createMock(IUserManager::class); $timeFactory = $this->createMock(ITimeFactory::class); $dispatcher = \OC::$server->get(IEventDispatcher::class); - $this->config = new Config($config, $this->secureRandom, $groupManager, $userManager, $this->urlGenerator, $timeFactory, $dispatcher); + $this->config = new Config($config, $appConfig, $this->secureRandom, $groupManager, $userManager, $this->urlGenerator, $timeFactory, $dispatcher); $this->recreateBackendNotifier(); diff --git a/tests/stubs/oca_federation_trustedservers.php b/tests/stubs/oca_federation_trustedservers.php new file mode 100644 index 000000000000..cf0eda78f3ae --- /dev/null +++ b/tests/stubs/oca_federation_trustedservers.php @@ -0,0 +1,88 @@ + + * @throws Exception + */ + public function getServers() + { + } + /** + * Check if given server is a trusted Nextcloud server + */ + public function isTrustedServer(string $url) : bool + { + } + /** + * Set server status + */ + public function setServerStatus(string $url, int $status) : void + { + } + /** + * Get server status + */ + public function getServerStatus(string $url) : int + { + } + /** + * Check if URL point to a ownCloud/Nextcloud server + */ + public function isNextcloudServer(string $url) : bool + { + } + /** + * Check if ownCloud/Nextcloud version is >= 9.0 + * @throws HintException + */ + protected function checkNextcloudVersion(string $status) : bool + { + } + /** + * Check if the URL contain a protocol, if not add https + */ + protected function updateProtocol(string $url) : string + { + } +} \ No newline at end of file