mirror of
https://github.com/nextcloud/server.git
synced 2026-04-15 22:11:17 -04:00
Merge pull request #54026 from nextcloud/enh/add-cloud-id-chars
feat: add ICloudIdResolver
This commit is contained in:
commit
4eda352397
14 changed files with 120 additions and 32 deletions
|
|
@ -34,11 +34,11 @@ class AddressHandlerTest extends \Test\TestCase {
|
|||
$this->contactsManager = $this->createMock(IManager::class);
|
||||
|
||||
$this->cloudIdManager = new CloudIdManager(
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class),
|
||||
$this->contactsManager,
|
||||
$this->urlGenerator,
|
||||
$this->createMock(IUserManager::class),
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class)
|
||||
);
|
||||
|
||||
$this->addressHandler = new AddressHandler($this->urlGenerator, $this->il10n, $this->cloudIdManager);
|
||||
|
|
|
|||
|
|
@ -64,11 +64,11 @@ class MountPublicLinkControllerTest extends \Test\TestCase {
|
|||
$this->clientService = $this->createMock(IClientService::class);
|
||||
$this->contactsManager = $this->createMock(IContactsManager::class);
|
||||
$this->cloudIdManager = new CloudIdManager(
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class),
|
||||
$this->contactsManager,
|
||||
$this->createMock(IURLGenerator::class),
|
||||
$this->userManager,
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class)
|
||||
);
|
||||
|
||||
$this->controller = new MountPublicLinkController(
|
||||
|
|
|
|||
|
|
@ -74,11 +74,11 @@ class FederatedShareProviderTest extends \Test\TestCase {
|
|||
$this->addressHandler = $this->createMock(AddressHandler::class);
|
||||
$this->contactsManager = $this->createMock(IContactsManager::class);
|
||||
$this->cloudIdManager = new CloudIdManager(
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class),
|
||||
$this->contactsManager,
|
||||
$this->createMock(IURLGenerator::class),
|
||||
$this->userManager,
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class)
|
||||
);
|
||||
$this->gsConfig = $this->createMock(\OCP\GlobalScale\IConfig::class);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@ class CacheTest extends TestCase {
|
|||
$this->contactsManager = $this->createMock(IManager::class);
|
||||
|
||||
$this->cloudIdManager = new CloudIdManager(
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class),
|
||||
$this->contactsManager,
|
||||
$this->createMock(IURLGenerator::class),
|
||||
$this->createMock(IUserManager::class),
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class)
|
||||
);
|
||||
$this->remoteUser = $this->getUniqueID('remoteuser');
|
||||
|
||||
|
|
|
|||
|
|
@ -90,11 +90,11 @@ class ManagerTest extends TestCase {
|
|||
$this->testMountProvider = new MountProvider(Server::get(IDBConnection::class), function () {
|
||||
return $this->manager;
|
||||
}, new CloudIdManager(
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class),
|
||||
$this->contactsManager,
|
||||
$this->createMock(IURLGenerator::class),
|
||||
$this->userManager,
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class)
|
||||
));
|
||||
|
||||
$group1 = $this->createMock(IGroup::class);
|
||||
|
|
|
|||
|
|
@ -376,6 +376,7 @@ return array(
|
|||
'OCP\\Federation\\ICloudFederationShare' => $baseDir . '/lib/public/Federation/ICloudFederationShare.php',
|
||||
'OCP\\Federation\\ICloudId' => $baseDir . '/lib/public/Federation/ICloudId.php',
|
||||
'OCP\\Federation\\ICloudIdManager' => $baseDir . '/lib/public/Federation/ICloudIdManager.php',
|
||||
'OCP\\Federation\\ICloudIdResolver' => $baseDir . '/lib/public/Federation/ICloudIdResolver.php',
|
||||
'OCP\\Files' => $baseDir . '/lib/public/Files.php',
|
||||
'OCP\\FilesMetadata\\AMetadataEvent' => $baseDir . '/lib/public/FilesMetadata/AMetadataEvent.php',
|
||||
'OCP\\FilesMetadata\\Event\\MetadataBackgroundEvent' => $baseDir . '/lib/public/FilesMetadata/Event/MetadataBackgroundEvent.php',
|
||||
|
|
|
|||
|
|
@ -417,6 +417,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\Federation\\ICloudFederationShare' => __DIR__ . '/../../..' . '/lib/public/Federation/ICloudFederationShare.php',
|
||||
'OCP\\Federation\\ICloudId' => __DIR__ . '/../../..' . '/lib/public/Federation/ICloudId.php',
|
||||
'OCP\\Federation\\ICloudIdManager' => __DIR__ . '/../../..' . '/lib/public/Federation/ICloudIdManager.php',
|
||||
'OCP\\Federation\\ICloudIdResolver' => __DIR__ . '/../../..' . '/lib/public/Federation/ICloudIdResolver.php',
|
||||
'OCP\\Files' => __DIR__ . '/../../..' . '/lib/public/Files.php',
|
||||
'OCP\\FilesMetadata\\AMetadataEvent' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/AMetadataEvent.php',
|
||||
'OCP\\FilesMetadata\\Event\\MetadataBackgroundEvent' => __DIR__ . '/../../..' . '/lib/public/FilesMetadata/Event/MetadataBackgroundEvent.php',
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use OCP\EventDispatcher\Event;
|
|||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Federation\ICloudId;
|
||||
use OCP\Federation\ICloudIdManager;
|
||||
use OCP\Federation\ICloudIdResolver;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IURLGenerator;
|
||||
|
|
@ -21,27 +22,19 @@ use OCP\IUserManager;
|
|||
use OCP\User\Events\UserChangedEvent;
|
||||
|
||||
class CloudIdManager implements ICloudIdManager {
|
||||
/** @var IManager */
|
||||
private $contactsManager;
|
||||
/** @var IURLGenerator */
|
||||
private $urlGenerator;
|
||||
/** @var IUserManager */
|
||||
private $userManager;
|
||||
private ICache $memCache;
|
||||
private ICache $displayNameCache;
|
||||
/** @var array[] */
|
||||
private array $cache = [];
|
||||
/** @var ICloudIdResolver[] */
|
||||
private array $cloudIdResolvers = [];
|
||||
|
||||
public function __construct(
|
||||
IManager $contactsManager,
|
||||
IURLGenerator $urlGenerator,
|
||||
IUserManager $userManager,
|
||||
ICacheFactory $cacheFactory,
|
||||
IEventDispatcher $eventDispatcher,
|
||||
private IManager $contactsManager,
|
||||
private IURLGenerator $urlGenerator,
|
||||
private IUserManager $userManager,
|
||||
) {
|
||||
$this->contactsManager = $contactsManager;
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
$this->userManager = $userManager;
|
||||
$this->memCache = $cacheFactory->createDistributed('cloud_id_');
|
||||
$this->displayNameCache = $cacheFactory->createDistributed('cloudid_name_');
|
||||
$eventDispatcher->addListener(UserChangedEvent::class, [$this, 'handleUserEvent']);
|
||||
|
|
@ -81,6 +74,12 @@ class CloudIdManager implements ICloudIdManager {
|
|||
public function resolveCloudId(string $cloudId): ICloudId {
|
||||
// TODO magic here to get the url and user instead of just splitting on @
|
||||
|
||||
foreach ($this->cloudIdResolvers as $resolver) {
|
||||
if ($resolver->isValidCloudId($cloudId)) {
|
||||
return $resolver->resolveCloudId($cloudId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->isValidCloudId($cloudId)) {
|
||||
throw new \InvalidArgumentException('Invalid cloud id');
|
||||
}
|
||||
|
|
@ -251,6 +250,26 @@ class CloudIdManager implements ICloudIdManager {
|
|||
* @return bool
|
||||
*/
|
||||
public function isValidCloudId(string $cloudId): bool {
|
||||
return str_contains($cloudId, '@');
|
||||
foreach ($this->cloudIdResolvers as $resolver) {
|
||||
if ($resolver->isValidCloudId($cloudId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return strpos($cloudId, '@') !== false;
|
||||
}
|
||||
|
||||
public function createCloudId(string $id, string $user, string $remote, ?string $displayName = null): ICloudId {
|
||||
return new CloudId($id, $user, $remote, $displayName);
|
||||
}
|
||||
|
||||
public function registerCloudIdResolver(ICloudIdResolver $resolver): void {
|
||||
array_unshift($this->cloudIdResolvers, $resolver);
|
||||
}
|
||||
|
||||
public function unregisterCloudIdResolver(ICloudIdResolver $resolver): void {
|
||||
if (($key = array_search($resolver, $this->cloudIdResolvers)) !== false) {
|
||||
array_splice($this->cloudIdResolvers, $key, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1160,11 +1160,11 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
|
||||
$this->registerService(ICloudIdManager::class, function (ContainerInterface $c) {
|
||||
return new CloudIdManager(
|
||||
$c->get(ICacheFactory::class),
|
||||
$c->get(IEventDispatcher::class),
|
||||
$c->get(\OCP\Contacts\IManager::class),
|
||||
$c->get(IURLGenerator::class),
|
||||
$c->get(IUserManager::class),
|
||||
$c->get(ICacheFactory::class),
|
||||
$c->get(IEventDispatcher::class),
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,14 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCP\Federation;
|
||||
|
||||
use OCP\AppFramework\Attribute\Consumable;
|
||||
|
||||
/**
|
||||
* Interface for resolving federated cloud ids
|
||||
*
|
||||
* @since 12.0.0
|
||||
*/
|
||||
#[Consumable(since: '12.0.0')]
|
||||
interface ICloudIdManager {
|
||||
/**
|
||||
* @param string $cloudId
|
||||
|
|
@ -55,4 +58,28 @@ interface ICloudIdManager {
|
|||
* @since 30.0.0 - Optional parameter $httpsOnly was added
|
||||
*/
|
||||
public function removeProtocolFromUrl(string $url, bool $httpsOnly = false): string;
|
||||
|
||||
/**
|
||||
* @param string $id The remote cloud id
|
||||
* @param string $user The user id on the remote server
|
||||
* @param string $remote The base address of the remote server
|
||||
* @param ?string $displayName The displayname of the remote user
|
||||
*
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function createCloudId(string $id, string $user, string $remote, ?string $displayName = null): ICloudId;
|
||||
|
||||
/**
|
||||
* @param $resolver The cloud id resolver to register
|
||||
*
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function registerCloudIdResolver(ICloudIdResolver $resolver): void;
|
||||
|
||||
/**
|
||||
* @param $resolver The cloud id resolver to unregister
|
||||
*
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function unregisterCloudIdResolver(ICloudIdResolver $resolver): void;
|
||||
}
|
||||
|
|
|
|||
40
lib/public/Federation/ICloudIdResolver.php
Normal file
40
lib/public/Federation/ICloudIdResolver.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
namespace OCP\Federation;
|
||||
|
||||
use OCP\AppFramework\Attribute\Consumable;
|
||||
use OCP\AppFramework\Attribute\Implementable;
|
||||
|
||||
/**
|
||||
* Interface for resolving federated cloud ids
|
||||
*
|
||||
* @since 32.0.0
|
||||
*/
|
||||
#[Consumable(since: '32.0.0')]
|
||||
#[Implementable(since: '32.0.0')]
|
||||
interface ICloudIdResolver {
|
||||
/**
|
||||
* @param string $cloudId
|
||||
* @return ICloudId
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function resolveCloudId(string $cloudId): ICloudId;
|
||||
|
||||
/**
|
||||
* Check if the input is a correctly formatted cloud id
|
||||
*
|
||||
* @param string $cloudId
|
||||
* @return bool
|
||||
*
|
||||
* @since 32.0.0
|
||||
*/
|
||||
public function isValidCloudId(string $cloudId): bool;
|
||||
}
|
||||
|
|
@ -64,11 +64,11 @@ class MailPluginTest extends TestCase {
|
|||
$this->userSession = $this->createMock(IUserSession::class);
|
||||
$this->mailer = $this->createMock(IMailer::class);
|
||||
$this->cloudIdManager = new CloudIdManager(
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class),
|
||||
$this->contactsManager,
|
||||
$this->createMock(IURLGenerator::class),
|
||||
$this->createMock(IUserManager::class),
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class)
|
||||
);
|
||||
|
||||
$this->searchResult = new SearchResult();
|
||||
|
|
|
|||
|
|
@ -49,11 +49,11 @@ class RemotePluginTest extends TestCase {
|
|||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->contactsManager = $this->createMock(IManager::class);
|
||||
$this->cloudIdManager = new CloudIdManager(
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class),
|
||||
$this->contactsManager,
|
||||
$this->createMock(IURLGenerator::class),
|
||||
$this->createMock(IUserManager::class),
|
||||
$this->createMock(ICacheFactory::class),
|
||||
$this->createMock(IEventDispatcher::class)
|
||||
);
|
||||
$this->searchResult = new SearchResult();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@ class CloudIdManagerTest extends TestCase {
|
|||
->willReturn(new ArrayCache(''));
|
||||
|
||||
$this->cloudIdManager = new CloudIdManager(
|
||||
$this->cacheFactory,
|
||||
$this->createMock(IEventDispatcher::class),
|
||||
$this->contactsManager,
|
||||
$this->urlGenerator,
|
||||
$this->userManager,
|
||||
$this->cacheFactory,
|
||||
$this->createMock(IEventDispatcher::class)
|
||||
);
|
||||
$this->overwriteService(ICloudIdManager::class, $this->cloudIdManager);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue