diff options
author | Jonas <jonas@freesources.org> | 2024-07-08 11:29:26 +0200 |
---|---|---|
committer | Jonas <jonas@freesources.org> | 2024-07-17 12:56:41 +0200 |
commit | 1671bf3ef219dd641b51b4d154ea701c6a7cf6b9 (patch) | |
tree | 70b971f9fea1968d7ec3c48b71dd5d1522500922 /lib/private/Collaboration | |
parent | b06ce832d8f280b9c008b91c41757e8eab37dc77 (diff) | |
download | nextcloud-server-1671bf3ef219dd641b51b4d154ea701c6a7cf6b9.tar.gz nextcloud-server-1671bf3ef219dd641b51b4d154ea701c6a7cf6b9.zip |
feat(Reference): Add public API endpoints to get references
Calling the public API endpoints will check for matching registered
reference providers that implement `IPublicReferenceProvider` and call
their respective functions. If no matching provider is found, the
default `LinkReferenceProvider` will be used to provide open graph data.
The frontend reference widget components will call these endpoints from
unauthorized sessions, e.g. in public shares.
If present, the sharing token of the origin URL is passed to
`resolveReferencePublic()` as additional information for the reference
provider to determine the access scope. This allows the respective
reference providers to determine whether the origin share has access to
the linked resource.
`getCacheKeyPublic` also gets the sharing token so it can scope the cached
entry to it.
Contributes to #45978
Signed-off-by: Jonas <jonas@freesources.org>
Diffstat (limited to 'lib/private/Collaboration')
-rw-r--r-- | lib/private/Collaboration/Reference/ReferenceManager.php | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/lib/private/Collaboration/Reference/ReferenceManager.php b/lib/private/Collaboration/Reference/ReferenceManager.php index 208c50a074b..5a1b39d9dff 100644 --- a/lib/private/Collaboration/Reference/ReferenceManager.php +++ b/lib/private/Collaboration/Reference/ReferenceManager.php @@ -11,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; @@ -59,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); } @@ -86,20 +87,25 @@ 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 !== '') { @@ -117,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; @@ -138,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)) : '' ); |