aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Collaboration
diff options
context:
space:
mode:
authorJonas <jonas@freesources.org>2024-07-08 11:29:26 +0200
committerJonas <jonas@freesources.org>2024-07-17 12:56:41 +0200
commit1671bf3ef219dd641b51b4d154ea701c6a7cf6b9 (patch)
tree70b971f9fea1968d7ec3c48b71dd5d1522500922 /lib/private/Collaboration
parentb06ce832d8f280b9c008b91c41757e8eab37dc77 (diff)
downloadnextcloud-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.php36
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)) : ''
);