summaryrefslogtreecommitdiffstats
path: root/lib/private/Federation/CloudIdManager.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Federation/CloudIdManager.php')
-rw-r--r--lib/private/Federation/CloudIdManager.php79
1 files changed, 73 insertions, 6 deletions
diff --git a/lib/private/Federation/CloudIdManager.php b/lib/private/Federation/CloudIdManager.php
index 77bb9437ba2..e4e42cb1293 100644
--- a/lib/private/Federation/CloudIdManager.php
+++ b/lib/private/Federation/CloudIdManager.php
@@ -30,11 +30,17 @@ declare(strict_types=1);
*/
namespace OC\Federation;
+use OCA\DAV\Events\CardUpdatedEvent;
use OCP\Contacts\IManager;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\ICloudId;
use OCP\Federation\ICloudIdManager;
+use OCP\ICache;
+use OCP\ICacheFactory;
use OCP\IURLGenerator;
use OCP\IUserManager;
+use OCP\User\Events\UserChangedEvent;
class CloudIdManager implements ICloudIdManager {
/** @var IManager */
@@ -43,11 +49,48 @@ class CloudIdManager implements ICloudIdManager {
private $urlGenerator;
/** @var IUserManager */
private $userManager;
-
- public function __construct(IManager $contactsManager, IURLGenerator $urlGenerator, IUserManager $userManager) {
+ private ICache $memCache;
+ /** @var array[] */
+ private array $cache = [];
+
+ public function __construct(
+ IManager $contactsManager,
+ IURLGenerator $urlGenerator,
+ IUserManager $userManager,
+ ICacheFactory $cacheFactory,
+ IEventDispatcher $eventDispatcher
+ ) {
$this->contactsManager = $contactsManager;
$this->urlGenerator = $urlGenerator;
$this->userManager = $userManager;
+ $this->memCache = $cacheFactory->createDistributed('cloud_id_');
+ $eventDispatcher->addListener(UserChangedEvent::class, [$this, 'handleUserEvent']);
+ $eventDispatcher->addListener(CardUpdatedEvent::class, [$this, 'handleCardEvent']);
+ }
+
+ public function handleUserEvent(Event $event): void {
+ if ($event instanceof UserChangedEvent && $event->getFeature() === 'displayName') {
+ $userId = $event->getUser()->getUID();
+ $key = $userId . '@local';
+ unset($this->cache[$key]);
+ $this->memCache->remove($key);
+ }
+ }
+
+ public function handleCardEvent(Event $event): void {
+ if ($event instanceof CardUpdatedEvent) {
+ $data = $event->getCardData()['carddata'];
+ foreach (explode("\r\n", $data) as $line) {
+ if (strpos($line, "CLOUD;") === 0) {
+ $parts = explode(':', $line, 2);
+ if (isset($parts[1])) {
+ $key = $parts[1];
+ unset($this->cache[$key]);
+ $this->memCache->remove($key);
+ }
+ }
+ }
+ }
}
/**
@@ -120,18 +163,42 @@ class CloudIdManager implements ICloudIdManager {
* @return CloudId
*/
public function getCloudId(string $user, ?string $remote): ICloudId {
- if ($remote === null) {
+ $isLocal = $remote === null;
+ if ($isLocal) {
$remote = rtrim($this->removeProtocolFromUrl($this->urlGenerator->getAbsoluteURL('/')), '/');
$fixedRemote = $this->fixRemoteURL($remote);
- $localUser = $this->userManager->get($user);
- $displayName = !is_null($localUser) ? $localUser->getDisplayName() : '';
+ $host = $fixedRemote;
} else {
- // TODO check what the correct url is for remote (asking the remote)
+ // note that for remote id's we don't strip the protocol for the remote we use to construct the CloudId
+ // this way if a user has an explicit non-https cloud id this will be preserved
+ // we do still use the version without protocol for looking up the display name
$fixedRemote = $this->fixRemoteURL($remote);
$host = $this->removeProtocolFromUrl($fixedRemote);
+ }
+
+ $key = $user . '@' . ($isLocal ? 'local' : $host);
+ $cached = $this->cache[$key] ?? $this->memCache->get($key);
+ if ($cached) {
+ $this->cache[$key] = $cached; // put items from memcache into local cache
+ return new CloudId($cached['id'], $cached['user'], $cached['remote'], $cached['displayName']);
+ }
+
+ if ($isLocal) {
+ $localUser = $this->userManager->get($user);
+ $displayName = $localUser ? $localUser->getDisplayName() : '';
+ } else {
$displayName = $this->getDisplayNameFromContact($user . '@' . $host);
}
$id = $user . '@' . $remote;
+
+ $data = [
+ 'id' => $id,
+ 'user' => $user,
+ 'remote' => $fixedRemote,
+ 'displayName' => $displayName,
+ ];
+ $this->cache[$key] = $data;
+ $this->memCache->set($key, $data, 15 * 60);
return new CloudId($id, $user, $fixedRemote, $displayName);
}