Skip to content

Commit cbb34c2

Browse files
Merge pull request #2335 from nextcloud/backport/2332/stable33
[stable33] add trusted servers as external
2 parents 7f4c8e7 + 0a0fd8b commit cbb34c2

File tree

5 files changed

+137
-75
lines changed

5 files changed

+137
-75
lines changed

lib/Command/CirclesRemote.php

Lines changed: 10 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
use OCA\Circles\Exceptions\RemoteNotFoundException;
1919
use OCA\Circles\Exceptions\RemoteUidException;
2020
use OCA\Circles\Model\Federated\RemoteInstance;
21-
use OCA\Circles\Service\ConfigService;
2221
use OCA\Circles\Service\GlobalScaleService;
2322
use OCA\Circles\Service\InterfaceService;
2423
use OCA\Circles\Service\RemoteStreamService;
24+
use OCA\Circles\Service\RemoteSyncService;
2525
use OCA\Circles\Tools\Exceptions\RequestNetworkException;
2626
use OCA\Circles\Tools\Exceptions\SignatoryException;
2727
use OCA\Circles\Tools\Exceptions\SignatureException;
@@ -47,54 +47,17 @@ class CirclesRemote extends Base {
4747
use TNCWellKnown;
4848
use TStringTools;
4949

50+
private InputInterface $input;
51+
private OutputInterface $output;
5052

51-
/** @var RemoteRequest */
52-
private $remoteRequest;
53-
54-
/** @var GlobalScaleService */
55-
private $globalScaleService;
56-
57-
/** @var RemoteStreamService */
58-
private $remoteStreamService;
59-
60-
/** @var InterfaceService */
61-
private $interfaceService;
62-
63-
/** @var ConfigService */
64-
private $configService;
65-
66-
67-
/** @var InputInterface */
68-
private $input;
69-
70-
/** @var OutputInterface */
71-
private $output;
72-
73-
74-
/**
75-
* CirclesRemote constructor.
76-
*
77-
* @param RemoteRequest $remoteRequest
78-
* @param GlobalScaleService $globalScaleService
79-
* @param RemoteStreamService $remoteStreamService
80-
* @param InterfaceService $interfaceService
81-
* @param ConfigService $configService
82-
*/
8353
public function __construct(
84-
RemoteRequest $remoteRequest,
85-
GlobalScaleService $globalScaleService,
86-
RemoteStreamService $remoteStreamService,
87-
InterfaceService $interfaceService,
88-
ConfigService $configService,
54+
private readonly RemoteRequest $remoteRequest,
55+
private GlobalScaleService $globalScaleService,
56+
private RemoteStreamService $remoteStreamService,
57+
private InterfaceService $interfaceService,
58+
private RemoteSyncService $remoteSyncService,
8959
) {
9060
parent::__construct();
91-
92-
$this->remoteRequest = $remoteRequest;
93-
$this->globalScaleService = $globalScaleService;
94-
$this->remoteStreamService = $remoteStreamService;
95-
$this->interfaceService = $interfaceService;
96-
$this->configService = $configService;
97-
9861
$this->setup('app', 'circles');
9962
}
10063

@@ -401,16 +364,12 @@ private function outgoingTest(string $remote, array $payload): NCSignedRequest {
401364
return $signedRequest;
402365
}
403366

404-
405-
/**
406-
*
407-
*/
408367
private function checkKnownInstance(): void {
409368
$this->verifyGSInstances();
369+
$this->remoteSyncService->syncTrustedServers();
410370
$this->checkRemoteInstances();
411371
}
412372

413-
414373
/**
415374
*
416375
*/
@@ -424,35 +383,11 @@ function (RemoteInstance $instance): string {
424383

425384
$missing = array_diff($instances, $known);
426385
foreach ($missing as $instance) {
427-
$this->syncGSInstance($instance);
386+
$this->remoteSyncService->syncRemoteInstance($instance, RemoteInstance::TYPE_GLOBALSCALE, InterfaceService::IFACE_INTERNAL);
428387
}
429388
}
430389

431390

432-
/**
433-
* @param string $instance
434-
*/
435-
private function syncGSInstance(string $instance): void {
436-
$this->output->write('Adding <comment>' . $instance . '</comment>: ');
437-
if ($this->configService->isLocalInstance($instance)) {
438-
$this->output->writeln('<comment>instance is local</comment>');
439-
return;
440-
}
441-
442-
try {
443-
$this->remoteStreamService->addRemoteInstance(
444-
$instance,
445-
RemoteInstance::TYPE_GLOBALSCALE,
446-
InterfaceService::IFACE_INTERNAL,
447-
true
448-
);
449-
$this->output->writeln('<info>ok</info>');
450-
} catch (Exception $e) {
451-
$msg = ($e->getMessage() === '') ? '' : ' (' . $e->getMessage() . ')';
452-
$this->output->writeln('<error>' . get_class($e) . $msg . '</error>');
453-
}
454-
}
455-
456391

457392
private function checkRemoteInstances(): void {
458393
$instances = $this->remoteRequest->getAllInstances();

lib/Service/ConfigService.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use OC;
1515
use OCA\Circles\AppInfo\Application;
16+
use OCA\Circles\ConfigLexicon;
1617
use OCA\Circles\Exceptions\GSStatusException;
1718
use OCA\Circles\IFederatedUser;
1819
use OCA\Circles\Model\Circle;
@@ -771,4 +772,9 @@ public function confirmAllowedCircleTypes(Circle $circle): void {
771772
$config &= ~$this->getAppValueInt(ConfigService::CIRCLE_TYPES_BLOCK);
772773
$circle->setConfig($config);
773774
}
775+
776+
public function isFederatedTeamsEnabled(): bool {
777+
return $this->appConfig->getAppValueBool(ConfigLexicon::FEDERATED_TEAMS_ENABLED) &&
778+
$this->appConfig->hasAppKey(ConfigLexicon::FEDERATED_TEAMS_FRONTAL, true);
779+
}
774780
}

lib/Service/MaintenanceService.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ public function __construct(
6868
private EventWrapperService $eventWrapperService,
6969
private CircleService $circleService,
7070
private ConfigService $configService,
71+
private RemoteSyncService $remoteSyncService,
7172
private LoggerInterface $logger,
7273
) {
7374
}
@@ -160,6 +161,12 @@ private function runMaintenance2(bool $forceRefresh = false): void {
160161
$this->eventWrapperService->retry(EventWrapperService::RETRY_ASAP);
161162
} catch (Exception $e) {
162163
}
164+
165+
try {
166+
$this->output('Sync unknown trusted server');
167+
$this->remoteSyncService->syncTrustedServers();
168+
} catch (Exception $e) {
169+
}
163170
}
164171

