diff --git a/apps/lookup_server_connector/lib/BackgroundJobs/RetryJob.php b/apps/lookup_server_connector/lib/BackgroundJobs/RetryJob.php index 233eb119713e5..42ffcdbe72395 100644 --- a/apps/lookup_server_connector/lib/BackgroundJobs/RetryJob.php +++ b/apps/lookup_server_connector/lib/BackgroundJobs/RetryJob.php @@ -14,6 +14,7 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; use OCP\BackgroundJob\Job; +use OCP\GlobalScale\IConfig as GlobalScaleConfig; use OCP\Http\Client\IClientService; use OCP\IConfig; use OCP\IUser; @@ -39,6 +40,7 @@ public function __construct( private IUserManager $userManager, private IAccountManager $accountManager, private Signer $signer, + private GlobalScaleConfig $globalScaleConfig, ) { parent::__construct($time); @@ -86,7 +88,7 @@ public function start(IJobList $jobList): void { protected function shouldRemoveBackgroundJob(): bool { // TODO: Remove global scale condition once lookup server is used for non-global scale federation // return $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'no') !== 'yes' - return !$this->config->getSystemValueBool('gs.enabled', false) + return !$this->globalScaleConfig->isGlobalScaleEnabled() || $this->config->getSystemValueBool('has_internet_connection', true) === false || $this->config->getSystemValueString('lookup_server', 'https://lookup.nextcloud.com') === '' || $this->retries >= 5; diff --git a/apps/lookup_server_connector/lib/UpdateLookupServer.php b/apps/lookup_server_connector/lib/UpdateLookupServer.php index 5d2d630fe61b4..09649403b0fd4 100644 --- a/apps/lookup_server_connector/lib/UpdateLookupServer.php +++ b/apps/lookup_server_connector/lib/UpdateLookupServer.php @@ -11,6 +11,8 @@ use OCA\LookupServerConnector\BackgroundJobs\RetryJob; use OCP\BackgroundJob\IJobList; +use OCP\Config\IUserConfig; +use OCP\GlobalScale\IConfig as GlobalScaleConfig; use OCP\IConfig; use OCP\IUser; @@ -20,26 +22,21 @@ * @package OCA\LookupServerConnector */ class UpdateLookupServer { - /** - * @param IJobList $jobList - * @param IConfig $config - */ public function __construct( - private IJobList $jobList, - private IConfig $config, + private readonly IJobList $jobList, + private readonly IConfig $config, + private readonly IUserConfig $userConfig, + private readonly GlobalScaleConfig $globalScaleConfig, ) { } - /** - * @param IUser $user - */ public function userUpdated(IUser $user): void { if (!$this->shouldUpdateLookupServer()) { return; } // Reset retry counter - $this->config->deleteUserValue( + $this->userConfig->deleteUserConfig( $user->getUID(), 'lookup_server_connector', 'update_retries' @@ -48,17 +45,15 @@ public function userUpdated(IUser $user): void { } /** - * check if we should update the lookup server, we only do it if + * Check if we should update the lookup server, we only do it if * * + we have an internet connection * + the lookup server update was not disabled by the admin * + we have a valid lookup server URL - * - * @return bool */ private function shouldUpdateLookupServer(): bool { // TODO: Consider reenable for non-global-scale setups by checking "'files_sharing', 'lookupServerUploadEnabled'" instead of "gs.enabled" - return $this->config->getSystemValueBool('gs.enabled', false) + return $this->globalScaleConfig->isGlobalScaleEnabled() && $this->config->getSystemValueBool('has_internet_connection', true) && $this->config->getSystemValueString('lookup_server', 'https://lookup.nextcloud.com') !== ''; } diff --git a/apps/settings/lib/BackgroundJobs/VerifyUserData.php b/apps/settings/lib/BackgroundJobs/VerifyUserData.php index 4bef610f26654..6a5e3e0c78c1c 100644 --- a/apps/settings/lib/BackgroundJobs/VerifyUserData.php +++ b/apps/settings/lib/BackgroundJobs/VerifyUserData.php @@ -15,6 +15,7 @@ use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; use OCP\BackgroundJob\Job; +use OCP\GlobalScale\IConfig as GlobalScaleConfig; use OCP\Http\Client\IClientService; use OCP\IConfig; use OCP\IUserManager; @@ -38,6 +39,7 @@ public function __construct( private LoggerInterface $logger, ITimeFactory $timeFactory, private IConfig $config, + private GlobalScaleConfig $globalScaleConfig, ) { parent::__construct($timeFactory); @@ -124,7 +126,7 @@ protected function verifyWebsite(array $argument) { protected function verifyViaLookupServer(array $argument, string $dataType): bool { // TODO: Consider to enable for non-global-scale setups by checking 'files_sharing', 'lookupServerUploadEnabled' - if (!$this->config->getSystemValueBool('gs.enabled', false) + if (!$this->globalScaleConfig->isGlobalScaleEnabled() || empty($this->lookupServerUrl) || $this->config->getSystemValue('has_internet_connection', true) === false ) { diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index 7e59e0d212c8e..b5094396bba21 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -2209,11 +2209,6 @@ - - - - - diff --git a/lib/private/Collaboration/Collaborators/LookupPlugin.php b/lib/private/Collaboration/Collaborators/LookupPlugin.php index 9c48670daaaa4..d05f939797cef 100644 --- a/lib/private/Collaboration/Collaborators/LookupPlugin.php +++ b/lib/private/Collaboration/Collaborators/LookupPlugin.php @@ -12,6 +12,7 @@ use OCP\Collaboration\Collaborators\ISearchResult; use OCP\Collaboration\Collaborators\SearchResultType; use OCP\Federation\ICloudIdManager; +use OCP\GlobalScale\IConfig as GlobalScaleConfig; use OCP\Http\Client\IClientService; use OCP\IConfig; use OCP\IUserSession; @@ -23,12 +24,13 @@ class LookupPlugin implements ISearchPlugin { private string $currentUserRemote; public function __construct( - private IConfig $config, - private IClientService $clientService, + private readonly IConfig $config, + private readonly IClientService $clientService, IUserSession $userSession, - private ICloudIdManager $cloudIdManager, - private LoggerInterface $logger, - private ?TrustedServers $trustedServers, + private readonly ICloudIdManager $cloudIdManager, + private readonly LoggerInterface $logger, + private readonly ?TrustedServers $trustedServers, + private readonly GlobalScaleConfig $globalScaleConfig, ) { $currentUserCloudId = $userSession->getUser()->getCloudId(); $this->currentUserRemote = $cloudIdManager->resolveCloudId($currentUserCloudId)->getRemote(); @@ -36,7 +38,7 @@ public function __construct( #[\Override] public function search($search, $limit, $offset, ISearchResult $searchResult): bool { - $isGlobalScaleEnabled = $this->config->getSystemValueBool('gs.enabled', false); + $isGlobalScaleEnabled = $this->globalScaleConfig->isGlobalScaleEnabled(); $isLookupServerEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no') === 'yes'; $hasInternetConnection = $this->config->getSystemValueBool('has_internet_connection', true); diff --git a/lib/private/GlobalScale/Config.php b/lib/private/GlobalScale/Config.php index a2cc1429c9538..be35487f3c314 100644 --- a/lib/private/GlobalScale/Config.php +++ b/lib/private/GlobalScale/Config.php @@ -35,4 +35,24 @@ public function onlyInternalFederation(): bool { return $enabled === 'internal'; } + + #[Override] + public function isPrimary(): bool { + return $this->isGlobalScaleEnabled() + && ($this->config->getSystemValueString('gss.mode', 'slave') === 'master' + || $this->config->getSystemValueString('gss.mode', 'slave') === 'primary'); + } + + #[Override] + public function isSecondary(): bool { + return $this->isGlobalScaleEnabled() + && ($this->config->getSystemValueString('gss.mode', 'slave') === 'slave' + || $this->config->getSystemValueString('gss.mode', 'slave') === 'secondary'); + } + + #[Override] + public function isPrimaryAdmin(string $userId): bool { + return in_array($userId, $this->config->getSystemValue('gss.master.admin', [])) + || in_array($userId, $this->config->getSystemValue('gss.primary.admin', [])); + } } diff --git a/lib/public/GlobalScale/IConfig.php b/lib/public/GlobalScale/IConfig.php index 1936e7912dcde..bd71adbed0c20 100644 --- a/lib/public/GlobalScale/IConfig.php +++ b/lib/public/GlobalScale/IConfig.php @@ -31,4 +31,33 @@ public function isGlobalScaleEnabled(): bool; * @since 12.0.1 */ public function onlyInternalFederation(): bool; + + /** + * Check if the current instance is the primary instance. + * + * This instance is then only used to log in the users and then redirect them + * to their associated secondary instance. + * + * @since 34.0.3 + */ + public function isPrimary(): bool; + + /** + * Check if the current instance is one of the secondary instance. + * + * These instances are the actual instance of a user and hold all their data. + * + * @since 34.0.3 + */ + public function isSecondary(): bool; + + /** + * Check if the given user is one of the admin on the primary instance. + * + * These users won't be redirected to a secondary instance and instead will + * stay on the primary instance to manage the configuration of the instance. + * + * @since 34.0.3 + */ + public function isPrimaryAdmin(string $userId): bool; } diff --git a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php index 7f70c3ba3d734..b919eff2855d0 100644 --- a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php @@ -1,5 +1,7 @@ userSession = $this->createMock(IUserSession::class); $this->cloudIdManager = $this->createMock(ICloudIdManager::class); $this->config = $this->createMock(IConfig::class); + $this->globalScaleConfig = $this->createMock(GlobalScaleConfig::class); $this->logger = $this->createMock(LoggerInterface::class); $this->clientService = $this->createMock(IClientService::class); $cloudId = $this->createMock(ICloudId::class); @@ -71,7 +70,8 @@ protected function setUp(): void { $this->userSession, $this->cloudIdManager, $this->logger, - null + null, + $this->globalScaleConfig, ); } @@ -80,13 +80,16 @@ public function testSearchNoLookupServerURI(): void { ->method('getAppValue') ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn('yes'); - $this->config->expects($this->exactly(2)) + $this->config->expects($this->once()) ->method('getSystemValueBool') ->willReturnMap([ - ['gs.enabled', false, true], ['has_internet_connection', true, true], ]); + $this->globalScaleConfig->expects($this->once()) + ->method('isGlobalScaleEnabled') + ->willReturn(true); + $this->config->expects($this->once()) ->method('getSystemValueString') ->with('lookup_server', 'https://lookup.nextcloud.com') @@ -106,13 +109,16 @@ public function testSearchNoInternet(): void { ->method('getAppValue') ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn('yes'); - $this->config->expects($this->exactly(2)) + $this->config->expects($this->exactly(1)) ->method('getSystemValueBool') ->willReturnMap([ - ['gs.enabled', false, false], ['has_internet_connection', true, false], ]); + $this->globalScaleConfig->expects($this->exactly(1)) + ->method('isGlobalScaleEnabled') + ->willReturn(false); + $this->clientService->expects($this->never()) ->method('newClient'); @@ -139,13 +145,16 @@ public function testSearch(array $searchParams): void { ->method('getAppValue') ->with('files_sharing', 'lookupServerEnabled', 'no') ->willReturn('yes'); - $this->config->expects($this->exactly(2)) + $this->config->expects($this->once()) ->method('getSystemValueBool') ->willReturnMap([ - ['gs.enabled', false, true], ['has_internet_connection', true, true], ]); + $this->globalScaleConfig->expects($this->once()) + ->method('isGlobalScaleEnabled') + ->willReturn(true); + $this->config->expects($this->once()) ->method('getSystemValueString') ->with('lookup_server', 'https://lookup.nextcloud.com') @@ -200,12 +209,15 @@ public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnab ->method('addResultSet') ->with($type, $searchParams['expectedResult'], []); - $this->config->expects($this->exactly(2)) + $this->config->expects($this->once()) ->method('getSystemValueBool') ->willReturnMap([ - ['gs.enabled', false, $GSEnabled], ['has_internet_connection', true, true], ]); + + $this->globalScaleConfig->expects($this->once()) + ->method('isGlobalScaleEnabled') + ->willReturn($GSEnabled); $this->config->expects($this->once()) ->method('getSystemValueString') ->with('lookup_server', 'https://lookup.nextcloud.com') @@ -230,12 +242,15 @@ public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnab ->willReturn($client); } else { $searchResult->expects($this->never())->method('addResultSet'); - $this->config->expects($this->exactly(2)) + $this->config->expects($this->once()) ->method('getSystemValueBool') ->willReturnMap([ - ['gs.enabled', false, $GSEnabled], ['has_internet_connection', true, true], ]); + + $this->globalScaleConfig->expects($this->once()) + ->method('isGlobalScaleEnabled') + ->willReturn($GSEnabled); } $moreResults = $this->plugin->search( $searchParams['search'], @@ -248,13 +263,16 @@ public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnab } public function testSearchGSDisabled(): void { - $this->config->expects($this->atLeastOnce()) + $this->config->expects($this->once()) ->method('getSystemValueBool') ->willReturnMap([ ['has_internet_connection', true, true], - ['gs.enabled', false, false], ]); + $this->globalScaleConfig->expects($this->once()) + ->method('isGlobalScaleEnabled') + ->willReturn(false); + /** @var ISearchResult|MockObject $searchResult */ $searchResult = $this->createMock(ISearchResult::class); $searchResult->expects($this->never())