aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Collaboration
diff options
context:
space:
mode:
authorJulius Härtl <jus@bitgrid.net>2022-08-28 20:54:21 +0200
committerJulius Härtl <jus@bitgrid.net>2022-08-31 16:24:33 +0200
commita392235e23c3b8af1d0eba4dbac18b18de826a1c (patch)
treec983c213d99937bb53463e759d703d85861fb631 /lib/private/Collaboration
parentbee8fd2408b053756e052a2b96899935c1adf872 (diff)
downloadnextcloud-server-a392235e23c3b8af1d0eba4dbac18b18de826a1c.tar.gz
nextcloud-server-a392235e23c3b8af1d0eba4dbac18b18de826a1c.zip
Cleanup
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Diffstat (limited to 'lib/private/Collaboration')
-rw-r--r--lib/private/Collaboration/Reference/FileReferenceProvider.php62
-rw-r--r--lib/private/Collaboration/Reference/LinkReferenceProvider.php23
-rw-r--r--lib/private/Collaboration/Reference/Reference.php12
-rw-r--r--lib/private/Collaboration/Reference/ReferenceManager.php17
4 files changed, 73 insertions, 41 deletions
diff --git a/lib/private/Collaboration/Reference/FileReferenceProvider.php b/lib/private/Collaboration/Reference/FileReferenceProvider.php
index 9a4bd65249f..358092ff508 100644
--- a/lib/private/Collaboration/Reference/FileReferenceProvider.php
+++ b/lib/private/Collaboration/Reference/FileReferenceProvider.php
@@ -1,4 +1,6 @@
<?php
+
+declare(strict_types=1);
/**
* @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
*
@@ -22,11 +24,15 @@
namespace OC\Collaboration\Reference;
+use OC\User\NoUserException;
use OCP\Collaboration\Reference\IReference;
use OCP\Collaboration\Reference\IReferenceProvider;
+use OCP\Files\InvalidPathException;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
+use OCP\Files\NotPermittedException;
+use OCP\IPreview;
use OCP\IURLGenerator;
use OCP\IUserSession;
@@ -34,11 +40,13 @@ class FileReferenceProvider implements IReferenceProvider {
private IURLGenerator $urlGenerator;
private IRootFolder $rootFolder;
private ?string $userId;
+ private IPreview $previewManager;
- public function __construct(IURLGenerator $urlGenerator, IRootFolder $rootFolder, IUserSession $userSession) {
+ public function __construct(IURLGenerator $urlGenerator, IRootFolder $rootFolder, IUserSession $userSession, IPreview $previewManager) {
$this->urlGenerator = $urlGenerator;
$this->rootFolder = $rootFolder;
$this->userId = $userSession->getUser() ? $userSession->getUser()->getUID() : null;
+ $this->previewManager = $previewManager;
}
public function matchReference(string $referenceText): bool {
@@ -52,6 +60,7 @@ class FileReferenceProvider implements IReferenceProvider {
try {
$this->fetchReference($reference);
} catch (NotFoundException $e) {
+ $reference->setRichObject('file', null);
$reference->setAccessible(false);
}
return $reference;
@@ -61,10 +70,7 @@ class FileReferenceProvider implements IReferenceProvider {
}
/**
- * @throws \OCP\Files\NotPermittedException
- * @throws \OCP\Files\InvalidPathException
* @throws NotFoundException
- * @throws \OC\User\NoUserException
*/
private function fetchReference(Reference $reference) {
if ($this->userId === null) {
@@ -74,30 +80,34 @@ class FileReferenceProvider implements IReferenceProvider {
$fileId = str_replace($this->urlGenerator->getAbsoluteURL('/index.php/f/'), '', $reference->getId());
$fileId = str_replace($this->urlGenerator->getAbsoluteURL('/f/'), '', $fileId);
- $userFolder = $this->rootFolder->getUserFolder($this->userId);
- $files = $userFolder->getById((int)$fileId);
+ try {
+ $userFolder = $this->rootFolder->getUserFolder($this->userId);
+ $files = $userFolder->getById((int)$fileId);
+
+ if (empty($files)) {
+ throw new NotFoundException();
+ }
- if (empty($files)) {
+ /** @var Node $file */
+ $file = array_shift($files);
+
+ $reference->setTitle($file->getName());
+ $reference->setDescription($file->getMimetype());
+ $reference->setUrl($this->urlGenerator->getAbsoluteURL('/index.php/f/' . $fileId));
+ $reference->setImageUrl($this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreviewByFileId', ['x' => 1600, 'y' => 630, 'fileId' => $fileId]));
+
+ $reference->setRichObject('file', [
+ 'id' => $file->getId(),
+ 'name' => $file->getName(),
+ 'size' => $file->getSize(),
+ 'path' => $file->getPath(),
+ 'link' => $reference->getUrl(),
+ 'mimetype' => $file->getMimetype(),
+ 'preview-available' => $this->previewManager->isAvailable($file)
+ ]);
+ } catch (InvalidPathException|NotFoundException|NotPermittedException|NoUserException $e) {
throw new NotFoundException();
}
-
- /** @var Node $file */
- $file = array_shift($files);
-
- $reference->setTitle($file->getName());
- $reference->setDescription($file->getMimetype());
- $reference->setUrl($this->urlGenerator->getAbsoluteURL('/index.php/f/' . $fileId));
- $reference->setImageUrl($this->urlGenerator->linkToRouteAbsolute('core.Preview.getPreviewByFileId', ['x' => 1600, 'y' => 630, 'fileId' => $fileId]));
-
- $reference->setRichObject('file', [
- 'id' => $file->getId(),
- 'name' => $file->getName(),
- 'size' => $file->getSize(),
- 'path' => $file->getPath(),
- 'link' => $reference->getUrl(),
- 'mimetype' => $file->getMimetype(),
- 'preview-available' => false
- ]);
}
public function isGloballyCacheable(): bool {
@@ -105,6 +115,6 @@ class FileReferenceProvider implements IReferenceProvider {
}
public function getCacheKey(string $referenceId): string {
- return $this->userId;
+ return $this->userId ?? '';
}
}
diff --git a/lib/private/Collaboration/Reference/LinkReferenceProvider.php b/lib/private/Collaboration/Reference/LinkReferenceProvider.php
index 74eb21b8785..7ac6aca5f89 100644
--- a/lib/private/Collaboration/Reference/LinkReferenceProvider.php
+++ b/lib/private/Collaboration/Reference/LinkReferenceProvider.php
@@ -27,6 +27,8 @@ namespace OC\Collaboration\Reference;
use Fusonic\OpenGraph\Consumer;
use GuzzleHttp\Psr7\LimitStream;
use GuzzleHttp\Psr7\Utils;
+use OC\Security\RateLimiting\Exception\RateLimitExceededException;
+use OC\Security\RateLimiting\Limiter;
use OC\SystemConfig;
use OCP\Collaboration\Reference\IReference;
use OCP\Collaboration\Reference\IReferenceProvider;
@@ -37,7 +39,6 @@ use OCP\IURLGenerator;
use Psr\Log\LoggerInterface;
class LinkReferenceProvider implements IReferenceProvider {
- public const URL_PATTERN = '/(\s|^)(https?:\/\/)?((?:[-A-Z0-9+_]+\.)+[-A-Z]+(?:\/[-A-Z0-9+&@#%?=~_|!:,.;()]*)*)(\s|$)/i';
public const MAX_PREVIEW_SIZE = 1024 * 1024;
public const ALLOWED_CONTENT_TYPES = [
@@ -54,13 +55,15 @@ class LinkReferenceProvider implements IReferenceProvider {
private SystemConfig $systemConfig;
private IAppDataFactory $appDataFactory;
private IURLGenerator $urlGenerator;
+ private Limiter $limiter;
- public function __construct(IClientService $clientService, LoggerInterface $logger, SystemConfig $systemConfig, IAppDataFactory $appDataFactory, IURLGenerator $urlGenerator) {
+ public function __construct(IClientService $clientService, LoggerInterface $logger, SystemConfig $systemConfig, IAppDataFactory $appDataFactory, IURLGenerator $urlGenerator, Limiter $limiter) {
$this->clientService = $clientService;
$this->logger = $logger;
$this->systemConfig = $systemConfig;
$this->appDataFactory = $appDataFactory;
$this->urlGenerator = $urlGenerator;
+ $this->limiter = $limiter;
}
public function matchReference(string $referenceText): bool {
@@ -68,7 +71,7 @@ class LinkReferenceProvider implements IReferenceProvider {
return false;
}
- return (bool)preg_match(self::URL_PATTERN, $referenceText);
+ return (bool)preg_match(IURLGenerator::URL_REGEX, $referenceText);
}
public function resolveReference(string $referenceText): ?IReference {
@@ -82,6 +85,17 @@ class LinkReferenceProvider implements IReferenceProvider {
}
private function fetchReference(Reference $reference) {
+ try {
+ $user = \OC::$server->getUserSession()->getUser();
+ if ($user) {
+ $this->limiter->registerUserRequest('opengraph', 10, 120, $user);
+ } else {
+ $this->limiter->registerAnonRequest('opengraph', 10, 120, \OC::$server->getRequest()->getRemoteAddress());
+ }
+ } catch (RateLimitExceededException $e) {
+ return;
+ }
+
$client = $this->clientService->newClient();
try {
$response = $client->get($reference->getId(), [ 'timeout' => 10 ]);
@@ -118,12 +132,11 @@ class LinkReferenceProvider implements IReferenceProvider {
$contentType = $response->getHeader('Content-Type');
$contentLength = $response->getHeader('Content-Length');
-
if (in_array($contentType, self::ALLOWED_CONTENT_TYPES, true) && $contentLength < self::MAX_PREVIEW_SIZE) {
$stream = Utils::streamFor($response->getBody());
$bodyStream = new LimitStream($stream, self::MAX_PREVIEW_SIZE, 0);
$reference->setImageContentType($contentType);
- $folder->newFile(md5($reference->getId()), $bodyStream);
+ $folder->newFile(md5($reference->getId()), $bodyStream->getContents());
$reference->setImageUrl($this->urlGenerator->linkToRouteAbsolute('core.Reference.preview', ['referenceId' => md5($reference->getId())]));
}
} catch (\Throwable $e) {
diff --git a/lib/private/Collaboration/Reference/Reference.php b/lib/private/Collaboration/Reference/Reference.php
index 69ce7fc9597..22dc57782d8 100644
--- a/lib/private/Collaboration/Reference/Reference.php
+++ b/lib/private/Collaboration/Reference/Reference.php
@@ -53,6 +53,10 @@ class Reference implements IReference {
$this->accessible = $accessible;
}
+ public function getAccessible(): bool {
+ return $this->accessible;
+ }
+
public function setTitle(string $title): void {
$this->title = $title;
}
@@ -93,20 +97,20 @@ class Reference implements IReference {
return $this->url;
}
- public function setRichObject(string $type, array $richObject): void {
+ public function setRichObject(string $type, ?array $richObject): void {
$this->richObjectType = $type;
$this->richObject = $richObject;
}
public function getRichObjectType(): string {
- if (!$this->richObjectType) {
+ if ($this->richObjectType === null) {
return 'open-graph';
}
return $this->richObjectType;
}
public function getRichObject(): array {
- if (!$this->richObject) {
+ if ($this->richObject === null) {
return $this->getOpenGraphObject();
}
return $this->richObject;
@@ -130,7 +134,7 @@ class Reference implements IReference {
'imageContentType' => $reference->getImageContentType(),
'description' => $reference->getDescription(),
'link' => $reference->getUrl(),
- 'accessible' => $reference->accessible,
+ 'accessible' => $reference->getAccessible(),
'richObjectType' => $reference->getRichObjectType(),
'richObject' => $reference->getRichObject(),
];
diff --git a/lib/private/Collaboration/Reference/ReferenceManager.php b/lib/private/Collaboration/Reference/ReferenceManager.php
index 1bd9bfac0b8..471f0efb3be 100644
--- a/lib/private/Collaboration/Reference/ReferenceManager.php
+++ b/lib/private/Collaboration/Reference/ReferenceManager.php
@@ -30,12 +30,12 @@ use OCP\Collaboration\Reference\IReferenceManager;
use OCP\Collaboration\Reference\IReferenceProvider;
use OCP\ICache;
use OCP\ICacheFactory;
+use OCP\IURLGenerator;
use Psr\Container\ContainerInterface;
+use Psr\Log\LoggerInterface;
use Throwable;
-use function OCP\Log\logger;
class ReferenceManager implements IReferenceManager {
- public const URL_PATTERN = '/(\s|\n|^)(https?:\/\/)?((?:[-A-Z0-9+_]+\.)+[-A-Z]+(?:\/[-A-Z0-9+&@#%?=~_|!:,.;()]*)*)(\s|\n|$)/mi';
public const CACHE_TTL = 60;
/** @var IReferenceProvider[]|null */
@@ -43,16 +43,19 @@ class ReferenceManager implements IReferenceManager {
private ICache $cache;
private Coordinator $coordinator;
private ContainerInterface $container;
+ private LinkReferenceProvider $linkReferenceProvider;
+ private LoggerInterface $logger;
- public function __construct(LinkReferenceProvider $linkReferenceProvider, ICacheFactory $cacheFactory, Coordinator $coordinator, ContainerInterface $container) {
+ public function __construct(LinkReferenceProvider $linkReferenceProvider, ICacheFactory $cacheFactory, Coordinator $coordinator, ContainerInterface $container, LoggerInterface $logger) {
$this->linkReferenceProvider = $linkReferenceProvider;
$this->cache = $cacheFactory->createDistributed('reference');
$this->coordinator = $coordinator;
$this->container = $container;
+ $this->logger = $logger;
}
public function extractReferences(string $text): array {
- preg_match_all(self::URL_PATTERN, $text, $matches);
+ preg_match_all(IURLGenerator::URL_REGEX, $text, $matches);
$references = $matches[0] ?? [];
return array_map(function ($reference) {
return trim($reference);
@@ -94,6 +97,9 @@ class ReferenceManager implements IReferenceManager {
$matchedProvider = null;
foreach ($this->getProviders() as $provider) {
$matchedProvider = $provider->matchReference($referenceId) ? $provider : null;
+ if ($matchedProvider !== null) {
+ break;
+ }
}
if ($matchedProvider === null && $this->linkReferenceProvider->matchReference($referenceId)) {
@@ -141,7 +147,7 @@ class ReferenceManager implements IReferenceManager {
/** @var IReferenceProvider $provider */
$provider = $this->container->get($registration->getService());
} catch (Throwable $e) {
- logger()->error('Could not load reference provider ' . $registration->getService() . ': ' . $e->getMessage(), [
+ $this->logger->error('Could not load reference provider ' . $registration->getService() . ': ' . $e->getMessage(), [
'exception' => $e,
]);
return null;
@@ -150,7 +156,6 @@ class ReferenceManager implements IReferenceManager {
return $provider;
}, $context->getReferenceProviders()));
- // TODO: Move to files app
$this->providers[] = $this->container->get(FileReferenceProvider::class);
}