From d89108994537400b3496fd6e4e19fcfeabda7500 Mon Sep 17 00:00:00 2001 From: Diogo Peralta Cordeiro Date: Sun, 26 Dec 2021 20:20:03 +0000 Subject: [PATCH] [PLUGIN][StoreRemoteMedia] Let the user decide the max file size to download --- plugins/Embed/Embed.php | 23 ++++-------- plugins/StoreRemoteMedia/StoreRemoteMedia.php | 35 +++++++++++++------ social.yaml | 2 +- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/plugins/Embed/Embed.php b/plugins/Embed/Embed.php index b888655f95..5af8046518 100644 --- a/plugins/Embed/Embed.php +++ b/plugins/Embed/Embed.php @@ -97,19 +97,11 @@ class Embed extends Plugin public ?int $max_size; public ?bool $smart_crop; - private function getStoreImage(): bool - { - return $this->store_image; - } + // TODO: storeThumbs setting - private function getMaxSize(): int + private function getMaxFileSize(): int { - return $this->max_size ?? Common::config('attachments', 'file_quota'); - } - - private function getSmartCrop(): bool - { - return $this->smart_crop ?? Common::config('thumbnail', 'smart_crop'); + return min(Common::config('plugin_embed', 'max_file_size'), Common::config('attachments', 'file_quota')); } /** @@ -209,7 +201,7 @@ class Embed extends Plugin $attachment->livesIncrementAndGet(); return Event::next; } catch (DuplicateFoundException|NotFoundException $e) { - Log::error($e); + Log::error($e->getMessage(), context: [$e]); } } @@ -356,10 +348,9 @@ class Embed extends Plugin try { $headers = $head->getHeaders(); } catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) { - Log::debug('Embed->downloadThumbnail@HTTPHead->getHeaders: ' . $e->getMessage()); + Log::debug('Embed->downloadThumbnail@HTTPHead->getHeaders: ' . $e->getMessage(), [$e]); return null; } - $headers = array_change_key_case($headers, \CASE_LOWER); if (empty($headers['content-type']) || GSFile::mimetypeMajor($headers['content-type'][0]) !== 'image') { Log::debug("URL ({$url}) doesn't point to an image (content-type: " . (!empty($headers['content-type'][0]) ? $headers['content-type'][0] : 'not available') . ') in Embed->downloadThumbnail.'); return null; @@ -367,9 +358,9 @@ class Embed extends Plugin // Does it respect the file quota? $file_size = $headers['content-length'][0] ?? null; - $max_size = Common::config('attachments', 'file_quota'); + $max_size = $this->getMaxFileSize(); if (\is_null($file_size) || $file_size > $max_size) { - Log::debug("Went to download remote thumbnail of size {$file_size} but the upload limit is {$max_size} so we aborted in Embed->downloadThumbnail."); + Log::debug("Went to download remote thumbnail of size {$file_size} but the plugin's filesize limit is {$max_size} so we aborted in Embed->downloadThumbnail."); return false; } diff --git a/plugins/StoreRemoteMedia/StoreRemoteMedia.php b/plugins/StoreRemoteMedia/StoreRemoteMedia.php index 6e83204446..1de558eca7 100644 --- a/plugins/StoreRemoteMedia/StoreRemoteMedia.php +++ b/plugins/StoreRemoteMedia/StoreRemoteMedia.php @@ -37,6 +37,10 @@ use Component\Attachment\Entity\AttachmentThumbnail; use Component\Attachment\Entity\AttachmentToLink; use Component\Attachment\Entity\AttachmentToNote; use Component\Link\Entity\Link; +use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface; +use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; /** * The StoreRemoteMedia plugin downloads remotely attached files to local server. @@ -76,19 +80,9 @@ class StoreRemoteMedia extends Plugin return Common::config('plugin_store_remote_media', 'store_original'); } - private function getThumbnailWidth(): int - { - return Common::config('thumbnail', 'width'); - } - - private function getThumbnailHeight(): int - { - return Common::config('thumbnail', 'height'); - } - private function getMaxFileSize(): int { - return Common::config('plugin_store_remote_media', 'max_file_size'); + return min(Common::config('plugin_store_remote_media', 'max_file_size'), Common::config('attachments', 'file_quota')); } private function getSmartCrop(): bool @@ -132,12 +126,31 @@ class StoreRemoteMedia extends Plugin DB::flush(); return Event::stop; } else { + // Validate if the URL really does point to a remote image + $head = HTTPClient::head($link->getUrl()); + try { + $headers = $head->getHeaders(); + } catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) { + Log::debug('StoreRemoteMedia->onNewLinkFromNote@HTTPHead->getHeaders: ' . $e->getMessage(), [$e]); + return Event::next; + } + + // Does it respect the file quota? + $file_size = $headers['content-length'][0] ?? null; + $max_size = $this->getMaxFileSize(); + if (\is_null($file_size) || $file_size > $max_size) { + Log::debug("Went to download remote media of size {$file_size} but the plugin's filesize limit is {$max_size} so we aborted in StoreRemoteMedia->onNewLinkFromNote."); + return Event::next; + } + // Retrieve media $get_response = HTTPClient::get($link->getUrl()); $media = $get_response->getContent(); $mimetype = $get_response->getHeaders()['content-type'][0] ?? null; unset($get_response); + // TODO: Add functionality to specify allowed content types to retrieve here + // Ensure we still want to handle it if ($mimetype != $link->getMimetype()) { $link->setMimetype($mimetype); diff --git a/social.yaml b/social.yaml index 94629dacc2..8dc81e9033 100644 --- a/social.yaml +++ b/social.yaml @@ -136,7 +136,7 @@ parameters: plugin_embed: max_px: 64000 - smart_crop: false + max_file_size: 4000000 theme: server: