aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Collaboration/Reference/ReferenceManager.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Collaboration/Reference/ReferenceManager.php')
-rw-r--r--lib/private/Collaboration/Reference/ReferenceManager.php71
1 files changed, 39 insertions, 32 deletions
diff --git a/lib/private/Collaboration/Reference/ReferenceManager.php b/lib/private/Collaboration/Reference/ReferenceManager.php
index 1db87a56494..9287b66b2a2 100644
--- a/lib/private/Collaboration/Reference/ReferenceManager.php
+++ b/lib/private/Collaboration/Reference/ReferenceManager.php
@@ -2,24 +2,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
- *
- * @author Julius Härtl <jus@bitgrid.net>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\Collaboration\Reference;
@@ -27,6 +11,7 @@ namespace OC\Collaboration\Reference;
use OC\AppFramework\Bootstrap\Coordinator;
use OC\Collaboration\Reference\File\FileReferenceProvider;
use OCP\Collaboration\Reference\IDiscoverableReferenceProvider;
+use OCP\Collaboration\Reference\IPublicReferenceProvider;
use OCP\Collaboration\Reference\IReference;
use OCP\Collaboration\Reference\IReferenceManager;
use OCP\Collaboration\Reference\IReferenceProvider;
@@ -75,14 +60,14 @@ class ReferenceManager implements IReferenceManager {
/**
* Try to get a cached reference object from a reference string
*/
- public function getReferenceFromCache(string $referenceId): ?IReference {
- $matchedProvider = $this->getMatchedProvider($referenceId);
+ public function getReferenceFromCache(string $referenceId, bool $public = false, string $sharingToken = ''): ?IReference {
+ $matchedProvider = $this->getMatchedProvider($referenceId, $public);
if ($matchedProvider === null) {
return null;
}
- $cacheKey = $this->getFullCacheKey($matchedProvider, $referenceId);
+ $cacheKey = $this->getFullCacheKey($matchedProvider, $referenceId, $public, $sharingToken);
return $this->getReferenceByCacheKey($cacheKey);
}
@@ -102,21 +87,31 @@ class ReferenceManager implements IReferenceManager {
* Get a reference object from a reference string with a matching provider
* Use a cached reference if possible
*/
- public function resolveReference(string $referenceId): ?IReference {
- $matchedProvider = $this->getMatchedProvider($referenceId);
+ public function resolveReference(string $referenceId, bool $public = false, $sharingToken = ''): ?IReference {
+ $matchedProvider = $this->getMatchedProvider($referenceId, $public);
if ($matchedProvider === null) {
return null;
}
- $cacheKey = $this->getFullCacheKey($matchedProvider, $referenceId);
+ $cacheKey = $this->getFullCacheKey($matchedProvider, $referenceId, $public, $sharingToken);
$cached = $this->cache->get($cacheKey);
if ($cached) {
return Reference::fromCache($cached);
}
- $reference = $matchedProvider->resolveReference($referenceId);
+ $reference = null;
+ if ($public && $matchedProvider instanceof IPublicReferenceProvider) {
+ $reference = $matchedProvider->resolveReferencePublic($referenceId, $sharingToken);
+ } elseif ($matchedProvider instanceof IReferenceProvider) {
+ $reference = $matchedProvider->resolveReference($referenceId);
+ }
if ($reference) {
+ $cachePrefix = $matchedProvider->getCachePrefix($referenceId);
+ if ($cachePrefix !== '') {
+ // If a prefix is used we set an additional key to know when we need to delete by prefix during invalidateCache()
+ $this->cache->set('hasPrefix-' . md5($cachePrefix), true, self::CACHE_TTL);
+ }
$this->cache->set($cacheKey, Reference::toCache($reference), self::CACHE_TTL);
return $reference;
}
@@ -128,11 +123,14 @@ class ReferenceManager implements IReferenceManager {
* Try to match a reference string with all the registered providers
* Fallback to the link reference provider (using OpenGraph)
*
- * @return IReferenceProvider|null the first matching provider
+ * @return IReferenceProvider|IPublicReferenceProvider|null the first matching provider
*/
- private function getMatchedProvider(string $referenceId): ?IReferenceProvider {
+ private function getMatchedProvider(string $referenceId, bool $public): null|IReferenceProvider|IPublicReferenceProvider {
$matchedProvider = null;
foreach ($this->getProviders() as $provider) {
+ if ($public && !($provider instanceof IPublicReferenceProvider)) {
+ continue;
+ }
$matchedProvider = $provider->matchReference($referenceId) ? $provider : null;
if ($matchedProvider !== null) {
break;
@@ -149,8 +147,13 @@ class ReferenceManager implements IReferenceManager {
/**
* Get a hashed full cache key from a key and prefix given by a provider
*/
- private function getFullCacheKey(IReferenceProvider $provider, string $referenceId): string {
- $cacheKey = $provider->getCacheKey($referenceId);
+ private function getFullCacheKey(IReferenceProvider $provider, string $referenceId, bool $public, string $sharingToken): string {
+ if ($public && !($provider instanceof IPublicReferenceProvider)) {
+ throw new \RuntimeException('Provider doesn\'t support public lookups');
+ }
+ $cacheKey = $public
+ ? $provider->getCacheKeyPublic($referenceId, $sharingToken)
+ : $provider->getCacheKey($referenceId);
return md5($provider->getCachePrefix($referenceId)) . (
$cacheKey !== null ? ('-' . md5($cacheKey)) : ''
);
@@ -161,7 +164,11 @@ class ReferenceManager implements IReferenceManager {
*/
public function invalidateCache(string $cachePrefix, ?string $cacheKey = null): void {
if ($cacheKey === null) {
- $this->cache->clear(md5($cachePrefix));
+ // clear might be a heavy operation, so we only do it if there have actually been keys set
+ if ($this->cache->remove('hasPrefix-' . md5($cachePrefix))) {
+ $this->cache->clear(md5($cachePrefix));
+ }
+
return;
}
@@ -224,7 +231,7 @@ class ReferenceManager implements IReferenceManager {
}
$configKey = 'provider-last-use_' . $providerId;
- $this->config->setUserValue($userId, 'references', $configKey, (string) $timestamp);
+ $this->config->setUserValue($userId, 'references', $configKey, (string)$timestamp);
return true;
}
return false;
@@ -247,7 +254,7 @@ class ReferenceManager implements IReferenceManager {
$timestamps = [];
foreach ($keys as $key) {
$providerId = substr($key, strlen($prefix));
- $timestamp = (int) $this->config->getUserValue($userId, 'references', $key);
+ $timestamp = (int)$this->config->getUserValue($userId, 'references', $key);
$timestamps[$providerId] = $timestamp;
}
return $timestamps;