mirror of
https://github.com/nextcloud/spreed.git
synced 2025-12-18 05:20:50 +01:00
feat(federation): Add appconfig options to restrict federation
- Incoming federation - Outgoing federation - Group list - Limit federation to trusted servers Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
parent
9dc0ff0219
commit
7412cf4c67
12 changed files with 224 additions and 32 deletions
|
|
@ -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<br>`yes` or `no` | `no` | No | | Whether call recordings should automatically be transcripted when a transcription provider is enabled. |
|
||||
| `sip_dialout` | string<br>`yes` or `no` | `no` | Yes | | SIP dial-out is allowed when a SIP bridge is configured |
|
||||
| `federation_enabled` | string<br>`yes` or `no` | `no` | Yes | | ποΈ *Work in progress:* Whether or not federation with this instance is allowed |
|
||||
| `federation_incoming_enabled` | string<br>`1` or `0` | `1` | Yes | | ποΈ *Work in progress:* Whether users of this instance can be invited to federated conversations |
|
||||
| `federation_outgoing_enabled` | string<br>`1` or `0` | `1` | Yes | | ποΈ *Work in progress:* Whether users of this instance can invite federated users into conversations |
|
||||
| `federation_only_trusted_servers` | string<br>`1` or `0` | `0` | Yes | | ποΈ *Work in progress:* Whether federation should be limited to the list of "Trusted servers" |
|
||||
| `conversations_files` | string<br>`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<br>`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<br>`1` or `0` | `0` | No | ποΈ | Whether the Matterbridge integration is enabled and can be configured |
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ use OCA\Talk\Events\BeforeTurnServersGetEvent;
|
|||
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 @@ class Config {
|
|||
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';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,10 @@ class RoomController extends AEnvironmentAwareController {
|
|||
$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 [
|
||||
|
|
|
|||
|
|
@ -26,11 +26,14 @@ declare(strict_types=1);
|
|||
namespace OCA\Talk\Federation;
|
||||
|
||||
use OCA\FederatedFileSharing\AddressHandler;
|
||||
use OCA\Talk\AppInfo\Application;
|
||||
use OCA\Federation\TrustedServers;
|
||||
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 +43,7 @@ use OCP\HintException;
|
|||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Server;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use SensitiveParameter;
|
||||
|
||||
|
|
@ -53,6 +57,9 @@ class BackendNotifier {
|
|||
private IJobList $jobList,
|
||||
private IUserManager $userManager,
|
||||
private IURLGenerator $url,
|
||||
private IAppManager $appManager,
|
||||
private Config $talkConfig,
|
||||
private IAppConfig $appConfig,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -68,8 +75,7 @@ class BackendNotifier {
|
|||
string $providerId,
|
||||
string $token,
|
||||
string $shareWith,
|
||||
string $sharedBy,
|
||||
string $sharedByFederatedId,
|
||||
IUser $sharedBy,
|
||||
string $shareType,
|
||||
Room $room,
|
||||
Attendee $roomOwnerAttendee,
|
||||
|
|
@ -81,13 +87,37 @@ class BackendNotifier {
|
|||
$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 +130,8 @@ class BackendNotifier {
|
|||
$providerId,
|
||||
$roomOwner->getCloudId(),
|
||||
$roomOwner->getDisplayName(),
|
||||
$sharedByFederatedId,
|
||||
$sharedBy,
|
||||
$sharedBy->getCloudId(),
|
||||
$sharedBy->getDisplayName(),
|
||||
$token,
|
||||
$shareType,
|
||||
FederationManager::TALK_ROOM_RESOURCE
|
||||
|
|
@ -118,10 +148,7 @@ class BackendNotifier {
|
|||
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 +179,7 @@ class BackendNotifier {
|
|||
]);
|
||||
$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 +210,7 @@ class BackendNotifier {
|
|||
);
|
||||
$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;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ use OCA\Talk\Service\ParticipantService;
|
|||
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 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
|
|||
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 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
|
|||
$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 @@ class CloudFederationProviderTalk implements ICloudFederationProvider {
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -507,7 +507,7 @@ class ParticipantService {
|
|||
$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();
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@
|
|||
<file name="tests/stubs/oc_hooks_emitter.php" />
|
||||
<file name="tests/stubs/oc_http_client_response.php" />
|
||||
<file name="tests/stubs/oca_circles.php" />
|
||||
<file name="tests/stubs/oca_federation_trustedservers.php" />
|
||||
<file name="tests/stubs/oca_files_events.php" />
|
||||
<file name="tests/stubs/GuzzleHttp_Exception_ClientException.php" />
|
||||
<file name="tests/stubs/GuzzleHttp_Exception_ConnectException.php" />
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ use OCA\Talk\Events\BeforeTurnServersGetEvent;
|
|||
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 @@ use Test\TestCase;
|
|||
|
||||
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 @@ class ConfigTest extends TestCase {
|
|||
/** @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 @@ class ConfigTest extends TestCase {
|
|||
->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 @@ class ConfigTest extends TestCase {
|
|||
->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 @@ class ConfigTest extends TestCase {
|
|||
->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 @@ class ConfigTest extends TestCase {
|
|||
|
||||
$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 @@ class ConfigTest extends TestCase {
|
|||
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 @@ class ConfigTest extends TestCase {
|
|||
->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 @@ class ConfigTest extends TestCase {
|
|||
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 @@ class ConfigTest extends TestCase {
|
|||
->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.
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ use OCA\Talk\Service\SessionService;
|
|||
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 @@ class SignalingControllerTest extends TestCase {
|
|||
|
||||
$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 @@ class SignalingControllerTest extends TestCase {
|
|||
$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);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ use OCA\Talk\Model\InvitationMapper;
|
|||
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 @@ class FederationTest extends TestCase {
|
|||
$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 @@ class FederationTest extends TestCase {
|
|||
$this->createMock(IJobList::class),
|
||||
$this->userManager,
|
||||
$this->url,
|
||||
$this->appManager,
|
||||
$this->config,
|
||||
$this->appConfig,
|
||||
);
|
||||
|
||||
$this->federationManager = $this->createMock(FederationManager::class);
|
||||
|
|
@ -115,6 +124,7 @@ class FederationTest extends TestCase {
|
|||
$this->addressHandler,
|
||||
$this->federationManager,
|
||||
$this->config,
|
||||
$this->appConfig,
|
||||
$this->notificationManager,
|
||||
$this->createMock(ParticipantService::class),
|
||||
$this->createMock(RoomService::class),
|
||||
|
|
@ -138,7 +148,7 @@ class FederationTest extends TestCase {
|
|||
$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 @@ class FederationTest extends TestCase {
|
|||
$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 @@ class FederationTest extends TestCase {
|
|||
$ownerFederatedId,
|
||||
$owner,
|
||||
$sharedByFederatedId,
|
||||
$sharedBy,
|
||||
$sharedByDisplayName,
|
||||
$token,
|
||||
$shareType,
|
||||
'talk-room'
|
||||
|
|
@ -203,7 +222,17 @@ class FederationTest extends TestCase {
|
|||
->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 @@ class FederationTest extends TestCase {
|
|||
$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)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ use OCA\Talk\Service\ParticipantService;
|
|||
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 @@ class BackendNotifierTest extends TestCase {
|
|||
$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();
|
||||
|
||||
|
|
|
|||
75
tests/stubs/oca_federation_trustedservers.php
Normal file
75
tests/stubs/oca_federation_trustedservers.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\Federation;
|
||||
|
||||
class TrustedServers {
|
||||
/** after a user list was exchanged at least once successfully */
|
||||
public const STATUS_OK = 1;
|
||||
/** waiting for shared secret or initial user list exchange */
|
||||
public const STATUS_PENDING = 2;
|
||||
/** something went wrong, misconfigured server, software bug,... user interaction needed */
|
||||
public const STATUS_FAILURE = 3;
|
||||
/** remote server revoked access */
|
||||
public const STATUS_ACCESS_REVOKED = 4;
|
||||
public function __construct(\OCA\Federation\DbHandler $dbHandler, \OCP\Http\Client\IClientService $httpClientService, \Psr\Log\LoggerInterface $logger, \OCP\BackgroundJob\IJobList $jobList, \OCP\Security\ISecureRandom $secureRandom, \OCP\IConfig $config, \OCP\EventDispatcher\IEventDispatcher $dispatcher, \OCP\AppFramework\Utility\ITimeFactory $timeFactory) {
|
||||
}
|
||||
/**
|
||||
* Add server to the list of trusted servers
|
||||
*/
|
||||
public function addServer(string $url) : int {
|
||||
}
|
||||
/**
|
||||
* Get shared secret for the given server
|
||||
*/
|
||||
public function getSharedSecret(string $url) : string {
|
||||
}
|
||||
/**
|
||||
* Add shared secret for the given server
|
||||
*/
|
||||
public function addSharedSecret(string $url, string $sharedSecret) : void {
|
||||
}
|
||||
/**
|
||||
* Remove server from the list of trusted servers
|
||||
*/
|
||||
public function removeServer(int $id) : void {
|
||||
}
|
||||
/**
|
||||
* Get all trusted servers
|
||||
*
|
||||
* @return list<array{id: int, url: string, url_hash: string, shared_secret: ?string, status: int, sync_token: ?string}>
|
||||
* @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 {
|
||||
}
|
||||
}
|
||||
Loadingβ¦
Add table
Add a link
Reference in a new issue