165172

lib/Service/RemoteSyncService.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
namespace OCA\Circles\Service;
10+
11+
use Exception;
12+
use OCA\Circles\Db\RemoteRequest;
13+
use OCA\Circles\Model\Federated\RemoteInstance;
14+
use Psr\Log\LoggerInterface;
15+
16+
class RemoteSyncService {
17+
18+
public function __construct(
19+
private ConfigService $configService,
20+
private RemoteRequest $remoteRequest,
21+
private TrustedServerService $trustedServerService,
22+
private RemoteStreamService $remoteStreamService,
23+
private LoggerInterface $logger,
24+
) {
25+
}
26+
27+
public function syncTrustedServers(): void {
28+
if (!$this->configService->isFederatedTeamsEnabled()) {
29+
return;
30+
}
31+
32+
$known = array_map(
33+
static function (RemoteInstance $instance): string {
34+
return $instance->getInstance();
35+
}, $this->remoteRequest->getFromType(RemoteInstance::TYPE_EXTERNAL)
36+
);
37+
38+
foreach ($this->trustedServerService->getTrustedServers() as $trusted) {
39+
if (in_array($trusted['address'], $known, true)) {
40+
continue;
41+
}
42+
43+
$this->syncRemoteInstance(
44+
$trusted['address'],
45+
RemoteInstance::TYPE_EXTERNAL,
46+
InterfaceService::IFACE_FRONTAL
47+
);
48+
}
49+
}
50+
51+
public function syncRemoteInstance(string $instance, string $type, int $iface): bool {
52+
if ($this->configService->isLocalInstance($instance)) {
53+
return false;
54+
}
55+
56+
try {
57+
$this->remoteStreamService->addRemoteInstance(
58+
$instance,
59+
$type,
60+
$iface,
61+
true
62+
);
63+
} catch (Exception $e) {
64+
$this->logger->warning('Could not sync remote instance ' . $instance, ['instance' => $instance, 'type' => $type, 'iface' => $iface, 'exception' => $e]);
65+
return false;
66+
}
67+
68+
return true;
69+
}
70+
71+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
namespace OCA\Circles\Service;
10+
11+
use OCA\Federation\TrustedServers;
12+
use Psr\Log\LoggerInterface;
13+
14+
/**
15+
* @psalm-suppress UndefinedClass
16+
*/
17+
class TrustedServerService {
18+
public function __construct(
19+
private readonly TrustedServers $trustedServers,
20+
private readonly LoggerInterface $logger,
21+
) {
22+
}
23+
24+
/**
25+
* @return list<array{id: int, url: string, url_hash: string, shared_secret: ?string, status: int, sync_token: ?string, address: string}>
26+
*/
27+
public function getTrustedServers(): array {
28+
$trustedServers = [];
29+
try {
30+
foreach ($this->trustedServers->getServers() as $server) {
31+
if (($server['status'] ?? 0) === TrustedServers::STATUS_OK &&
32+
str_starts_with($server['url'], 'https://')) {
33+
$server['address'] = substr($server['url'], 8);
34+
$trustedServers[] = $server;
35+
}
36+
}
37+
} catch (\Exception $e) {
38+
$this->logger->warning('Could not get trusted servers', ['exception' => $e]);
39+
}
40+
41+
return $trustedServers;
42+
}
43+
}

0 commit comments

Comments
 (0)